[Sound-open-firmware] [PATCH] cache: Add cache management API to writeback/invalidate regions
Liam Girdwood
liam.r.girdwood at linux.intel.com
Wed Jun 7 11:14:19 CEST 2017
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 at 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;
--
2.11.0
More information about the Sound-open-firmware
mailing list