Skip to content

Commit 6297bd9

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 658cb65 commit 6297bd9

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>
@@ -301,6 +302,14 @@ int pipeline_complete(struct pipeline *p, struct comp_dev *source,
301302
data.start = source;
302303
data.p = p;
303304

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

src/include/sof/audio/component.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,9 @@ struct comp_dev {
586586
bool is_shared; /**< indicates whether component is shared
587587
* across cores
588588
*/
589+
bool deep_buffering; /**< indicates whether component is able to work
590+
* deep buffering
591+
*/
589592
struct comp_ipc_config ipc_config; /**< Component IPC configuration */
590593
struct tr_ctx tctx; /**< trace settings */
591594

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 */
@@ -199,7 +198,8 @@ static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc)
199198
}
200199

201200
pipe->time_domain = SOF_TIME_DOMAIN_TIMER;
202-
pipe->period = LL_TIMER_PERIOD_US;
201+
pipe->period = 0;
202+
pipe->deep_buffering = true;
203203

204204
/* sched_id is set in FW so initialize it to a invalid value */
205205
pipe->sched_id = 0xFFFFFFFF;
@@ -787,6 +787,23 @@ int ipc4_add_comp_dev(struct comp_dev *dev)
787787
/* add new component to the list */
788788
list_item_append(&icd->list, &ipc->comp_list);
789789

790+
/* If new component added to the pipeline is not fitted for deep buffering we need to
791+
* inform pipeline it cannot work on long periods.
792+
*/
793+
if (!dev->deep_buffering) {
794+
if (!dev->pipeline) {
795+
const uint32_t pipe_id = dev->ipc_config.pipeline_id;
796+
struct ipc_comp_dev *ipc_comp =
797+
ipc_get_comp_by_ppl_id(ipc,
798+
COMP_TYPE_PIPELINE,
799+
pipe_id);
800+
801+
dev->pipeline = ipc_comp->pipeline;
802+
}
803+
804+
dev->pipeline->deep_buffering = false;
805+
}
806+
790807
return IPC4_SUCCESS;
791808
};
792809

0 commit comments

Comments
 (0)