summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2025-03-28 13:12:46 +0800
committersakumisu <[email protected]>2025-03-28 13:29:04 +0800
commite9257baa5d42a9ab40faaab57df56c021646dde4 (patch)
treec59e5db2f5aeffa383683d5fbed1f424dc698413
parentf48fa44368ac49911274afaae5b40025bc1496a3 (diff)
update(port/ehci): add pad for qh&qtd cachemaintain, add CONFIG_USB_EHCI_DESC_DCACHE_ENABLE for qh&qtd&itd
Signed-off-by: sakumisu <[email protected]>
-rw-r--r--port/ehci/usb_hc_ehci.c36
-rw-r--r--port/ehci/usb_hc_ehci.h17
2 files changed, 31 insertions, 22 deletions
diff --git a/port/ehci/usb_hc_ehci.c b/port/ehci/usb_hc_ehci.c
index 84c24ed5..f835443d 100644
--- a/port/ehci/usb_hc_ehci.c
+++ b/port/ehci/usb_hc_ehci.c
@@ -76,7 +76,7 @@ static void ehci_qh_free(struct usbh_bus *bus, struct ehci_qh_hw *qh)
}
}
-#ifdef CONFIG_USB_DCACHE_ENABLE
+#if defined(CONFIG_USB_EHCI_DESC_DCACHE_ENABLE)
static inline void usb_ehci_qh_qtd_flush(struct ehci_qh_hw *qh)
{
struct ehci_qtd_hw *qtd;
@@ -84,15 +84,10 @@ static inline void usb_ehci_qh_qtd_flush(struct ehci_qh_hw *qh)
qtd = EHCI_ADDR2QTD(qh->first_qtd);
while (qtd) {
- usb_dcache_clean((uintptr_t)&qtd->hw, USB_ALIGN_UP(SIZEOF_EHCI_QTD, CONFIG_USB_EHCI_ALIGN_SIZE));
-
- if (!qtd->dir_in) {
- usb_dcache_clean(qtd->bufaddr, USB_ALIGN_UP(qtd->length, CONFIG_USB_ALIGN_SIZE));
- }
+ usb_dcache_clean((uintptr_t)&qtd->hw, CONFIG_USB_EHCI_ALIGN_SIZE);
qtd = EHCI_ADDR2QTD(qtd->hw.next_qtd);
}
-
- usb_dcache_clean((uintptr_t)&qh->hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
+ usb_dcache_clean((uintptr_t)&qh->hw, CONFIG_USB_EHCI_ALIGN_SIZE);
}
#else
#define usb_ehci_qh_qtd_flush(qh)
@@ -103,9 +98,12 @@ static inline void ehci_qh_add_head(struct ehci_qh_hw *head, struct ehci_qh_hw *
n->hw.hlp = head->hw.hlp;
usb_ehci_qh_qtd_flush(n);
- head->hw.hlp = QH_HLP_QH(n);
+ usb_dcache_flush((uintptr_t)n->urb->transfer_buffer, USB_ALIGN_UP(n->urb->transfer_buffer_length, CONFIG_USB_ALIGN_SIZE));
- usb_dcache_clean((uintptr_t)&head->hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
+ head->hw.hlp = QH_HLP_QH(n);
+#if defined(CONFIG_USB_EHCI_DESC_DCACHE_ENABLE)
+ usb_dcache_clean((uintptr_t)&head->hw, CONFIG_USB_EHCI_ALIGN_SIZE);
+#endif
}
static inline void ehci_qh_remove(struct ehci_qh_hw *head, struct ehci_qh_hw *n)
@@ -118,7 +116,9 @@ static inline void ehci_qh_remove(struct ehci_qh_hw *head, struct ehci_qh_hw *n)
if (tmp) {
tmp->hw.hlp = n->hw.hlp;
- usb_dcache_clean((uintptr_t)&tmp->hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
+#if defined(CONFIG_USB_EHCI_DESC_DCACHE_ENABLE)
+ usb_dcache_clean((uintptr_t)&tmp->hw, CONFIG_USB_EHCI_ALIGN_SIZE);
+#endif
}
}
@@ -282,7 +282,6 @@ static void ehci_qtd_fill(struct ehci_qtd_hw *qtd, uint32_t bufaddr, size_t bufl
qtd->hw.token = token;
ehci_qtd_bpl_fill(qtd, usb_phyaddr2ramaddr(bufaddr), buflen);
- qtd->dir_in = ((token & QTD_TOKEN_PID_MASK) == QTD_TOKEN_PID_IN) ? true : false;
qtd->bufaddr = bufaddr;
qtd->length = buflen;
}
@@ -620,9 +619,6 @@ static void ehci_qh_scan_qtds(struct usbh_bus *bus, struct ehci_qh_hw *qhead, st
qtd = EHCI_ADDR2QTD(qh->first_qtd);
while (qtd) {
- if (qtd->dir_in) {
- usb_dcache_invalidate(qtd->bufaddr, USB_ALIGN_UP(qtd->length - ((qtd->hw.token & QTD_TOKEN_NBYTES_MASK) >> QTD_TOKEN_NBYTES_SHIFT), CONFIG_USB_ALIGN_SIZE));
- }
qtd->urb->actual_length += (qtd->length - ((qtd->hw.token & QTD_TOKEN_NBYTES_MASK) >> QTD_TOKEN_NBYTES_SHIFT));
qh->first_qtd = qtd->hw.next_qtd;
@@ -643,7 +639,9 @@ static void ehci_check_qh(struct usbh_bus *bus, struct ehci_qh_hw *qhead, struct
}
while (qtd) {
- usb_dcache_invalidate((uintptr_t)&qtd->hw, USB_ALIGN_UP(SIZEOF_EHCI_QTD, CONFIG_USB_EHCI_ALIGN_SIZE));
+#if defined(CONFIG_USB_EHCI_DESC_DCACHE_ENABLE)
+ usb_dcache_invalidate((uintptr_t)&qtd->hw, CONFIG_USB_EHCI_ALIGN_SIZE);
+#endif
token = qtd->hw.token;
if (token & QTD_TOKEN_STATUS_ERRORS) {
@@ -799,9 +797,11 @@ int usb_hc_init(struct usbh_bus *bus)
g_framelist[bus->hcd.hcd_id][i] = QH_HLP_QH(&g_periodic_qh_head[bus->hcd.hcd_id]);
}
- usb_dcache_clean((uintptr_t)&g_async_qh_head[bus->hcd.hcd_id].hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
- usb_dcache_clean((uintptr_t)&g_periodic_qh_head[bus->hcd.hcd_id].hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
+#if defined(CONFIG_USB_EHCI_DESC_DCACHE_ENABLE)
+ usb_dcache_clean((uintptr_t)&g_async_qh_head[bus->hcd.hcd_id].hw, CONFIG_USB_EHCI_ALIGN_SIZE);
+ usb_dcache_clean((uintptr_t)&g_periodic_qh_head[bus->hcd.hcd_id].hw, CONFIG_USB_EHCI_ALIGN_SIZE);
usb_dcache_clean((uintptr_t)g_framelist[bus->hcd.hcd_id], sizeof(uint32_t) * CONFIG_USB_EHCI_FRAME_LIST_SIZE);
+#endif
usb_hc_low_level_init(bus);
diff --git a/port/ehci/usb_hc_ehci.h b/port/ehci/usb_hc_ehci.h
index 8d08cfa1..3ae618a8 100644
--- a/port/ehci/usb_hc_ehci.h
+++ b/port/ehci/usb_hc_ehci.h
@@ -30,22 +30,30 @@
#ifndef CONFIG_USB_EHCI_ISO_NUM
#define CONFIG_USB_EHCI_ISO_NUM 4
#endif
-#ifndef CONFIG_USB_EHCI_ALIGN_SIZE
+
+#if CONFIG_USB_ALIGN_SIZE <= 32
+#define CONFIG_USB_EHCI_ALIGN_SIZE 32
+#elif CONFIG_USB_ALIGN_SIZE <= 64
#define CONFIG_USB_EHCI_ALIGN_SIZE 64
+#else
+#error "CONFIG_USB_ALIGN_SIZE must be 32 or 64"
#endif
-extern uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port);
-
struct ehci_qtd_hw {
struct ehci_qtd hw;
+#if defined(CONFIG_USB_EHCI_DESC_DCACHE_ENABLE) && (CONFIG_USB_ALIGN_SIZE == 64)
+ uint8_t pad[32];
+#endif
struct usbh_urb *urb;
- bool dir_in;
uintptr_t bufaddr;
uint32_t length;
} __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));
struct ehci_qh_hw {
struct ehci_qh hw;
+#if defined(CONFIG_USB_EHCI_DESC_DCACHE_ENABLE)
+ uint16_t pad[16];
+#endif
struct ehci_qtd_hw qtd_pool[CONFIG_USB_EHCI_QTD_NUM];
uint32_t first_qtd;
struct usbh_urb *urb;
@@ -82,6 +90,7 @@ struct ehci_hcd {
extern struct ehci_hcd g_ehci_hcd[CONFIG_USBHOST_MAX_BUS];
extern uint32_t g_framelist[CONFIG_USBHOST_MAX_BUS][USB_ALIGN_UP(CONFIG_USB_EHCI_FRAME_LIST_SIZE, 1024)];
+extern uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port);
int ehci_iso_urb_init(struct usbh_bus *bus, struct usbh_urb *urb);
void ehci_kill_iso_urb(struct usbh_bus *bus, struct usbh_urb *urb);