diff --git a/src/audio/buffer.c b/src/audio/buffer.c index a4cb3dc34..d66adde3d 100644 --- a/src/audio/buffer.c +++ b/src/audio/buffer.c @@ -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)); +} diff --git a/src/audio/dai.c b/src/audio/dai.c index 7cef5a7bd..6ac15d1e7 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -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: diff --git a/src/audio/host.c b/src/audio/host.c index e374a2fa0..a138a6d66 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -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: diff --git a/src/include/sof/audio/buffer.h b/src/include/sof/audio/buffer.h index a8b98b6d1..f7a49dc59 100644 --- a/src/include/sof/audio/buffer.h +++ b/src/include/sof/audio/buffer.h @@ -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, diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index 0451b560e..f5835283b 100644 --- a/src/include/sof/audio/component.h +++ b/src/include/sof/audio/component.h @@ -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 */