uboot/drivers/usb/host/ehci-mx5.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
   3 * Copyright (C) 2010 Freescale Semiconductor, Inc.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <usb.h>
  10#include <errno.h>
  11#include <linux/compiler.h>
  12#include <usb/ehci-fsl.h>
  13#include <asm/io.h>
  14#include <asm/arch/imx-regs.h>
  15#include <asm/arch/clock.h>
  16
  17#include "ehci.h"
  18
  19#define MX5_USBOTHER_REGS_OFFSET 0x800
  20
  21
  22#define MXC_OTG_OFFSET                  0
  23#define MXC_H1_OFFSET                   0x200
  24#define MXC_H2_OFFSET                   0x400
  25#define MXC_H3_OFFSET                   0x600
  26
  27#define MXC_USBCTRL_OFFSET              0
  28#define MXC_USB_PHY_CTR_FUNC_OFFSET     0x8
  29#define MXC_USB_PHY_CTR_FUNC2_OFFSET    0xc
  30#define MXC_USB_CTRL_1_OFFSET           0x10
  31#define MXC_USBH2CTRL_OFFSET            0x14
  32#define MXC_USBH3CTRL_OFFSET            0x18
  33
  34/* USB_CTRL */
  35/* OTG wakeup intr enable */
  36#define MXC_OTG_UCTRL_OWIE_BIT          (1 << 27)
  37/* OTG power mask */
  38#define MXC_OTG_UCTRL_OPM_BIT           (1 << 24)
  39/* OTG power pin polarity */
  40#define MXC_OTG_UCTRL_O_PWR_POL_BIT     (1 << 24)
  41/* Host1 ULPI interrupt enable */
  42#define MXC_H1_UCTRL_H1UIE_BIT          (1 << 12)
  43/* HOST1 wakeup intr enable */
  44#define MXC_H1_UCTRL_H1WIE_BIT          (1 << 11)
  45/* HOST1 power mask */
  46#define MXC_H1_UCTRL_H1PM_BIT           (1 << 8)
  47/* HOST1 power pin polarity */
  48#define MXC_H1_UCTRL_H1_PWR_POL_BIT     (1 << 8)
  49
  50/* USB_PHY_CTRL_FUNC */
  51/* OTG Polarity of Overcurrent */
  52#define MXC_OTG_PHYCTRL_OC_POL_BIT      (1 << 9)
  53/* OTG Disable Overcurrent Event */
  54#define MXC_OTG_PHYCTRL_OC_DIS_BIT      (1 << 8)
  55/* UH1 Polarity of Overcurrent */
  56#define MXC_H1_OC_POL_BIT               (1 << 6)
  57/* UH1 Disable Overcurrent Event */
  58#define MXC_H1_OC_DIS_BIT               (1 << 5)
  59/* OTG Power Pin Polarity */
  60#define MXC_OTG_PHYCTRL_PWR_POL_BIT     (1 << 3)
  61
  62/* USBH2CTRL */
  63#define MXC_H2_UCTRL_H2_OC_POL_BIT      (1 << 31)
  64#define MXC_H2_UCTRL_H2_OC_DIS_BIT      (1 << 30)
  65#define MXC_H2_UCTRL_H2UIE_BIT          (1 << 8)
  66#define MXC_H2_UCTRL_H2WIE_BIT          (1 << 7)
  67#define MXC_H2_UCTRL_H2PM_BIT           (1 << 4)
  68#define MXC_H2_UCTRL_H2_PWR_POL_BIT     (1 << 4)
  69
  70/* USBH3CTRL */
  71#define MXC_H3_UCTRL_H3_OC_POL_BIT      (1 << 31)
  72#define MXC_H3_UCTRL_H3_OC_DIS_BIT      (1 << 30)
  73#define MXC_H3_UCTRL_H3UIE_BIT          (1 << 8)
  74#define MXC_H3_UCTRL_H3WIE_BIT          (1 << 7)
  75#define MXC_H3_UCTRL_H3_PWR_POL_BIT     (1 << 4)
  76
  77/* USB_CTRL_1 */
  78#define MXC_USB_CTRL_UH1_EXT_CLK_EN     (1 << 25)
  79
  80int mxc_set_usbcontrol(int port, unsigned int flags)
  81{
  82        unsigned int v;
  83        void __iomem *usb_base = (void __iomem *)OTG_BASE_ADDR;
  84        void __iomem *usbother_base;
  85        int ret = 0;
  86
  87        usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
  88
  89        switch (port) {
  90        case 0: /* OTG port */
  91                if (flags & MXC_EHCI_INTERNAL_PHY) {
  92                        v = __raw_readl(usbother_base +
  93                                        MXC_USB_PHY_CTR_FUNC_OFFSET);
  94                        if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW)
  95                                v |= MXC_OTG_PHYCTRL_OC_POL_BIT;
  96                        else
  97                                v &= ~MXC_OTG_PHYCTRL_OC_POL_BIT;
  98                        if (flags & MXC_EHCI_POWER_PINS_ENABLED)
  99                                /* OC/USBPWR is used */
 100                                v &= ~MXC_OTG_PHYCTRL_OC_DIS_BIT;
 101                        else
 102                                /* OC/USBPWR is not used */
 103                                v |= MXC_OTG_PHYCTRL_OC_DIS_BIT;
 104#ifdef CONFIG_MX51
 105                        if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
 106                                v |= MXC_OTG_PHYCTRL_PWR_POL_BIT;
 107                        else
 108                                v &= ~MXC_OTG_PHYCTRL_PWR_POL_BIT;
 109#endif
 110                        __raw_writel(v, usbother_base +
 111                                        MXC_USB_PHY_CTR_FUNC_OFFSET);
 112
 113                        v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
 114#ifdef CONFIG_MX51
 115                        if (flags & MXC_EHCI_POWER_PINS_ENABLED)
 116                                v &= ~MXC_OTG_UCTRL_OPM_BIT;
 117                        else
 118                                v |= MXC_OTG_UCTRL_OPM_BIT;
 119#endif
 120#ifdef CONFIG_MX53
 121                        if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
 122                                v |= MXC_OTG_UCTRL_O_PWR_POL_BIT;
 123                        else
 124                                v &= ~MXC_OTG_UCTRL_O_PWR_POL_BIT;
 125#endif
 126                        __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
 127                }
 128                break;
 129        case 1: /* Host 1 ULPI */
 130#ifdef CONFIG_MX51
 131                /* The clock for the USBH1 ULPI port will come externally
 132                   from the PHY. */
 133                v = __raw_readl(usbother_base + MXC_USB_CTRL_1_OFFSET);
 134                __raw_writel(v | MXC_USB_CTRL_UH1_EXT_CLK_EN, usbother_base +
 135                                MXC_USB_CTRL_1_OFFSET);
 136#endif
 137
 138                v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
 139#ifdef CONFIG_MX51
 140                if (flags & MXC_EHCI_POWER_PINS_ENABLED)
 141                        v &= ~MXC_H1_UCTRL_H1PM_BIT; /* H1 power mask unused */
 142                else
 143                        v |= MXC_H1_UCTRL_H1PM_BIT; /* H1 power mask used */
 144#endif
 145#ifdef CONFIG_MX53
 146                if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
 147                        v |= MXC_H1_UCTRL_H1_PWR_POL_BIT;
 148                else
 149                        v &= ~MXC_H1_UCTRL_H1_PWR_POL_BIT;
 150#endif
 151                __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
 152
 153                v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
 154                if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW)
 155                        v |= MXC_H1_OC_POL_BIT;
 156                else
 157                        v &= ~MXC_H1_OC_POL_BIT;
 158                if (flags & MXC_EHCI_POWER_PINS_ENABLED)
 159                        v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */
 160                else
 161                        v |= MXC_H1_OC_DIS_BIT; /* OC is not used */
 162                __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
 163
 164                break;
 165        case 2: /* Host 2 ULPI */
 166                v = __raw_readl(usbother_base + MXC_USBH2CTRL_OFFSET);
 167#ifdef CONFIG_MX51
 168                if (flags & MXC_EHCI_POWER_PINS_ENABLED)
 169                        v &= ~MXC_H2_UCTRL_H2PM_BIT; /* H2 power mask unused */
 170                else
 171                        v |= MXC_H2_UCTRL_H2PM_BIT; /* H2 power mask used */
 172#endif
 173#ifdef CONFIG_MX53
 174                if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW)
 175                        v |= MXC_H2_UCTRL_H2_OC_POL_BIT;
 176                else
 177                        v &= ~MXC_H2_UCTRL_H2_OC_POL_BIT;
 178                if (flags & MXC_EHCI_POWER_PINS_ENABLED)
 179                        v &= ~MXC_H2_UCTRL_H2_OC_DIS_BIT; /* OC is used */
 180                else
 181                        v |= MXC_H2_UCTRL_H2_OC_DIS_BIT; /* OC is not used */
 182                if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
 183                        v |= MXC_H2_UCTRL_H2_PWR_POL_BIT;
 184                else
 185                        v &= ~MXC_H2_UCTRL_H2_PWR_POL_BIT;
 186#endif
 187                __raw_writel(v, usbother_base + MXC_USBH2CTRL_OFFSET);
 188                break;
 189#ifdef CONFIG_MX53
 190        case 3: /* Host 3 ULPI */
 191                v = __raw_readl(usbother_base + MXC_USBH3CTRL_OFFSET);
 192                if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW)
 193                        v |= MXC_H3_UCTRL_H3_OC_POL_BIT;
 194                else
 195                        v &= ~MXC_H3_UCTRL_H3_OC_POL_BIT;
 196                if (flags & MXC_EHCI_POWER_PINS_ENABLED)
 197                        v &= ~MXC_H3_UCTRL_H3_OC_DIS_BIT; /* OC is used */
 198                else
 199                        v |= MXC_H3_UCTRL_H3_OC_DIS_BIT; /* OC is not used */
 200                if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
 201                        v |= MXC_H3_UCTRL_H3_PWR_POL_BIT;
 202                else
 203                        v &= ~MXC_H3_UCTRL_H3_PWR_POL_BIT;
 204                __raw_writel(v, usbother_base + MXC_USBH3CTRL_OFFSET);
 205                break;
 206#endif
 207        }
 208
 209        return ret;
 210}
 211
 212int __weak board_ehci_hcd_init(int port)
 213{
 214        return 0;
 215}
 216
 217void __weak board_ehci_hcd_postinit(struct usb_ehci *ehci, int port)
 218{
 219}
 220
 221__weak void mx5_ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
 222                                   uint32_t *reg)
 223{
 224        mdelay(50);
 225}
 226
 227static const struct ehci_ops mx5_ehci_ops = {
 228        .powerup_fixup          = mx5_ehci_powerup_fixup,
 229};
 230
 231int ehci_hcd_init(int index, enum usb_init_type init,
 232                struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 233{
 234        struct usb_ehci *ehci;
 235
 236        /* The only user for this is efikamx-usb */
 237        ehci_set_controller_priv(index, NULL, &mx5_ehci_ops);
 238        set_usboh3_clk();
 239        enable_usboh3_clk(true);
 240        set_usb_phy_clk();
 241        enable_usb_phy1_clk(true);
 242        enable_usb_phy2_clk(true);
 243        mdelay(1);
 244
 245        /* Do board specific initialization */
 246        board_ehci_hcd_init(CONFIG_MXC_USB_PORT);
 247
 248        ehci = (struct usb_ehci *)(OTG_BASE_ADDR +
 249                (0x200 * CONFIG_MXC_USB_PORT));
 250        *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
 251        *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
 252                        HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 253        setbits_le32(&ehci->usbmode, CM_HOST);
 254
 255        __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
 256        setbits_le32(&ehci->portsc, USB_EN);
 257
 258        mxc_set_usbcontrol(CONFIG_MXC_USB_PORT, CONFIG_MXC_USB_FLAGS);
 259        mdelay(10);
 260
 261        /* Do board specific post-initialization */
 262        board_ehci_hcd_postinit(ehci, CONFIG_MXC_USB_PORT);
 263
 264        return 0;
 265}
 266
 267int ehci_hcd_stop(int index)
 268{
 269        return 0;
 270}
 271