[U-Boot] [PATCH] usb: ehci: add missing cache managment

From: Stephen Warren swarren@nvidia.com
Commit 8f62ca6 "usb: ehci: Support interrupt transfers via periodic list" didn't include any cache management in the new interrupt transfer path. It also added an extra write to or_asynclistaddr in usb_lowlevel_init(), without having flushed out the data there.
Add the missing cache management calls, so that the code works again.
This allows the USB keyboard on Tegra's Seaboard/Springbank boards to work.
Cc: Patrick Georgi patrick@georgi-clan.de Cc: Vincent Palatin vpalatin@chromium.org Cc: Julius Werner jwerner@chromium.org Cc: Simon Glass sjg@chromium.org Cc: Marek Vasut marex@denx.de Signed-off-by: Stephen Warren swarren@nvidia.com --- drivers/usb/host/ehci-hcd.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index e0f3e4b..5c6aaf6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -903,6 +903,9 @@ int usb_lowlevel_init(int index, void **controller) qh_list->qh_overlay.qt_token = cpu_to_hc32(QT_TOKEN_STATUS(QT_TOKEN_STATUS_HALTED));
+ flush_dcache_range((uint32_t)qh_list, + ALIGN_END_ADDR(struct QH, qh_list, 1)); + /* Set async. queue head pointer. */ ehci_writel(&ehcic[index].hcor->or_asynclistaddr, (uint32_t)qh_list);
@@ -916,6 +919,9 @@ int usb_lowlevel_init(int index, void **controller) periodic->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); periodic->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+ flush_dcache_range((uint32_t)periodic, + ALIGN_END_ADDR(struct QH, periodic, 1)); + /* * Step 2: Setup frame-list: Every microframe, USB tries the same list. * In particular, device specifications on polling frequency @@ -933,6 +939,10 @@ int usb_lowlevel_init(int index, void **controller) | QH_LINK_TYPE_QH; }
+ flush_dcache_range((uint32_t)ehcic[index].periodic_list, + ALIGN_END_ADDR(uint32_t, ehcic[index].periodic_list, + 1024)); + /* Set periodic list base address */ ehci_writel(&ehcic[index].hcor->or_periodiclistbase, (uint32_t)ehcic[index].periodic_list); @@ -1144,6 +1154,16 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, *buf = buffer + i * elementsize; }
+ flush_dcache_range((uint32_t)buffer, + ALIGN_END_ADDR(char, buffer, + queuesize * elementsize)); + flush_dcache_range((uint32_t)result->first, + ALIGN_END_ADDR(struct QH, result->first, + queuesize)); + flush_dcache_range((uint32_t)result->tds, + ALIGN_END_ADDR(struct qTD, result->tds, + queuesize)); + if (disable_periodic(ctrl) < 0) { debug("FATAL: periodic should never fail, but did"); goto fail3; @@ -1154,6 +1174,11 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, result->last->qh_link = list->qh_link; list->qh_link = (uint32_t)result->first | QH_LINK_TYPE_QH;
+ flush_dcache_range((uint32_t)result->last, + ALIGN_END_ADDR(struct QH, result->last, 1)); + flush_dcache_range((uint32_t)list, + ALIGN_END_ADDR(struct QH, list, 1)); + if (enable_periodic(ctrl) < 0) { debug("FATAL: periodic should never fail, but did"); goto fail3; @@ -1184,6 +1209,8 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue) return NULL; } /* still active */ + invalidate_dcache_range((uint32_t)cur, + ALIGN_END_ADDR(struct QH, cur, 1)); if (cur->qh_overlay.qt_token & 0x80) { debug("Exit poll_int_queue with no completed intr transfer. " "token is %x\n", cur->qh_overlay.qt_token); @@ -1290,6 +1317,9 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, return -EINVAL; }
+ invalidate_dcache_range((uint32_t)buffer, + ALIGN_END_ADDR(char, buffer, length)); + ret = destroy_int_queue(dev, queue); if (ret < 0) return ret;

Dear Stephen Warren,
From: Stephen Warren swarren@nvidia.com
Commit 8f62ca6 "usb: ehci: Support interrupt transfers via periodic list" didn't include any cache management in the new interrupt transfer path. It also added an extra write to or_asynclistaddr in usb_lowlevel_init(), without having flushed out the data there.
Add the missing cache management calls, so that the code works again.
This allows the USB keyboard on Tegra's Seaboard/Springbank boards to work.
Cc: Patrick Georgi patrick@georgi-clan.de Cc: Vincent Palatin vpalatin@chromium.org Cc: Julius Werner jwerner@chromium.org Cc: Simon Glass sjg@chromium.org Cc: Marek Vasut marex@denx.de Signed-off-by: Stephen Warren swarren@nvidia.com
Good find, applied!
Best regards, Marek Vasut
participants (2)
-
Marek Vasut
-
Stephen Warren