Skip to content

Commit db78be6

Browse files
committed
copier: pipeline period recalculation
In case of a deep buffering pipelines don't require scheduling on every millisecond. We can calculate period based on the gateway buffer size. At pipeline creation we assume that it can work on longer periods, period value is set to zero to be later adjust base on the pipeline components. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
1 parent 6d2352a commit db78be6

5 files changed

Lines changed: 69 additions & 2 deletions

File tree

src/audio/copier/copier.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <sof/audio/dai_copier.h>
4141
#include <sof/audio/ipcgtw_copier.h>
4242
#include <sof/audio/module_adapter/module/generic.h>
43+
#include <sof/schedule/ll_schedule_domain.h>
4344

4445
#if CONFIG_ZEPHYR_NATIVE_DRIVERS
4546
#include <zephyr/drivers/dai.h>
@@ -92,6 +93,41 @@ static int copier_init(struct processing_module *mod)
9293
}
9394

9495
dev->pipeline = ipc_pipe->pipeline;
96+
/* Calculation of the period in which the component should be scheduled based on
97+
* the input buffer size.
98+
*/
99+
if (copier->gtw_cfg.dma_buffer_size > 0 && dev->pipeline->deep_buffering) {
100+
/* Size of the single frame in bytes. */
101+
uint32_t frame_size = copier->base.audio_fmt.channels_count *
102+
(copier->base.audio_fmt.depth >> 3);
103+
/* Size of the one second of audio data in bytes. */
104+
uint32_t one_s = frame_size * copier->base.audio_fmt.sampling_frequency;
105+
/* Size of the ten millisecond of audio data in bytes. */
106+
uint32_t ten_ms = DIV_ROUND_UP(one_s, 100);
107+
/* The number of ten milliseconds chunks of data that will fit into the buffer. */
108+
uint32_t chunk_count = copier->gtw_cfg.dma_buffer_size / ten_ms;
109+
110+
/* If buffer can fit at more than ten milliseconds of data we can try to schedule
111+
* pipe on periods bigger than one millisecond.
112+
*/
113+
if (chunk_count) {
114+
dev->deep_buffering = true;
115+
if (chunk_count == 1)
116+
dev->period = (5 * LL_TIMER_PERIOD_US);
117+
else
118+
dev->period = (10 * LL_TIMER_PERIOD_US);
119+
120+
/* If a component that may run on bigger periods has already been added to
121+
* the pipeline, the pipe must run at the lowest possible value.
122+
*/
123+
if (!dev->pipeline->period || dev->pipeline->period < dev->period) {
124+
dev->pipeline->period = dev->period;
125+
comp_cl_warn(&comp_copier,
126+
"changing the period for the pipe (new value %u)",
127+
dev->pipeline->period);
128+
}
129+
}
130+
}
95131

96132
node_id = copier->gtw_cfg.node_id;
97133
/* copier is linked to gateway */

src/audio/pipeline/pipeline-graph.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <sof/lib/uuid.h>
1515
#include <sof/compiler_attributes.h>
1616
#include <sof/list.h>
17+
#include <sof/schedule/ll_schedule_domain.h>
1718
#include <rtos/spinlock.h>
1819
#include <rtos/string.h>
1920
#include <rtos/clk.h>
@@ -302,6 +303,14 @@ int pipeline_complete(struct pipeline *p, struct comp_dev *source,
302303
data.start = source;
303304
data.p = p;
304305

306+
/* If a component has been added to the pipeline that cannot run on longer periods
307+
* we need to set pipe period to one ms.
308+
*/
309+
if (!p->deep_buffering) {
310+
p->period = LL_TIMER_PERIOD_US;
311+
pipe_info(p, "setting pipe period to %llu us", LL_TIMER_PERIOD_US);
312+
}
313+
305314
/* now walk downstream from source component and
306315
* complete component task and pipeline initialization
307316
*/

src/include/sof/audio/component.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,9 @@ struct comp_dev {
591591
bool is_shared; /**< indicates whether component is shared
592592
* across cores
593593
*/
594+
bool deep_buffering; /**< indicates whether component is able to work
595+
* deep buffering
596+
*/
594597
struct comp_ipc_config ipc_config; /**< Component IPC configuration */
595598
struct tr_ctx tctx; /**< trace settings */
596599

src/include/sof/audio/pipeline.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ struct pipeline {
9494
bool aborted; /* STOP or PAUSE failed, stay active */
9595
bool pending; /* trigger scheduled but not executed yet */
9696
} trigger;
97+
/* pipe can use long periods for scheduling in case of a deep buffering */
98+
bool deep_buffering;
9799
};
98100

99101
struct pipeline_walk_context {

src/ipc/ipc4/helper.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <sof/lib/mailbox.h>
1919
#include <sof/list.h>
2020
#include <sof/platform.h>
21-
#include <sof/schedule/ll_schedule_domain.h>
2221
#include <rtos/wait.h>
2322

2423
/* TODO: Remove platform-specific code, see https://github.com/thesofproject/sof/issues/7549 */
@@ -206,7 +205,8 @@ static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc)
206205
}
207206

208207
pipe->time_domain = SOF_TIME_DOMAIN_TIMER;
209-
pipe->period = LL_TIMER_PERIOD_US;
208+
pipe->period = 0;
209+
pipe->deep_buffering = true;
210210

211211
/* sched_id is set in FW so initialize it to a invalid value */
212212
pipe->sched_id = 0xFFFFFFFF;
@@ -869,6 +869,23 @@ int ipc4_add_comp_dev(struct comp_dev *dev)
869869
/* add new component to the list */
870870
list_item_append(&icd->list, &ipc->comp_list);
871871

872+
/* If new component added to the pipeline is not fitted for deep buffering we need to
873+
* inform pipeline it cannot work on long periods.
874+
*/
875+
if (!dev->deep_buffering) {
876+
if (!dev->pipeline) {
877+
const uint32_t pipe_id = dev->ipc_config.pipeline_id;
878+
struct ipc_comp_dev *ipc_comp =
879+
ipc_get_comp_by_ppl_id(ipc,
880+
COMP_TYPE_PIPELINE,
881+
pipe_id);
882+
883+
dev->pipeline = ipc_comp->pipeline;
884+
}
885+
886+
dev->pipeline->deep_buffering = false;
887+
}
888+
872889
return IPC4_SUCCESS;
873890
};
874891

0 commit comments

Comments
 (0)