diff options
-rw-r--r-- | drivers/usb/gadget/tegra_udc.c | 15 | ||||
-rw-r--r-- | drivers/usb/host/ehci-tegra.c | 40 |
2 files changed, 55 insertions, 0 deletions
diff --git a/drivers/usb/gadget/tegra_udc.c b/drivers/usb/gadget/tegra_udc.c index ddf9c602dc89..1dd2cceb741b 100644 --- a/drivers/usb/gadget/tegra_udc.c +++ b/drivers/usb/gadget/tegra_udc.c @@ -94,6 +94,11 @@ static const u8 tegra_udc_test_packet[53] = { 0xfc, 0x7e, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0x7e }; +#ifdef CONFIG_MACH_COLIBRI_T20 +/* To limit the speed of USB to full speed */ +extern int g_usb_high_speed; +#endif /* CONFIG_MACH_COLIBRI_T20 */ + static struct tegra_udc *the_udc; #ifdef CONFIG_TEGRA_GADGET_BOOST_CPU_FREQ @@ -252,6 +257,16 @@ static int dr_controller_reset(struct tegra_udc *udc) cpu_relax(); } +#ifdef CONFIG_MACH_COLIBRI_T20 + /* To limit the speed of USB to full speed */ + if (!g_usb_high_speed) { + tmp = udc_readl(udc, PORTSCX_REG_OFFSET); + tmp |= PORTSCX_PORT_FORCE_FULL_SPEED; + udc_writel(udc, tmp, PORTSCX_REG_OFFSET); + tmp = udc_readl(udc, PORTSCX_REG_OFFSET); + } +#endif /* CONFIG_MACH_COLIBRI_T20 */ + DBG("%s(%d) END\n", __func__, __LINE__); return 0; } diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 1800a38f48ec..f183349fd8d1 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -31,6 +31,8 @@ #define EHCI_DBG(stuff...) do {} while (0) #endif +#define TEGRA_USB_PORTSC1_PFSC (1 << 24) + static const char driver_name[] = "tegra-ehci"; #define TEGRA_USB_DMA_ALIGN 32 @@ -53,6 +55,21 @@ struct dma_align_buffer { u8 data[0]; }; +#ifdef CONFIG_MACH_COLIBRI_T20 +/* To limit the speed of USB to full speed */ +int g_usb_high_speed = 0; + +/* To limit the speed of USB to full speed */ +static int __init enable_usb_high_speed(char *s) +{ + if (!(*s) || !strcmp(s, "1")) + g_usb_high_speed = 1; + + return 0; +} +__setup("usb_high_speed=", enable_usb_high_speed); +#endif /* CONFIG_MACH_COLIBRI_T20 */ + static void free_align_buffer(struct urb *urb) { struct dma_align_buffer *temp = container_of(urb->transfer_buffer, @@ -268,6 +285,29 @@ static int tegra_ehci_hub_control( int retval = 0; u32 __iomem *status_reg; +#ifdef CONFIG_MACH_COLIBRI_T20 + u32 temp; + + /* To limit the speed of USB to full speed */ + if (!g_usb_high_speed) { + /* Check whether port is not 2nd one internally connected to + ASIX Ethernet chip, set PFSC (Port Force Full Speed) only + for externally accessible OTG and host port */ + if (tegra->phy->inst != 1) { + status_reg = &ehci->regs->port_status[(wIndex & 0xff) + - 1]; + temp = ehci_readl(ehci, status_reg); + /* Check whether PFSC bit is already set or not */ + if (!(temp & TEGRA_USB_PORTSC1_PFSC)) { + ehci_writel(ehci, (temp | + TEGRA_USB_PORTSC1_PFSC), + status_reg); + temp = ehci_readl(ehci, status_reg); + } + } + } +#endif /* CONFIG_MACH_COLIBRI_T20 */ + if (!tegra_usb_phy_hw_accessible(tegra->phy)) { if (buf) memset(buf, 0, wLength); |