Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DNM] dai-zephyr: use frames aligned for multi-endpoint copy #9196

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions src/audio/copier/copier_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ int create_endpoint_buffer(struct comp_dev *dev,
audio_stream_set_buffer_fmt(&buffer->stream,
copier_cfg->base.audio_fmt.interleaving_style);

audio_stream_set_align(1, 1, &buffer->stream);

for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++)
buffer->chmap[i] = (chan_map >> i * 4) & 0xf;

Expand Down
46 changes: 23 additions & 23 deletions src/audio/dai-zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1334,19 +1334,15 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev,
struct comp_buffer *multi_endpoint_buffer,
int num_endpoints)
{
uint32_t avail_bytes = UINT32_MAX;
uint32_t free_bytes = UINT32_MAX;
uint32_t frames;
uint32_t src_frames, sink_frames;
uint32_t frame_bytes;
uint32_t frames_aligned;
uint32_t frames = UINT32_MAX;
int ret, i;
int direction;

if (!num_endpoints || !dd || !multi_endpoint_buffer)
return 0;

frame_bytes = audio_stream_frame_bytes(&dd[0]->dma_buffer->stream);

direction = dev->direction;

/* calculate min available/free from all endpoint DMA buffers */
Expand All @@ -1361,37 +1357,41 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev,
case -EPIPE:
/* DMA status can return -EPIPE and current status content if xrun occurs */
if (direction == SOF_IPC_STREAM_PLAYBACK)
comp_dbg(dev, "dai_zephyr_multi_endpoint_copy(): dma_get_status() underrun occurred, endpoint: %d ret = %u",
comp_dbg(dev, "dma_get_status() underrun occurred endpoint: %d ret = %u",
i, ret);
else
comp_dbg(dev, "dai_zephyr_multi_endpoint_copy(): dma_get_status() overrun occurred, enpdoint: %d ret = %u",
comp_dbg(dev, "dma_get_status() overrun occurred, enpdoint: %d ret = %u",
i, ret);
break;
default:
return ret;
}

avail_bytes = MIN(avail_bytes, stat.pending_length);
free_bytes = MIN(free_bytes, stat.free);
}

/* calculate minimum size to copy */
if (direction == SOF_IPC_STREAM_PLAYBACK) {
src_frames = audio_stream_get_avail_frames(&multi_endpoint_buffer->stream);
sink_frames = free_bytes / frame_bytes;
} else {
src_frames = avail_bytes / frame_bytes;
sink_frames = audio_stream_get_free_frames(&multi_endpoint_buffer->stream);
/* Use frames_aligned here to avoid glitches, especially for streams
* with odd number of channels. Update frames for every dai in a loop.
*/
if (direction == SOF_IPC_STREAM_PLAYBACK)
frames_aligned =
audio_stream_avail_frames_aligned(&multi_endpoint_buffer->stream,
&dd[i]->dma_buffer->stream);
else
frames_aligned =
audio_stream_avail_frames_aligned(&dd[i]->dma_buffer->stream,
&multi_endpoint_buffer->stream);
frames = MIN(frames, frames_aligned);
Copy link
Collaborator

Choose a reason for hiding this comment

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

shouldn't stat be used? If not - do we still need dma_get_status()?

}

frames = MIN(src_frames, sink_frames);

/* limit bytes per copy to one period for the whole pipeline in order to avoid high load
* spike if FAST_MODE is enabled, then one period limitation is omitted. All dd's have the
* same period_bytes, so use the period_bytes from dd[0]
*/
if (!(dd[0]->ipc_config.feature_mask & BIT(IPC4_COPIER_FAST_MODE)))
frames = MIN(frames, dd[0]->period_bytes / frame_bytes);
if (!dd[0]->fast_mode) {
size_t period_frames = dd[0]->period_bytes /
audio_stream_frame_bytes(&dd[0]->dma_buffer->stream);
if (period_frames < frames)
frames = period_frames;
}

comp_dbg(dev, "dai_zephyr_multi_endpoint_copy(), dir: %d copy frames= 0x%x",
dev->direction, frames);

Expand Down