Skip to content

Commit 4da5de7

Browse files
committed
have p4 dma somewhat working but having issue with buffer that does not occupy the whole cache line
1 parent 43a45f2 commit 4da5de7

File tree

6 files changed

+104
-18
lines changed

6 files changed

+104
-18
lines changed

hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ list(APPEND compile_definitions
1515
BOARD_TUH_MAX_SPEED=${RHPORT_HOST_SPEED}
1616
)
1717

18+
if (target STREQUAL esp32p4)
19+
# P4 change alignment to 64 (DCache line size) for possible DMA configuration
20+
list(APPEND compile_definitions
21+
CFG_TUSB_MEM_ALIGN=__attribute__\(\(aligned\(64\)\)\)
22+
)
23+
endif ()
24+
1825
list(APPEND srcs
1926
# common
2027
${tusb_src}/tusb.c
@@ -68,6 +75,7 @@ endif()
6875
idf_component_register(SRCS ${srcs}
6976
INCLUDE_DIRS ${tusb_src}
7077
REQUIRES src
78+
PRIV_REQUIRES esp_mm
7179
)
7280

7381
target_compile_definitions(${COMPONENT_LIB} PUBLIC ${compile_definitions})

src/device/dcd.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,15 @@ typedef struct TU_ATTR_ALIGNED(4) {
9393

9494
// clean/flush data cache: write cache -> memory.
9595
// Required before an DMA TX transfer to make sure data is in memory
96-
void dcd_dcache_clean(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
96+
void dcd_dcache_clean(const void* addr, uint32_t data_size);
9797

9898
// invalidate data cache: mark cache as invalid, next read will read from memory
9999
// Required BOTH before and after an DMA RX transfer
100-
void dcd_dcache_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
100+
void dcd_dcache_invalidate(const void* addr, uint32_t data_size);
101101

102102
// clean and invalidate data cache
103103
// Required before an DMA transfer where memory is both read/write by DMA
104-
void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
104+
void dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size);
105105

106106
//--------------------------------------------------------------------+
107107
// Controller API

src/device/usbd.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@
4646
// Weak stubs: invoked if no strong implementation is available
4747
//--------------------------------------------------------------------+
4848
TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) {
49-
(void) rhport;
50-
(void) eventid;
51-
(void) in_isr;
49+
(void) rhport; (void) eventid; (void) in_isr;
5250
}
5351

5452
TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count) {
@@ -82,9 +80,7 @@ TU_ATTR_WEAK void tud_resume_cb(void) {
8280
}
8381

8482
TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) {
85-
(void) rhport;
86-
(void) stage;
87-
(void) request;
83+
(void) rhport; (void) stage; (void) request;
8884
return false;
8985
}
9086

@@ -101,6 +97,18 @@ TU_ATTR_WEAK void dcd_disconnect(uint8_t rhport) {
10197
(void) rhport;
10298
}
10399

100+
TU_ATTR_WEAK void dcd_dcache_clean(const void* addr, uint32_t data_size) {
101+
(void) addr; (void) data_size;
102+
}
103+
104+
TU_ATTR_WEAK void dcd_dcache_invalidate(const void* addr, uint32_t data_size) {
105+
(void) addr; (void) data_size;
106+
}
107+
108+
TU_ATTR_WEAK void dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) {
109+
(void) addr; (void) data_size;
110+
}
111+
104112
//--------------------------------------------------------------------+
105113
// Device Data
106114
//--------------------------------------------------------------------+

src/portable/synopsys/dwc2/dcd_dwc2.c

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@
4646
//--------------------------------------------------------------------+
4747
// MACRO TYPEDEF CONSTANT ENUM
4848
//--------------------------------------------------------------------+
49-
50-
static CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2];
49+
static CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN uint32_t _setup_packet[2];
5150

5251
typedef struct {
5352
uint8_t* buffer;
@@ -73,6 +72,25 @@ static bool _sof_en;
7372
//--------------------------------------------------------------------
7473
// DMA
7574
//--------------------------------------------------------------------
75+
#if DWC2_ENABLE_MEM_CACHE
76+
void dcd_dcache_clean(const void* addr, uint32_t data_size) {
77+
if (addr && data_size) {
78+
dwc2_dcache_clean(addr, data_size);
79+
}
80+
}
81+
82+
void dcd_dcache_invalidate(const void* addr, uint32_t data_size) {
83+
if (addr && data_size) {
84+
dwc2_dcache_invalidate(addr, data_size);
85+
}
86+
}
87+
88+
void dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) {
89+
if (addr && data_size) {
90+
dwc2_dcache_clean_invalidate(addr, data_size);
91+
}
92+
}
93+
#endif
7694

7795
TU_ATTR_ALWAYS_INLINE static inline bool dma_device_enabled(const dwc2_regs_t* dwc2) {
7896
(void) dwc2;
@@ -180,7 +198,7 @@ static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) {
180198
// Check if free space is available
181199
TU_ASSERT(_dfifo_top >= fifo_size + dwc2->grxfsiz);
182200
_dfifo_top -= fifo_size;
183-
TU_LOG(DWC2_DEBUG, " TX FIFO %u: allocated %u words at offset %u\r\n", epnum, fifo_size, _dfifo_top);
201+
// TU_LOG(DWC2_DEBUG, " TX FIFO %u: allocated %u words at offset %u\r\n", epnum, fifo_size, _dfifo_top);
184202

185203
// Both TXFD and TXSA are in unit of 32-bit words.
186204
if (epnum == 0) {
@@ -348,14 +366,18 @@ static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uin
348366

349367
const bool is_dma = dma_device_enabled(dwc2);
350368
if(is_dma) {
369+
if (dir == TUSB_DIR_IN && total_bytes != 0) {
370+
dcd_dcache_clean(xfer->buffer, total_bytes);
371+
}
351372
dep->diepdma = (uintptr_t) xfer->buffer;
352-
}
353-
354-
dep->diepctl = depctl.value; // enable endpoint
373+
dep->diepctl = depctl.value; // enable endpoint
374+
} else {
375+
dep->diepctl = depctl.value; // enable endpoint
355376

356-
// Slave: enable tx fifo empty interrupt only if there is data. Note must after depctl enable
357-
if (!is_dma && dir == TUSB_DIR_IN && total_bytes != 0) {
358-
dwc2->diepempmsk |= (1 << epnum);
377+
// Enable tx fifo empty interrupt only if there is data. Note must after depctl enable
378+
if (dir == TUSB_DIR_IN && total_bytes != 0) {
379+
dwc2->diepempmsk |= (1 << epnum);
380+
}
359381
}
360382
}
361383

@@ -847,6 +869,7 @@ static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepi
847869

848870
if (doepint_bm.setup_phase_done) {
849871
dma_setup_prepare(rhport);
872+
dcd_dcache_invalidate(_setup_packet, 8);
850873
dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true);
851874
return;
852875
}
@@ -873,6 +896,7 @@ static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepi
873896
dma_setup_prepare(rhport);
874897
}
875898

899+
dcd_dcache_invalidate(xfer->buffer, xfer->total_len);
876900
dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true);
877901
}
878902
}

src/portable/synopsys/dwc2/dwc2_common.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ bool dwc2_core_init(uint8_t rhport, bool is_highspeed, bool is_dma) {
229229
dwc2->gotgint = 0xFFFFFFFFU;
230230
dwc2->gintmsk = 0;
231231

232+
TU_LOG(DWC2_COMMON_DEBUG, "DMA = %u\r\n", is_dma);
233+
232234
if (is_dma) {
233235
// DMA seems to be only settable after a core reset, and not possible to switch on-the-fly
234236
dwc2->gahbcfg |= GAHBCFG_DMAEN | GAHBCFG_HBSTLEN_2;

src/portable/synopsys/dwc2/dwc2_esp32.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,50 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint
111111
// maybe usb_utmi_hal_disable()
112112
}
113113

114+
//--------------------------------------------------------------------+
115+
// Data Cache
116+
//--------------------------------------------------------------------+
117+
#if defined(SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE) && SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
118+
#include "sdkconfig.h"
119+
#include "hal/cache_hal.h"
120+
#include "esp_cache.h"
121+
#include "esp_log.h"
122+
123+
#define DWC2_MEM_CACHE_LINE_SIZE CONFIG_CACHE_L1_CACHE_LINE_SIZE
124+
#define DWC2_ENABLE_MEM_CACHE 1
125+
126+
TU_ATTR_ALWAYS_INLINE static inline uint32_t round_up_to_cache_line_size(uint32_t size) {
127+
if (size & (CONFIG_CACHE_L1_CACHE_LINE_SIZE-1)) {
128+
size = (size & ~(CONFIG_CACHE_L1_CACHE_LINE_SIZE-1)) + CONFIG_CACHE_L1_CACHE_LINE_SIZE;
129+
}
130+
return size;
131+
}
132+
133+
TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcache_clean(const void* addr, uint32_t data_size) {
134+
// round up to cache line size
135+
const int flag = ESP_CACHE_MSYNC_FLAG_TYPE_DATA | ESP_CACHE_MSYNC_FLAG_DIR_C2M;
136+
data_size = round_up_to_cache_line_size(data_size);
137+
//ESP_EARLY_LOGI("ESP32_DWC", "dcache clean, addr 0x%"PRIx32", size %d (%s)", (uintptr_t)addr, data_size);
138+
assert(ESP_OK == esp_cache_msync((void*)addr, data_size, flag));
139+
}
140+
141+
TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcache_invalidate(const void* addr, uint32_t data_size) {
142+
const int flag = ESP_CACHE_MSYNC_FLAG_TYPE_DATA | ESP_CACHE_MSYNC_FLAG_DIR_M2C;
143+
data_size = round_up_to_cache_line_size(data_size);
144+
//ESP_EARLY_LOGI("ESP32_DWC", "dcache invalidate, addr 0x%"PRIx32", size %d (%s)", (uintptr_t)addr, data_size);
145+
assert(ESP_OK == esp_cache_msync((void*)addr, data_size, flag));
146+
}
147+
148+
TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcache_clean_invalidate(const void* addr, uint32_t data_size) {
149+
const int flag = ESP_CACHE_MSYNC_FLAG_TYPE_DATA | ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_DIR_M2C;
150+
data_size = round_up_to_cache_line_size(data_size);
151+
//ESP_EARLY_LOGI("ESP32_DWC", "dcache clean_invalidate, addr 0x%"PRIx32", size %d (%s)", (uintptr_t)addr, data_size);
152+
assert(ESP_OK == esp_cache_msync((void*)addr, data_size, flag));
153+
}
154+
155+
#endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
156+
157+
114158
#ifdef __cplusplus
115159
}
116160
#endif

0 commit comments

Comments
 (0)