diff options
| author | Tom Rini <trini@ti.com> | 2013-08-27 09:49:43 -0400 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2013-08-27 09:49:43 -0400 | 
| commit | 529c0d9b8cdfae232e4ed082fd8cde5416b266b7 (patch) | |
| tree | ea7b948c6faafb4ad9d754eca568a2ae2a0100fc | |
| parent | 880a41273265233004516351189aad126f964c86 (diff) | |
| parent | c95e2b9eaeadc0f985030ffa0638278acc2d8727 (diff) | |
| download | olio-uboot-2014.01-529c0d9b8cdfae232e4ed082fd8cde5416b266b7.tar.xz olio-uboot-2014.01-529c0d9b8cdfae232e4ed082fd8cde5416b266b7.zip | |
Merge branch 'master' of git://git.denx.de/u-boot-usb
| -rw-r--r-- | arch/arm/cpu/armv7/mx5/clock.c | 10 | ||||
| -rw-r--r-- | arch/arm/include/asm/arch-mx5/clock.h | 6 | ||||
| -rw-r--r-- | arch/arm/include/asm/arch-omap5/clock.h | 17 | ||||
| -rw-r--r-- | arch/arm/include/asm/arch-omap5/ehci.h | 43 | ||||
| -rw-r--r-- | arch/arm/include/asm/ehci-omap.h | 2 | ||||
| -rw-r--r-- | board/ti/omap5_uevm/evm.c | 96 | ||||
| -rw-r--r-- | board/ti/omap5_uevm/mux_data.h | 4 | ||||
| -rw-r--r-- | common/usb.c | 87 | ||||
| -rw-r--r-- | common/usb_hub.c | 26 | ||||
| -rw-r--r-- | common/usb_kbd.c | 15 | ||||
| -rw-r--r-- | drivers/dfu/dfu_nand.c | 38 | ||||
| -rw-r--r-- | drivers/usb/gadget/g_dnl.c | 17 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-mx5.c | 15 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-omap.c | 33 | ||||
| -rw-r--r-- | include/configs/omap5_uevm.h | 24 | ||||
| -rw-r--r-- | include/dfu.h | 2 | ||||
| -rw-r--r-- | net/net.c | 11 | 
17 files changed, 388 insertions, 58 deletions
| diff --git a/arch/arm/cpu/armv7/mx5/clock.c b/arch/arm/cpu/armv7/mx5/clock.c index fbbb365cb..6bef25445 100644 --- a/arch/arm/cpu/armv7/mx5/clock.c +++ b/arch/arm/cpu/armv7/mx5/clock.c @@ -85,7 +85,7 @@ void set_usboh3_clk(void)  			MXC_CCM_CSCDR1_USBOH3_CLK_PODF(1));  } -void enable_usboh3_clk(unsigned char enable) +void enable_usboh3_clk(bool enable)  {  	unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; @@ -122,7 +122,7 @@ void set_usb_phy_clk(void)  }  #if defined(CONFIG_MX51) -void enable_usb_phy1_clk(unsigned char enable) +void enable_usb_phy1_clk(bool enable)  {  	unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; @@ -131,12 +131,12 @@ void enable_usb_phy1_clk(unsigned char enable)  			MXC_CCM_CCGR2_USB_PHY(cg));  } -void enable_usb_phy2_clk(unsigned char enable) +void enable_usb_phy2_clk(bool enable)  {  	/* i.MX51 has a single USB PHY clock, so do nothing here. */  }  #elif defined(CONFIG_MX53) -void enable_usb_phy1_clk(unsigned char enable) +void enable_usb_phy1_clk(bool enable)  {  	unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; @@ -145,7 +145,7 @@ void enable_usb_phy1_clk(unsigned char enable)  			MXC_CCM_CCGR4_USB_PHY1(cg));  } -void enable_usb_phy2_clk(unsigned char enable) +void enable_usb_phy2_clk(bool enable)  {  	unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; diff --git a/arch/arm/include/asm/arch-mx5/clock.h b/arch/arm/include/asm/arch-mx5/clock.h index 406d150ae..9ee79aede 100644 --- a/arch/arm/include/asm/arch-mx5/clock.h +++ b/arch/arm/include/asm/arch-mx5/clock.h @@ -46,10 +46,10 @@ u32 imx_get_fecclk(void);  unsigned int mxc_get_clock(enum mxc_clock clk);  int mxc_set_clock(u32 ref, u32 freq, u32 clk_type);  void set_usb_phy_clk(void); -void enable_usb_phy1_clk(unsigned char enable); -void enable_usb_phy2_clk(unsigned char enable); +void enable_usb_phy1_clk(bool enable); +void enable_usb_phy2_clk(bool enable);  void set_usboh3_clk(void); -void enable_usboh3_clk(unsigned char enable); +void enable_usboh3_clk(bool enable);  void mxc_set_sata_internal_clock(void);  int enable_i2c_clk(unsigned char enable, unsigned i2c_num);  void enable_nfc_clk(unsigned char enable); diff --git a/arch/arm/include/asm/arch-omap5/clock.h b/arch/arm/include/asm/arch-omap5/clock.h index 3adfc090f..9a2166ce4 100644 --- a/arch/arm/include/asm/arch-omap5/clock.h +++ b/arch/arm/include/asm/arch-omap5/clock.h @@ -149,6 +149,23 @@  /* CM_L3INIT_USBPHY_CLKCTRL */  #define USBPHY_CLKCTRL_OPTFCLKEN_PHY_48M_MASK	8 +/* CM_L3INIT_USB_HOST_HS_CLKCTRL */ +#define OPTFCLKEN_FUNC48M_CLK			(1 << 15) +#define OPTFCLKEN_HSIC480M_P2_CLK		(1 << 14) +#define OPTFCLKEN_HSIC480M_P1_CLK		(1 << 13) +#define OPTFCLKEN_HSIC60M_P2_CLK		(1 << 12) +#define OPTFCLKEN_HSIC60M_P1_CLK		(1 << 11) +#define OPTFCLKEN_UTMI_P3_CLK			(1 << 10) +#define OPTFCLKEN_UTMI_P2_CLK			(1 << 9) +#define OPTFCLKEN_UTMI_P1_CLK			(1 << 8) +#define OPTFCLKEN_HSIC480M_P3_CLK		(1 << 7) +#define OPTFCLKEN_HSIC60M_P3_CLK		(1 << 6) + +/* CM_L3INIT_USB_TLL_HS_CLKCTRL */ +#define OPTFCLKEN_USB_CH0_CLK_ENABLE	(1 << 8) +#define OPTFCLKEN_USB_CH1_CLK_ENABLE	(1 << 9) +#define OPTFCLKEN_USB_CH2_CLK_ENABLE	(1 << 10) +  /* CM_MPU_MPU_CLKCTRL */  #define MPU_CLKCTRL_CLKSEL_EMIF_DIV_MODE_SHIFT	24  #define MPU_CLKCTRL_CLKSEL_EMIF_DIV_MODE_MASK	(3 << 24) diff --git a/arch/arm/include/asm/arch-omap5/ehci.h b/arch/arm/include/asm/arch-omap5/ehci.h new file mode 100644 index 000000000..3921e4ab4 --- /dev/null +++ b/arch/arm/include/asm/arch-omap5/ehci.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2013 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 as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _EHCI_H +#define _EHCI_H + +#define OMAP_EHCI_BASE				(OMAP54XX_L4_CORE_BASE + 0x64C00) +#define OMAP_UHH_BASE				(OMAP54XX_L4_CORE_BASE + 0x64000) +#define OMAP_USBTLL_BASE			(OMAP54XX_L4_CORE_BASE + 0x62000) + +/* 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 /* _EHCI_H */ diff --git a/arch/arm/include/asm/ehci-omap.h b/arch/arm/include/asm/ehci-omap.h index 77e81701b..ac83a539a 100644 --- a/arch/arm/include/asm/ehci-omap.h +++ b/arch/arm/include/asm/ehci-omap.h @@ -42,6 +42,7 @@ enum usbhs_omap_port_mode {  /* Values of UHH_REVISION - Note: these are not given in the TRM */  #define OMAP_USBHS_REV1					0x00000010 /* OMAP3 */  #define OMAP_USBHS_REV2					0x50700100 /* OMAP4 */ +#define OMAP_USBHS_REV2_1				0x50700101 /* OMAP5 */  /* UHH Register Set */  #define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN		(1 << 2) @@ -60,6 +61,7 @@ enum usbhs_omap_port_mode {  #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_CLEAR				(3 << 20)  #define OMAP_P3_MODE_HSIC				(3 << 20)  /* EHCI Register Set */ diff --git a/board/ti/omap5_uevm/evm.c b/board/ti/omap5_uevm/evm.c index 2c0064847..47063309e 100644 --- a/board/ti/omap5_uevm/evm.c +++ b/board/ti/omap5_uevm/evm.c @@ -14,10 +14,22 @@  #include "mux_data.h" +#ifdef CONFIG_USB_EHCI +#include <usb.h> +#include <asm/gpio.h> +#include <asm/arch/clock.h> +#include <asm/arch/ehci.h> +#include <asm/ehci-omap.h> + +#define DIE_ID_REG_BASE     (OMAP54XX_L4_CORE_BASE + 0x2000) +#define DIE_ID_REG_OFFSET	0x200 + +#endif +  DECLARE_GLOBAL_DATA_PTR;  const struct omap_sysinfo sysinfo = { -	"Board: OMAP5430 EVM\n" +	"Board: OMAP5432 uEVM\n"  };  /** @@ -109,3 +121,85 @@ int board_mmc_init(bd_t *bis)  	return 0;  }  #endif + +#ifdef CONFIG_USB_EHCI +static struct omap_usbhs_board_data usbhs_bdata = { +	.port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, +	.port_mode[1] = OMAP_EHCI_PORT_MODE_HSIC, +	.port_mode[2] = OMAP_EHCI_PORT_MODE_HSIC, +}; + +static void enable_host_clocks(void) +{ +	int hs_clk_ctrl_val = (OPTFCLKEN_HSIC60M_P3_CLK | +				OPTFCLKEN_HSIC480M_P3_CLK | +				OPTFCLKEN_HSIC60M_P2_CLK | +				OPTFCLKEN_HSIC480M_P2_CLK | +				OPTFCLKEN_UTMI_P3_CLK | OPTFCLKEN_UTMI_P2_CLK); + +	/* Enable port 2 and 3 clocks*/ +	setbits_le32((*prcm)->cm_l3init_hsusbhost_clkctrl, hs_clk_ctrl_val); + +	/* Enable port 2 and 3 usb host ports tll clocks*/ +	setbits_le32((*prcm)->cm_l3init_hsusbtll_clkctrl, +			(OPTFCLKEN_USB_CH1_CLK_ENABLE | OPTFCLKEN_USB_CH2_CLK_ENABLE)); +} + +int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor) +{ +	int ret; +	int auxclk; +	int reg; +	uint8_t device_mac[6]; + +	enable_host_clocks(); + +	if (!getenv("usbethaddr")) { +		reg = DIE_ID_REG_BASE + DIE_ID_REG_OFFSET; + +		/* +		 * create a fake MAC address from the processor ID code. +		 * first byte is 0x02 to signify locally administered. +		 */ +		device_mac[0] = 0x02; +		device_mac[1] = readl(reg + 0x10) & 0xff; +		device_mac[2] = readl(reg + 0xC) & 0xff; +		device_mac[3] = readl(reg + 0x8) & 0xff; +		device_mac[4] = readl(reg) & 0xff; +		device_mac[5] = (readl(reg) >> 8) & 0xff; + +		eth_setenv_enetaddr("usbethaddr", device_mac); +	} + +	auxclk = readl((*prcm)->scrm_auxclk1); +	/* Request auxilary clock */ +	auxclk |= AUXCLK_ENABLE_MASK; +	writel(auxclk, (*prcm)->scrm_auxclk1); + +	ret = omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor); +	if (ret < 0) { +		puts("Failed to initialize ehci\n"); +		return ret; +	} + +	return 0; +} + +int ehci_hcd_stop(void) +{ +	int ret; + +	ret = omap_ehci_hcd_stop(); +	return ret; +} + +void usb_hub_reset_devices(int port) +{ +	/* The LAN9730 needs to be reset after the port power has been set. */ +	if (port == 3) { +		gpio_direction_output(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO, 0); +		udelay(10); +		gpio_direction_output(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO, 1); +	} +} +#endif diff --git a/board/ti/omap5_uevm/mux_data.h b/board/ti/omap5_uevm/mux_data.h index 612c13e47..31ce363b6 100644 --- a/board/ti/omap5_uevm/mux_data.h +++ b/board/ti/omap5_uevm/mux_data.h @@ -42,7 +42,8 @@ const struct pad_conf_entry core_padconf_array_essential[] = {  	{USBD0_SS_RX, (IEN | M0)},	/*  USBD0_SS_RX */  	{I2C5_SCL, (IEN | M0)}, /* I2C5_SCL */  	{I2C5_SDA, (IEN | M0)}, /* I2C5_SDA */ - +	{HSI2_ACWAKE, (PTU | M6)},    /*  HSI2_ACWAKE */ +	{HSI2_CAFLAG, (PTU | M6)},    /*  HSI2_CAFLAG */  };  const struct pad_conf_entry wkup_padconf_array_essential[] = { @@ -50,6 +51,7 @@ const struct pad_conf_entry wkup_padconf_array_essential[] = {  	{SR_PMIC_SCL, (PTU | IEN | M0)}, /* SR_PMIC_SCL */  	{SR_PMIC_SDA, (PTU | IEN | M0)}, /* SR_PMIC_SDA */  	{SYS_32K, (IEN | M0)}, /*  SYS_32K     */ +	{FREF_CLK1_OUT, (PTD | IEN | M0)},    /*  FREF_CLK1_OUT  */  }; diff --git a/common/usb.c b/common/usb.c index f740e5ec2..c97f522be 100644 --- a/common/usb.c +++ b/common/usb.c @@ -323,6 +323,7 @@ static int usb_set_maxpacket(struct usb_device *dev)  /*******************************************************************************   * Parse the config, located in buffer, and fills the dev->config structure.   * Note that all little/big endian swapping are done automatically. + * (wTotalLength has already been swapped and sanitized when it was read.)   */  static int usb_parse_config(struct usb_device *dev,  			unsigned char *buffer, int cfgno) @@ -343,24 +344,43 @@ static int usb_parse_config(struct usb_device *dev,  			head->bDescriptorType);  		return -1;  	} -	memcpy(&dev->config, buffer, buffer[0]); -	le16_to_cpus(&(dev->config.desc.wTotalLength)); +	if (head->bLength != USB_DT_CONFIG_SIZE) { +		printf("ERROR: Invalid USB CFG length (%d)\n", head->bLength); +		return -1; +	} +	memcpy(&dev->config, head, USB_DT_CONFIG_SIZE);  	dev->config.no_of_if = 0;  	index = dev->config.desc.bLength;  	/* Ok the first entry must be a configuration entry,  	 * now process the others */  	head = (struct usb_descriptor_header *) &buffer[index]; -	while (index + 1 < dev->config.desc.wTotalLength) { +	while (index + 1 < dev->config.desc.wTotalLength && head->bLength) {  		switch (head->bDescriptorType) {  		case USB_DT_INTERFACE: +			if (head->bLength != USB_DT_INTERFACE_SIZE) { +				printf("ERROR: Invalid USB IF length (%d)\n", +					head->bLength); +				break; +			} +			if (index + USB_DT_INTERFACE_SIZE > +			    dev->config.desc.wTotalLength) { +				puts("USB IF descriptor overflowed buffer!\n"); +				break; +			}  			if (((struct usb_interface_descriptor *) \ -			     &buffer[index])->bInterfaceNumber != curr_if_num) { +			     head)->bInterfaceNumber != curr_if_num) {  				/* this is a new interface, copy new desc */  				ifno = dev->config.no_of_if; +				if (ifno >= USB_MAXINTERFACES) { +					puts("Too many USB interfaces!\n"); +					/* try to go on with what we have */ +					return 1; +				}  				if_desc = &dev->config.if_desc[ifno];  				dev->config.no_of_if++; -				memcpy(if_desc,	&buffer[index], buffer[index]); +				memcpy(if_desc, head, +					USB_DT_INTERFACE_SIZE);  				if_desc->no_of_ep = 0;  				if_desc->num_altsetting = 1;  				curr_if_num = @@ -374,12 +394,31 @@ static int usb_parse_config(struct usb_device *dev,  			}  			break;  		case USB_DT_ENDPOINT: +			if (head->bLength != USB_DT_ENDPOINT_SIZE) { +				printf("ERROR: Invalid USB EP length (%d)\n", +					head->bLength); +				break; +			} +			if (index + USB_DT_ENDPOINT_SIZE > +			    dev->config.desc.wTotalLength) { +				puts("USB EP descriptor overflowed buffer!\n"); +				break; +			} +			if (ifno < 0) { +				puts("Endpoint descriptor out of order!\n"); +				break; +			}  			epno = dev->config.if_desc[ifno].no_of_ep;  			if_desc = &dev->config.if_desc[ifno]; +			if (epno > USB_MAXENDPOINTS) { +				printf("Interface %d has too many endpoints!\n", +					if_desc->desc.bInterfaceNumber); +				return 1; +			}  			/* found an endpoint */  			if_desc->no_of_ep++; -			memcpy(&if_desc->ep_desc[epno], -				&buffer[index], buffer[index]); +			memcpy(&if_desc->ep_desc[epno], head, +				USB_DT_ENDPOINT_SIZE);  			ep_wMaxPacketSize = get_unaligned(&dev->config.\  							if_desc[ifno].\  							ep_desc[epno].\ @@ -392,9 +431,23 @@ static int usb_parse_config(struct usb_device *dev,  			debug("if %d, ep %d\n", ifno, epno);  			break;  		case USB_DT_SS_ENDPOINT_COMP: +			if (head->bLength != USB_DT_SS_EP_COMP_SIZE) { +				printf("ERROR: Invalid USB EPC length (%d)\n", +					head->bLength); +				break; +			} +			if (index + USB_DT_SS_EP_COMP_SIZE > +			    dev->config.desc.wTotalLength) { +				puts("USB EPC descriptor overflowed buffer!\n"); +				break; +			} +			if (ifno < 0 || epno < 0) { +				puts("EPC descriptor out of order!\n"); +				break; +			}  			if_desc = &dev->config.if_desc[ifno]; -			memcpy(&if_desc->ss_ep_comp_desc[epno], -				&buffer[index], buffer[index]); +			memcpy(&if_desc->ss_ep_comp_desc[epno], head, +				USB_DT_SS_EP_COMP_SIZE);  			break;  		default:  			if (head->bLength == 0) @@ -473,7 +526,7 @@ int usb_get_configuration_no(struct usb_device *dev,  			     unsigned char *buffer, int cfgno)  {  	int result; -	unsigned int tmp; +	unsigned int length;  	struct usb_config_descriptor *config;  	config = (struct usb_config_descriptor *)&buffer[0]; @@ -487,16 +540,18 @@ int usb_get_configuration_no(struct usb_device *dev,  				"(expected %i, got %i)\n", 9, result);  		return -1;  	} -	tmp = le16_to_cpu(config->wTotalLength); +	length = le16_to_cpu(config->wTotalLength); -	if (tmp > USB_BUFSIZ) { -		printf("usb_get_configuration_no: failed to get " \ -		       "descriptor - too long: %d\n", tmp); +	if (length > USB_BUFSIZ) { +		printf("%s: failed to get descriptor - too long: %d\n", +			__func__, length);  		return -1;  	} -	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, tmp); -	debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result, tmp); +	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, length); +	debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result, length); +	config->wTotalLength = length; /* validated, with CPU byte order */ +  	return result;  } diff --git a/common/usb_hub.c b/common/usb_hub.c index a11b401e6..ffac0e743 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -44,6 +44,10 @@  static struct usb_hub_device hub_dev[USB_MAX_HUB];  static int usb_hub_index; +__weak void usb_hub_reset_devices(int port) +{ +	return; +}  static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)  { @@ -302,7 +306,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)  static int usb_hub_configure(struct usb_device *dev)  { -	int i; +	int i, length;  	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);  	unsigned char *bitmap;  	short hubCharacteristics; @@ -323,20 +327,14 @@ static int usb_hub_configure(struct usb_device *dev)  	}  	descriptor = (struct usb_hub_descriptor *)buffer; -	/* silence compiler warning if USB_BUFSIZ is > 256 [= sizeof(char)] */ -	i = descriptor->bLength; -	if (i > USB_BUFSIZ) { -		debug("usb_hub_configure: failed to get hub " \ -		      "descriptor - too long: %d\n", descriptor->bLength); -		return -1; -	} +	length = min(descriptor->bLength, sizeof(struct usb_hub_descriptor)); -	if (usb_get_hub_descriptor(dev, buffer, descriptor->bLength) < 0) { +	if (usb_get_hub_descriptor(dev, buffer, length) < 0) {  		debug("usb_hub_configure: failed to get hub " \  		      "descriptor 2nd giving up %lX\n", dev->status);  		return -1;  	} -	memcpy((unsigned char *)&hub->desc, buffer, descriptor->bLength); +	memcpy((unsigned char *)&hub->desc, buffer, length);  	/* adjust 16bit values */  	put_unaligned(le16_to_cpu(get_unaligned(  			&descriptor->wHubCharacteristics)), @@ -426,6 +424,14 @@ static int usb_hub_configure(struct usb_device *dev)  	      "" : "no ");  	usb_hub_power_on(hub); +	/* +	 * Reset any devices that may be in a bad state when applying +	 * the power.  This is a __weak function.  Resetting of the devices +	 * should occur in the board file of the device. +	 */ +	for (i = 0; i < dev->maxchild; i++) +		usb_hub_reset_devices(i + 1); +  	for (i = 0; i < dev->maxchild; i++) {  		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);  		unsigned short portstatus, portchange; diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 2ca3767ec..1ad67caf1 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -104,6 +104,11 @@ struct usb_kbd_pdata {  	uint8_t		flags;  }; +extern int __maybe_unused net_busy_flag; + +/* The period of time between two calls of usb_kbd_testc(). */ +static unsigned long __maybe_unused kbd_testc_tms; +  /* Generic keyboard event polling. */  void usb_kbd_generic_poll(void)  { @@ -349,6 +354,16 @@ static int usb_kbd_testc(void)  	struct usb_device *usb_kbd_dev;  	struct usb_kbd_pdata *data; +#ifdef CONFIG_CMD_NET +	/* +	 * If net_busy_flag is 1, NET transfer is running, +	 * then we check key-pressed every second (first check may be +	 * less than 1 second) to improve TFTP booting performance. +	 */ +	if (net_busy_flag && (get_timer(kbd_testc_tms) < CONFIG_SYS_HZ)) +		return 0; +	kbd_testc_tms = get_timer(0); +#endif  	dev = stdio_get_by_name(DEVNAME);  	usb_kbd_dev = (struct usb_device *)dev->priv;  	data = usb_kbd_dev->privptr; diff --git a/drivers/dfu/dfu_nand.c b/drivers/dfu/dfu_nand.c index 2a01cc11b..0ec12cff2 100644 --- a/drivers/dfu/dfu_nand.c +++ b/drivers/dfu/dfu_nand.c @@ -136,11 +136,43 @@ static int dfu_read_medium_nand(struct dfu_entity *dfu, u64 offset, void *buf,  	return ret;  } +static int dfu_flush_medium_nand(struct dfu_entity *dfu) +{ +	int ret = 0; + +	/* in case of ubi partition, erase rest of the partition */ +	if (dfu->data.nand.ubi) { +		nand_info_t *nand; +		nand_erase_options_t opts; + +		if (nand_curr_device < 0 || +		    nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE || +		    !nand_info[nand_curr_device].name) { +			printf("%s: invalid nand device\n", __func__); +			return -1; +		} + +		nand = &nand_info[nand_curr_device]; + +		memset(&opts, 0, sizeof(opts)); +		opts.offset = dfu->data.nand.start + dfu->offset + +				dfu->bad_skip; +		opts.length = dfu->data.nand.start + +				dfu->data.nand.size - opts.offset; +		ret = nand_erase_opts(nand, &opts); +		if (ret != 0) +			printf("Failure erase: %d\n", ret); +	} + +	return ret; +} +  int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)  {  	char *st;  	int ret, dev, part; +	dfu->data.nand.ubi = 0;  	dfu->dev_type = DFU_DEV_NAND;  	st = strsep(&s, " ");  	if (!strcmp(st, "raw")) { @@ -148,7 +180,7 @@ int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)  		dfu->data.nand.start = simple_strtoul(s, &s, 16);  		s++;  		dfu->data.nand.size = simple_strtoul(s, &s, 16); -	} else if (!strcmp(st, "part")) { +	} else if ((!strcmp(st, "part")) || (!strcmp(st, "partubi"))) {  		char mtd_id[32];  		struct mtd_device *mtd_dev;  		u8 part_num; @@ -173,7 +205,8 @@ int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)  		dfu->data.nand.start = pi->offset;  		dfu->data.nand.size = pi->size; - +		if (!strcmp(st, "partubi")) +			dfu->data.nand.ubi = 1;  	} else {  		printf("%s: Memory layout (%s) not supported!\n", __func__, st);  		return -1; @@ -181,6 +214,7 @@ int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)  	dfu->read_medium = dfu_read_medium_nand;  	dfu->write_medium = dfu_write_medium_nand; +	dfu->flush_medium = dfu_flush_medium_nand;  	/* initial state */  	dfu->inited = 0; diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c index cbfcb2d07..a3e05a872 100644 --- a/drivers/usb/gadget/g_dnl.c +++ b/drivers/usb/gadget/g_dnl.c @@ -31,8 +31,10 @@  #define STRING_MANUFACTURER 25  #define STRING_PRODUCT 2 +/* Index of String Descriptor describing this configuration */  #define STRING_USBDOWN 2 -#define CONFIG_USBDOWNLOADER 2 +/* Number of supported configurations */ +#define CONFIGURATION_NUMBER 1  #define DRIVER_VERSION		"usb_dnl 2.0" @@ -54,11 +56,14 @@ static struct usb_device_descriptor device_desc = {  	.bNumConfigurations = 1,  }; -/* static strings, in UTF-8 */ +/* + * static strings, in UTF-8 + * IDs for those strings are assigned dynamically at g_dnl_bind() + */  static struct usb_string g_dnl_string_defs[] = { -	{ 0, manufacturer, }, -	{ 1, product, }, -	{  }		/* end of list */ +	{.s = manufacturer}, +	{.s = product}, +	{ }		/* end of list */  };  static struct usb_gadget_strings g_dnl_string_tab = { @@ -104,7 +109,7 @@ static int g_dnl_config_register(struct usb_composite_dev *cdev)  	static struct usb_configuration config = {  		.label = "usb_dnload",  		.bmAttributes =	USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, -		.bConfigurationValue =	CONFIG_USBDOWNLOADER, +		.bConfigurationValue =	CONFIGURATION_NUMBER,  		.iConfiguration =	STRING_USBDOWN,  		.bind = g_dnl_do_config, diff --git a/drivers/usb/host/ehci-mx5.c b/drivers/usb/host/ehci-mx5.c index 3548620ec..dd11f535a 100644 --- a/drivers/usb/host/ehci-mx5.c +++ b/drivers/usb/host/ehci-mx5.c @@ -221,21 +221,12 @@ void __weak board_ehci_hcd_postinit(struct usb_ehci *ehci, int port)  int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)  {  	struct usb_ehci *ehci; -#ifdef CONFIG_MX53 -	struct clkctl *sc_regs = (struct clkctl *)CCM_BASE_ADDR; -	u32 reg; - -	reg = __raw_readl(&sc_regs->cscmr1) & ~(1 << 26); -	/* derive USB PHY clock multiplexer from PLL3 */ -	reg |= 1 << 26; -	__raw_writel(reg, &sc_regs->cscmr1); -#endif  	set_usboh3_clk(); -	enable_usboh3_clk(1); +	enable_usboh3_clk(true);  	set_usb_phy_clk(); -	enable_usb_phy1_clk(1); -	enable_usb_phy2_clk(1); +	enable_usb_phy1_clk(true); +	enable_usb_phy2_clk(true);  	mdelay(1);  	/* Do board specific initialization */ diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 032d5e5ec..3c58f9e65 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -79,6 +79,7 @@ static void omap_usbhs_hsic_init(int port)  	writel(reg, &usbtll->channel_conf + port);  } +#ifdef CONFIG_USB_ULPI  static void omap_ehci_soft_phy_reset(int port)  {  	struct ulpi_viewport ulpi_vp; @@ -88,6 +89,12 @@ static void omap_ehci_soft_phy_reset(int port)  	ulpi_reset(&ulpi_vp);  } +#else +static void omap_ehci_soft_phy_reset(int port) +{ +	return; +} +#endif  inline int __board_usb_init(void)  { @@ -96,7 +103,8 @@ inline int __board_usb_init(void)  int board_usb_init(void) __attribute__((weak, alias("__board_usb_init")));  #if defined(CONFIG_OMAP_EHCI_PHY1_RESET_GPIO) || \ -	defined(CONFIG_OMAP_EHCI_PHY2_RESET_GPIO) +	defined(CONFIG_OMAP_EHCI_PHY2_RESET_GPIO) || \ +	defined(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO)  /* controls PHY(s) reset signal(s) */  static inline void omap_ehci_phy_reset(int on, int delay)  { @@ -115,6 +123,10 @@ static inline void omap_ehci_phy_reset(int on, int delay)  	gpio_request(CONFIG_OMAP_EHCI_PHY2_RESET_GPIO, "USB PHY2 reset");  	gpio_direction_output(CONFIG_OMAP_EHCI_PHY2_RESET_GPIO, !on);  #endif +#ifdef CONFIG_OMAP_EHCI_PHY3_RESET_GPIO +	gpio_request(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO, "USB PHY3 reset"); +	gpio_direction_output(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO, !on); +#endif  	/* Hold the PHY in RESET for enough time till DIR is high */  	/* Refer: ISSUE1 */ @@ -198,10 +210,27 @@ int omap_ehci_hcd_init(struct omap_usbhs_board_data *usbhs_pdata,  		else  			setbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P3_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*/ +		/* 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); + +	} else if (rev == OMAP_USBHS_REV2_1) { + +		clrsetbits_le32(®, +				(OMAP_P1_MODE_CLEAR | +				 OMAP_P2_MODE_CLEAR | +				 OMAP_P3_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); diff --git a/include/configs/omap5_uevm.h b/include/configs/omap5_uevm.h index d10c2b56f..0bba84bd4 100644 --- a/include/configs/omap5_uevm.h +++ b/include/configs/omap5_uevm.h @@ -40,6 +40,30 @@  #define CONFIG_SYS_I2C_TCA642X_BUS_NUM 4  #define CONFIG_SYS_I2C_TCA642X_ADDR 0x22 +/* USB UHH support options */ +#define CONFIG_CMD_USB +#define CONFIG_USB_HOST +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_OMAP +#define CONFIG_USB_STORAGE +#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET + +#define CONFIG_OMAP_EHCI_PHY2_RESET_GPIO 80 +#define CONFIG_OMAP_EHCI_PHY3_RESET_GPIO 79 + +/* Enabled commands */ +#define CONFIG_NET_MULTI +#define CONFIG_CMD_DHCP		/* DHCP Support			*/ +#define CONFIG_CMD_NET		/* bootp, tftpboot, rarpboot	*/ +#define CONFIG_CMD_NFS		/* NFS support			*/ + +/* USB Networking options */ +#define CONFIG_USB_HOST_ETHER +#define CONFIG_USB_ETHER_SMSC95XX + +#define CONFIG_SYS_PROMPT		"OMAP5432 uEVM # " +  #define CONSOLEDEV		"ttyO2"  #define CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC	16296 diff --git a/include/dfu.h b/include/dfu.h index 1d4006de8..47b90559d 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -47,6 +47,8 @@ struct nand_internal_data {  	unsigned int dev;  	unsigned int part; +	/* for nand/ubi use */ +	unsigned int ubi;  };  static inline unsigned int get_mmc_blk_size(int dev) @@ -207,6 +207,8 @@ static int net_check_prereq(enum proto_t protocol);  static int NetTryCount; +int __maybe_unused net_busy_flag; +  /**********************************************************************/  static int on_bootfile(const char *name, const char *value, enum env_op op, @@ -342,6 +344,9 @@ int NetLoop(enum proto_t protocol)  		eth_init_state_only(bd);  restart: +#ifdef CONFIG_USB_KEYBOARD +	net_busy_flag = 0; +#endif  	net_set_state(NETLOOP_CONTINUE);  	/* @@ -454,6 +459,9 @@ restart:  		status_led_set(STATUS_LED_RED, STATUS_LED_ON);  #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */  #endif /* CONFIG_MII, ... */ +#ifdef CONFIG_USB_KEYBOARD +	net_busy_flag = 1; +#endif  	/*  	 *	Main packet reception loop.  Loop receiving packets until @@ -559,6 +567,9 @@ restart:  	}  done: +#ifdef CONFIG_USB_KEYBOARD +	net_busy_flag = 0; +#endif  #ifdef CONFIG_CMD_TFTPPUT  	/* Clear out the handlers */  	net_set_udp_handler(NULL); |