Add an API to allow drivers to writeback or invalidate cache contents. This is useful where the DSP firmware runs from cache and needs to writeback/buffer prior to DMA or other peripheral usage.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/dai.c | 7 +++++++ src/audio/host.c | 7 +++++++ src/include/reef/mailbox.h | 9 +++++++-- src/lib/trace.c | 4 ++++ 4 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/src/audio/dai.c b/src/audio/dai.c index 8be8776..d02e365 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -43,6 +43,7 @@ #include <reef/audio/component.h> #include <reef/audio/pipeline.h> #include <platform/dma.h> +#include <arch/cache.h>
#define DAI_PLAYBACK_STREAM 0 #define DAI_CAPTURE_STREAM 1 @@ -94,6 +95,9 @@ static void dai_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next) dd->dai_pos_blks += dma_buffer->ipc_buffer.size; }
+ /* writeback buffer contents from cache */ + dcache_writeback_region(dma_buffer->r_ptr, dev->period_bytes); + #if 0 // TODO: move this to new trace mechanism trace_value((uint32_t)(dma_buffer->r_ptr - dma_buffer->addr)); @@ -111,6 +115,9 @@ static void dai_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next) dma_buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
+ /* invalidate buffer contents */ + dcache_writeback_region(dma_buffer->w_ptr, dev->period_bytes); + dma_buffer->w_ptr += dev->period_bytes;
/* check for end of buffer */ diff --git a/src/audio/host.c b/src/audio/host.c index 51ece99..9f81a1c 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -44,6 +44,7 @@ #include <reef/audio/component.h> #include <reef/audio/pipeline.h> #include <platform/dma.h> +#include <arch/cache.h> #include <uapi/ipc.h>
#define trace_host(__e) trace_event(TRACE_CLASS_HOST, __e) @@ -127,6 +128,9 @@ static void host_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next) if (hd->params.pcm->direction == SOF_IPC_STREAM_PLAYBACK) { dma_buffer->w_ptr += local_elem->size;
+ /* invalidate audio data */ + dcache_invalidate_region(dma_buffer->w_ptr, local_elem->size); + if (dma_buffer->w_ptr >= dma_buffer->end_addr) dma_buffer->w_ptr = dma_buffer->addr; #if 0 @@ -144,6 +148,9 @@ static void host_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next) trace_value((uint32_t)(hd->dma_buffer->r_ptr - hd->dma_buffer->addr)); #endif
+ /* writeback audio data */ + dcache_writeback_region(dma_buffer->r_ptr, local_elem->size); + /* recalc available buffer space */ comp_update_buffer_consume(hd->dma_buffer); } diff --git a/src/include/reef/mailbox.h b/src/include/reef/mailbox.h index d3a7bf6..44366e4 100644 --- a/src/include/reef/mailbox.h +++ b/src/include/reef/mailbox.h @@ -32,6 +32,7 @@ #define __INCLUDE_MAILBOX__
#include <platform/mailbox.h> +#include <arch/cache.h> #include <stdint.h>
/* almost 1k should be enough for everyone ..... */ @@ -62,15 +63,19 @@ MAILBOX_DEBUG_SIZE
#define mailbox_outbox_write(dest, src, bytes) \ - rmemcpy((void*)(MAILBOX_OUTBOX_BASE + dest), src, bytes); + rmemcpy((void*)(MAILBOX_OUTBOX_BASE + dest), src, bytes); \ + dcache_writeback_region((void*)(MAILBOX_OUTBOX_BASE + dest), bytes);
#define mailbox_outbox_read(dest, src, bytes) \ + dcache_invalidate_region((void*)(MAILBOX_OUTBOX_BASE + src), bytes); \ rmemcpy(dest, (void*)(MAILBOX_OUTBOX_BASE + src), bytes);
#define mailbox_inbox_write(dest, src, bytes) \ - rmemcpy((void*)(MAILBOX_INBOX_BASE + dest), src, bytes); + rmemcpy((void*)(MAILBOX_INBOX_BASE + dest), src, bytes); \ + dcache_writeback_region((void*)(MAILBOX_INBOX_BASE + dest), bytes);
#define mailbox_inbox_read(dest, src, bytes) \ + dcache_invalidate_region((void*)(MAILBOX_INBOX_BASE + src), bytes); \ rmemcpy(dest, (void*)(MAILBOX_INBOX_BASE + src), bytes);
#endif diff --git a/src/lib/trace.c b/src/lib/trace.c index 278a59b..79d026e 100644 --- a/src/lib/trace.c +++ b/src/lib/trace.c @@ -29,6 +29,7 @@ */
#include <reef/trace.h> +#include <arch/cache.h> #include <stdint.h>
/* trace position */ @@ -47,6 +48,9 @@ void _trace_event(uint32_t event) t[0] = platform_timer_get(0); t[1] = event;
+ /* writeback trace data */ + dcache_writeback_region((void*)t, sizeof(uint32_t) * 2); + trace_pos += (sizeof(uint32_t) << 1); if (trace_pos >= MAILBOX_TRACE_SIZE) trace_pos = 0;