Skip to content

Commit 2a56780

Browse files
committed
feature(dcd_dwc2): Added cache synchronization
1 parent 0569188 commit 2a56780

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

src/portable/synopsys/dwc2/dcd_dwc2.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ static bool _sof_en;
6767
//--------------------------------------------------------------------
6868
// DMA
6969
//--------------------------------------------------------------------
70+
// When DMA requires cache synchronization for memory
71+
// Data synchronization: cache to memory
72+
#ifndef dsync_c2m
73+
#define dsync_c2m(_addr, _size)
74+
#endif // dsync_c2m
75+
76+
// Data synchronization: memory to cache
77+
#ifndef dsync_m2c
78+
#define dsync_m2c(_addr, _size)
79+
#endif // dsync_m2c
7080

7181
TU_ATTR_ALWAYS_INLINE static inline bool dma_device_enabled(const dwc2_regs_t* dwc2) {
7282
(void) dwc2;
@@ -359,7 +369,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
359369

360370
if(dma_device_enabled(dwc2)) {
361371
dep->diepdma = (uintptr_t)xfer->buffer;
362-
372+
dsync_c2m(xfer->buffer, total_bytes);
363373
// For ISO endpoint set correct odd/even bit for next frame.
364374
if ((dep->diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) {
365375
// Take odd/even bit from frame counter.
@@ -397,6 +407,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
397407

398408
if(dma_device_enabled(dwc2)) {
399409
dep->doepdma = (uintptr_t)xfer->buffer;
410+
dsync_c2m(xfer->buffer, total_bytes);
400411
}
401412

402413
dep->doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK;
@@ -775,6 +786,7 @@ static void handle_epout_irq(uint8_t rhport) {
775786

776787
if(dma_device_enabled(dwc2)) {
777788
dma_setup_prepare(rhport);
789+
dsync_m2c((uint8_t*) _setup_packet, sizeof(_setup_packet));
778790
}
779791

780792
dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true);
@@ -801,7 +813,7 @@ static void handle_epout_irq(uint8_t rhport) {
801813
if(epnum == 0 && xfer->total_len == 0) {
802814
dma_setup_prepare(rhport);
803815
}
804-
816+
dsync_m2c(xfer->buffer, xfer->total_len);
805817
dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true);
806818
}
807819
} else {

src/portable/synopsys/dwc2/dwc2_esp32.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@
3939
#include "soc/periph_defs.h"
4040
#include "soc/usb_wrap_struct.h"
4141

42+
#if TU_CHECK_MCU(OPT_MCU_ESP32P4)
43+
#if (CFG_TUD_DWC2_DMA && SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE)
44+
#include "hal/cache_hal.h"
45+
#include "esp_cache.h"
46+
#include "esp_log.h"
47+
#define DWC2_ENABLE_MEM_CACHE 1
48+
#endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
49+
#endif // OPT_MCU_ESP32P4
50+
51+
4252
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
4353
#define DWC2_FS_REG_BASE 0x60080000UL
4454
#define DWC2_EP_MAX 7
@@ -111,6 +121,42 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint
111121
// maybe usb_utmi_hal_disable()
112122
}
113123

124+
// MCU specific cache synchronization call
125+
TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_sync_cache_to_memory(void *addr, size_t size) {
126+
#if DWC2_ENABLE_MEM_CACHE
127+
ESP_EARLY_LOGV("dwc2_esp32", "cache to mem sync, addr 0x%"PRIx32", size %d", (uintptr_t)addr, size);
128+
int flags = ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED;
129+
if (addr != NULL && size) {
130+
esp_err_t ret = esp_cache_msync(addr, size, flags);
131+
assert(ret == ESP_OK);
132+
}
133+
#else
134+
(void) addr;
135+
(void) size;
136+
// nothing to do
137+
#endif // DWC2_ENABLE_MEM_CACHE
138+
}
139+
140+
TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_sync_memory_to_cache(void *addr, size_t size) {
141+
#if DWC2_ENABLE_MEM_CACHE
142+
ESP_EARLY_LOGV("dwc2", "mem to cache sync, addr 0x%"PRIx32", size %d", (uintptr_t)addr, size);
143+
int flags = ESP_CACHE_MSYNC_FLAG_DIR_M2C;
144+
if (addr != NULL && size) {
145+
// TODO: size should be multiply of CONFIG_CACHE_L1_CACHE_LINE_SIZE?
146+
size = (size < CONFIG_CACHE_L1_CACHE_LINE_SIZE)? CONFIG_CACHE_L1_CACHE_LINE_SIZE : size;
147+
esp_err_t ret = esp_cache_msync(addr, size, flags);
148+
assert(ret == ESP_OK);
149+
}
150+
#else
151+
(void) addr;
152+
(void) size;
153+
// nothing to do
154+
#endif // DWC2_ENABLE_MEM_CACHE
155+
}
156+
157+
#define dsync_c2m(_addr, _size) dwc2_dcd_sync_cache_to_memory((_addr), (_size))
158+
#define dsync_m2c(_addr, _size) dwc2_dcd_sync_memory_to_cache((_addr), (_size))
159+
114160
#ifdef __cplusplus
115161
}
116162
#endif

0 commit comments

Comments
 (0)