diff options
| -rw-r--r-- | arch/arm/include/asm/arch-omap3/ehci.h (renamed from arch/arm/include/asm/arch-omap3/ehci_omap3.h) | 45 | ||||
| -rw-r--r-- | arch/arm/include/asm/arch-omap4/ehci.h | 49 | ||||
| -rw-r--r-- | arch/arm/include/asm/ehci-omap.h | 142 | ||||
| -rw-r--r-- | board/ti/beagle/beagle.c | 22 | ||||
| -rw-r--r-- | board/ti/panda/panda.c | 38 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-omap.c | 207 | 
6 files changed, 425 insertions, 78 deletions
| diff --git a/arch/arm/include/asm/arch-omap3/ehci_omap3.h b/arch/arm/include/asm/arch-omap3/ehci.h index cd01f5029..0f73d2029 100644 --- a/arch/arm/include/asm/arch-omap3/ehci_omap3.h +++ b/arch/arm/include/asm/arch-omap3/ehci.h @@ -24,35 +24,32 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,   * MA 02110-1301 USA   */ -#ifndef _EHCI_OMAP3_H_ -#define _EHCI_OMAP3_H_ +#ifndef _OMAP3_EHCI_H_ +#define _OMAP3_EHCI_H_  /* USB/EHCI registers */ -#define OMAP3_USBTLL_BASE				0x48062000UL -#define OMAP3_UHH_BASE					0x48064000UL -#define OMAP3_EHCI_BASE					0x48064800UL +#define OMAP_USBTLL_BASE				0x48062000UL +#define OMAP_UHH_BASE					0x48064000UL +#define OMAP_EHCI_BASE					0x48064800UL  /* TLL Register Set */ -#define	OMAP_USBTLL_SYSCONFIG				(0x10) -#define	OMAP_USBTLL_SYSCONFIG_SOFTRESET			(1 << 1) -#define	OMAP_USBTLL_SYSCONFIG_ENAWAKEUP			(1 << 2) -#define	OMAP_USBTLL_SYSCONFIG_SIDLEMODE			(1 << 3) -#define	OMAP_USBTLL_SYSCONFIG_CACTIVITY			(1 << 8) - -#define	OMAP_USBTLL_SYSSTATUS				(0x14) -#define	OMAP_USBTLL_SYSSTATUS_RESETDONE			(1 << 0) +#define OMAP_USBTLL_SYSCONFIG_SOFTRESET			(1 << 1) +#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP			(1 << 2) +#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE			(1 << 3) +#define OMAP_USBTLL_SYSCONFIG_CACTIVITY			(1 << 8) +#define OMAP_USBTLL_SYSSTATUS_RESETDONE			1  /* UHH Register Set */ -#define	OMAP_UHH_SYSCONFIG				(0x10) -#define	OMAP_UHH_SYSCONFIG_SOFTRESET			(1 << 1) -#define	OMAP_UHH_SYSCONFIG_CACTIVITY			(1 << 8) -#define	OMAP_UHH_SYSCONFIG_SIDLEMODE			(1 << 3) -#define	OMAP_UHH_SYSCONFIG_ENAWAKEUP			(1 << 2) -#define	OMAP_UHH_SYSCONFIG_MIDLEMODE			(1 << 12) +#define OMAP_UHH_SYSCONFIG_SOFTRESET			(1 << 1) +#define OMAP_UHH_SYSCONFIG_CACTIVITY			(1 << 8) +#define OMAP_UHH_SYSCONFIG_SIDLEMODE			(1 << 3) +#define OMAP_UHH_SYSCONFIG_ENAWAKEUP			(1 << 2) +#define OMAP_UHH_SYSCONFIG_MIDLEMODE			(1 << 12) +#define OMAP_UHH_SYSSTATUS_EHCI_RESETDONE		(1 << 2) -#define	OMAP_UHH_HOSTCONFIG				(0x40) -#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN		(1 << 2) -#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN		(1 << 3) -#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN		(1 << 4) +#define OMAP_UHH_SYSCONFIG_VAL		(OMAP_UHH_SYSCONFIG_CACTIVITY | \ +					OMAP_UHH_SYSCONFIG_SIDLEMODE | \ +					OMAP_UHH_SYSCONFIG_ENAWAKEUP | \ +					OMAP_UHH_SYSCONFIG_MIDLEMODE) -#endif /* _EHCI_OMAP3_H_ */ +#endif /* _OMAP3_EHCI_H_ */ diff --git a/arch/arm/include/asm/arch-omap4/ehci.h b/arch/arm/include/asm/arch-omap4/ehci.h new file mode 100644 index 000000000..984c8b9f7 --- /dev/null +++ b/arch/arm/include/asm/arch-omap4/ehci.h @@ -0,0 +1,49 @@ +/* + * OMAP EHCI port support + * Based on LINUX KERNEL + * drivers/usb/host/ehci-omap.c and drivers/mfd/omap-usb-host.c + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com + * Author: Govindraj R <govindraj.raja@ti.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2  of + * the License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _OMAP4_EHCI_H_ +#define _OMAP4_EHCI_H_ + +#define OMAP_EHCI_BASE				(OMAP44XX_L4_CORE_BASE + 0x64C00) +#define OMAP_UHH_BASE				(OMAP44XX_L4_CORE_BASE + 0x64000) +#define OMAP_USBTLL_BASE			(OMAP44XX_L4_CORE_BASE + 0x62000) + +/* UHH, TLL and opt clocks */ +#define CM_L3INIT_HSUSBHOST_CLKCTRL		0x4A009358UL + +#define HSUSBHOST_CLKCTRL_CLKSEL_UTMI_P1_MASK	(1 << 24) + +/* TLL Register Set */ +#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE		(1 << 3) +#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP		(1 << 2) +#define OMAP_USBTLL_SYSCONFIG_SOFTRESET		(1 << 1) +#define OMAP_USBTLL_SYSCONFIG_CACTIVITY		(1 << 8) +#define OMAP_USBTLL_SYSSTATUS_RESETDONE		1 + +#define OMAP_UHH_SYSCONFIG_SOFTRESET		1 +#define OMAP_UHH_SYSSTATUS_EHCI_RESETDONE	(1 << 2) +#define OMAP_UHH_SYSCONFIG_NOIDLE		(1 << 2) +#define OMAP_UHH_SYSCONFIG_NOSTDBY		(1 << 4) + +#define OMAP_UHH_SYSCONFIG_VAL	(OMAP_UHH_SYSCONFIG_NOIDLE | \ +					OMAP_UHH_SYSCONFIG_NOSTDBY) + +#endif /* _OMAP4_EHCI_H_ */ diff --git a/arch/arm/include/asm/ehci-omap.h b/arch/arm/include/asm/ehci-omap.h new file mode 100644 index 000000000..e72c5df11 --- /dev/null +++ b/arch/arm/include/asm/ehci-omap.h @@ -0,0 +1,142 @@ +/* + * OMAP EHCI port support + * Based on LINUX KERNEL + * drivers/usb/host/ehci-omap.c and drivers/mfd/omap-usb-host.c + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com* + * Author: Govindraj R <govindraj.raja@ti.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2  of + * the License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _OMAP_COMMON_EHCI_H_ +#define _OMAP_COMMON_EHCI_H_ + +enum usbhs_omap_port_mode { +	OMAP_USBHS_PORT_MODE_UNUSED, +	OMAP_EHCI_PORT_MODE_PHY, +	OMAP_EHCI_PORT_MODE_TLL, +	OMAP_EHCI_PORT_MODE_HSIC, +}; + +#ifdef CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS +#define OMAP_HS_USB_PORTS	CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS +#else +#define OMAP_HS_USB_PORTS	3 +#endif + +#define is_ehci_phy_mode(x)	((x) == OMAP_EHCI_PORT_MODE_PHY) +#define is_ehci_tll_mode(x)	((x) == OMAP_EHCI_PORT_MODE_TLL) +#define is_ehci_hsic_mode(x)	((x) == OMAP_EHCI_PORT_MODE_HSIC) + +/* Values of UHH_REVISION - Note: these are not given in the TRM */ +#define OMAP_USBHS_REV1					0x00000010 /* OMAP3 */ +#define OMAP_USBHS_REV2					0x50700100 /* OMAP4 */ + +/* UHH Register Set */ +#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN		(1 << 2) +#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN		(1 << 3) +#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN		(1 << 4) +#define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN		(1 << 5) + +#define OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS		1 +#define OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS		(1 << 11) +#define OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS		(1 << 12) +#define OMAP4_UHH_HOSTCONFIG_APP_START_CLK		(1 << 31) + +#define OMAP_P1_MODE_CLEAR				(3 << 16) +#define OMAP_P1_MODE_TLL				(1 << 16) +#define OMAP_P1_MODE_HSIC				(3 << 16) +#define OMAP_P2_MODE_CLEAR				(3 << 18) +#define OMAP_P2_MODE_TLL				(1 << 18) +#define OMAP_P2_MODE_HSIC				(3 << 18) +#define OMAP_P3_MODE_HSIC				(3 << 20) + +/* EHCI Register Set */ +#define EHCI_INSNREG04_DISABLE_UNSUSPEND		(1 << 5) +#define EHCI_INSNREG05_ULPI_CONTROL_SHIFT		31 +#define EHCI_INSNREG05_ULPI_PORTSEL_SHIFT		24 +#define EHCI_INSNREG05_ULPI_OPSEL_SHIFT			22 +#define EHCI_INSNREG05_ULPI_REGADD_SHIFT		16 + +#define OMAP_REV1_TLL_CHANNEL_COUNT			3 +#define OMAP_REV2_TLL_CHANNEL_COUNT			2 + +/* TLL Register Set */ +#define OMAP_TLL_CHANNEL_CONF(num)			(0x004 * num) +#define OMAP_TLL_CHANNEL_CONF_DRVVBUS			(1 << 16) +#define OMAP_TLL_CHANNEL_CONF_CHRGVBUS			(1 << 15) +#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF		(1 << 11) +#define OMAP_TLL_CHANNEL_CONF_CHANMODE_TRANSPARENT_UTMI	(2 << 1) +#define OMAP_TLL_CHANNEL_CONF_CHANEN			1 + +struct omap_usbhs_board_data { +	enum usbhs_omap_port_mode port_mode[OMAP_HS_USB_PORTS]; +}; + +struct omap_usbtll { +	u32 rev;		/* 0x00 */ +	u32 hwinfo;		/* 0x04 */ +	u8 reserved1[0x8]; +	u32 sysc;		/* 0x10 */ +	u32 syss;		/* 0x14 */ +	u32 irqst;		/* 0x18 */ +	u32 irqen;		/* 0x1c */ +	u8 reserved2[0x10]; +	u32 shared_conf;	/* 0x30 */ +	u8 reserved3[0xc]; +	u32 channel_conf;	/* 0x40 */ +}; + +struct omap_uhh { +	u32 rev;	/* 0x00 */ +	u32 hwinfo;	/* 0x04 */ +	u8 reserved1[0x8]; +	u32 sysc;	/* 0x10 */ +	u32 syss;	/* 0x14 */ +	u8 reserved2[0x28]; +	u32 hostconfig;	/* 0x40 */ +	u32 debugcsr;	/* 0x44 */ +}; + +struct omap_ehci { +	u32 hccapbase;		/* 0x00 */ +	u32 hcsparams;		/* 0x04 */ +	u32 hccparams;		/* 0x08 */ +	u8 reserved1[0x04]; +	u32 usbcmd;		/* 0x10 */ +	u32 usbsts;		/* 0x14 */ +	u32 usbintr;		/* 0x18 */ +	u32 frindex;		/* 0x1c */ +	u32 ctrldssegment;	/* 0x20 */ +	u32 periodiclistbase;	/* 0x24 */ +	u32 asysnclistaddr;	/* 0x28 */ +	u8 reserved2[0x24]; +	u32 configflag;		/* 0x50 */ +	u32 portsc_i;		/* 0x54 */ +	u8 reserved3[0x38]; +	u32 insreg00;		/* 0x90 */ +	u32 insreg01;		/* 0x94 */ +	u32 insreg02;		/* 0x98 */ +	u32 insreg03;		/* 0x9c */ +	u32 insreg04;		/* 0xa0 */ +	u32 insreg05_utmi_ulpi;	/* 0xa4 */ +	u32 insreg06;		/* 0xa8 */ +	u32 insreg07;		/* 0xac */ +	u32 insreg08;		/* 0xb0 */ +}; + +int omap_ehci_hcd_init(struct omap_usbhs_board_data *usbhs_pdata); +int omap_ehci_hcd_stop(void); + +#endif /* _OMAP_COMMON_EHCI_H_ */ diff --git a/board/ti/beagle/beagle.c b/board/ti/beagle/beagle.c index 624ff70d8..87578763b 100644 --- a/board/ti/beagle/beagle.c +++ b/board/ti/beagle/beagle.c @@ -45,6 +45,11 @@  #include "beagle.h"  #include <command.h> +#ifdef CONFIG_USB_EHCI +#include <usb.h> +#include <asm/ehci-omap.h> +#endif +  #define pr_debug(fmt, args...) debug(fmt, ##args)  #define TWL4030_I2C_BUS			0 @@ -449,6 +454,23 @@ void show_boot_progress(int val)  	if(val == 15)  		usb_stop();  } + +static struct omap_usbhs_board_data usbhs_bdata = { +	.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, +	.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, +	.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED +}; + +int ehci_hcd_init(void) +{ +	return omap_ehci_hcd_init(&usbhs_bdata); +} + +int ehci_hcd_stop(void) +{ +	return omap_ehci_hcd_stop(); +} +  #endif /* CONFIG_USB_EHCI */  #ifndef CONFIG_SPL_BUILD diff --git a/board/ti/panda/panda.c b/board/ti/panda/panda.c index fc8c0b4bc..ca4b8b35e 100644 --- a/board/ti/panda/panda.c +++ b/board/ti/panda/panda.c @@ -26,9 +26,16 @@  #include <asm/arch/mmc_host_def.h>  #include <asm/arch/clocks.h>  #include <asm/arch/gpio.h> +#include <asm/gpio.h>  #include "panda_mux_data.h" +#ifdef CONFIG_USB_EHCI +#include <usb.h> +#include <asm/arch/ehci.h> +#include <asm/ehci-omap.h> +#endif +  #define PANDA_ULPI_PHY_TYPE_GPIO       182  DECLARE_GLOBAL_DATA_PTR; @@ -177,6 +184,37 @@ int board_mmc_init(bd_t *bis)  }  #endif +#ifdef CONFIG_USB_EHCI + +static struct omap_usbhs_board_data usbhs_bdata = { +	.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, +	.port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, +	.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, +}; + +int ehci_hcd_init(void) +{ +	int ret; +	unsigned int utmi_clk; + +	/* Now we can enable our port clocks */ +	utmi_clk = readl((void *)CM_L3INIT_HSUSBHOST_CLKCTRL); +	utmi_clk |= HSUSBHOST_CLKCTRL_CLKSEL_UTMI_P1_MASK; +	sr32((void *)CM_L3INIT_HSUSBHOST_CLKCTRL, 0, 32, utmi_clk); + +	ret = omap_ehci_hcd_init(&usbhs_bdata); +	if (ret < 0) +		return ret; + +	return 0; +} + +int ehci_hcd_stop(void) +{ +	return omap_ehci_hcd_stop(); +} +#endif +  /*   * get_board_rev() - get board revision   */ diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 93d3bb734..00f787fc9 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -27,14 +27,78 @@   */  #include <common.h>  #include <usb.h> +#include <usb/ulpi.h> +#include <errno.h>  #include <asm/io.h>  #include <asm/gpio.h> -#include <asm/arch/clocks.h> -#include <asm/arch/clocks_omap3.h> -#include <asm/arch/ehci_omap3.h> -#include <asm/arch/sys_proto.h> +#include <asm/arch/ehci.h> +#include <asm/ehci-omap.h>  #include "ehci-core.h" +static struct omap_uhh *const uhh = (struct omap_uhh *)OMAP_UHH_BASE; +static struct omap_usbtll *const usbtll = (struct omap_usbtll *)OMAP_USBTLL_BASE; +static struct omap_ehci *const ehci = (struct omap_ehci *)OMAP_EHCI_BASE; + +static int omap_uhh_reset(void) +{ +	unsigned long init = get_timer(0); + +	/* perform UHH soft reset, and wait until reset is complete */ +	writel(OMAP_UHH_SYSCONFIG_SOFTRESET, &uhh->sysc); + +	/* Wait for UHH reset to complete */ +	while (!(readl(&uhh->syss) & OMAP_UHH_SYSSTATUS_EHCI_RESETDONE)) +		if (get_timer(init) > CONFIG_SYS_HZ) { +			debug("OMAP UHH error: timeout resetting ehci\n"); +			return -EL3RST; +		} + +	return 0; +} + +static int omap_ehci_tll_reset(void) +{ +	unsigned long init = get_timer(0); + +	/* perform TLL soft reset, and wait until reset is complete */ +	writel(OMAP_USBTLL_SYSCONFIG_SOFTRESET, &usbtll->sysc); + +	/* Wait for TLL reset to complete */ +	while (!(readl(&usbtll->syss) & OMAP_USBTLL_SYSSTATUS_RESETDONE)) +		if (get_timer(init) > CONFIG_SYS_HZ) { +			debug("OMAP EHCI error: timeout resetting TLL\n"); +			return -EL3RST; +	} + +	return 0; +} + +static void omap_usbhs_hsic_init(int port) +{ +	unsigned int reg; + +	/* Enable channels now */ +	reg = readl(&usbtll->channel_conf + port); + +	setbits_le32(®, (OMAP_TLL_CHANNEL_CONF_CHANMODE_TRANSPARENT_UTMI +		| OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF +		| OMAP_TLL_CHANNEL_CONF_DRVVBUS +		| OMAP_TLL_CHANNEL_CONF_CHRGVBUS +		| OMAP_TLL_CHANNEL_CONF_CHANEN)); + +	writel(reg, &usbtll->channel_conf + port); +} + +static void omap_ehci_soft_phy_reset(int port) +{ +	struct ulpi_viewport ulpi_vp; + +	ulpi_vp.viewport_addr = (u32)&ehci->insreg05_utmi_ulpi; +	ulpi_vp.port_num = port; + +	ulpi_reset(&ulpi_vp); +} +  inline int __board_usb_init(void)  {  	return 0; @@ -72,31 +136,31 @@ static inline void omap_ehci_phy_reset(int on, int delay)  #endif  /* Reset is needed otherwise the kernel-driver will throw an error. */ -int ehci_hcd_stop(void) +int omap_ehci_hcd_stop(void)  { -	debug("Resetting OMAP3 EHCI\n"); +	debug("Resetting OMAP EHCI\n");  	omap_ehci_phy_reset(1, 0); -	writel(OMAP_UHH_SYSCONFIG_SOFTRESET, -			OMAP3_UHH_BASE + OMAP_UHH_SYSCONFIG); -	/* disable USB clocks */ -	struct prcm *prcm_base = (struct prcm *)PRCM_BASE; -	sr32(&prcm_base->iclken_usbhost, 0, 1, 0); -	sr32(&prcm_base->fclken_usbhost, 0, 2, 0); -	sr32(&prcm_base->iclken3_core, 2, 1, 0); -	sr32(&prcm_base->fclken3_core, 2, 1, 0); + +	if (omap_uhh_reset() < 0) +		return -1; + +	if (omap_ehci_tll_reset() < 0) +		return -1; +  	return 0;  }  /* - * Initialize the OMAP3 EHCI controller and PHY. - * Based on "drivers/usb/host/ehci-omap.c" from Linux 2.6.37. + * Initialize the OMAP EHCI controller and PHY. + * Based on "drivers/usb/host/ehci-omap.c" from Linux 3.1   * See there for additional Copyrights.   */ -int ehci_hcd_init(void) +int omap_ehci_hcd_init(struct omap_usbhs_board_data *usbhs_pdata)  {  	int ret; +	unsigned int i, reg = 0, rev = 0; -	debug("Initializing OMAP3 EHCI\n"); +	debug("Initializing OMAP EHCI\n");  	ret = board_usb_init();  	if (ret < 0) @@ -105,52 +169,87 @@ int ehci_hcd_init(void)  	/* Put the PHY in RESET */  	omap_ehci_phy_reset(1, 10); -	struct prcm *prcm_base = (struct prcm *)PRCM_BASE; -	/* Enable USBHOST_L3_ICLK (USBHOST_MICLK) */ -	sr32(&prcm_base->iclken_usbhost, 0, 1, 1); -	/* -	 * Enable USBHOST_48M_FCLK (USBHOST_FCLK1) -	 * and USBHOST_120M_FCLK (USBHOST_FCLK2) -	 */ -	sr32(&prcm_base->fclken_usbhost, 0, 2, 3); -	/* Enable USBTTL_ICLK */ -	sr32(&prcm_base->iclken3_core, 2, 1, 1); -	/* Enable USBTTL_FCLK */ -	sr32(&prcm_base->fclken3_core, 2, 1, 1); -	debug("USB clocks enabled\n"); +	ret = omap_uhh_reset(); +	if (ret < 0) +		return ret; -	/* perform TLL soft reset, and wait until reset is complete */ -	writel(OMAP_USBTLL_SYSCONFIG_SOFTRESET, -		OMAP3_USBTLL_BASE + OMAP_USBTLL_SYSCONFIG); -	/* Wait for TLL reset to complete */ -	while (!(readl(OMAP3_USBTLL_BASE + OMAP_USBTLL_SYSSTATUS) -			& OMAP_USBTLL_SYSSTATUS_RESETDONE)) -		; -	debug("TLL reset done\n"); +	ret = omap_ehci_tll_reset(); +	if (ret) +		return ret;  	writel(OMAP_USBTLL_SYSCONFIG_ENAWAKEUP |  		OMAP_USBTLL_SYSCONFIG_SIDLEMODE | -		OMAP_USBTLL_SYSCONFIG_CACTIVITY, -		OMAP3_USBTLL_BASE + OMAP_USBTLL_SYSCONFIG); +		OMAP_USBTLL_SYSCONFIG_CACTIVITY, &usbtll->sysc);  	/* Put UHH in NoIdle/NoStandby mode */ -	writel(OMAP_UHH_SYSCONFIG_ENAWAKEUP -		| OMAP_UHH_SYSCONFIG_SIDLEMODE -		| OMAP_UHH_SYSCONFIG_CACTIVITY -		| OMAP_UHH_SYSCONFIG_MIDLEMODE, -		OMAP3_UHH_BASE + OMAP_UHH_SYSCONFIG); +	writel(OMAP_UHH_SYSCONFIG_VAL, &uhh->sysc); + +	/* setup ULPI bypass and burst configurations */ +	clrsetbits_le32(®, OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN, +		(OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN | +		OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN | +		OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN)); -	/* setup burst configurations */ -	writel(OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN -		| OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN -		| OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN, -		OMAP3_UHH_BASE + OMAP_UHH_HOSTCONFIG); +	rev = readl(&uhh->rev); +	if (rev == OMAP_USBHS_REV1) { +		if (is_ehci_phy_mode(usbhs_pdata->port_mode[0])) +			clrbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS); +		else +			setbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS); + +		if (is_ehci_phy_mode(usbhs_pdata->port_mode[1])) +			clrbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS); +		else +			setbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS); + +		if (is_ehci_phy_mode(usbhs_pdata->port_mode[2])) +			clrbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS); +		else +			setbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS); +	} else if (rev == OMAP_USBHS_REV2) { +		clrsetbits_le32(®, (OMAP_P1_MODE_CLEAR | OMAP_P2_MODE_CLEAR), +					OMAP4_UHH_HOSTCONFIG_APP_START_CLK); + +		/* Clear port mode fields for PHY mode*/ + +		if (is_ehci_hsic_mode(usbhs_pdata->port_mode[0])) +			setbits_le32(®, OMAP_P1_MODE_HSIC); + +		if (is_ehci_hsic_mode(usbhs_pdata->port_mode[1])) +			setbits_le32(®, OMAP_P2_MODE_HSIC); + +		if (is_ehci_hsic_mode(usbhs_pdata->port_mode[2])) +			setbits_le32(®, OMAP_P3_MODE_HSIC); +	} + +	debug("OMAP UHH_REVISION 0x%x\n", rev); +	writel(reg, &uhh->hostconfig); + +	for (i = 0; i < OMAP_HS_USB_PORTS; i++) +		if (is_ehci_hsic_mode(usbhs_pdata->port_mode[i])) +			omap_usbhs_hsic_init(i);  	omap_ehci_phy_reset(0, 10); -	hccr = (struct ehci_hccr *)(OMAP3_EHCI_BASE); -	hcor = (struct ehci_hcor *)(OMAP3_EHCI_BASE + 0x10); +	/* +	 * An undocumented "feature" in the OMAP3 EHCI controller, +	 * causes suspended ports to be taken out of suspend when +	 * the USBCMD.Run/Stop bit is cleared (for example when +	 * we do ehci_bus_suspend). +	 * This breaks suspend-resume if the root-hub is allowed +	 * to suspend. Writing 1 to this undocumented register bit +	 * disables this feature and restores normal behavior. +	 */ +	writel(EHCI_INSNREG04_DISABLE_UNSUSPEND, &ehci->insreg04); + +	for (i = 0; i < OMAP_HS_USB_PORTS; i++) +		if (is_ehci_phy_mode(usbhs_pdata->port_mode[i])) +			omap_ehci_soft_phy_reset(i); + +	dcache_disable(); +	hccr = (struct ehci_hccr *)(OMAP_EHCI_BASE); +	hcor = (struct ehci_hcor *)(OMAP_EHCI_BASE + 0x10); -	debug("OMAP3 EHCI init done\n"); +	debug("OMAP EHCI init done\n");  	return 0;  } |