summaryrefslogtreecommitdiff
path: root/src/portable
diff options
context:
space:
mode:
authorhathach <[email protected]>2024-11-26 10:20:38 +0700
committerhathach <[email protected]>2024-11-26 10:20:38 +0700
commitbe25aa31f6720e0efe96e8656f46adf0ccbbce50 (patch)
tree4facacecc11a41afa07f1336657a3ddb07ad858c /src/portable
parent62f0e87bf16c750622999f3952506e3a364e4075 (diff)
hcd dwc2 add dcache support, usbh correctly use cache line size with TUH_EPBUF_DEF
Diffstat (limited to 'src/portable')
-rw-r--r--src/portable/synopsys/dwc2/dcd_dwc2.c2
-rw-r--r--src/portable/synopsys/dwc2/hcd_dwc2.c28
2 files changed, 28 insertions, 2 deletions
diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c
index 8a9d06bc2..04108499d 100644
--- a/src/portable/synopsys/dwc2/dcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/dcd_dwc2.c
@@ -31,7 +31,7 @@
#if CFG_TUD_ENABLED && defined(TUP_USBIP_DWC2)
-#if !CFG_TUD_DWC2_SLAVE_ENABLE && !CFG_TUH_DWC2_DMA_ENABLE
+#if !(CFG_TUD_DWC2_SLAVE_ENABLE || CFG_TUH_DWC2_DMA_ENABLE)
#error DWC2 require either CFG_TUD_DWC2_SLAVE_ENABLE or CFG_TUH_DWC2_DMA_ENABLE to be enabled
#endif
diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c
index 8e0162ed6..ebbb6200a 100644
--- a/src/portable/synopsys/dwc2/hcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/hcd_dwc2.c
@@ -28,6 +28,10 @@
#if CFG_TUH_ENABLED && defined(TUP_USBIP_DWC2)
+#if !(CFG_TUH_DWC2_SLAVE_ENABLE || CFG_TUH_DWC2_DMA_ENABLE)
+#error DWC2 require either CFG_TUH_DWC2_SLAVE_ENABLE or CFG_TUH_DWC2_DMA_ENABLE to be enabled
+#endif
+
// Debug level for DWC2
#define DWC2_DEBUG 2
@@ -132,6 +136,23 @@ TU_ATTR_ALWAYS_INLINE static inline bool dma_host_enabled(const dwc2_regs_t* dwc
return CFG_TUH_DWC2_DMA_ENABLE && dwc2->ghwcfg2_bm.arch == GHWCFG2_ARCH_INTERNAL_DMA;
}
+#if CFG_TUH_MEM_DCACHE_ENABLE
+bool hcd_dcache_clean(const void* addr, uint32_t data_size) {
+ TU_VERIFY(addr && data_size);
+ return dwc2_dcache_clean(addr, data_size);
+}
+
+bool hcd_dcache_invalidate(const void* addr, uint32_t data_size) {
+ TU_VERIFY(addr && data_size);
+ return dwc2_dcache_invalidate(addr, data_size);
+}
+
+bool hcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) {
+ TU_VERIFY(addr && data_size);
+ return dwc2_dcache_clean_invalidate(addr, data_size);
+}
+#endif
+
// Allocate a channel for new transfer
TU_ATTR_ALWAYS_INLINE static inline uint8_t channel_alloc(dwc2_regs_t* dwc2) {
const uint8_t max_channel = DWC2_CHANNEL_COUNT(dwc2);
@@ -555,6 +576,7 @@ static bool channel_xfer_start(dwc2_regs_t* dwc2, uint8_t ch_id) {
if (hcchar_bm->ep_dir == TUSB_DIR_IN) {
channel_send_in_token(dwc2, channel);
} else {
+ hcd_dcache_clean(edpt->buffer, edpt->buflen);
channel->hcchar |= HCCHAR_CHENA;
}
} else {
@@ -1119,13 +1141,17 @@ static void handle_channel_irq(uint8_t rhport, bool in_isr) {
const uint32_t hcint = channel->hcint;
channel->hcint = hcint; // clear interrupt
- bool is_done;
+ bool is_done = false;
if (is_dma) {
#if CFG_TUH_DWC2_DMA_ENABLE
if (hcchar_bm.ep_dir == TUSB_DIR_OUT) {
is_done = handle_channel_out_dma(dwc2, ch_id, hcint);
} else {
is_done = handle_channel_in_dma(dwc2, ch_id, hcint);
+ if (is_done && (channel->hcdma > xfer->xferred_bytes)) {
+ // hcdma is increased by word --> need to align4
+ hcd_dcache_invalidate((void*) tu_align4(channel->hcdma - xfer->xferred_bytes), xfer->xferred_bytes);
+ }
}
#endif
} else {