CONFIG_USB_EHCI_DATA_ALIGN sets the required alignment of data for USB packets (e.g. 4 means word-aligned). This is required for Tegra to operate.
CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the txfilltuning field in the EHCI controller on reset. Signed-off-by: Simon Glass <s...@chromium.org> --- README | 7 +++++++ drivers/usb/host/ehci-hcd.c | 39 +++++++++++++++++++++++++++++++++++++++ drivers/usb/host/ehci.h | 6 +++++- 3 files changed, 51 insertions(+), 1 deletions(-) diff --git a/README b/README index 07f1d11..d3289d2 100644 --- a/README +++ b/README @@ -1096,6 +1096,13 @@ The following options need to be configured: May be defined to allow interrupt polling instead of using asynchronous interrupts + CONFIG_USB_EHCI_DATA_ALIGN sets the required alignment of + data for USB packets (e.g. 4 means word-aligned). This is + required for Tegra to operate. + + CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the + txfilltuning field in the EHCI controller on reset. + - USB Device: Define the below if you wish to use the USB console. Once firmware is rebuilt from a serial console issue the diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 2197119..d3eeefe 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -247,6 +247,13 @@ static int ehci_reset(void) #endif ehci_writel(reg_ptr, tmp); } + +#ifdef CONFIG_USB_EHCI_TXFIFO_THRESH + cmd = ehci_readl(&hcor->or_txfilltuning); + cmd &= ~TXFIFO_THRESH(0x3f); + cmd |= TXFIFO_THRESH(CONFIG_USB_EHCI_TXFIFO_THRESH); + ehci_writel(&hcor->or_txfilltuning, cmd); +#endif out: return ret; } @@ -322,6 +329,27 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, int timeout; int ret = 0; +#ifdef CONFIG_USB_EHCI_DATA_ALIGN + /* In case ehci host requires alignment for buffers */ + void *align_buf = NULL; + void *orig_buf = buffer; + int unaligned = ((int)buffer & (CONFIG_USB_EHCI_DATA_ALIGN - 1)) != 0; + + if (unaligned) { + align_buf = malloc(length + CONFIG_USB_EHCI_DATA_ALIGN); + if (!align_buf) + return -1; + if ((int)align_buf & (CONFIG_USB_EHCI_DATA_ALIGN - 1)) + buffer = (void *)((int)align_buf + + CONFIG_USB_EHCI_DATA_ALIGN - + ((int)align_buf & + (CONFIG_USB_EHCI_DATA_ALIGN - 1))); + else + buffer = align_buf; + if (usb_pipeout(pipe)) + memcpy(buffer, orig_buf, length); + } +#endif debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe, buffer, length, req); if (req != NULL) @@ -513,9 +541,20 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, ehci_readl(&hcor->or_portsc[1])); } +#ifdef CONFIG_USB_EHCI_DATA_ALIGN + if (unaligned) { + if (usb_pipein(pipe) && dev->act_len) + memcpy(orig_buf, buffer, length); + free(align_buf); + } +#endif return (dev->status != USB_ST_NOT_PROC) ? 0 : -1; fail: +#ifdef CONFIG_USB_EHCI_DATA_ALIGN + if (unaligned) + free(align_buf); +#endif td = (void *)hc32_to_cpu(qh->qh_overlay.qt_next); while (td != (void *)QT_NEXT_TERMINATE) { qh->qh_overlay.qt_next = td->qt_next; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 3d0ad0c..cc00ce4 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -80,7 +80,11 @@ struct ehci_hcor { uint32_t or_ctrldssegment; uint32_t or_periodiclistbase; uint32_t or_asynclistaddr; - uint32_t _reserved_[9]; + uint32_t _reserved_0_; + uint32_t or_burstsize; + uint32_t or_txfilltuning; +#define TXFIFO_THRESH(p) ((p & 0x3f) << 16) + uint32_t _reserved_1_[6]; uint32_t or_configflag; #define FLAG_CF (1 << 0) /* true: we'll support "high speed" */ uint32_t or_portsc[CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS]; -- 1.7.3.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot