diff options
| -rw-r--r-- | Makefile | 20 | ||||
| -rw-r--r-- | drivers/dfu/dfu.c | 5 | ||||
| -rw-r--r-- | drivers/mtd/nand/nand_util.c | 2 | ||||
| -rw-r--r-- | drivers/mtd/nand/omap_gpmc.c | 108 | ||||
| -rw-r--r-- | drivers/usb/gadget/f_dfu.c | 43 | ||||
| -rw-r--r-- | drivers/usb/gadget/f_dfu.h | 2 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-hcd.c | 5 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-pci.c | 28 | ||||
| -rw-r--r-- | include/configs/trats.h | 1 | ||||
| -rw-r--r-- | include/dfu.h | 4 | 
10 files changed, 149 insertions, 69 deletions
| @@ -163,7 +163,7 @@ endif  include $(TOPDIR)/config.mk  # Targets which don't build the source code -NON_BUILD_TARGETS = backup clean clobber distclean mkproper tidy unconfig +NON_BUILD_TARGETS = backup clean clobber distclean mrproper tidy unconfig  # Only do the generic board check when actually building, not configuring  ifeq ($(filter $(NON_BUILD_TARGETS),$(MAKECMDGOALS)),) @@ -471,12 +471,10 @@ $(obj)u-boot.sb:       $(obj)u-boot.bin $(obj)spl/u-boot-spl.bin  $(obj)u-boot.spr:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin  		$(obj)tools/mkimage -A $(ARCH) -T firmware -C none \  		-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) -n XLOADER \ -		-d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.img -		tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_SPL_PAD_TO) \ -			of=$(obj)spl/u-boot-spl-pad.img 2>/dev/null -		dd if=$(obj)spl/u-boot-spl.img of=$(obj)spl/u-boot-spl-pad.img \ -			conv=notrunc 2>/dev/null -		cat $(obj)spl/u-boot-spl-pad.img $(obj)u-boot.img > $@ +		-d $(obj)spl/u-boot-spl.bin $@ +		$(OBJCOPY) -I binary -O binary \ +			--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff $@ +		cat $(obj)u-boot.img >> $@  ifneq ($(CONFIG_TEGRA),)  $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin @@ -499,11 +497,9 @@ $(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img  # at the start padded up to the start of the SPL image. And then concat  # the SPL image to the end.  $(obj)u-boot-img-spl-at-end.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img -		tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_UBOOT_PAD_TO) \ -			of=$(obj)u-boot-pad.img 2>/dev/null -		dd if=$(obj)u-boot.img of=$(obj)u-boot-pad.img \ -			conv=notrunc 2>/dev/null -		cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@ +		$(OBJCOPY) -I binary -O binary --pad-to=$(CONFIG_UBOOT_PAD_TO) \ +			 --gap-fill=0xff $(obj)u-boot.img $@ +		cat $(obj)spl/u-boot-spl.bin >> $@  ifeq ($(CONFIG_SANDBOX),y)  GEN_UBOOT = \ diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index 1eb92e541..07011e99a 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -74,6 +74,11 @@ unsigned char *dfu_free_buf(void)  	return dfu_buf;  } +unsigned long dfu_get_buf_size(void) +{ +	return dfu_buf_size; +} +  unsigned char *dfu_get_buf(void)  {  	char *s; diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index eeaa7e8a4..b29282603 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -315,7 +315,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length,  	int page;  	struct nand_chip *chip = mtd->priv; -	debug("nand_unlock%s: start: %08llx, length: %d!\n", +	debug("nand_unlock%s: start: %08llx, length: %zd!\n",  		allexcept ? " (allexcept)" : "", start, length);  	/* select the NAND device */ diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index 5e7e6b337..790d5385e 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -283,53 +283,55 @@ static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)  	if (bch->ecc_scheme == OMAP_ECC_BCH8_CODE_HW) {  		wr_mode = BCH_WRAPMODE_1; -	switch (bch->nibbles) { -	case ECC_BCH4_NIBBLES: -		unused_length = 3; -		break; -	case ECC_BCH8_NIBBLES: -		unused_length = 2; -		break; -	case ECC_BCH16_NIBBLES: -		unused_length = 0; -		break; -	} - -	/* -	 * This is ecc_size_config for ELM mode. -	 * Here we are using different settings for read and write access and -	 * also depending on BCH strength. -	 */ -	switch (mode) { -	case NAND_ECC_WRITE: -		/* write access only setup eccsize1 config */ -		val = ((unused_length + bch->nibbles) << 22); -		break; +		switch (bch->nibbles) { +		case ECC_BCH4_NIBBLES: +			unused_length = 3; +			break; +		case ECC_BCH8_NIBBLES: +			unused_length = 2; +			break; +		case ECC_BCH16_NIBBLES: +			unused_length = 0; +			break; +		} -	case NAND_ECC_READ: -	default:  		/* -		 * by default eccsize0 selected for ecc1resultsize -		 * eccsize0 config. +		 * This is ecc_size_config for ELM mode.  Here we are using +		 * different settings for read and write access and also +		 * depending on BCH strength.  		 */ -		val  = (bch->nibbles << 12); -		/* eccsize1 config */ -		val |= (unused_length << 22); -		break; -	} +		switch (mode) { +		case NAND_ECC_WRITE: +			/* write access only setup eccsize1 config */ +			val = ((unused_length + bch->nibbles) << 22); +			break; + +		case NAND_ECC_READ: +		default: +			/* +			 * by default eccsize0 selected for ecc1resultsize +			 * eccsize0 config. +			 */ +			val  = (bch->nibbles << 12); +			/* eccsize1 config */ +			val |= (unused_length << 22); +			break; +		}  	} else { -	/* -	 * This ecc_size_config setting is for BCH sw library. -	 * -	 * Note: we only support BCH8 currently with BCH sw library! -	 * Should be really easy to adobt to BCH4, however some omap3 have -	 * flaws with BCH4. -	 * -	 * Here we are using wrapping mode 6 both for reading and writing, with: -	 *  size0 = 0  (no additional protected byte in spare area) -	 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area) -	 */ -	val = (32 << 22) | (0 << 12); +		/* +		 * This ecc_size_config setting is for BCH sw library. +		 * +		 * Note: we only support BCH8 currently with BCH sw library! +		 * Should be really easy to adobt to BCH4, however some omap3 +		 * have flaws with BCH4. +		 * +		 * Here we are using wrapping mode 6 both for reading and +		 * writing, with: +		 *  size0 = 0  (no additional protected byte in spare area) +		 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in +		 *		spare area) +		 */ +		val = (32 << 22) | (0 << 12);  	}  	/* ecc size configuration */  	writel(val, &gpmc_cfg->ecc_size_config); @@ -761,7 +763,7 @@ static void __maybe_unused omap_free_bch(struct mtd_info *mtd)  static int omap_select_ecc_scheme(struct nand_chip *nand,  	enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {  	struct nand_bch_priv	*bch		= nand->priv; -	struct nand_ecclayout	*ecclayout	= nand->ecc.layout; +	struct nand_ecclayout	*ecclayout	= &omap_ecclayout;  	int eccsteps = pagesize / SECTOR_BYTES;  	int i; @@ -774,7 +776,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,  		bch_priv.type		= 0;  		nand->ecc.mode		= NAND_ECC_SOFT;  		nand->ecc.layout	= NULL; -		nand->ecc.size		= pagesize; +		nand->ecc.size		= 0;  		bch->ecc_scheme		= OMAP_ECC_HAM1_CODE_SW;  		break; @@ -789,6 +791,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,  		bch_priv.control	= NULL;  		bch_priv.type		= 0;  		/* populate ecc specific fields */ +		memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));  		nand->ecc.mode		= NAND_ECC_HW;  		nand->ecc.strength	= 1;  		nand->ecc.size		= SECTOR_BYTES; @@ -798,8 +801,12 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,  		nand->ecc.calculate	= omap_calculate_ecc;  		/* define ecc-layout */  		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps; -		for (i = 0; i < ecclayout->eccbytes; i++) -			ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH; +		for (i = 0; i < ecclayout->eccbytes; i++) { +			if (nand->options & NAND_BUSWIDTH_16) +				ecclayout->eccpos[i] = i + 2; +			else +				ecclayout->eccpos[i] = i + 1; +		}  		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;  		ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -  						BADBLOCK_MARKER_LENGTH; @@ -823,6 +830,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,  		}  		bch_priv.type = ECC_BCH8;  		/* populate ecc specific fields */ +		memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));  		nand->ecc.mode		= NAND_ECC_HW;  		nand->ecc.strength	= 8;  		nand->ecc.size		= SECTOR_BYTES; @@ -865,6 +873,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,  		elm_init();  		bch_priv.type		= ECC_BCH8;  		/* populate ecc specific fields */ +		memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));  		nand->ecc.mode		= NAND_ECC_HW;  		nand->ecc.strength	= 8;  		nand->ecc.size		= SECTOR_BYTES; @@ -891,6 +900,11 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,  		debug("nand: error: ecc scheme not enabled or supported\n");  		return -EINVAL;  	} + +	/* nand_scan_tail() sets ham1 sw ecc; hw ecc layout is set by driver */ +	if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW) +		nand->ecc.layout = ecclayout; +  	return 0;  } diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index 37d04a192..a045864d7 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -40,6 +40,7 @@ struct f_dfu {  	/* Send/received block number is handy for data integrity check */  	int                             blk_seq_num; +	unsigned int                    poll_timeout;  };  typedef int (*dfu_state_fn) (struct f_dfu *, @@ -128,6 +129,33 @@ static struct usb_gadget_strings *dfu_strings[] = {  	NULL,  }; +static void dfu_set_poll_timeout(struct dfu_status *dstat, unsigned int ms) +{ +	/* +	 * The bwPollTimeout DFU_GETSTATUS request payload provides information +	 * about minimum time, in milliseconds, that the host should wait before +	 * sending a subsequent DFU_GETSTATUS request +	 * +	 * This permits the device to vary the delay depending on its need to +	 * erase or program the memory +	 * +	 */ + +	unsigned char *p = (unsigned char *)&ms; + +	if (!ms || (ms & ~DFU_POLL_TIMEOUT_MASK)) { +		dstat->bwPollTimeout[0] = 0; +		dstat->bwPollTimeout[1] = 0; +		dstat->bwPollTimeout[2] = 0; + +		return; +	} + +	dstat->bwPollTimeout[0] = *p++; +	dstat->bwPollTimeout[1] = *p++; +	dstat->bwPollTimeout[2] = *p; +} +  /*-------------------------------------------------------------------------*/  static void dnload_request_complete(struct usb_ep *ep, struct usb_request *req) @@ -157,11 +185,15 @@ static void handle_getstatus(struct usb_request *req)  		break;  	} +	dfu_set_poll_timeout(dstat, 0); + +	if (f_dfu->poll_timeout) +		if (!(f_dfu->blk_seq_num % +		      (dfu_get_buf_size() / DFU_USB_BUFSIZ))) +			dfu_set_poll_timeout(dstat, f_dfu->poll_timeout); +  	/* send status response */  	dstat->bStatus = f_dfu->dfu_status; -	dstat->bwPollTimeout[0] = 0; -	dstat->bwPollTimeout[1] = 0; -	dstat->bwPollTimeout[2] = 0;  	dstat->bState = f_dfu->dfu_state;  	dstat->iString = 0;  } @@ -723,8 +755,9 @@ static int dfu_bind_config(struct usb_configuration *c)  	f_dfu->usb_function.unbind = dfu_unbind;  	f_dfu->usb_function.set_alt = dfu_set_alt;  	f_dfu->usb_function.disable = dfu_disable; -	f_dfu->usb_function.strings = dfu_generic_strings, -	f_dfu->usb_function.setup = dfu_handle, +	f_dfu->usb_function.strings = dfu_generic_strings; +	f_dfu->usb_function.setup = dfu_handle; +	f_dfu->poll_timeout = DFU_DEFAULT_POLL_TIMEOUT;  	status = usb_add_function(c, &f_dfu->usb_function);  	if (status) diff --git a/drivers/usb/gadget/f_dfu.h b/drivers/usb/gadget/f_dfu.h index cc2c45567..0c29954ad 100644 --- a/drivers/usb/gadget/f_dfu.h +++ b/drivers/usb/gadget/f_dfu.h @@ -82,4 +82,6 @@ struct dfu_function_descriptor {  	__le16				wTransferSize;  	__le16				bcdDFUVersion;  } __packed; + +#define DFU_POLL_TIMEOUT_MASK           (0xFFFFFFUL)  #endif /* __F_DFU_H_ */ diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 8bd1eb8a9..17187caed 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -201,6 +201,9 @@ static int ehci_shutdown(struct ehci_ctrl *ctrl)  	int i, ret = 0;  	uint32_t cmd, reg; +	if (!ctrl || !ctrl->hcor) +		return -EINVAL; +  	cmd = ehci_readl(&ctrl->hcor->or_usbcmd);  	cmd &= ~(CMD_PSE | CMD_ASE);  	ehci_writel(&ctrl->hcor->or_usbcmd, cmd); @@ -945,7 +948,7 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)  #endif  	/* Set the high address word (aka segment) for 64-bit controller */  	if (ehci_readl(&ehcic[index].hccr->cr_hccparams) & 1) -		ehci_writel(ehcic[index].hcor->or_ctrldssegment, 0); +		ehci_writel(&ehcic[index].hcor->or_ctrldssegment, 0);  	qh_list = &ehcic[index].qh_list; diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 7a1ffe5e2..991b19998 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -54,9 +54,31 @@ static pci_dev_t ehci_find_class(int index)  					bdf += PCI_BDF(0, 0, 1)) {  				pci_read_config_dword(bdf, PCI_CLASS_REVISION,  						      &class); -				if ((class >> 8 == PCI_CLASS_SERIAL_USB_EHCI) -						&& !index--) -					return bdf; +				class >>= 8; +				/* +				 * Here be dragons! In case we have multiple +				 * PCI EHCI controllers, this function will +				 * be called multiple times as well. This +				 * function will scan the PCI busses, always +				 * starting from bus 0, device 0, function 0, +				 * until it finds an USB controller. The USB +				 * stack gives us an 'index' of a controller +				 * that is currently being registered, which +				 * is a number, starting from 0 and growing +				 * in ascending order as controllers are added. +				 * To avoid probing the same controller in tne +				 * subsequent runs of this function, we will +				 * skip 'index - 1' detected controllers and +				 * report the index'th controller. +				 */ +				if (class != PCI_CLASS_SERIAL_USB_EHCI) +					continue; +				if (index) { +					index--; +					continue; +				} +				/* Return index'th controller. */ +				return bdf;  			}  		}  	} diff --git a/include/configs/trats.h b/include/configs/trats.h index 08771422e..6cd15c25b 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -99,6 +99,7 @@  #define CONFIG_THOR_FUNCTION  #define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_32M +#define DFU_DEFAULT_POLL_TIMEOUT 300  #define CONFIG_DFU_FUNCTION  #define CONFIG_DFU_MMC diff --git a/include/dfu.h b/include/dfu.h index cc1404492..f973426aa 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -77,6 +77,9 @@ static inline unsigned int get_mmc_blk_size(int dev)  #ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE  #define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE  #endif +#ifndef DFU_DEFAULT_POLL_TIMEOUT +#define DFU_DEFAULT_POLL_TIMEOUT 0 +#endif  struct dfu_entity {  	char			name[DFU_NAME_SIZE]; @@ -131,6 +134,7 @@ bool dfu_reset(void);  int dfu_init_env_entities(char *interface, int dev);  unsigned char *dfu_get_buf(void);  unsigned char *dfu_free_buf(void); +unsigned long dfu_get_buf_size(void);  int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num);  int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num); |