11ca56202SWolfgang Grandegger /* 21ca56202SWolfgang Grandegger * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> 31ca56202SWolfgang Grandegger * Copyright (C) 2010 Freescale Semiconductor, Inc. 41ca56202SWolfgang Grandegger * 51ca56202SWolfgang Grandegger * This program is free software; you can redistribute it and/or modify it 61ca56202SWolfgang Grandegger * under the terms of the GNU General Public License as published by the 71ca56202SWolfgang Grandegger * Free Software Foundation; either version 2 of the License, or (at your 81ca56202SWolfgang Grandegger * option) any later version. 91ca56202SWolfgang Grandegger * 101ca56202SWolfgang Grandegger * This program is distributed in the hope that it will be useful, but 111ca56202SWolfgang Grandegger * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 121ca56202SWolfgang Grandegger * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 131ca56202SWolfgang Grandegger * for more details. 141ca56202SWolfgang Grandegger */ 151ca56202SWolfgang Grandegger 161ca56202SWolfgang Grandegger #include <common.h> 171ca56202SWolfgang Grandegger #include <usb.h> 181ca56202SWolfgang Grandegger #include <errno.h> 191ca56202SWolfgang Grandegger #include <linux/compiler.h> 201ca56202SWolfgang Grandegger #include <usb/ehci-fsl.h> 211ca56202SWolfgang Grandegger #include <asm/io.h> 221ca56202SWolfgang Grandegger #include <asm/arch/imx-regs.h> 231ca56202SWolfgang Grandegger #include <asm/arch/clock.h> 241ca56202SWolfgang Grandegger #include <asm/arch/mx5x_pins.h> 251b80f270SMarek Vasut #include <asm/arch/iomux.h> 261ca56202SWolfgang Grandegger 271ca56202SWolfgang Grandegger #include "ehci.h" 281ca56202SWolfgang Grandegger 291ca56202SWolfgang Grandegger #define MX5_USBOTHER_REGS_OFFSET 0x800 301ca56202SWolfgang Grandegger 311ca56202SWolfgang Grandegger 321ca56202SWolfgang Grandegger #define MXC_OTG_OFFSET 0 331ca56202SWolfgang Grandegger #define MXC_H1_OFFSET 0x200 341ca56202SWolfgang Grandegger #define MXC_H2_OFFSET 0x400 352cfe0b8fSBenoît Thébaudeau #define MXC_H3_OFFSET 0x600 361ca56202SWolfgang Grandegger 371ca56202SWolfgang Grandegger #define MXC_USBCTRL_OFFSET 0 381ca56202SWolfgang Grandegger #define MXC_USB_PHY_CTR_FUNC_OFFSET 0x8 391ca56202SWolfgang Grandegger #define MXC_USB_PHY_CTR_FUNC2_OFFSET 0xc 401ca56202SWolfgang Grandegger #define MXC_USB_CTRL_1_OFFSET 0x10 411ca56202SWolfgang Grandegger #define MXC_USBH2CTRL_OFFSET 0x14 422cfe0b8fSBenoît Thébaudeau #define MXC_USBH3CTRL_OFFSET 0x18 431ca56202SWolfgang Grandegger 441ca56202SWolfgang Grandegger /* USB_CTRL */ 45bdc52020SBenoît Thébaudeau /* OTG wakeup intr enable */ 46bdc52020SBenoît Thébaudeau #define MXC_OTG_UCTRL_OWIE_BIT (1 << 27) 47bdc52020SBenoît Thébaudeau /* OTG power mask */ 48bdc52020SBenoît Thébaudeau #define MXC_OTG_UCTRL_OPM_BIT (1 << 24) 4931ac2d0cSBenoît Thébaudeau /* OTG power pin polarity */ 5031ac2d0cSBenoît Thébaudeau #define MXC_OTG_UCTRL_O_PWR_POL_BIT (1 << 24) 51bdc52020SBenoît Thébaudeau /* Host1 ULPI interrupt enable */ 52bdc52020SBenoît Thébaudeau #define MXC_H1_UCTRL_H1UIE_BIT (1 << 12) 53bdc52020SBenoît Thébaudeau /* HOST1 wakeup intr enable */ 54bdc52020SBenoît Thébaudeau #define MXC_H1_UCTRL_H1WIE_BIT (1 << 11) 55bdc52020SBenoît Thébaudeau /* HOST1 power mask */ 56bdc52020SBenoît Thébaudeau #define MXC_H1_UCTRL_H1PM_BIT (1 << 8) 5731ac2d0cSBenoît Thébaudeau /* HOST1 power pin polarity */ 5831ac2d0cSBenoît Thébaudeau #define MXC_H1_UCTRL_H1_PWR_POL_BIT (1 << 8) 591ca56202SWolfgang Grandegger 601ca56202SWolfgang Grandegger /* USB_PHY_CTRL_FUNC */ 6131ac2d0cSBenoît Thébaudeau /* OTG Polarity of Overcurrent */ 6231ac2d0cSBenoît Thébaudeau #define MXC_OTG_PHYCTRL_OC_POL_BIT (1 << 9) 63bdc52020SBenoît Thébaudeau /* OTG Disable Overcurrent Event */ 64bdc52020SBenoît Thébaudeau #define MXC_OTG_PHYCTRL_OC_DIS_BIT (1 << 8) 6531ac2d0cSBenoît Thébaudeau /* UH1 Polarity of Overcurrent */ 6631ac2d0cSBenoît Thébaudeau #define MXC_H1_OC_POL_BIT (1 << 6) 67bdc52020SBenoît Thébaudeau /* UH1 Disable Overcurrent Event */ 68bdc52020SBenoît Thébaudeau #define MXC_H1_OC_DIS_BIT (1 << 5) 6931ac2d0cSBenoît Thébaudeau /* OTG Power Pin Polarity */ 7031ac2d0cSBenoît Thébaudeau #define MXC_OTG_PHYCTRL_PWR_POL_BIT (1 << 3) 711ca56202SWolfgang Grandegger 721ca56202SWolfgang Grandegger /* USBH2CTRL */ 7331ac2d0cSBenoît Thébaudeau #define MXC_H2_UCTRL_H2_OC_POL_BIT (1 << 31) 742cfe0b8fSBenoît Thébaudeau #define MXC_H2_UCTRL_H2_OC_DIS_BIT (1 << 30) 751ca56202SWolfgang Grandegger #define MXC_H2_UCTRL_H2UIE_BIT (1 << 8) 761ca56202SWolfgang Grandegger #define MXC_H2_UCTRL_H2WIE_BIT (1 << 7) 771ca56202SWolfgang Grandegger #define MXC_H2_UCTRL_H2PM_BIT (1 << 4) 7831ac2d0cSBenoît Thébaudeau #define MXC_H2_UCTRL_H2_PWR_POL_BIT (1 << 4) 791ca56202SWolfgang Grandegger 802cfe0b8fSBenoît Thébaudeau /* USBH3CTRL */ 8131ac2d0cSBenoît Thébaudeau #define MXC_H3_UCTRL_H3_OC_POL_BIT (1 << 31) 822cfe0b8fSBenoît Thébaudeau #define MXC_H3_UCTRL_H3_OC_DIS_BIT (1 << 30) 832cfe0b8fSBenoît Thébaudeau #define MXC_H3_UCTRL_H3UIE_BIT (1 << 8) 842cfe0b8fSBenoît Thébaudeau #define MXC_H3_UCTRL_H3WIE_BIT (1 << 7) 8531ac2d0cSBenoît Thébaudeau #define MXC_H3_UCTRL_H3_PWR_POL_BIT (1 << 4) 862cfe0b8fSBenoît Thébaudeau 871ca56202SWolfgang Grandegger /* USB_CTRL_1 */ 881ca56202SWolfgang Grandegger #define MXC_USB_CTRL_UH1_EXT_CLK_EN (1 << 25) 891ca56202SWolfgang Grandegger 900f8c86b5SMarek Vasut /* USB pin configuration */ 910f8c86b5SMarek Vasut #define USB_PAD_CONFIG (PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST | \ 920f8c86b5SMarek Vasut PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | \ 930f8c86b5SMarek Vasut PAD_CTL_HYS_ENABLE | PAD_CTL_PUE_PULL) 940f8c86b5SMarek Vasut 950f8c86b5SMarek Vasut #ifdef CONFIG_MX51 960f8c86b5SMarek Vasut /* 970f8c86b5SMarek Vasut * Configure the MX51 USB H1 IOMUX 980f8c86b5SMarek Vasut */ 990f8c86b5SMarek Vasut void setup_iomux_usb_h1(void) 1000f8c86b5SMarek Vasut { 1010f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0); 1020f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_USBH1_STP, USB_PAD_CONFIG); 1030f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_USBH1_CLK, IOMUX_CONFIG_ALT0); 1040f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_USBH1_CLK, USB_PAD_CONFIG); 1050f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_USBH1_DIR, IOMUX_CONFIG_ALT0); 1060f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_USBH1_DIR, USB_PAD_CONFIG); 1070f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_USBH1_NXT, IOMUX_CONFIG_ALT0); 1080f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_USBH1_NXT, USB_PAD_CONFIG); 1090f8c86b5SMarek Vasut 1100f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_USBH1_DATA0, IOMUX_CONFIG_ALT0); 1110f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_USBH1_DATA0, USB_PAD_CONFIG); 1120f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_USBH1_DATA1, IOMUX_CONFIG_ALT0); 1130f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_USBH1_DATA1, USB_PAD_CONFIG); 1140f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_USBH1_DATA2, IOMUX_CONFIG_ALT0); 1150f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_USBH1_DATA2, USB_PAD_CONFIG); 1160f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_USBH1_DATA3, IOMUX_CONFIG_ALT0); 1170f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_USBH1_DATA3, USB_PAD_CONFIG); 1180f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_USBH1_DATA4, IOMUX_CONFIG_ALT0); 1190f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_USBH1_DATA4, USB_PAD_CONFIG); 1200f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_USBH1_DATA5, IOMUX_CONFIG_ALT0); 1210f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_USBH1_DATA5, USB_PAD_CONFIG); 1220f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_USBH1_DATA6, IOMUX_CONFIG_ALT0); 1230f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_USBH1_DATA6, USB_PAD_CONFIG); 1240f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_USBH1_DATA7, IOMUX_CONFIG_ALT0); 1250f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_USBH1_DATA7, USB_PAD_CONFIG); 1260f8c86b5SMarek Vasut } 1270f8c86b5SMarek Vasut 1280f8c86b5SMarek Vasut /* 1290f8c86b5SMarek Vasut * Configure the MX51 USB H2 IOMUX 1300f8c86b5SMarek Vasut */ 1310f8c86b5SMarek Vasut void setup_iomux_usb_h2(void) 1320f8c86b5SMarek Vasut { 1330f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_EIM_A24, IOMUX_CONFIG_ALT2); 1340f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_EIM_A24, USB_PAD_CONFIG); 1350f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_EIM_A25, IOMUX_CONFIG_ALT2); 1360f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_EIM_A25, USB_PAD_CONFIG); 1370f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT2); 1380f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_EIM_A26, USB_PAD_CONFIG); 1390f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_EIM_A27, IOMUX_CONFIG_ALT2); 1400f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_EIM_A27, USB_PAD_CONFIG); 1410f8c86b5SMarek Vasut 1420f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_EIM_D16, IOMUX_CONFIG_ALT2); 1430f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_EIM_D16, USB_PAD_CONFIG); 1440f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_EIM_D17, IOMUX_CONFIG_ALT2); 1450f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_EIM_D17, USB_PAD_CONFIG); 1460f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_EIM_D18, IOMUX_CONFIG_ALT2); 1470f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_EIM_D18, USB_PAD_CONFIG); 1480f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_EIM_D19, IOMUX_CONFIG_ALT2); 1490f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_EIM_D19, USB_PAD_CONFIG); 1500f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_EIM_D20, IOMUX_CONFIG_ALT2); 1510f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_EIM_D20, USB_PAD_CONFIG); 1520f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_EIM_D21, IOMUX_CONFIG_ALT2); 1530f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_EIM_D21, USB_PAD_CONFIG); 1540f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_EIM_D22, IOMUX_CONFIG_ALT2); 1550f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_EIM_D22, USB_PAD_CONFIG); 1560f8c86b5SMarek Vasut mxc_request_iomux(MX51_PIN_EIM_D23, IOMUX_CONFIG_ALT2); 1570f8c86b5SMarek Vasut mxc_iomux_set_pad(MX51_PIN_EIM_D23, USB_PAD_CONFIG); 1580f8c86b5SMarek Vasut } 1590f8c86b5SMarek Vasut #endif 1600f8c86b5SMarek Vasut 1611ca56202SWolfgang Grandegger int mxc_set_usbcontrol(int port, unsigned int flags) 1621ca56202SWolfgang Grandegger { 1631ca56202SWolfgang Grandegger unsigned int v; 1641ca56202SWolfgang Grandegger void __iomem *usb_base = (void __iomem *)OTG_BASE_ADDR; 1651ca56202SWolfgang Grandegger void __iomem *usbother_base; 1661ca56202SWolfgang Grandegger int ret = 0; 1671ca56202SWolfgang Grandegger 1681ca56202SWolfgang Grandegger usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; 1691ca56202SWolfgang Grandegger 1701ca56202SWolfgang Grandegger switch (port) { 1711ca56202SWolfgang Grandegger case 0: /* OTG port */ 1721ca56202SWolfgang Grandegger if (flags & MXC_EHCI_INTERNAL_PHY) { 1731ca56202SWolfgang Grandegger v = __raw_readl(usbother_base + 1741ca56202SWolfgang Grandegger MXC_USB_PHY_CTR_FUNC_OFFSET); 17531ac2d0cSBenoît Thébaudeau if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW) 17631ac2d0cSBenoît Thébaudeau v |= MXC_OTG_PHYCTRL_OC_POL_BIT; 17731ac2d0cSBenoît Thébaudeau else 17831ac2d0cSBenoît Thébaudeau v &= ~MXC_OTG_PHYCTRL_OC_POL_BIT; 1791ca56202SWolfgang Grandegger if (flags & MXC_EHCI_POWER_PINS_ENABLED) 1801ca56202SWolfgang Grandegger /* OC/USBPWR is used */ 1811ca56202SWolfgang Grandegger v &= ~MXC_OTG_PHYCTRL_OC_DIS_BIT; 1827d42432dSBenoît Thébaudeau else 1837d42432dSBenoît Thébaudeau /* OC/USBPWR is not used */ 1847d42432dSBenoît Thébaudeau v |= MXC_OTG_PHYCTRL_OC_DIS_BIT; 18531ac2d0cSBenoît Thébaudeau #ifdef CONFIG_MX51 18631ac2d0cSBenoît Thébaudeau if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH) 18731ac2d0cSBenoît Thébaudeau v |= MXC_OTG_PHYCTRL_PWR_POL_BIT; 18831ac2d0cSBenoît Thébaudeau else 18931ac2d0cSBenoît Thébaudeau v &= ~MXC_OTG_PHYCTRL_PWR_POL_BIT; 19031ac2d0cSBenoît Thébaudeau #endif 1911ca56202SWolfgang Grandegger __raw_writel(v, usbother_base + 1921ca56202SWolfgang Grandegger MXC_USB_PHY_CTR_FUNC_OFFSET); 1931ca56202SWolfgang Grandegger 1941ca56202SWolfgang Grandegger v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET); 195661052f4SBenoît Thébaudeau #ifdef CONFIG_MX51 1961ca56202SWolfgang Grandegger if (flags & MXC_EHCI_POWER_PINS_ENABLED) 1971ca56202SWolfgang Grandegger v &= ~MXC_OTG_UCTRL_OPM_BIT; 198394c00dcSBenoît Thébaudeau else 199394c00dcSBenoît Thébaudeau v |= MXC_OTG_UCTRL_OPM_BIT; 200661052f4SBenoît Thébaudeau #endif 20131ac2d0cSBenoît Thébaudeau #ifdef CONFIG_MX53 20231ac2d0cSBenoît Thébaudeau if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH) 20331ac2d0cSBenoît Thébaudeau v |= MXC_OTG_UCTRL_O_PWR_POL_BIT; 20431ac2d0cSBenoît Thébaudeau else 20531ac2d0cSBenoît Thébaudeau v &= ~MXC_OTG_UCTRL_O_PWR_POL_BIT; 20631ac2d0cSBenoît Thébaudeau #endif 2071ca56202SWolfgang Grandegger __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET); 2081ca56202SWolfgang Grandegger } 2091ca56202SWolfgang Grandegger break; 210bdc52020SBenoît Thébaudeau case 1: /* Host 1 ULPI */ 2111ca56202SWolfgang Grandegger #ifdef CONFIG_MX51 2121ca56202SWolfgang Grandegger /* The clock for the USBH1 ULPI port will come externally 2131ca56202SWolfgang Grandegger from the PHY. */ 2141ca56202SWolfgang Grandegger v = __raw_readl(usbother_base + MXC_USB_CTRL_1_OFFSET); 2151ca56202SWolfgang Grandegger __raw_writel(v | MXC_USB_CTRL_UH1_EXT_CLK_EN, usbother_base + 2161ca56202SWolfgang Grandegger MXC_USB_CTRL_1_OFFSET); 2171ca56202SWolfgang Grandegger #endif 2181ca56202SWolfgang Grandegger 2191ca56202SWolfgang Grandegger v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET); 220661052f4SBenoît Thébaudeau #ifdef CONFIG_MX51 2211ca56202SWolfgang Grandegger if (flags & MXC_EHCI_POWER_PINS_ENABLED) 222bdc52020SBenoît Thébaudeau v &= ~MXC_H1_UCTRL_H1PM_BIT; /* H1 power mask unused */ 2231ca56202SWolfgang Grandegger else 224bdc52020SBenoît Thébaudeau v |= MXC_H1_UCTRL_H1PM_BIT; /* H1 power mask used */ 225661052f4SBenoît Thébaudeau #endif 22631ac2d0cSBenoît Thébaudeau #ifdef CONFIG_MX53 22731ac2d0cSBenoît Thébaudeau if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH) 22831ac2d0cSBenoît Thébaudeau v |= MXC_H1_UCTRL_H1_PWR_POL_BIT; 22931ac2d0cSBenoît Thébaudeau else 23031ac2d0cSBenoît Thébaudeau v &= ~MXC_H1_UCTRL_H1_PWR_POL_BIT; 23131ac2d0cSBenoît Thébaudeau #endif 2321ca56202SWolfgang Grandegger __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET); 2331ca56202SWolfgang Grandegger 2341ca56202SWolfgang Grandegger v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); 23531ac2d0cSBenoît Thébaudeau if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW) 23631ac2d0cSBenoît Thébaudeau v |= MXC_H1_OC_POL_BIT; 23731ac2d0cSBenoît Thébaudeau else 23831ac2d0cSBenoît Thébaudeau v &= ~MXC_H1_OC_POL_BIT; 2391ca56202SWolfgang Grandegger if (flags & MXC_EHCI_POWER_PINS_ENABLED) 2401ca56202SWolfgang Grandegger v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */ 2411ca56202SWolfgang Grandegger else 2421ca56202SWolfgang Grandegger v |= MXC_H1_OC_DIS_BIT; /* OC is not used */ 2431ca56202SWolfgang Grandegger __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); 2441ca56202SWolfgang Grandegger 2451ca56202SWolfgang Grandegger break; 2461ca56202SWolfgang Grandegger case 2: /* Host 2 ULPI */ 2471ca56202SWolfgang Grandegger v = __raw_readl(usbother_base + MXC_USBH2CTRL_OFFSET); 248661052f4SBenoît Thébaudeau #ifdef CONFIG_MX51 2491ca56202SWolfgang Grandegger if (flags & MXC_EHCI_POWER_PINS_ENABLED) 250bdc52020SBenoît Thébaudeau v &= ~MXC_H2_UCTRL_H2PM_BIT; /* H2 power mask unused */ 2511ca56202SWolfgang Grandegger else 252bdc52020SBenoît Thébaudeau v |= MXC_H2_UCTRL_H2PM_BIT; /* H2 power mask used */ 253661052f4SBenoît Thébaudeau #endif 2542cfe0b8fSBenoît Thébaudeau #ifdef CONFIG_MX53 25531ac2d0cSBenoît Thébaudeau if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW) 25631ac2d0cSBenoît Thébaudeau v |= MXC_H2_UCTRL_H2_OC_POL_BIT; 25731ac2d0cSBenoît Thébaudeau else 25831ac2d0cSBenoît Thébaudeau v &= ~MXC_H2_UCTRL_H2_OC_POL_BIT; 2592cfe0b8fSBenoît Thébaudeau if (flags & MXC_EHCI_POWER_PINS_ENABLED) 2602cfe0b8fSBenoît Thébaudeau v &= ~MXC_H2_UCTRL_H2_OC_DIS_BIT; /* OC is used */ 2612cfe0b8fSBenoît Thébaudeau else 2622cfe0b8fSBenoît Thébaudeau v |= MXC_H2_UCTRL_H2_OC_DIS_BIT; /* OC is not used */ 26331ac2d0cSBenoît Thébaudeau if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH) 26431ac2d0cSBenoît Thébaudeau v |= MXC_H2_UCTRL_H2_PWR_POL_BIT; 26531ac2d0cSBenoît Thébaudeau else 26631ac2d0cSBenoît Thébaudeau v &= ~MXC_H2_UCTRL_H2_PWR_POL_BIT; 2672cfe0b8fSBenoît Thébaudeau #endif 2681ca56202SWolfgang Grandegger __raw_writel(v, usbother_base + MXC_USBH2CTRL_OFFSET); 2691ca56202SWolfgang Grandegger break; 2702cfe0b8fSBenoît Thébaudeau #ifdef CONFIG_MX53 2712cfe0b8fSBenoît Thébaudeau case 3: /* Host 3 ULPI */ 2722cfe0b8fSBenoît Thébaudeau v = __raw_readl(usbother_base + MXC_USBH3CTRL_OFFSET); 27331ac2d0cSBenoît Thébaudeau if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW) 27431ac2d0cSBenoît Thébaudeau v |= MXC_H3_UCTRL_H3_OC_POL_BIT; 27531ac2d0cSBenoît Thébaudeau else 27631ac2d0cSBenoît Thébaudeau v &= ~MXC_H3_UCTRL_H3_OC_POL_BIT; 2772cfe0b8fSBenoît Thébaudeau if (flags & MXC_EHCI_POWER_PINS_ENABLED) 2782cfe0b8fSBenoît Thébaudeau v &= ~MXC_H3_UCTRL_H3_OC_DIS_BIT; /* OC is used */ 2792cfe0b8fSBenoît Thébaudeau else 2802cfe0b8fSBenoît Thébaudeau v |= MXC_H3_UCTRL_H3_OC_DIS_BIT; /* OC is not used */ 28131ac2d0cSBenoît Thébaudeau if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH) 28231ac2d0cSBenoît Thébaudeau v |= MXC_H3_UCTRL_H3_PWR_POL_BIT; 28331ac2d0cSBenoît Thébaudeau else 28431ac2d0cSBenoît Thébaudeau v &= ~MXC_H3_UCTRL_H3_PWR_POL_BIT; 2852cfe0b8fSBenoît Thébaudeau __raw_writel(v, usbother_base + MXC_USBH3CTRL_OFFSET); 2862cfe0b8fSBenoît Thébaudeau break; 2872cfe0b8fSBenoît Thébaudeau #endif 2881ca56202SWolfgang Grandegger } 2891ca56202SWolfgang Grandegger 2901ca56202SWolfgang Grandegger return ret; 2911ca56202SWolfgang Grandegger } 2921ca56202SWolfgang Grandegger 293*f22e4faeSBenoît Thébaudeau int __weak board_ehci_hcd_init(int port) 2941b80f270SMarek Vasut { 295*f22e4faeSBenoît Thébaudeau return 0; 2961b80f270SMarek Vasut } 2971b80f270SMarek Vasut 298*f22e4faeSBenoît Thébaudeau void __weak board_ehci_hcd_postinit(struct usb_ehci *ehci, int port) 299*f22e4faeSBenoît Thébaudeau { 300*f22e4faeSBenoît Thébaudeau } 3011b80f270SMarek Vasut 302676ae068SLucas Stach int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor) 3031ca56202SWolfgang Grandegger { 3041ca56202SWolfgang Grandegger struct usb_ehci *ehci; 3051ca56202SWolfgang Grandegger #ifdef CONFIG_MX53 3061ca56202SWolfgang Grandegger struct clkctl *sc_regs = (struct clkctl *)CCM_BASE_ADDR; 3071ca56202SWolfgang Grandegger u32 reg; 3081ca56202SWolfgang Grandegger 3091ca56202SWolfgang Grandegger reg = __raw_readl(&sc_regs->cscmr1) & ~(1 << 26); 3101ca56202SWolfgang Grandegger /* derive USB PHY clock multiplexer from PLL3 */ 3111ca56202SWolfgang Grandegger reg |= 1 << 26; 3121ca56202SWolfgang Grandegger __raw_writel(reg, &sc_regs->cscmr1); 3131ca56202SWolfgang Grandegger #endif 3141ca56202SWolfgang Grandegger 3151ca56202SWolfgang Grandegger set_usboh3_clk(); 3161ca56202SWolfgang Grandegger enable_usboh3_clk(1); 317414e1660SBenoît Thébaudeau set_usb_phy_clk(); 318414e1660SBenoît Thébaudeau enable_usb_phy1_clk(1); 3191ca56202SWolfgang Grandegger enable_usb_phy2_clk(1); 3201ca56202SWolfgang Grandegger mdelay(1); 3211ca56202SWolfgang Grandegger 3221b80f270SMarek Vasut /* Do board specific initialization */ 3231ca56202SWolfgang Grandegger board_ehci_hcd_init(CONFIG_MXC_USB_PORT); 3241ca56202SWolfgang Grandegger 3251ca56202SWolfgang Grandegger ehci = (struct usb_ehci *)(OTG_BASE_ADDR + 3261ca56202SWolfgang Grandegger (0x200 * CONFIG_MXC_USB_PORT)); 327676ae068SLucas Stach *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); 328676ae068SLucas Stach *hcor = (struct ehci_hcor *)((uint32_t)*hccr + 329676ae068SLucas Stach HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); 3301ca56202SWolfgang Grandegger setbits_le32(&ehci->usbmode, CM_HOST); 3311ca56202SWolfgang Grandegger 3321ca56202SWolfgang Grandegger __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc); 3331ca56202SWolfgang Grandegger setbits_le32(&ehci->portsc, USB_EN); 3341ca56202SWolfgang Grandegger 3351ca56202SWolfgang Grandegger mxc_set_usbcontrol(CONFIG_MXC_USB_PORT, CONFIG_MXC_USB_FLAGS); 3361ca56202SWolfgang Grandegger mdelay(10); 3371ca56202SWolfgang Grandegger 3381b80f270SMarek Vasut /* Do board specific post-initialization */ 3391b80f270SMarek Vasut board_ehci_hcd_postinit(ehci, CONFIG_MXC_USB_PORT); 3401b80f270SMarek Vasut 3411ca56202SWolfgang Grandegger return 0; 3421ca56202SWolfgang Grandegger } 3431ca56202SWolfgang Grandegger 344676ae068SLucas Stach int ehci_hcd_stop(int index) 3451ca56202SWolfgang Grandegger { 3461ca56202SWolfgang Grandegger return 0; 3471ca56202SWolfgang Grandegger } 348