ehci-omap.c revision a42ccdc14de388a35ad0e8057543369351395eb9
154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* 254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * ehci-omap.c - driver for USBHOST on OMAP 34xx processor 354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * 454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Bus Glue for OMAP34xx USBHOST 3 port EHCI controller 554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Tested on OMAP3430 ES2.0 SDP 654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * 754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Copyright (C) 2007-2008 Texas Instruments, Inc. 854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Author: Vikram Pandita <vikram.pandita@ti.com> 954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * 1054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Copyright (C) 2009 Nokia Corporation 1154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Contact: Felipe Balbi <felipe.balbi@nokia.com> 1254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * 1354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Based on "ehci-fsl.c" and "ehci-au1xxx.c" ehci glue layers 1454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * 1554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * This program is free software; you can redistribute it and/or modify 1654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * it under the terms of the GNU General Public License as published by 1754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * the Free Software Foundation; either version 2 of the License, or 1854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * (at your option) any later version. 1954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * 2054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * This program is distributed in the hope that it will be useful, 2154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * but WITHOUT ANY WARRANTY; without even the implied warranty of 2254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * GNU General Public License for more details. 2454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * 2554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * You should have received a copy of the GNU General Public License 2654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * along with this program; if not, write to the Free Software 2754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 2854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * 29bdee2d8432f5af5af953896182a59ec1c5d6fa3aAnand Gadiyar * TODO (last updated Feb 12, 2010): 3054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * - add kernel-doc 3154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * - enable AUTOIDLE 3254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * - add suspend/resume 3354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * - move workarounds to board-files 3454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */ 3554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 3654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#include <linux/platform_device.h> 3754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#include <linux/clk.h> 3854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#include <linux/gpio.h> 39881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta#include <linux/regulator/consumer.h> 405a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 415aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta#include <linux/usb/ulpi.h> 42c76f782cb3cfffc1fd4233e11f3116655fa0fcd2Thomas Weber#include <plat/usb.h> 4354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 4454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* 4554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * OMAP USBHOST Register addresses: VIRTUAL ADDRESSES 4654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Use ehci_omap_readl()/ehci_omap_writel() functions 4754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */ 4854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 4954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* TLL Register Set */ 5054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_USBTLL_REVISION (0x00) 5154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_USBTLL_SYSCONFIG (0x10) 5254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8) 5354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3) 5454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2) 5554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1) 5654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_USBTLL_SYSCONFIG_AUTOIDLE (1 << 0) 5754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 5854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_USBTLL_SYSSTATUS (0x14) 5954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0) 6054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 6154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_USBTLL_IRQSTATUS (0x18) 6254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_USBTLL_IRQENABLE (0x1C) 6354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 6454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_SHARED_CONF (0x30) 6554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN (1 << 6) 6654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN (1 << 5) 6754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_SHARED_CONF_USB_DIVRATION (1 << 2) 6854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_SHARED_CONF_FCLK_REQ (1 << 1) 6954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_SHARED_CONF_FCLK_IS_ON (1 << 0) 7054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 7154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num) 7254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11) 7354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10) 7454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9) 7554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8) 7654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0) 7754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 7854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_ULPI_FUNCTION_CTRL(num) (0x804 + 0x100 * num) 7954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_ULPI_INTERFACE_CTRL(num) (0x807 + 0x100 * num) 8054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_ULPI_OTG_CTRL(num) (0x80A + 0x100 * num) 8154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_ULPI_INT_EN_RISE(num) (0x80D + 0x100 * num) 8254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_ULPI_INT_EN_FALL(num) (0x810 + 0x100 * num) 8354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_ULPI_INT_STATUS(num) (0x813 + 0x100 * num) 8454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_ULPI_INT_LATCH(num) (0x814 + 0x100 * num) 8554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_ULPI_DEBUG(num) (0x815 + 0x100 * num) 8654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num) 8754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 8854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_COUNT 3 8954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 1) 9054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 2) 9154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 4) 9254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 9354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* UHH Register Set */ 9454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_REVISION (0x00) 9554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_SYSCONFIG (0x10) 9654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_SYSCONFIG_MIDLEMODE (1 << 12) 9754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_SYSCONFIG_CACTIVITY (1 << 8) 9854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_SYSCONFIG_SIDLEMODE (1 << 3) 9954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_SYSCONFIG_ENAWAKEUP (1 << 2) 10054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_SYSCONFIG_SOFTRESET (1 << 1) 10154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_SYSCONFIG_AUTOIDLE (1 << 0) 10254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 10354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_SYSSTATUS (0x14) 10454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG (0x40) 10554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_ULPI_BYPASS (1 << 0) 10654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS (1 << 0) 10754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS (1 << 11) 10854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS (1 << 12) 10954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN (1 << 2) 11054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN (1 << 3) 11154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN (1 << 4) 11254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN (1 << 5) 11354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS (1 << 8) 11454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) 11554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) 11654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 11754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define OMAP_UHH_DEBUG_CSR (0x44) 11854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 11954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* EHCI Register Set */ 120572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar#define EHCI_INSNREG04 (0xA0) 121572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar#define EHCI_INSNREG04_DISABLE_UNSUSPEND (1 << 5) 12254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define EHCI_INSNREG05_ULPI (0xA4) 12354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define EHCI_INSNREG05_ULPI_CONTROL_SHIFT 31 12454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define EHCI_INSNREG05_ULPI_PORTSEL_SHIFT 24 12554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define EHCI_INSNREG05_ULPI_OPSEL_SHIFT 22 12654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define EHCI_INSNREG05_ULPI_REGADD_SHIFT 16 12754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 12854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi#define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 12954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 130a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar#define is_ehci_phy_mode(x) (x == EHCI_HCD_OMAP_MODE_PHY) 131a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar#define is_ehci_tll_mode(x) (x == EHCI_HCD_OMAP_MODE_TLL) 132a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar 13354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/ 13454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 13554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic inline void ehci_omap_writel(void __iomem *base, u32 reg, u32 val) 13654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{ 13754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi __raw_writel(val, base + reg); 13854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi} 13954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 14054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic inline u32 ehci_omap_readl(void __iomem *base, u32 reg) 14154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{ 14254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi return __raw_readl(base + reg); 14354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi} 14454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 14554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic inline void ehci_omap_writeb(void __iomem *base, u8 reg, u8 val) 14654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{ 14754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi __raw_writeb(val, base + reg); 14854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi} 14954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 15054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic inline u8 ehci_omap_readb(void __iomem *base, u8 reg) 15154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{ 15254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi return __raw_readb(base + reg); 15354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi} 15454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 15554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/ 15654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 15754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistruct ehci_hcd_omap { 15854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct ehci_hcd *ehci; 15954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct device *dev; 16054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 16154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct clk *usbhost_ick; 1626dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda struct clk *usbhost_hs_fck; 1636dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda struct clk *usbhost_fs_fck; 16454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct clk *usbtll_fck; 16554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct clk *usbtll_ick; 16654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 16754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* FIXME the following two workarounds are 16854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * board specific not silicon-specific so these 16954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * should be moved to board-file instead. 17054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * 17154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Maybe someone from TI will know better which 17254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * board is affected and needs the workarounds 17354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * to be applied 17454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */ 17554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 17654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* gpio for resetting phy */ 17754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi int reset_gpio_port[OMAP3_HS_USB_PORTS]; 17854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 17954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* phy reset workaround */ 18054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi int phy_reset; 18154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 18254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* desired phy_mode: TLL, PHY */ 18354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; 18454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 18554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi void __iomem *uhh_base; 18654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi void __iomem *tll_base; 18754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi void __iomem *ehci_base; 188881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta 189881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta /* Regulators for USB PHYs. 190a8cd4561ea176f51e9f4707873ca4eff8fd5ee70Anand Gadiyar * Each PHY can have a separate regulator. 191881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta */ 192881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta struct regulator *regulator[OMAP3_HS_USB_PORTS]; 19354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}; 19454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 19554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/ 19654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 197c072604115ab50d023eb5c33d4f3229400e441f4Keshava Munegowdastatic void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask, 198c072604115ab50d023eb5c33d4f3229400e441f4Keshava Munegowda u8 tll_channel_count) 19954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{ 20054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi unsigned reg; 20154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi int i; 20254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 20354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Program the 3 TLL channels upfront */ 204c072604115ab50d023eb5c33d4f3229400e441f4Keshava Munegowda for (i = 0; i < tll_channel_count; i++) { 20554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); 20654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 20754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Disable AutoIdle, BitStuffing and use SDR Mode */ 20854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE 20954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF 21054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE); 21154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ehci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg); 21254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 21354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 21454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Program Common TLL register */ 21554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_SHARED_CONF); 21654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON 21754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi | OMAP_TLL_SHARED_CONF_USB_DIVRATION 21854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi | OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN); 21954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN; 22054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 22154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ehci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); 22254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 22354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Enable channels now */ 224c072604115ab50d023eb5c33d4f3229400e441f4Keshava Munegowda for (i = 0; i < tll_channel_count; i++) { 22554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); 22654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 22754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Enable only the reg that is needed */ 22854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (!(tll_channel_mask & 1<<i)) 22954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi continue; 23054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 23154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg |= OMAP_TLL_CHANNEL_CONF_CHANEN; 23254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ehci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg); 23354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 23454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ehci_omap_writeb(omap->tll_base, 23554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe); 23654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(omap->dev, "ULPI_SCRATCH_REG[ch=%d]= 0x%02x\n", 23754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi i+1, ehci_omap_readb(omap->tll_base, 23854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi OMAP_TLL_ULPI_SCRATCH_REGISTER(i))); 23954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 24054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi} 24154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 24254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/ 24354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 2445aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Guptastatic void omap_ehci_soft_phy_reset(struct ehci_hcd_omap *omap, u8 port) 2455aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta{ 2465aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta unsigned long timeout = jiffies + msecs_to_jiffies(1000); 2475aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta unsigned reg = 0; 2485aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta 2495aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta reg = ULPI_FUNC_CTRL_RESET 2505aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta /* FUNCTION_CTRL_SET register */ 2515aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta | (ULPI_SET(ULPI_FUNC_CTRL) << EHCI_INSNREG05_ULPI_REGADD_SHIFT) 2525aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta /* Write */ 2535aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta | (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) 2545aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta /* PORTn */ 2555aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta | ((port + 1) << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) 2565aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta /* start ULPI access*/ 2575aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta | (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT); 2585aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta 2595aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta ehci_omap_writel(omap->ehci_base, EHCI_INSNREG05_ULPI, reg); 2605aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta 2615aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta /* Wait for ULPI access completion */ 2625aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta while ((ehci_omap_readl(omap->ehci_base, EHCI_INSNREG05_ULPI) 2635aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta & (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT))) { 2645aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta cpu_relax(); 2655aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta 2665aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta if (time_after(jiffies, timeout)) { 2675aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta dev_dbg(omap->dev, "phy reset operation timed out\n"); 2685aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta break; 2695aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta } 2705aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta } 2715aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta} 2725aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta 27354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* omap_start_ehc 27454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * - Start the TI USBHOST controller 27554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */ 27654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) 27754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{ 27854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi unsigned long timeout = jiffies + msecs_to_jiffies(1000); 27954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi u8 tll_ch_mask = 0; 28054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi unsigned reg = 0; 28154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi int ret = 0; 28254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 28354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(omap->dev, "starting TI EHCI USB Controller\n"); 28454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 28554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Enable Clocks for USBHOST */ 28654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->usbhost_ick = clk_get(omap->dev, "usbhost_ick"); 28754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (IS_ERR(omap->usbhost_ick)) { 28854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ret = PTR_ERR(omap->usbhost_ick); 28954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_host_ick; 29054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 29154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_enable(omap->usbhost_ick); 29254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 293c5dff5545c97ab33bdb2a529a2375966ceb0700cAnand Gadiyar omap->usbhost_hs_fck = clk_get(omap->dev, "hs_fck"); 2946dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda if (IS_ERR(omap->usbhost_hs_fck)) { 2956dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda ret = PTR_ERR(omap->usbhost_hs_fck); 29654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_host_120m_fck; 29754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 2986dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda clk_enable(omap->usbhost_hs_fck); 29954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 300c5dff5545c97ab33bdb2a529a2375966ceb0700cAnand Gadiyar omap->usbhost_fs_fck = clk_get(omap->dev, "fs_fck"); 3016dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda if (IS_ERR(omap->usbhost_fs_fck)) { 3026dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda ret = PTR_ERR(omap->usbhost_fs_fck); 30354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_host_48m_fck; 30454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 3056dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda clk_enable(omap->usbhost_fs_fck); 30654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 30754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->phy_reset) { 30854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Refer: ISSUE1 */ 30954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (gpio_is_valid(omap->reset_gpio_port[0])) { 31054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi gpio_request(omap->reset_gpio_port[0], 31154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi "USB1 PHY reset"); 31254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi gpio_direction_output(omap->reset_gpio_port[0], 0); 31354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 31454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 31554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (gpio_is_valid(omap->reset_gpio_port[1])) { 31654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi gpio_request(omap->reset_gpio_port[1], 31754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi "USB2 PHY reset"); 31854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi gpio_direction_output(omap->reset_gpio_port[1], 0); 31954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 32054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 32154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Hold the PHY in RESET for enough time till DIR is high */ 32254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi udelay(10); 32354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 32454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 32554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Configure TLL for 60Mhz clk for ULPI */ 32654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->usbtll_fck = clk_get(omap->dev, "usbtll_fck"); 32754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (IS_ERR(omap->usbtll_fck)) { 32854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ret = PTR_ERR(omap->usbtll_fck); 32954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_tll_fck; 33054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 33154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_enable(omap->usbtll_fck); 33254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 33354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->usbtll_ick = clk_get(omap->dev, "usbtll_ick"); 33454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (IS_ERR(omap->usbtll_ick)) { 33554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ret = PTR_ERR(omap->usbtll_ick); 33654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_tll_ick; 33754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 33854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_enable(omap->usbtll_ick); 33954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 34054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* perform TLL soft reset, and wait until reset is complete */ 34154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, 34254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi OMAP_USBTLL_SYSCONFIG_SOFTRESET); 34354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 34454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Wait for TLL reset to complete */ 34554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi while (!(ehci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS) 34654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi & OMAP_USBTLL_SYSSTATUS_RESETDONE)) { 34754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi cpu_relax(); 34854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 34954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (time_after(jiffies, timeout)) { 35054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(omap->dev, "operation timed out\n"); 35154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ret = -EINVAL; 35254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_sys_status; 35354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 35454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 35554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 35654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(omap->dev, "TLL RESET DONE\n"); 35754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 35854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* (1<<3) = no idle mode only for initial debugging */ 35954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, 36054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | 36154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi OMAP_USBTLL_SYSCONFIG_SIDLEMODE | 36254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi OMAP_USBTLL_SYSCONFIG_CACTIVITY); 36354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 36454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 36554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Put UHH in NoIdle/NoStandby mode */ 36654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); 36754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP 36854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi | OMAP_UHH_SYSCONFIG_SIDLEMODE 36954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi | OMAP_UHH_SYSCONFIG_CACTIVITY 37054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi | OMAP_UHH_SYSCONFIG_MIDLEMODE); 37154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; 37254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 37354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); 37454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 37554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); 37654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 37754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* setup ULPI bypass and burst configurations */ 37854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN 37954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi | OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN 38054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); 38154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; 38254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 38354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN) 38454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; 38554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN) 38654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; 38754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN) 38854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; 38954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 39054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Bypass the TLL module for PHY mode operation */ 39197dc7c61f1a25e906c0eb65fac2573e1ce063d63Ajay Kumar Gupta if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { 39297dc7c61f1a25e906c0eb65fac2573e1ce063d63Ajay Kumar Gupta dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n"); 393a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar if (is_ehci_phy_mode(omap->port_mode[0]) || 394a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar is_ehci_phy_mode(omap->port_mode[1]) || 395a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar is_ehci_phy_mode(omap->port_mode[2])) 39654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; 39754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi else 39854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; 39954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } else { 40054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); 401a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar if (is_ehci_phy_mode(omap->port_mode[0])) 40254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; 403a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar else if (is_ehci_tll_mode(omap->port_mode[0])) 40454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; 40554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 406a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar if (is_ehci_phy_mode(omap->port_mode[1])) 40754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; 408a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar else if (is_ehci_tll_mode(omap->port_mode[1])) 40954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; 41054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 411a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar if (is_ehci_phy_mode(omap->port_mode[2])) 41254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; 413a42ccdc14de388a35ad0e8057543369351395eb9Anand Gadiyar else if (is_ehci_tll_mode(omap->port_mode[2])) 41454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; 41554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 41654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 41754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); 41854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); 41954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 42054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 421572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar /* 422572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar * An undocumented "feature" in the OMAP3 EHCI controller, 423572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar * causes suspended ports to be taken out of suspend when 424572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar * the USBCMD.Run/Stop bit is cleared (for example when 425572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar * we do ehci_bus_suspend). 426572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar * This breaks suspend-resume if the root-hub is allowed 427572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar * to suspend. Writing 1 to this undocumented register bit 428572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar * disables this feature and restores normal behavior. 429572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar */ 430572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar ehci_omap_writel(omap->ehci_base, EHCI_INSNREG04, 431572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar EHCI_INSNREG04_DISABLE_UNSUSPEND); 432572538dee7a4b25f3e77fdc11d20dbb753ecf367Anand Gadiyar 43354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) || 43454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) || 43554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)) { 43654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 43754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) 43854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi tll_ch_mask |= OMAP_TLL_CHANNEL_1_EN_MASK; 43954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) 44054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi tll_ch_mask |= OMAP_TLL_CHANNEL_2_EN_MASK; 44154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL) 44254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK; 44354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 44454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Enable UTMI mode for required TLL channels */ 445c072604115ab50d023eb5c33d4f3229400e441f4Keshava Munegowda omap_usb_utmi_init(omap, tll_ch_mask, OMAP_TLL_CHANNEL_COUNT); 44654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 44754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 44854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->phy_reset) { 44954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Refer ISSUE1: 45054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Hold the PHY in RESET for enough time till 45154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * PHY is settled and ready 45254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */ 45354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi udelay(10); 45454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 45554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (gpio_is_valid(omap->reset_gpio_port[0])) 45654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi gpio_set_value(omap->reset_gpio_port[0], 1); 45754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 45854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (gpio_is_valid(omap->reset_gpio_port[1])) 45954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi gpio_set_value(omap->reset_gpio_port[1], 1); 46054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 46154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 4625aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta /* Soft reset the PHY using PHY reset command over ULPI */ 4635aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) 4645aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta omap_ehci_soft_phy_reset(omap, 0); 4655aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) 4665aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta omap_ehci_soft_phy_reset(omap, 1); 4675aa4af2ce6a0643f32d47f21614817792b85298dAjay Kumar Gupta 46854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi return 0; 46954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 47054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_sys_status: 47154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_disable(omap->usbtll_ick); 47254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_put(omap->usbtll_ick); 47354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 47454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_tll_ick: 47554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_disable(omap->usbtll_fck); 47654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_put(omap->usbtll_fck); 47754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 47854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_tll_fck: 4796dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda clk_disable(omap->usbhost_fs_fck); 4806dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda clk_put(omap->usbhost_fs_fck); 48154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 48254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->phy_reset) { 48354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (gpio_is_valid(omap->reset_gpio_port[0])) 48454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi gpio_free(omap->reset_gpio_port[0]); 48554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 48654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (gpio_is_valid(omap->reset_gpio_port[1])) 48754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi gpio_free(omap->reset_gpio_port[1]); 48854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 48954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 49054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_host_48m_fck: 4916dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda clk_disable(omap->usbhost_hs_fck); 4926dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda clk_put(omap->usbhost_hs_fck); 49354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 49454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_host_120m_fck: 49554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_disable(omap->usbhost_ick); 49654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_put(omap->usbhost_ick); 49754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 49854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_host_ick: 49954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi return ret; 50054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi} 50154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 50254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) 50354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{ 50454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi unsigned long timeout = jiffies + msecs_to_jiffies(100); 50554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 50654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(omap->dev, "stopping TI EHCI USB Controller\n"); 50754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 50854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* Reset OMAP modules for insmod/rmmod to work */ 50954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, 51054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi OMAP_UHH_SYSCONFIG_SOFTRESET); 51154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) 51254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi & (1 << 0))) { 51354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi cpu_relax(); 51454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 51554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (time_after(jiffies, timeout)) 51654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(omap->dev, "operation timed out\n"); 51754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 51854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 51954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) 52054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi & (1 << 1))) { 52154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi cpu_relax(); 52254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 52354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (time_after(jiffies, timeout)) 52454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(omap->dev, "operation timed out\n"); 52554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 52654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 52754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) 52854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi & (1 << 2))) { 52954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi cpu_relax(); 53054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 53154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (time_after(jiffies, timeout)) 53254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(omap->dev, "operation timed out\n"); 53354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 53454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 53554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1)); 53654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 53754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi while (!(ehci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS) 53854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi & (1 << 0))) { 53954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi cpu_relax(); 54054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 54154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (time_after(jiffies, timeout)) 54254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(omap->dev, "operation timed out\n"); 54354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 54454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 54554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->usbtll_fck != NULL) { 54654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_disable(omap->usbtll_fck); 54754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_put(omap->usbtll_fck); 54854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->usbtll_fck = NULL; 54954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 55054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 55154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->usbhost_ick != NULL) { 55254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_disable(omap->usbhost_ick); 55354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_put(omap->usbhost_ick); 55454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->usbhost_ick = NULL; 55554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 55654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 5576dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda if (omap->usbhost_fs_fck != NULL) { 5586dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda clk_disable(omap->usbhost_fs_fck); 5596dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda clk_put(omap->usbhost_fs_fck); 5606dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda omap->usbhost_fs_fck = NULL; 56154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 56254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 5636dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda if (omap->usbhost_hs_fck != NULL) { 5646dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda clk_disable(omap->usbhost_hs_fck); 5656dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda clk_put(omap->usbhost_hs_fck); 5666dba39e278b81665a838f37a75fe37b89f3ce610Keshava Munegowda omap->usbhost_hs_fck = NULL; 56754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 56854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 56954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->usbtll_ick != NULL) { 57054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_disable(omap->usbtll_ick); 57154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi clk_put(omap->usbtll_ick); 57254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->usbtll_ick = NULL; 57354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 57454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 57554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (omap->phy_reset) { 57654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (gpio_is_valid(omap->reset_gpio_port[0])) 57754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi gpio_free(omap->reset_gpio_port[0]); 57854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 57954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (gpio_is_valid(omap->reset_gpio_port[1])) 58054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi gpio_free(omap->reset_gpio_port[1]); 58154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 58254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 58354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(omap->dev, "Clock to USB host has been disabled\n"); 58454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi} 58554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 58654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/ 58754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 58854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic const struct hc_driver ehci_omap_hc_driver; 58954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 59054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* configure so an HC device and id are always provided */ 59154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* always called with process context; sleeping is OK */ 59254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 59354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/** 59454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * ehci_hcd_omap_probe - initialize TI-based HCDs 59554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * 59654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Allocates basic resources for this USB host controller, and 59754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * then invokes the start() method for the HCD associated with it 59854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * through the hotplug entry's driver_data. 59954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */ 60054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic int ehci_hcd_omap_probe(struct platform_device *pdev) 60154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{ 60254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct ehci_hcd_omap_platform_data *pdata = pdev->dev.platform_data; 60354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct ehci_hcd_omap *omap; 60454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct resource *res; 60554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct usb_hcd *hcd; 60654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 60754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi int irq = platform_get_irq(pdev, 0); 60854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi int ret = -ENODEV; 609881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta int i; 610881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta char supply[7]; 61154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 61254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (!pdata) { 61354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(&pdev->dev, "missing platform_data\n"); 61454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_pdata; 61554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 61654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 61754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (usb_disabled()) 61854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_disabled; 61954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 62054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap = kzalloc(sizeof(*omap), GFP_KERNEL); 62154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (!omap) { 62254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ret = -ENOMEM; 623b2b608090544ecd30a826c32958bca74fb717963Julia Lawall goto err_disabled; 62454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 62554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 62654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev, 62754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_name(&pdev->dev)); 62854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (!hcd) { 62954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(&pdev->dev, "failed to create hcd with err %d\n", ret); 63054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ret = -ENOMEM; 63154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_create_hcd; 63254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 63354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 63454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi platform_set_drvdata(pdev, omap); 63554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->dev = &pdev->dev; 63654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->phy_reset = pdata->phy_reset; 63754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->reset_gpio_port[0] = pdata->reset_gpio_port[0]; 63854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->reset_gpio_port[1] = pdata->reset_gpio_port[1]; 63954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->reset_gpio_port[2] = pdata->reset_gpio_port[2]; 64054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->port_mode[0] = pdata->port_mode[0]; 64154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->port_mode[1] = pdata->port_mode[1]; 64254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->port_mode[2] = pdata->port_mode[2]; 64354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->ehci = hcd_to_ehci(hcd); 64454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->ehci->sbrn = 0x20; 64554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 64654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 64754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 64854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi hcd->rsrc_start = res->start; 64954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi hcd->rsrc_len = resource_size(res); 65054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 65154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); 65254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (!hcd->regs) { 65354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_err(&pdev->dev, "EHCI ioremap failed\n"); 65454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ret = -ENOMEM; 65554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_ioremap; 65654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 65754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 65854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* we know this is the memory we want, no need to ioremap again */ 65954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->ehci->caps = hcd->regs; 66054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->ehci_base = hcd->regs; 66154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 66254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 66354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->uhh_base = ioremap(res->start, resource_size(res)); 66454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (!omap->uhh_base) { 66554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_err(&pdev->dev, "UHH ioremap failed\n"); 66654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ret = -ENOMEM; 66754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_uhh_ioremap; 66854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 66954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 67054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi res = platform_get_resource(pdev, IORESOURCE_MEM, 2); 67154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->tll_base = ioremap(res->start, resource_size(res)); 67254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (!omap->tll_base) { 67354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_err(&pdev->dev, "TLL ioremap failed\n"); 67454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ret = -ENOMEM; 67554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_tll_ioremap; 67654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 67754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 678881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta /* get ehci regulator and enable */ 679881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { 680881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta if (omap->port_mode[i] != EHCI_HCD_OMAP_MODE_PHY) { 681881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta omap->regulator[i] = NULL; 682881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta continue; 683881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta } 684881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta snprintf(supply, sizeof(supply), "hsusb%d", i); 685881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta omap->regulator[i] = regulator_get(omap->dev, supply); 68618f91196b6e7994bd694a96a6c3b0ac1f3e81d82Ajay Kumar Gupta if (IS_ERR(omap->regulator[i])) { 68718f91196b6e7994bd694a96a6c3b0ac1f3e81d82Ajay Kumar Gupta omap->regulator[i] = NULL; 688881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta dev_dbg(&pdev->dev, 689881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta "failed to get ehci port%d regulator\n", i); 69018f91196b6e7994bd694a96a6c3b0ac1f3e81d82Ajay Kumar Gupta } else { 691881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta regulator_enable(omap->regulator[i]); 69218f91196b6e7994bd694a96a6c3b0ac1f3e81d82Ajay Kumar Gupta } 693881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta } 694881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta 69554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ret = omap_start_ehc(omap, hcd); 69654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (ret) { 69754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(&pdev->dev, "failed to start ehci\n"); 69854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_start; 69954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 70054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 70154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->ehci->regs = hcd->regs 70254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi + HC_LENGTH(readl(&omap->ehci->caps->hc_capbase)); 70354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 704bdb581bd6bd59a3303974977544d679d849214d1Anand Gadiyar dbg_hcs_params(omap->ehci, "reset"); 705bdb581bd6bd59a3303974977544d679d849214d1Anand Gadiyar dbg_hcc_params(omap->ehci, "reset"); 706bdb581bd6bd59a3303974977544d679d849214d1Anand Gadiyar 70754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* cache this readonly data; minimize chip reads */ 70854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap->ehci->hcs_params = readl(&omap->ehci->caps->hcs_params); 70954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 71054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); 71154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (ret) { 71254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); 71354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi goto err_add_hcd; 71454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 71554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 716289621c31bffb743e4007f6332b9004cdd080644Ajay Kumar Gupta /* root ports should always stay powered */ 717289621c31bffb743e4007f6332b9004cdd080644Ajay Kumar Gupta ehci_port_power(omap->ehci, 1); 718289621c31bffb743e4007f6332b9004cdd080644Ajay Kumar Gupta 71954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi return 0; 72054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 72154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_add_hcd: 72254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap_stop_ehc(omap, hcd); 72354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 72454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_start: 725881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { 726881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta if (omap->regulator[i]) { 727881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta regulator_disable(omap->regulator[i]); 728881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta regulator_put(omap->regulator[i]); 729881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta } 730881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta } 73154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi iounmap(omap->tll_base); 73254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 73354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_tll_ioremap: 73454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi iounmap(omap->uhh_base); 73554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 73654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_uhh_ioremap: 73754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi iounmap(hcd->regs); 73854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 73954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_ioremap: 74054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi usb_put_hcd(hcd); 74154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 74254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_create_hcd: 743b2b608090544ecd30a826c32958bca74fb717963Julia Lawall kfree(omap); 74454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_disabled: 74554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbierr_pdata: 74654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi return ret; 74754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi} 74854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 74954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* may be called without controller electrically present */ 75054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/* may be called with controller, bus, and devices active */ 75154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 75254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/** 75354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * ehci_hcd_omap_remove - shutdown processing for EHCI HCDs 75454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * @pdev: USB Host Controller being removed 75554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * 75654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * Reverses the effect of usb_ehci_hcd_omap_probe(), first invoking 75754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * the HCD's stop() method. It is always called from a thread 75854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * context, normally "rmmod", "apmd", or something similar. 75954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */ 76054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic int ehci_hcd_omap_remove(struct platform_device *pdev) 76154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{ 76254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); 76354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); 764881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta int i; 76554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 76654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi usb_remove_hcd(hcd); 76754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi omap_stop_ehc(omap, hcd); 76854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi iounmap(hcd->regs); 769881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { 770881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta if (omap->regulator[i]) { 771881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta regulator_disable(omap->regulator[i]); 772881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta regulator_put(omap->regulator[i]); 773881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta } 774881142660697bba0f3ef44f070d80632082c978fAjay Kumar Gupta } 77554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi iounmap(omap->tll_base); 77654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi iounmap(omap->uhh_base); 77754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi usb_put_hcd(hcd); 778d3ae8562d43fe2b97d605dd67dc67bf8fa9b956aAjay Kumar Gupta kfree(omap); 77954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 78054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi return 0; 78154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi} 78254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 78354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic void ehci_hcd_omap_shutdown(struct platform_device *pdev) 78454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi{ 78554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); 78654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); 78754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 78854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi if (hcd->driver->shutdown) 78954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi hcd->driver->shutdown(hcd); 79054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi} 79154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 79254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic struct platform_driver ehci_hcd_omap_driver = { 79354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .probe = ehci_hcd_omap_probe, 79454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .remove = ehci_hcd_omap_remove, 79554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .shutdown = ehci_hcd_omap_shutdown, 79654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /*.suspend = ehci_hcd_omap_suspend, */ 79754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /*.resume = ehci_hcd_omap_resume, */ 79854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .driver = { 79954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .name = "ehci-omap", 80054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi } 80154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}; 80254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 80354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi/*-------------------------------------------------------------------------*/ 80454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 80554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbistatic const struct hc_driver ehci_omap_hc_driver = { 80654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .description = hcd_name, 80754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .product_desc = "OMAP-EHCI Host Controller", 80854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .hcd_priv_size = sizeof(struct ehci_hcd), 80954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 81054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* 81154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * generic hardware linkage 81254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */ 81354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .irq = ehci_irq, 81454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .flags = HCD_MEMORY | HCD_USB2, 81554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 81654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* 81754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * basic lifecycle operations 81854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */ 81954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .reset = ehci_init, 82054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .start = ehci_run, 82154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .stop = ehci_stop, 82254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .shutdown = ehci_shutdown, 82354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 82454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* 82554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * managing i/o requests and associated device resources 82654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */ 82754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .urb_enqueue = ehci_urb_enqueue, 82854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .urb_dequeue = ehci_urb_dequeue, 82954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .endpoint_disable = ehci_endpoint_disable, 83054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .endpoint_reset = ehci_endpoint_reset, 83154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 83254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* 83354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * scheduling support 83454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */ 83554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .get_frame_number = ehci_get_frame, 83654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 83754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi /* 83854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi * root hub support 83954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi */ 84054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .hub_status_data = ehci_hub_status_data, 84154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .hub_control = ehci_hub_control, 84254ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .bus_suspend = ehci_bus_suspend, 84354ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .bus_resume = ehci_bus_resume, 84454ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 84554ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, 84654ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi}; 84754ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 84854ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe BalbiMODULE_ALIAS("platform:omap-ehci"); 84954ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe BalbiMODULE_AUTHOR("Texas Instruments, Inc."); 85054ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe BalbiMODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>"); 85154ab2b02ef6a454b4cca969f546d0dd43fec7308Felipe Balbi 852