From 6a18e5a8c95d4583162ad42cadc3585ad9434b3d Mon Sep 17 00:00:00 2001 From: YC Hung Date: Tue, 28 Dec 2021 20:05:54 +0800 Subject: [PATCH] audio: host: update position every period to improve precision The position is currently updated by the host component when a period was consumed. The granularity of this position is too large, applications relying on timer-based scheduling may query the position at any time and conformance test suites fail. This patch introduce another field "cont_update_posn" in sof_ipc_stream_params which suggests a more precise position reporting, by storing the latest position in a memory window when the host component completes a transfer. This will increase the traffic to memory windows, but allow for a much smaller granularity in position updates. In hindsight, this solution should have been the default behavior but to avoid backwards compatibility issues is added as a new capability controlled by an ABI check. Only with a recent-enough Linux kernel will this behavior be enabled. Signed-off-by: YC Hung --- src/audio/host.c | 20 ++++++++++++++++---- src/include/ipc/stream.h | 3 ++- src/include/kernel/abi.h | 4 ++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/audio/host.c b/src/audio/host.c index 5e48665d5..519856f53 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -76,6 +76,7 @@ struct host_data { uint32_t host_period_bytes; uint16_t stream_tag; uint16_t no_stream_position; /**< 1 means don't send stream position */ + uint8_t cont_update_posn; /**< 1 means continuous update stream position */ /* host component attributes */ enum comp_copy_type copy_type; /**< Current host copy type */ @@ -307,6 +308,8 @@ static void host_update_position(struct comp_dev *dev, uint32_t bytes) struct comp_buffer *source; struct comp_buffer *sink; int ret; + bool update_mailbox = false; + bool send_ipc = false; if (dev->direction == SOF_IPC_STREAM_PLAYBACK) @@ -345,6 +348,8 @@ static void host_update_position(struct comp_dev *dev, uint32_t bytes) #else hd->local_pos = 0; #endif + if (hd->cont_update_posn) + update_mailbox = true; /* Don't send stream position if no_stream_position == 1 */ if (!hd->no_stream_position) { @@ -361,12 +366,18 @@ static void host_update_position(struct comp_dev *dev, uint32_t bytes) /* send timestamped position to host * (updates position first, by calling ops.position()) */ - pipeline_get_timestamp(dev->pipeline, dev, &hd->posn); - mailbox_stream_write(dev->pipeline->posn_offset, - &hd->posn, sizeof(hd->posn)); - ipc_msg_send(hd->msg, &hd->posn, false); + update_mailbox = true; + send_ipc = true; } } + + if (update_mailbox) { + pipeline_get_timestamp(dev->pipeline, dev, &hd->posn); + mailbox_stream_write(dev->pipeline->posn_offset, + &hd->posn, sizeof(hd->posn)); + if (send_ipc) + ipc_msg_send(hd->msg, &hd->posn, false); + } } /* The host memory is not guaranteed to be continuous and also not guaranteed @@ -761,6 +772,7 @@ static int host_params(struct comp_dev *dev, hd->stream_tag = params->stream_tag; hd->no_stream_position = params->no_stream_position; hd->host_period_bytes = params->host_period_bytes; + hd->cont_update_posn = params->cont_update_posn; /* retrieve DMA buffer address alignment */ err = dma_get_attribute(hd->dma, DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT, diff --git a/src/include/ipc/stream.h b/src/include/ipc/stream.h index 1bf75832d..e4723972a 100644 --- a/src/include/ipc/stream.h +++ b/src/include/ipc/stream.h @@ -94,8 +94,9 @@ struct sof_ipc_stream_params { uint32_t host_period_bytes; uint16_t no_stream_position; /**< 1 means don't send stream position */ + uint8_t cont_update_posn; /**< 1 means continuous update stream position */ - uint16_t reserved[3]; + uint8_t reserved[5]; uint16_t chmap[SOF_IPC_MAX_CHANNELS]; /**< channel map - SOF_CHMAP_ */ } __attribute__((packed, aligned(4))); diff --git a/src/include/kernel/abi.h b/src/include/kernel/abi.h index 43580b178..cc061fb0a 100644 --- a/src/include/kernel/abi.h +++ b/src/include/kernel/abi.h @@ -29,8 +29,8 @@ /** \brief SOF ABI version major, minor and patch numbers */ #define SOF_ABI_MAJOR 3 -#define SOF_ABI_MINOR 20 -#define SOF_ABI_PATCH 1 +#define SOF_ABI_MINOR 21 +#define SOF_ABI_PATCH 0 /** \brief SOF ABI version number. Format within 32bit word is MMmmmppp */ #define SOF_ABI_MAJOR_SHIFT 24