summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile20
-rw-r--r--drivers/dfu/dfu.c5
-rw-r--r--drivers/mtd/nand/nand_util.c2
-rw-r--r--drivers/mtd/nand/omap_gpmc.c108
-rw-r--r--drivers/usb/gadget/f_dfu.c43
-rw-r--r--drivers/usb/gadget/f_dfu.h2
-rw-r--r--drivers/usb/host/ehci-hcd.c5
-rw-r--r--drivers/usb/host/ehci-pci.c28
-rw-r--r--include/configs/trats.h1
-rw-r--r--include/dfu.h4
10 files changed, 149 insertions, 69 deletions
diff --git a/Makefile b/Makefile
index f03d116..cbd45a7 100644
--- a/Makefile
+++ b/Makefile
@@ -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 1eb92e5..07011e9 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 eeaa7e8..b292826 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 5e7e6b3..790d538 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 37d04a1..a045864 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 cc2c455..0c29954 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 8bd1eb8..17187ca 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 7a1ffe5..991b199 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 0877142..6cd15c2 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 cc14044..f973426 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);