15b591502SStefano Babic /* 25b591502SStefano Babic * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> 35b591502SStefano Babic * 45b591502SStefano Babic * This program is free software; you can redistribute it and/or modify it 55b591502SStefano Babic * under the terms of the GNU General Public License as published by the 65b591502SStefano Babic * Free Software Foundation; either version 2 of the License, or (at your 75b591502SStefano Babic * option) any later version. 85b591502SStefano Babic * 95b591502SStefano Babic * This program is distributed in the hope that it will be useful, but 105b591502SStefano Babic * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 115b591502SStefano Babic * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 125b591502SStefano Babic * for more details. 135b591502SStefano Babic * 145b591502SStefano Babic * You should have received a copy of the GNU General Public License 155b591502SStefano Babic * along with this program; if not, write to the Free Software Foundation, 165b591502SStefano Babic * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 175b591502SStefano Babic */ 185b591502SStefano Babic 195b591502SStefano Babic 205b591502SStefano Babic #include <common.h> 215b591502SStefano Babic #include <usb.h> 225b591502SStefano Babic #include <asm/io.h> 2386271115SStefano Babic #include <asm/arch/imx-regs.h> 245b591502SStefano Babic #include <usb/ehci-fsl.h> 255b591502SStefano Babic #include <errno.h> 265b591502SStefano Babic 275b591502SStefano Babic #include "ehci.h" 285b591502SStefano Babic #include "ehci-core.h" 295b591502SStefano Babic 305b591502SStefano Babic #define USBCTRL_OTGBASE_OFFSET 0x600 315b591502SStefano Babic 32dddb7c9fSMatthias Weisser #ifdef CONFIG_MX25 33dddb7c9fSMatthias Weisser #define MX25_USB_CTRL_IP_PUE_DOWN_BIT (1<<6) 34dddb7c9fSMatthias Weisser #define MX25_USB_CTRL_HSTD_BIT (1<<5) 35dddb7c9fSMatthias Weisser #define MX25_USB_CTRL_USBTE_BIT (1<<4) 36dddb7c9fSMatthias Weisser #define MX25_USB_CTRL_OCPOL_OTG_BIT (1<<3) 37dddb7c9fSMatthias Weisser #endif 38dddb7c9fSMatthias Weisser 39dddb7c9fSMatthias Weisser #ifdef CONFIG_MX31 405b591502SStefano Babic #define MX31_OTG_SIC_SHIFT 29 415b591502SStefano Babic #define MX31_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT) 425b591502SStefano Babic #define MX31_OTG_PM_BIT (1 << 24) 435b591502SStefano Babic 445b591502SStefano Babic #define MX31_H2_SIC_SHIFT 21 455b591502SStefano Babic #define MX31_H2_SIC_MASK (0x3 << MX31_H2_SIC_SHIFT) 465b591502SStefano Babic #define MX31_H2_PM_BIT (1 << 16) 475b591502SStefano Babic #define MX31_H2_DT_BIT (1 << 5) 485b591502SStefano Babic 495b591502SStefano Babic #define MX31_H1_SIC_SHIFT 13 505b591502SStefano Babic #define MX31_H1_SIC_MASK (0x3 << MX31_H1_SIC_SHIFT) 515b591502SStefano Babic #define MX31_H1_PM_BIT (1 << 8) 525b591502SStefano Babic #define MX31_H1_DT_BIT (1 << 4) 53dddb7c9fSMatthias Weisser #endif 545b591502SStefano Babic 555b591502SStefano Babic static int mxc_set_usbcontrol(int port, unsigned int flags) 565b591502SStefano Babic { 575b591502SStefano Babic unsigned int v; 58dddb7c9fSMatthias Weisser 59dddb7c9fSMatthias Weisser #ifdef CONFIG_MX25 60dddb7c9fSMatthias Weisser v = MX25_USB_CTRL_IP_PUE_DOWN_BIT | MX25_USB_CTRL_HSTD_BIT | 61dddb7c9fSMatthias Weisser MX25_USB_CTRL_USBTE_BIT | MX25_USB_CTRL_OCPOL_OTG_BIT; 62dddb7c9fSMatthias Weisser #endif 63dddb7c9fSMatthias Weisser 645b591502SStefano Babic #ifdef CONFIG_MX31 65dddb7c9fSMatthias Weisser v = readl(IMX_USB_BASE + USBCTRL_OTGBASE_OFFSET); 665b591502SStefano Babic 675b591502SStefano Babic switch (port) { 685b591502SStefano Babic case 0: /* OTG port */ 695b591502SStefano Babic v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); 705b591502SStefano Babic v |= (flags & MXC_EHCI_INTERFACE_MASK) 715b591502SStefano Babic << MX31_OTG_SIC_SHIFT; 725b591502SStefano Babic if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) 735b591502SStefano Babic v |= MX31_OTG_PM_BIT; 745b591502SStefano Babic 755b591502SStefano Babic break; 765b591502SStefano Babic case 1: /* H1 port */ 775b591502SStefano Babic v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | 785b591502SStefano Babic MX31_H1_DT_BIT); 795b591502SStefano Babic v |= (flags & MXC_EHCI_INTERFACE_MASK) 805b591502SStefano Babic << MX31_H1_SIC_SHIFT; 815b591502SStefano Babic if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) 825b591502SStefano Babic v |= MX31_H1_PM_BIT; 835b591502SStefano Babic 845b591502SStefano Babic if (!(flags & MXC_EHCI_TTL_ENABLED)) 855b591502SStefano Babic v |= MX31_H1_DT_BIT; 865b591502SStefano Babic 875b591502SStefano Babic break; 885b591502SStefano Babic case 2: /* H2 port */ 895b591502SStefano Babic v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | 905b591502SStefano Babic MX31_H2_DT_BIT); 915b591502SStefano Babic v |= (flags & MXC_EHCI_INTERFACE_MASK) 925b591502SStefano Babic << MX31_H2_SIC_SHIFT; 935b591502SStefano Babic if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) 945b591502SStefano Babic v |= MX31_H2_PM_BIT; 955b591502SStefano Babic 965b591502SStefano Babic if (!(flags & MXC_EHCI_TTL_ENABLED)) 975b591502SStefano Babic v |= MX31_H2_DT_BIT; 985b591502SStefano Babic 995b591502SStefano Babic break; 1005b591502SStefano Babic default: 1015b591502SStefano Babic return -EINVAL; 1025b591502SStefano Babic } 1035b591502SStefano Babic #endif 104dddb7c9fSMatthias Weisser 105dddb7c9fSMatthias Weisser writel(v, IMX_USB_BASE + USBCTRL_OTGBASE_OFFSET); 1065b591502SStefano Babic return 0; 1075b591502SStefano Babic } 1085b591502SStefano Babic 1095b591502SStefano Babic int ehci_hcd_init(void) 1105b591502SStefano Babic { 1115b591502SStefano Babic struct usb_ehci *ehci; 112dddb7c9fSMatthias Weisser #ifdef CONFIG_MX31 1135b591502SStefano Babic struct clock_control_regs *sc_regs = 1145b591502SStefano Babic (struct clock_control_regs *)CCM_BASE; 1155b591502SStefano Babic 116*f55feafdSAnatolij Gustschin __raw_readl(&sc_regs->ccmr); 1175b591502SStefano Babic __raw_writel(__raw_readl(&sc_regs->ccmr) | (1 << 9), &sc_regs->ccmr) ; 118dddb7c9fSMatthias Weisser #endif 1195b591502SStefano Babic 1205b591502SStefano Babic udelay(80); 1215b591502SStefano Babic 122dddb7c9fSMatthias Weisser ehci = (struct usb_ehci *)(IMX_USB_BASE + 1235b591502SStefano Babic (0x200 * CONFIG_MXC_USB_PORT)); 1245b591502SStefano Babic hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); 1255b591502SStefano Babic hcor = (struct ehci_hcor *)((uint32_t) hccr + 1265b591502SStefano Babic HC_LENGTH(ehci_readl(&hccr->cr_capbase))); 1275b591502SStefano Babic setbits_le32(&ehci->usbmode, CM_HOST); 128dddb7c9fSMatthias Weisser #ifdef CONFIG_MX31 1295b591502SStefano Babic setbits_le32(&ehci->control, USB_EN); 1305b591502SStefano Babic 1315b591502SStefano Babic __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc); 132dddb7c9fSMatthias Weisser #endif 1335b591502SStefano Babic mxc_set_usbcontrol(CONFIG_MXC_USB_PORT, CONFIG_MXC_USB_FLAGS); 1345b591502SStefano Babic 135a2f9bff9SStefano Babic udelay(10000); 136a2f9bff9SStefano Babic 1375b591502SStefano Babic return 0; 1385b591502SStefano Babic } 1395b591502SStefano Babic 1405b591502SStefano Babic /* 1415b591502SStefano Babic * Destroy the appropriate control structures corresponding 1425b591502SStefano Babic * the the EHCI host controller. 1435b591502SStefano Babic */ 1445b591502SStefano Babic int ehci_hcd_stop(void) 1455b591502SStefano Babic { 1465b591502SStefano Babic return 0; 1475b591502SStefano Babic } 148