uboot/drivers/usb/host/ehci-mx6.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
   4 * Copyright (C) 2010 Freescale Semiconductor, Inc.
   5 */
   6
   7#include <common.h>
   8#include <log.h>
   9#include <usb.h>
  10#include <errno.h>
  11#include <wait_bit.h>
  12#include <linux/compiler.h>
  13#include <linux/delay.h>
  14#include <usb/ehci-ci.h>
  15#include <asm/io.h>
  16#include <asm/arch/imx-regs.h>
  17#include <asm/arch/clock.h>
  18#include <asm/mach-imx/iomux-v3.h>
  19#include <asm/mach-imx/sys_proto.h>
  20#include <dm.h>
  21#include <asm/mach-types.h>
  22#include <power/regulator.h>
  23#include <linux/usb/otg.h>
  24
  25#include "ehci.h"
  26
  27DECLARE_GLOBAL_DATA_PTR;
  28
  29#define USB_OTGREGS_OFFSET      0x000
  30#define USB_H1REGS_OFFSET       0x200
  31#define USB_H2REGS_OFFSET       0x400
  32#define USB_H3REGS_OFFSET       0x600
  33#define USB_OTHERREGS_OFFSET    0x800
  34
  35#define USB_H1_CTRL_OFFSET      0x04
  36
  37#define USBPHY_CTRL                             0x00000030
  38#define USBPHY_CTRL_SET                         0x00000034
  39#define USBPHY_CTRL_CLR                         0x00000038
  40#define USBPHY_CTRL_TOG                         0x0000003c
  41
  42#define USBPHY_PWD                              0x00000000
  43#define USBPHY_CTRL_SFTRST                      0x80000000
  44#define USBPHY_CTRL_CLKGATE                     0x40000000
  45#define USBPHY_CTRL_ENUTMILEVEL3                0x00008000
  46#define USBPHY_CTRL_ENUTMILEVEL2                0x00004000
  47#define USBPHY_CTRL_OTG_ID                      0x08000000
  48
  49#define ANADIG_USB2_CHRG_DETECT_EN_B            0x00100000
  50#define ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B      0x00080000
  51
  52#define ANADIG_USB2_PLL_480_CTRL_BYPASS         0x00010000
  53#define ANADIG_USB2_PLL_480_CTRL_ENABLE         0x00002000
  54#define ANADIG_USB2_PLL_480_CTRL_POWER          0x00001000
  55#define ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS    0x00000040
  56
  57#define USBNC_OFFSET            0x200
  58#define USBNC_PHY_STATUS_OFFSET 0x23C
  59#define USBNC_PHYSTATUS_ID_DIG  (1 << 4) /* otg_id status */
  60#define USBNC_PHYCFG2_ACAENB    (1 << 4) /* otg_id detection enable */
  61#define UCTRL_PWR_POL           (1 << 9) /* OTG Polarity of Power Pin */
  62#define UCTRL_OVER_CUR_POL      (1 << 8) /* OTG Polarity of Overcurrent */
  63#define UCTRL_OVER_CUR_DIS      (1 << 7) /* Disable OTG Overcurrent Detection */
  64
  65/* USBCMD */
  66#define UCMD_RUN_STOP           (1 << 0) /* controller run/stop */
  67#define UCMD_RESET              (1 << 1) /* controller reset */
  68
  69#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP)
  70static const unsigned phy_bases[] = {
  71        USB_PHY0_BASE_ADDR,
  72#if defined(USB_PHY1_BASE_ADDR)
  73        USB_PHY1_BASE_ADDR,
  74#endif
  75};
  76
  77static void usb_internal_phy_clock_gate(int index, int on)
  78{
  79        void __iomem *phy_reg;
  80
  81        if (index >= ARRAY_SIZE(phy_bases))
  82                return;
  83
  84        phy_reg = (void __iomem *)phy_bases[index];
  85        phy_reg += on ? USBPHY_CTRL_CLR : USBPHY_CTRL_SET;
  86        writel(USBPHY_CTRL_CLKGATE, phy_reg);
  87}
  88
  89static void usb_power_config(int index)
  90{
  91#if defined(CONFIG_MX7ULP)
  92        struct usbphy_regs __iomem *usbphy =
  93                (struct usbphy_regs __iomem *)USB_PHY0_BASE_ADDR;
  94
  95        if (index > 0)
  96                return;
  97
  98        writel(ANADIG_USB2_CHRG_DETECT_EN_B |
  99                   ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B,
 100                   &usbphy->usb1_chrg_detect);
 101
 102        scg_enable_usb_pll(true);
 103
 104#else
 105        struct anatop_regs __iomem *anatop =
 106                (struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
 107        void __iomem *chrg_detect;
 108        void __iomem *pll_480_ctrl_clr;
 109        void __iomem *pll_480_ctrl_set;
 110
 111        switch (index) {
 112        case 0:
 113                chrg_detect = &anatop->usb1_chrg_detect;
 114                pll_480_ctrl_clr = &anatop->usb1_pll_480_ctrl_clr;
 115                pll_480_ctrl_set = &anatop->usb1_pll_480_ctrl_set;
 116                break;
 117        case 1:
 118                chrg_detect = &anatop->usb2_chrg_detect;
 119                pll_480_ctrl_clr = &anatop->usb2_pll_480_ctrl_clr;
 120                pll_480_ctrl_set = &anatop->usb2_pll_480_ctrl_set;
 121                break;
 122        default:
 123                return;
 124        }
 125        /*
 126         * Some phy and power's special controls
 127         * 1. The external charger detector needs to be disabled
 128         * or the signal at DP will be poor
 129         * 2. The PLL's power and output to usb
 130         * is totally controlled by IC, so the Software only needs
 131         * to enable them at initializtion.
 132         */
 133        writel(ANADIG_USB2_CHRG_DETECT_EN_B |
 134                     ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B,
 135                     chrg_detect);
 136
 137        writel(ANADIG_USB2_PLL_480_CTRL_BYPASS,
 138                     pll_480_ctrl_clr);
 139
 140        writel(ANADIG_USB2_PLL_480_CTRL_ENABLE |
 141                     ANADIG_USB2_PLL_480_CTRL_POWER |
 142                     ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS,
 143                     pll_480_ctrl_set);
 144
 145#endif
 146}
 147
 148/* Return 0 : host node, <>0 : device mode */
 149static int usb_phy_enable(int index, struct usb_ehci *ehci)
 150{
 151        void __iomem *phy_reg;
 152        void __iomem *phy_ctrl;
 153        void __iomem *usb_cmd;
 154        int ret;
 155
 156        if (index >= ARRAY_SIZE(phy_bases))
 157                return 0;
 158
 159        phy_reg = (void __iomem *)phy_bases[index];
 160        phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL);
 161        usb_cmd = (void __iomem *)&ehci->usbcmd;
 162
 163        /* Stop then Reset */
 164        clrbits_le32(usb_cmd, UCMD_RUN_STOP);
 165        ret = wait_for_bit_le32(usb_cmd, UCMD_RUN_STOP, false, 10000, false);
 166        if (ret)
 167                return ret;
 168
 169        setbits_le32(usb_cmd, UCMD_RESET);
 170        ret = wait_for_bit_le32(usb_cmd, UCMD_RESET, false, 10000, false);
 171        if (ret)
 172                return ret;
 173
 174        /* Reset USBPHY module */
 175        setbits_le32(phy_ctrl, USBPHY_CTRL_SFTRST);
 176        udelay(10);
 177
 178        /* Remove CLKGATE and SFTRST */
 179        clrbits_le32(phy_ctrl, USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST);
 180        udelay(10);
 181
 182        /* Power up the PHY */
 183        writel(0, phy_reg + USBPHY_PWD);
 184        /* enable FS/LS device */
 185        setbits_le32(phy_ctrl, USBPHY_CTRL_ENUTMILEVEL2 |
 186                        USBPHY_CTRL_ENUTMILEVEL3);
 187
 188        return 0;
 189}
 190
 191int usb_phy_mode(int port)
 192{
 193        void __iomem *phy_reg;
 194        void __iomem *phy_ctrl;
 195        u32 val;
 196
 197        phy_reg = (void __iomem *)phy_bases[port];
 198        phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL);
 199
 200        val = readl(phy_ctrl);
 201
 202        if (val & USBPHY_CTRL_OTG_ID)
 203                return USB_INIT_DEVICE;
 204        else
 205                return USB_INIT_HOST;
 206}
 207
 208#if defined(CONFIG_MX7ULP)
 209struct usbnc_regs {
 210        u32 ctrl1;
 211        u32 ctrl2;
 212        u32 reserve0[2];
 213        u32 hsic_ctrl;
 214};
 215#else
 216/* Base address for this IP block is 0x02184800 */
 217struct usbnc_regs {
 218        u32     ctrl[4];        /* otg/host1-3 */
 219        u32     uh2_hsic_ctrl;
 220        u32     uh3_hsic_ctrl;
 221        u32     otg_phy_ctrl_0;
 222        u32     uh1_phy_ctrl_0;
 223};
 224#endif
 225
 226#elif defined(CONFIG_MX7)
 227struct usbnc_regs {
 228        u32 ctrl1;
 229        u32 ctrl2;
 230        u32 reserve1[10];
 231        u32 phy_cfg1;
 232        u32 phy_cfg2;
 233        u32 reserve2;
 234        u32 phy_status;
 235        u32 reserve3[4];
 236        u32 adp_cfg1;
 237        u32 adp_cfg2;
 238        u32 adp_status;
 239};
 240
 241static void usb_power_config(int index)
 242{
 243        struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR +
 244                        (0x10000 * index) + USBNC_OFFSET);
 245        void __iomem *phy_cfg2 = (void __iomem *)(&usbnc->phy_cfg2);
 246
 247        /*
 248         * Clear the ACAENB to enable usb_otg_id detection,
 249         * otherwise it is the ACA detection enabled.
 250         */
 251        clrbits_le32(phy_cfg2, USBNC_PHYCFG2_ACAENB);
 252}
 253
 254int usb_phy_mode(int port)
 255{
 256        struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR +
 257                        (0x10000 * port) + USBNC_OFFSET);
 258        void __iomem *status = (void __iomem *)(&usbnc->phy_status);
 259        u32 val;
 260
 261        val = readl(status);
 262
 263        if (val & USBNC_PHYSTATUS_ID_DIG)
 264                return USB_INIT_DEVICE;
 265        else
 266                return USB_INIT_HOST;
 267}
 268#endif
 269
 270static void usb_oc_config(int index)
 271{
 272#if defined(CONFIG_MX6)
 273        struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR +
 274                        USB_OTHERREGS_OFFSET);
 275        void __iomem *ctrl = (void __iomem *)(&usbnc->ctrl[index]);
 276#elif defined(CONFIG_MX7) || defined(CONFIG_MX7ULP)
 277        struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR +
 278                        (0x10000 * index) + USBNC_OFFSET);
 279        void __iomem *ctrl = (void __iomem *)(&usbnc->ctrl1);
 280#endif
 281
 282#if CONFIG_MACH_TYPE == MACH_TYPE_MX6Q_ARM2
 283        /* mx6qarm2 seems to required a different setting*/
 284        clrbits_le32(ctrl, UCTRL_OVER_CUR_POL);
 285#else
 286        setbits_le32(ctrl, UCTRL_OVER_CUR_POL);
 287#endif
 288
 289        setbits_le32(ctrl, UCTRL_OVER_CUR_DIS);
 290
 291        /* Set power polarity to high active */
 292#ifdef CONFIG_MXC_USB_OTG_HACTIVE
 293        setbits_le32(ctrl, UCTRL_PWR_POL);
 294#else
 295        clrbits_le32(ctrl, UCTRL_PWR_POL);
 296#endif
 297}
 298
 299/**
 300 * board_usb_phy_mode - override usb phy mode
 301 * @port:       usb host/otg port
 302 *
 303 * Target board specific, override usb_phy_mode.
 304 * When usb-otg is used as usb host port, iomux pad usb_otg_id can be
 305 * left disconnected in this case usb_phy_mode will not be able to identify
 306 * the phy mode that usb port is used.
 307 * Machine file overrides board_usb_phy_mode.
 308 *
 309 * Return: USB_INIT_DEVICE or USB_INIT_HOST
 310 */
 311int __weak board_usb_phy_mode(int port)
 312{
 313        return usb_phy_mode(port);
 314}
 315
 316/**
 317 * board_ehci_hcd_init - set usb vbus voltage
 318 * @port:      usb otg port
 319 *
 320 * Target board specific, setup iomux pad to setup supply vbus voltage
 321 * for usb otg port. Machine board file overrides board_ehci_hcd_init
 322 *
 323 * Return: 0 Success
 324 */
 325int __weak board_ehci_hcd_init(int port)
 326{
 327        return 0;
 328}
 329
 330/**
 331 * board_ehci_power - enables/disables usb vbus voltage
 332 * @port:      usb otg port
 333 * @on:        on/off vbus voltage
 334 *
 335 * Enables/disables supply vbus voltage for usb otg port.
 336 * Machine board file overrides board_ehci_power
 337 *
 338 * Return: 0 Success
 339 */
 340int __weak board_ehci_power(int port, int on)
 341{
 342        return 0;
 343}
 344
 345int ehci_mx6_common_init(struct usb_ehci *ehci, int index)
 346{
 347        int ret;
 348
 349        enable_usboh3_clk(1);
 350        mdelay(1);
 351
 352        /* Do board specific initialization */
 353        ret = board_ehci_hcd_init(index);
 354        if (ret)
 355                return ret;
 356
 357        usb_power_config(index);
 358        usb_oc_config(index);
 359
 360#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP)
 361        usb_internal_phy_clock_gate(index, 1);
 362        usb_phy_enable(index, ehci);
 363#endif
 364
 365        return 0;
 366}
 367
 368#if !CONFIG_IS_ENABLED(DM_USB)
 369int ehci_hcd_init(int index, enum usb_init_type init,
 370                struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 371{
 372        enum usb_init_type type;
 373#if defined(CONFIG_MX6)
 374        u32 controller_spacing = 0x200;
 375#elif defined(CONFIG_MX7) || defined(CONFIG_MX7ULP)
 376        u32 controller_spacing = 0x10000;
 377#endif
 378        struct usb_ehci *ehci = (struct usb_ehci *)(USB_BASE_ADDR +
 379                (controller_spacing * index));
 380        int ret;
 381
 382        if (index > 3)
 383                return -EINVAL;
 384
 385        if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) {
 386                if (usb_fused((ulong)ehci)) {
 387                        printf("SoC fuse indicates USB@0x%lx is unavailable.\n",
 388                               (ulong)ehci);
 389                        return  -ENODEV;
 390                }
 391        }
 392
 393        ret = ehci_mx6_common_init(ehci, index);
 394        if (ret)
 395                return ret;
 396
 397        type = board_usb_phy_mode(index);
 398
 399        if (hccr && hcor) {
 400                *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
 401                *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
 402                                HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 403        }
 404
 405        if ((type == init) || (type == USB_INIT_DEVICE))
 406                board_ehci_power(index, (type == USB_INIT_DEVICE) ? 0 : 1);
 407        if (type != init)
 408                return -ENODEV;
 409        if (type == USB_INIT_DEVICE)
 410                return 0;
 411
 412        setbits_le32(&ehci->usbmode, CM_HOST);
 413        writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
 414        setbits_le32(&ehci->portsc, USB_EN);
 415
 416        mdelay(10);
 417
 418        return 0;
 419}
 420
 421int ehci_hcd_stop(int index)
 422{
 423        return 0;
 424}
 425#else
 426struct ehci_mx6_priv_data {
 427        struct ehci_ctrl ctrl;
 428        struct usb_ehci *ehci;
 429        struct udevice *vbus_supply;
 430        enum usb_init_type init_type;
 431        int portnr;
 432};
 433
 434static int mx6_init_after_reset(struct ehci_ctrl *dev)
 435{
 436        struct ehci_mx6_priv_data *priv = dev->priv;
 437        enum usb_init_type type = priv->init_type;
 438        struct usb_ehci *ehci = priv->ehci;
 439        int ret;
 440
 441        ret = ehci_mx6_common_init(priv->ehci, priv->portnr);
 442        if (ret)
 443                return ret;
 444
 445#if CONFIG_IS_ENABLED(DM_REGULATOR)
 446        if (priv->vbus_supply) {
 447                ret = regulator_set_enable(priv->vbus_supply,
 448                                           (type == USB_INIT_DEVICE) ?
 449                                           false : true);
 450                if (ret && ret != -ENOSYS) {
 451                        printf("Error enabling VBUS supply (ret=%i)\n", ret);
 452                        return ret;
 453                }
 454        }
 455#endif
 456
 457        if (type == USB_INIT_DEVICE)
 458                return 0;
 459
 460        setbits_le32(&ehci->usbmode, CM_HOST);
 461        writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
 462        setbits_le32(&ehci->portsc, USB_EN);
 463
 464        mdelay(10);
 465
 466        return 0;
 467}
 468
 469static const struct ehci_ops mx6_ehci_ops = {
 470        .init_after_reset = mx6_init_after_reset
 471};
 472
 473static int ehci_usb_phy_mode(struct udevice *dev)
 474{
 475        struct usb_platdata *plat = dev_get_platdata(dev);
 476        void *__iomem addr = (void *__iomem)devfdt_get_addr(dev);
 477        void *__iomem phy_ctrl, *__iomem phy_status;
 478        const void *blob = gd->fdt_blob;
 479        int offset = dev_of_offset(dev), phy_off;
 480        u32 val;
 481
 482        /*
 483         * About fsl,usbphy, Refer to
 484         * Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt.
 485         */
 486        if (is_mx6() || is_mx7ulp()) {
 487                phy_off = fdtdec_lookup_phandle(blob,
 488                                                offset,
 489                                                "fsl,usbphy");
 490                if (phy_off < 0)
 491                        return -EINVAL;
 492
 493                addr = (void __iomem *)fdtdec_get_addr(blob, phy_off,
 494                                                       "reg");
 495                if ((fdt_addr_t)addr == FDT_ADDR_T_NONE)
 496                        return -EINVAL;
 497
 498                phy_ctrl = (void __iomem *)(addr + USBPHY_CTRL);
 499                val = readl(phy_ctrl);
 500
 501                if (val & USBPHY_CTRL_OTG_ID)
 502                        plat->init_type = USB_INIT_DEVICE;
 503                else
 504                        plat->init_type = USB_INIT_HOST;
 505        } else if (is_mx7()) {
 506                phy_status = (void __iomem *)(addr +
 507                                              USBNC_PHY_STATUS_OFFSET);
 508                val = readl(phy_status);
 509
 510                if (val & USBNC_PHYSTATUS_ID_DIG)
 511                        plat->init_type = USB_INIT_DEVICE;
 512                else
 513                        plat->init_type = USB_INIT_HOST;
 514        } else {
 515                return -EINVAL;
 516        }
 517
 518        return 0;
 519}
 520
 521static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
 522{
 523        struct usb_platdata *plat = dev_get_platdata(dev);
 524        enum usb_dr_mode dr_mode;
 525
 526        dr_mode = usb_get_dr_mode(dev->node);
 527
 528        switch (dr_mode) {
 529        case USB_DR_MODE_HOST:
 530                plat->init_type = USB_INIT_HOST;
 531                break;
 532        case USB_DR_MODE_PERIPHERAL:
 533                plat->init_type = USB_INIT_DEVICE;
 534                break;
 535        case USB_DR_MODE_OTG:
 536        case USB_DR_MODE_UNKNOWN:
 537                return ehci_usb_phy_mode(dev);
 538        };
 539
 540        return 0;
 541}
 542
 543static int ehci_usb_bind(struct udevice *dev)
 544{
 545        /*
 546         * TODO:
 547         * This driver is only partly converted to DT probing and still uses
 548         * a tremendous amount of hard-coded addresses. To make things worse,
 549         * the driver depends on specific sequential indexing of controllers,
 550         * from which it derives offsets in the PHY and ANATOP register sets.
 551         *
 552         * Here we attempt to calculate these indexes from DT information as
 553         * well as we can. The USB controllers on all existing iMX6 SoCs
 554         * are placed next to each other, at addresses incremented by 0x200,
 555         * and iMX7 their addresses are shifted by 0x10000.
 556         * Thus, the index is derived from the multiple of 0x200 (0x10000 for
 557         * iMX7) offset from the first controller address.
 558         *
 559         * However, to complete conversion of this driver to DT probing, the
 560         * following has to be done:
 561         * - DM clock framework support for iMX must be implemented
 562         * - usb_power_config() has to be converted to clock framework
 563         *   -> Thus, the ad-hoc "index" variable goes away.
 564         * - USB PHY handling has to be factored out into separate driver
 565         *   -> Thus, the ad-hoc "index" variable goes away from the PHY
 566         *      code, the PHY driver must parse it's address from DT. This
 567         *      USB driver must find the PHY driver via DT phandle.
 568         *   -> usb_power_config() shall be moved to PHY driver
 569         * With these changes in place, the ad-hoc indexing goes away and
 570         * the driver is fully converted to DT probing.
 571         */
 572        u32 controller_spacing = is_mx7() ? 0x10000 : 0x200;
 573        fdt_addr_t addr = devfdt_get_addr_index(dev, 0);
 574
 575        dev->req_seq = (addr - USB_BASE_ADDR) / controller_spacing;
 576
 577        return 0;
 578}
 579
 580static int ehci_usb_probe(struct udevice *dev)
 581{
 582        struct usb_platdata *plat = dev_get_platdata(dev);
 583        struct usb_ehci *ehci = (struct usb_ehci *)devfdt_get_addr(dev);
 584        struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
 585        enum usb_init_type type = plat->init_type;
 586        struct ehci_hccr *hccr;
 587        struct ehci_hcor *hcor;
 588        int ret;
 589
 590        if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) {
 591                if (usb_fused((ulong)ehci)) {
 592                        printf("SoC fuse indicates USB@0x%lx is unavailable.\n",
 593                               (ulong)ehci);
 594                        return -ENODEV;
 595                }
 596        }
 597
 598        priv->ehci = ehci;
 599        priv->portnr = dev->seq;
 600        priv->init_type = type;
 601
 602#if CONFIG_IS_ENABLED(DM_REGULATOR)
 603        ret = device_get_supply_regulator(dev, "vbus-supply",
 604                                          &priv->vbus_supply);
 605        if (ret)
 606                debug("%s: No vbus supply\n", dev->name);
 607#endif
 608        ret = ehci_mx6_common_init(ehci, priv->portnr);
 609        if (ret)
 610                return ret;
 611
 612#if CONFIG_IS_ENABLED(DM_REGULATOR)
 613        if (priv->vbus_supply) {
 614                ret = regulator_set_enable(priv->vbus_supply,
 615                                           (type == USB_INIT_DEVICE) ?
 616                                           false : true);
 617                if (ret && ret != -ENOSYS) {
 618                        printf("Error enabling VBUS supply (ret=%i)\n", ret);
 619                        return ret;
 620                }
 621        }
 622#endif
 623
 624        if (priv->init_type == USB_INIT_HOST) {
 625                setbits_le32(&ehci->usbmode, CM_HOST);
 626                writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
 627                setbits_le32(&ehci->portsc, USB_EN);
 628        }
 629
 630        mdelay(10);
 631
 632        hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
 633        hcor = (struct ehci_hcor *)((uint32_t)hccr +
 634                        HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
 635
 636        return ehci_register(dev, hccr, hcor, &mx6_ehci_ops, 0, priv->init_type);
 637}
 638
 639static const struct udevice_id mx6_usb_ids[] = {
 640        { .compatible = "fsl,imx27-usb" },
 641        { }
 642};
 643
 644U_BOOT_DRIVER(usb_mx6) = {
 645        .name   = "ehci_mx6",
 646        .id     = UCLASS_USB,
 647        .of_match = mx6_usb_ids,
 648        .ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
 649        .bind   = ehci_usb_bind,
 650        .probe  = ehci_usb_probe,
 651        .remove = ehci_deregister,
 652        .ops    = &ehci_usb_ops,
 653        .platdata_auto_alloc_size = sizeof(struct usb_platdata),
 654        .priv_auto_alloc_size = sizeof(struct ehci_mx6_priv_data),
 655        .flags  = DM_FLAG_ALLOC_PRIV_DMA,
 656};
 657#endif
 658