mirror of https://github.com/thesofproject/sof.git
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:
parent
11716bb415
commit
76596a89b3
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue