buffer: L1 cache operations handling

Moves L1 cache operations from other components to buffer.
Right now handles buffers connected to DMAs.
Will handle connections to other cores in the future.

Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
This commit is contained in:
Tomasz Lauda 2018-06-26 16:46:31 +02:00
parent 11716bb415
commit 76596a89b3
5 changed files with 85 additions and 94 deletions

View File

@ -99,3 +99,73 @@ void buffer_free(struct comp_buffer *buffer)
rfree(buffer->addr);
rfree(buffer);
}
void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes)
{
uint32_t flags;
spin_lock_irq(&buffer->lock, flags);
if (buffer->source->is_dma_connected)
dcache_invalidate_region(buffer->w_ptr, bytes);
else if (buffer->sink->is_dma_connected)
dcache_writeback_region(buffer->w_ptr, bytes);
buffer->w_ptr += bytes;
/* check for pointer wrap */
if (buffer->w_ptr >= buffer->end_addr)
buffer->w_ptr = buffer->addr + (buffer->w_ptr - buffer->end_addr);
/* calculate available bytes */
if (buffer->r_ptr < buffer->w_ptr)
buffer->avail = buffer->w_ptr - buffer->r_ptr;
else if (buffer->r_ptr == buffer->w_ptr)
buffer->avail = buffer->size; /* full */
else
buffer->avail = buffer->size - (buffer->r_ptr - buffer->w_ptr);
/* calculate free bytes */
buffer->free = buffer->size - buffer->avail;
spin_unlock_irq(&buffer->lock, flags);
tracev_buffer("pro");
tracev_value((buffer->avail << 16) | buffer->free);
tracev_value((buffer->ipc_buffer.comp.id << 16) | buffer->size);
tracev_value((buffer->r_ptr - buffer->addr) << 16 | (buffer->w_ptr - buffer->addr));
}
void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes)
{
uint32_t flags;
spin_lock_irq(&buffer->lock, flags);
buffer->r_ptr += bytes;
/* check for pointer wrap */
if (buffer->r_ptr >= buffer->end_addr)
buffer->r_ptr = buffer->addr + (buffer->r_ptr - buffer->end_addr);
/* calculate available bytes */
if (buffer->r_ptr < buffer->w_ptr)
buffer->avail = buffer->w_ptr - buffer->r_ptr;
else if (buffer->r_ptr == buffer->w_ptr)
buffer->avail = 0; /* empty */
else
buffer->avail = buffer->size - (buffer->r_ptr - buffer->w_ptr);
/* calculate free bytes */
buffer->free = buffer->size - buffer->avail;
if (buffer->sink->is_dma_connected)
dcache_writeback_region(buffer->r_ptr, bytes);
spin_unlock_irq(&buffer->lock, flags);
tracev_buffer("con");
tracev_value((buffer->avail << 16) | buffer->free);
tracev_value((buffer->ipc_buffer.comp.id << 16) | buffer->size);
tracev_value((buffer->r_ptr - buffer->addr) << 16 | (buffer->w_ptr - buffer->addr));
}

View File

@ -123,9 +123,6 @@ static void dai_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next)
/* recalc available buffer space */
comp_update_buffer_consume(dma_buffer, copied_size);
/* writeback buffer contents from cache */
dcache_writeback_region(dma_buffer->r_ptr, copied_size);
/* update host position(in bytes offset) for drivers */
dev->position += copied_size;
if (dd->dai_pos) {
@ -144,9 +141,6 @@ 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_invalidate_region(dma_buffer->w_ptr, dd->period_bytes);
/* recalc available buffer space */
comp_update_buffer_produce(dma_buffer, dd->period_bytes);
@ -229,6 +223,7 @@ static struct comp_dev *dai_new(struct sof_ipc_comp *comp)
dma_set_cb(dd->dma, dd->chan, DMA_IRQ_TYPE_BLOCK |
DMA_IRQ_TYPE_LLIST, dai_dma_cb, dev);
dev->state = COMP_STATE_READY;
dev->is_dma_connected = 1;
return dev;
error:

View File

@ -134,22 +134,13 @@ static void host_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next)
/* update buffer positions */
dma_buffer = hd->dma_buffer;
if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK) {
/* invalidate audio data */
dcache_invalidate_region(dma_buffer->w_ptr, local_elem->size);
if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK)
/* recalc available buffer space */
comp_update_buffer_produce(hd->dma_buffer, local_elem->size);
} else {
else
/* recalc available buffer space */
comp_update_buffer_consume(hd->dma_buffer, local_elem->size);
/* writeback audio data */
dcache_writeback_region(dma_buffer->r_ptr, local_elem->size);
}
/* new local period, update host buffer position blks */
hd->local_pos += local_elem->size;
dev->position += local_elem->size;
@ -319,20 +310,13 @@ static void host_gw_dma_update(struct comp_dev *dev)
/* update buffer positions */
dma_buffer = hd->dma_buffer;
if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK) {
/* invalidate audio data */
dcache_invalidate_region(dma_buffer->w_ptr, local_elem->size);
if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK)
/* recalc available buffer space */
comp_update_buffer_produce(hd->dma_buffer, local_elem->size);
} else {
else
/* recalc available buffer space */
comp_update_buffer_consume(hd->dma_buffer, local_elem->size);
/* writeback audio data */
dcache_writeback_region(dma_buffer->r_ptr, local_elem->size);
}
dev->position += local_elem->size;
/* new local period, update host buffer position blks */
@ -565,6 +549,7 @@ static struct comp_dev *host_new(struct sof_ipc_comp *comp)
/* init posn data. TODO: other fields */
hd->posn.comp_id = comp->id;
dev->state = COMP_STATE_READY;
dev->is_dma_connected = 1;
return dev;
error:

View File

@ -80,70 +80,10 @@ struct comp_buffer *buffer_new(struct sof_ipc_buffer *desc);
void buffer_free(struct comp_buffer *buffer);
/* called by a component after producing data into this buffer */
static inline void comp_update_buffer_produce(struct comp_buffer *buffer,
uint32_t bytes)
{
uint32_t flags;
spin_lock_irq(&buffer->lock, flags);
buffer->w_ptr += bytes;
/* check for pointer wrap */
if (buffer->w_ptr >= buffer->end_addr)
buffer->w_ptr = buffer->addr + (buffer->w_ptr - buffer->end_addr);
/* calculate available bytes */
if (buffer->r_ptr < buffer->w_ptr)
buffer->avail = buffer->w_ptr - buffer->r_ptr;
else if (buffer->r_ptr == buffer->w_ptr)
buffer->avail = buffer->size; /* full */
else
buffer->avail = buffer->size - (buffer->r_ptr - buffer->w_ptr);
/* calculate free bytes */
buffer->free = buffer->size - buffer->avail;
spin_unlock_irq(&buffer->lock, flags);
tracev_buffer("pro");
tracev_value((buffer->avail << 16) | buffer->free);
tracev_value((buffer->ipc_buffer.comp.id << 16) | buffer->size);
tracev_value((buffer->r_ptr - buffer->addr) << 16 | (buffer->w_ptr - buffer->addr));
}
void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes);
/* called by a component after consuming data from this buffer */
static inline void comp_update_buffer_consume(struct comp_buffer *buffer,
uint32_t bytes)
{
uint32_t flags;
spin_lock_irq(&buffer->lock, flags);
buffer->r_ptr += bytes;
/* check for pointer wrap */
if (buffer->r_ptr >= buffer->end_addr)
buffer->r_ptr = buffer->addr + (buffer->r_ptr - buffer->end_addr);
/* calculate available bytes */
if (buffer->r_ptr < buffer->w_ptr)
buffer->avail = buffer->w_ptr - buffer->r_ptr;
else if (buffer->r_ptr == buffer->w_ptr)
buffer->avail = 0; /* empty */
else
buffer->avail = buffer->size - (buffer->r_ptr - buffer->w_ptr);
/* calculate free bytes */
buffer->free = buffer->size - buffer->avail;
spin_unlock_irq(&buffer->lock, flags);
tracev_buffer("con");
tracev_value((buffer->avail << 16) | buffer->free);
tracev_value((buffer->ipc_buffer.comp.id << 16) | buffer->size);
tracev_value((buffer->r_ptr - buffer->addr) << 16 | (buffer->w_ptr - buffer->addr));
}
void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes);
/* get the max number of bytes that can be copied between sink and source */
static inline int comp_buffer_can_copy_bytes(struct comp_buffer *source,

View File

@ -173,12 +173,13 @@ struct comp_driver {
struct comp_dev {
/* runtime */
uint16_t state; /* COMP_STATE_ */
uint16_t is_endpoint; /* component is end point in pipeline */
spinlock_t lock; /* lock for this component */
uint64_t position; /* component rendering position */
uint32_t frames; /* number of frames we copy to sink */
uint32_t frame_bytes; /* frames size copied to sink in bytes */
uint16_t state; /* COMP_STATE_ */
uint16_t is_endpoint; /* component is end point in pipeline */
uint16_t is_dma_connected; /* component is connected to DMA */
spinlock_t lock; /* lock for this component */
uint64_t position; /* component rendering position */
uint32_t frames; /* number of frames we copy to sink */
uint32_t frame_bytes; /* frames size copied to sink in bytes */
struct pipeline *pipeline; /* pipeline we belong to */
/* common runtime configuration for downstream/upstream */