Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DCD_DWC2][ESP32P4][HS] Added cache synchronization #2877

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/portable/synopsys/dwc2/dcd_dwc2.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ static bool _sof_en;
//--------------------------------------------------------------------
// DMA
//--------------------------------------------------------------------
// When DMA requires cache synchronization for memory
roma-jam marked this conversation as resolved.
Show resolved Hide resolved
// Data synchronization: cache to memory
#ifndef dsync_c2m
#define dsync_c2m(_addr, _size)
#endif // dsync_c2m

// Data synchronization: memory to cache
#ifndef dsync_m2c
#define dsync_m2c(_addr, _size)
#endif // dsync_m2c

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

if(dma_device_enabled(dwc2)) {
dep->diepdma = (uintptr_t)xfer->buffer;

dsync_c2m(xfer->buffer, total_bytes);
// For ISO endpoint set correct odd/even bit for next frame.
if ((dep->diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) {
// Take odd/even bit from frame counter.
Expand Down Expand Up @@ -397,6 +407,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c

if(dma_device_enabled(dwc2)) {
dep->doepdma = (uintptr_t)xfer->buffer;
dsync_c2m(xfer->buffer, total_bytes);
}

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

if(dma_device_enabled(dwc2)) {
dma_setup_prepare(rhport);
dsync_m2c((uint8_t*) _setup_packet, sizeof(_setup_packet));
}

dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true);
Expand All @@ -801,7 +813,7 @@ static void handle_epout_irq(uint8_t rhport) {
if(epnum == 0 && xfer->total_len == 0) {
dma_setup_prepare(rhport);
}

dsync_m2c(xfer->buffer, xfer->total_len);
dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true);
}
} else {
Expand Down
46 changes: 46 additions & 0 deletions src/portable/synopsys/dwc2/dwc2_esp32.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@
#include "soc/periph_defs.h"
#include "soc/usb_wrap_struct.h"

#if TU_CHECK_MCU(OPT_MCU_ESP32P4)
#if (CFG_TUD_DWC2_DMA && SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE)
#include "hal/cache_hal.h"
#include "esp_cache.h"
#include "esp_log.h"
#define DWC2_ENABLE_MEM_CACHE 1
#endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
#endif // OPT_MCU_ESP32P4


#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
#define DWC2_FS_REG_BASE 0x60080000UL
#define DWC2_EP_MAX 7
Expand Down Expand Up @@ -111,6 +121,42 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint
// maybe usb_utmi_hal_disable()
}

// MCU specific cache synchronization call
TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_sync_cache_to_memory(void *addr, size_t size) {
#if DWC2_ENABLE_MEM_CACHE
ESP_EARLY_LOGV("dwc2_esp32", "cache to mem sync, addr 0x%"PRIx32", size %d", (uintptr_t)addr, size);
int flags = ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED;
if (addr != NULL && size) {
esp_err_t ret = esp_cache_msync(addr, size, flags);
assert(ret == ESP_OK);
}
#else
(void) addr;
(void) size;
// nothing to do
#endif // DWC2_ENABLE_MEM_CACHE
}

TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_sync_memory_to_cache(void *addr, size_t size) {
#if DWC2_ENABLE_MEM_CACHE
ESP_EARLY_LOGV("dwc2", "mem to cache sync, addr 0x%"PRIx32", size %d", (uintptr_t)addr, size);
int flags = ESP_CACHE_MSYNC_FLAG_DIR_M2C;
if (addr != NULL && size) {
// TODO: size should be multiply of CONFIG_CACHE_L1_CACHE_LINE_SIZE?
size = (size < CONFIG_CACHE_L1_CACHE_LINE_SIZE)? CONFIG_CACHE_L1_CACHE_LINE_SIZE : size;
esp_err_t ret = esp_cache_msync(addr, size, flags);
assert(ret == ESP_OK);
}
#else
(void) addr;
(void) size;
// nothing to do
#endif // DWC2_ENABLE_MEM_CACHE
}

#define dsync_c2m(_addr, _size) dwc2_dcd_sync_cache_to_memory((_addr), (_size))
#define dsync_m2c(_addr, _size) dwc2_dcd_sync_memory_to_cache((_addr), (_size))

#ifdef __cplusplus
}
#endif
Expand Down
Loading