Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions posix/include/sof/lib/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -534,14 +534,14 @@ int dma_buffer_copy_to(struct comp_buffer __sparse_cache *source,
dma_process_func process, uint32_t sink_bytes, uint32_t chmap);

/*
* Used when copying DMA buffer bytes into multiple sink buffers, one at a time using the provided
* Used when copying stream audio into multiple sink buffers, one at a time using the provided
* conversion function. DMA buffer consume should be performed after the data has been copied
* to all sinks.
*/
int dma_buffer_copy_from_no_consume(struct comp_buffer __sparse_cache *source,
struct comp_buffer __sparse_cache *sink,
dma_process_func process,
uint32_t source_bytes, uint32_t chmap);
int stream_copy_from_no_consume(struct comp_buffer __sparse_cache *source,
struct comp_buffer __sparse_cache *sink,
dma_process_func process,
uint32_t source_bytes, uint32_t chmap);

/* generic DMA DSP <-> Host copier */

Expand Down
73 changes: 67 additions & 6 deletions src/audio/dai-zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,16 +268,56 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes,
}

if (dev->direction == SOF_IPC_STREAM_PLAYBACK) {
#if CONFIG_IPC_MAJOR_4
struct list_item *sink_list;
/*
* copy from local buffer to all sinks that are not gateway buffers
* using the right PCM converter function.
*/
list_for_item(sink_list, &dev->bsink_list) {
struct comp_dev *sink_dev;
struct comp_buffer *sink;
int j;

sink = container_of(sink_list, struct comp_buffer, source_list);

if (sink == dd->dma_buffer)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dma_buffer is not on the list of sinks, so this condition is always false. However, maybe it is OK to leave it as is or replace with assert() "just in case" someone add dma_buffer to sink list in some future refactoring.

continue;

sink_dev = sink->sink;

j = IPC4_SRC_QUEUE_ID(buf_get_id(sink));

if (j >= IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT) {
comp_err(dev, "Sink queue ID: %d >= max output pin count: %d\n",
j, IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT);
ret = -EINVAL;
continue;
}

if (!converter[j]) {
comp_err(dev, "No PCM converter for sink queue %d\n", j);
ret = -EINVAL;
continue;
}

if (sink_dev && sink_dev->state == COMP_STATE_ACTIVE &&
sink->hw_params_configured) {
ret = stream_copy_from_no_consume(dd->local_buffer, sink,
converter[j], bytes, dd->chmap);
}
}
#endif
ret = dma_buffer_copy_to(dd->local_buffer, dd->dma_buffer,
dd->process, bytes, dd->chmap);
} else {
audio_stream_invalidate(&dd->dma_buffer->stream, bytes);
/*
* The PCM converter functions used during DMA buffer copy can never fail,
* so no need to check the return value of dma_buffer_copy_from_no_consume().
* so no need to check the return value of stream_copy_from_no_consume().
*/
ret = dma_buffer_copy_from_no_consume(dd->dma_buffer, dd->local_buffer,
dd->process, bytes, dd->chmap);
ret = stream_copy_from_no_consume(dd->dma_buffer, dd->local_buffer,
dd->process, bytes, dd->chmap);
#if CONFIG_IPC_MAJOR_4
struct list_item *sink_list;
/* Skip in case of endpoint DAI devices created by the copier */
Expand Down Expand Up @@ -316,9 +356,9 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes,

if (sink_dev && sink_dev->state == COMP_STATE_ACTIVE &&
sink->hw_params_configured)
ret = dma_buffer_copy_from_no_consume(dd->dma_buffer,
sink, converter[j],
bytes, dd->chmap);
ret = stream_copy_from_no_consume(dd->dma_buffer,
sink, converter[j],
bytes, dd->chmap);
}
}
#endif
Expand Down Expand Up @@ -1553,6 +1593,27 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun
src_frames = audio_stream_get_avail_frames(&dd->local_buffer->stream);
sink_frames = free_bytes / audio_stream_frame_bytes(&dd->dma_buffer->stream);
frames = MIN(src_frames, sink_frames);

struct list_item *sink_list;
/*
* In the case of playback DAI's with multiple sink buffers, compute the
* minimum number of frames based on the DMA avail_bytes and the free
* samples in all active sink buffers.
*/
list_for_item(sink_list, &dev->bsink_list) {
struct comp_dev *sink_dev;
struct comp_buffer *sink;

sink = container_of(sink_list, struct comp_buffer, source_list);
sink_dev = sink->sink;

if (sink_dev && sink_dev->state == COMP_STATE_ACTIVE &&
sink->hw_params_configured) {
sink_frames =
audio_stream_get_free_frames(&sink->stream);
frames = MIN(frames, sink_frames);
}
}
} else {
struct list_item *sink_list;

Expand Down
5 changes: 2 additions & 3 deletions src/lib/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,9 +447,8 @@ int dma_buffer_copy_to(struct comp_buffer *source,
return ret;
}

int dma_buffer_copy_from_no_consume(struct comp_buffer *source,
struct comp_buffer *sink,
dma_process_func process, uint32_t source_bytes, uint32_t chmap)
int stream_copy_from_no_consume(struct comp_buffer *source, struct comp_buffer *sink,
dma_process_func process, uint32_t source_bytes, uint32_t chmap)
{
int source_channels = audio_stream_get_channels(&source->stream);
int sink_channels = audio_stream_get_channels(&sink->stream);
Expand Down
10 changes: 5 additions & 5 deletions xtos/include/sof/lib/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -534,14 +534,14 @@ int dma_buffer_copy_from(struct comp_buffer *source,
dma_process_func process, uint32_t source_bytes, uint32_t chmap);

/*
* Used when copying DMA buffer bytes into multiple sink buffers, one at a time using the provided
* Used when copying stream audio into multiple sink buffers, one at a time using the provided
* conversion function. DMA buffer consume should be performed after the data has been copied
* to all sinks.
*/
int dma_buffer_copy_from_no_consume(struct comp_buffer *source,
struct comp_buffer *sink,
dma_process_func process,
uint32_t source_bytes, uint32_t chmap);
int stream_copy_from_no_consume(struct comp_buffer *source,
struct comp_buffer *sink,
dma_process_func process,
uint32_t source_bytes, uint32_t chmap);

/* copies data to DMA buffer using provided processing function */
int dma_buffer_copy_to(struct comp_buffer *source,
Expand Down