summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-04-23 07:31:36 -0400
committerTom Rini <trini@konsulko.com>2021-04-23 07:31:36 -0400
commit4d85f42716ceff1143e55c7697dd559cfc438489 (patch)
tree0f5cbea48fa44cfc84388c9aabba17eca6f5013d
parente8b8c2085c3eabf6b5e8764dceda02cfc2d08b2f (diff)
parente1769da17ed339bc937d30c49176bc3664b261af (diff)
downloadu-boot-WIP/23Apr2021.tar.gz
Merge https://source.denx.de/u-boot/custodians/u-boot-usbWIP/23Apr2021
-rw-r--r--drivers/usb/host/ehci-hcd.c27
-rw-r--r--drivers/usb/host/ehci.h1
2 files changed, 28 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 8933f60843..ba75c27d04 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -346,6 +346,28 @@ static int ehci_disable_async(struct ehci_ctrl *ctrl)
return ret;
}
+static int ehci_iaa_cycle(struct ehci_ctrl *ctrl)
+{
+ u32 cmd, status;
+ int ret;
+
+ /* Enable Interrupt on Async Advance Doorbell. */
+ cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
+ cmd |= CMD_IAAD;
+ ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+
+ ret = handshake(&ctrl->hcor->or_usbsts, STS_IAA, STS_IAA,
+ 10 * 1000); /* 10ms timeout */
+ if (ret < 0)
+ printf("EHCI fail timeout STS_IAA set\n");
+
+ status = ehci_readl(&ctrl->hcor->or_usbsts);
+ if (status & STS_IAA)
+ ehci_writel(&ctrl->hcor->or_usbsts, STS_IAA);
+
+ return ret;
+}
+
static int
ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
int length, struct devrequest *req)
@@ -631,6 +653,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
flush_dcache_range((unsigned long)&ctrl->qh_list,
ALIGN_END_ADDR(struct QH, &ctrl->qh_list, 1));
+ /* Set IAAD, poll IAA */
+ ret = ehci_iaa_cycle(ctrl);
+ if (ret)
+ goto fail;
+
/*
* Invalidate the memory area occupied by buffer
* Don't try to fix the buffer alignment, if it isn't properly
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 8e0755423a..e9e6f2a551 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -44,6 +44,7 @@ struct ehci_hcor {
#define STS_ASS (1 << 15)
#define STS_PSS (1 << 14)
#define STS_HALT (1 << 12)
+#define STS_IAA (1 << 5)
uint32_t or_usbintr;
#define INTR_UE (1 << 0) /* USB interrupt enable */
#define INTR_UEE (1 << 1) /* USB error interrupt enable */