mirror of https://github.com/thesofproject/sof.git
buffer: fix buffer produce dcache circular wrap
dcache_writeback is called for dma connected buffers, however it doesn't take into account the possible circular wrap if bytes size is not exact multiple of frames period. Signed-off-by: Jaska Uimonen <jaska.uimonen@intel.com>
This commit is contained in:
parent
fd084b765c
commit
0dad013067
|
@ -108,9 +108,17 @@ void buffer_free(struct comp_buffer *buffer)
|
||||||
void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes)
|
void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes)
|
||||||
{
|
{
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
uint32_t head = bytes;
|
||||||
|
uint32_t tail = 0;
|
||||||
|
|
||||||
spin_lock_irq(&buffer->lock, flags);
|
spin_lock_irq(&buffer->lock, flags);
|
||||||
|
|
||||||
|
/* calculate head and tail size for dcache circular wrap ops */
|
||||||
|
if (buffer->w_ptr + bytes > buffer->end_addr) {
|
||||||
|
head = buffer->end_addr - buffer->w_ptr;
|
||||||
|
tail = bytes - head;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* new data produce, handle consistency for buffer and cache:
|
* new data produce, handle consistency for buffer and cache:
|
||||||
* 1. source(DMA) --> buffer --> sink(non-DMA): invalidate cache.
|
* 1. source(DMA) --> buffer --> sink(non-DMA): invalidate cache.
|
||||||
|
@ -119,13 +127,19 @@ void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes)
|
||||||
* 4. source(non-DMA) --> buffer --> sink(non-DMA): do nothing.
|
* 4. source(non-DMA) --> buffer --> sink(non-DMA): do nothing.
|
||||||
*/
|
*/
|
||||||
if (buffer->source->is_dma_connected &&
|
if (buffer->source->is_dma_connected &&
|
||||||
!buffer->sink->is_dma_connected)
|
!buffer->sink->is_dma_connected) {
|
||||||
/* need invalidate cache for sink component to use */
|
/* need invalidate cache for sink component to use */
|
||||||
dcache_invalidate_region(buffer->w_ptr, bytes);
|
dcache_invalidate_region(buffer->w_ptr, head);
|
||||||
|
if (tail)
|
||||||
|
dcache_invalidate_region(buffer->addr, tail);
|
||||||
|
}
|
||||||
else if (!buffer->source->is_dma_connected &&
|
else if (!buffer->source->is_dma_connected &&
|
||||||
buffer->sink->is_dma_connected)
|
buffer->sink->is_dma_connected) {
|
||||||
/* need write back to memory for sink component to use */
|
/* need write back to memory for sink component to use */
|
||||||
dcache_writeback_region(buffer->w_ptr, bytes);
|
dcache_writeback_region(buffer->w_ptr, head);
|
||||||
|
if (tail)
|
||||||
|
dcache_writeback_region(buffer->addr, tail);
|
||||||
|
}
|
||||||
|
|
||||||
buffer->w_ptr += bytes;
|
buffer->w_ptr += bytes;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue