Skip to content

Commit 553b2a6

Browse files
kfrydryxabonislawski
authored andcommitted
pipeline: Register and unregister pipelines CPS consumption on run/pause
Register and unregister pipelines CPS consumption on run/pause Signed-off-by: Krzysztof Frydryk <krzysztofx.frydryk@intel.com>
1 parent 2202d3c commit 553b2a6

1 file changed

Lines changed: 97 additions & 2 deletions

File tree

src/audio/pipeline/pipeline-stream.c

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717
#include <ipc/topology.h>
1818
#include <ipc4/module.h>
1919
#include <rtos/kernel.h>
20+
#include <sof/audio/module_adapter/module/generic.h>
21+
#include <sof/lib/cpu-clk-manager.h>
2022

2123
#include <errno.h>
2224
#include <stdbool.h>
2325
#include <stddef.h>
2426
#include <stdint.h>
2527

2628
LOG_MODULE_DECLARE(pipe, CONFIG_SOF_LOG_LEVEL);
29+
// LOG_MODULE_REGISTER(cpsBudget, CONFIG_SOF_LOG_LEVEL);
2730

2831
/*
2932
* Check whether pipeline is incapable of acquiring data for capture.
@@ -267,24 +270,109 @@ static void pipeline_trigger_xrun(struct pipeline *p, struct comp_dev **host)
267270
} while (true);
268271
}
269272

273+
static int add_pipeline_cps_consumption(struct comp_dev *current,
274+
struct comp_buffer *calling_buf,
275+
struct pipeline_walk_context *ctx, int dir)
276+
{
277+
struct pipeline_data *ppl_data = ctx->comp_data;
278+
struct ipc4_base_module_cfg *cd = NULL;
279+
280+
pipe_dbg(ppl_data->p, "pipeline_comp_complete(), current->comp.id = %u, dir = %u",
281+
dev_comp_id(current), dir);
282+
283+
if (!comp_is_single_pipeline(current, ppl_data->start)) {
284+
pipe_dbg(ppl_data->p, "pipeline_comp_complete(), current is from another pipeline");
285+
return 0;
286+
}
287+
288+
/* complete component init */
289+
current->pipeline = ppl_data->p;
290+
291+
/* modules created throug module adapter have different priv_data */
292+
if(current->drv->type != SOF_COMP_MODULE_ADAPTER) {
293+
cd = comp_get_drvdata(current);
294+
} else {
295+
struct processing_module *mod = comp_get_drvdata(current);
296+
struct module_data *md = &mod->priv;
297+
cd = &md->cfg.base_cfg;
298+
}
299+
300+
int kcps = cd->cpc * 1000 / ppl_data->p->period;
301+
core_kcps_adjust(0, kcps);
302+
tr_err(pipe, "Registering KCPS consumption: %d, core: %d", kcps, ppl_data->p->core);
303+
int summary_cps = core_kcps_get(0);
304+
tr_err(pipe, "Sum of KCPS consumption: %d, core: %d", summary_cps, ppl_data->p->core);
305+
return pipeline_for_each_comp(current, ctx, dir);
306+
}
307+
308+
static int remove_pipeline_cps_consumption(struct comp_dev *current,
309+
struct comp_buffer *calling_buf,
310+
struct pipeline_walk_context *ctx, int dir)
311+
{
312+
struct pipeline_data *ppl_data = ctx->comp_data;
313+
struct ipc4_base_module_cfg *cd = NULL;
314+
315+
pipe_dbg(ppl_data->p, "pipeline_comp_complete(), current->comp.id = %u, dir = %u",
316+
dev_comp_id(current), dir);
317+
318+
if (!comp_is_single_pipeline(current, ppl_data->start)) {
319+
pipe_dbg(ppl_data->p, "pipeline_comp_complete(), current is from another pipeline");
320+
return 0;
321+
}
322+
323+
/* complete component init */
324+
current->pipeline = ppl_data->p;
325+
326+
/* modules created throug module adapter have different priv_data */
327+
if(current->drv->type != SOF_COMP_MODULE_ADAPTER) {
328+
cd = comp_get_drvdata(current);
329+
} else {
330+
struct processing_module *mod = comp_get_drvdata(current);
331+
struct module_data *md = &mod->priv;
332+
cd = &md->cfg.base_cfg;
333+
}
334+
335+
int kcps = cd->cpc * 1000/ppl_data->p->period;
336+
core_kcps_adjust(0, -kcps); /* 1000 chunks per second, so cpc value matches kcps? */
337+
tr_err(pipe, "Unregistering KCPS consumption: %d, core: %d", kcps, ppl_data->p->core);
338+
int summary_cps = core_kcps_get(0);
339+
tr_err(pipe, "Sum of KCPS consumption: %d, core: %d", summary_cps, ppl_data->p->core);
340+
return pipeline_for_each_comp(current, ctx, dir);
341+
}
342+
343+
344+
345+
270346
/* trigger pipeline in IPC context */
271347
int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd)
272348
{
273349
int ret;
274-
350+
bool clocks_handled = false;
351+
struct pipeline_data data;
352+
struct pipeline_walk_context walk_ctx = {
353+
.comp_func = remove_pipeline_cps_consumption,
354+
.comp_data = &data,
355+
};
275356
pipe_info(p, "pipe trigger cmd %d", cmd);
276357

277358
p->trigger.aborted = false;
278359

279360
switch (cmd) {
280361
case COMP_TRIGGER_PAUSE:
362+
/* dirty - dont add kcps on fallthrough */
363+
clocks_handled = true;
364+
/* setup walking ctx for adding consumption */
365+
data.start = p->source_comp;
366+
data.p = p;
367+
walk_ctx.comp_func = remove_pipeline_cps_consumption;
368+
369+
ret = walk_ctx.comp_func(p->source_comp, NULL, &walk_ctx, PPL_DIR_DOWNSTREAM);
281370
case COMP_TRIGGER_STOP:
282371
if (p->status == COMP_STATE_PAUSED || p->xrun_bytes) {
283372
/* The task isn't running, trigger inline */
284373
ret = pipeline_trigger_run(p, host, cmd);
285374
return ret < 0 ? ret : 0;
286375
}
287-
288376
COMPILER_FALLTHROUGH;
289377
case COMP_TRIGGER_XRUN:
290378
if (cmd == COMP_TRIGGER_XRUN)
@@ -294,6 +382,13 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd)
294382
case COMP_TRIGGER_PRE_RELEASE:
295383
case COMP_TRIGGER_PRE_START:
296384
/* Add all connected pipelines to the list and trigger them all */
385+
/* setup walking ctx for removing consumption */
386+
data.start = p->source_comp;
387+
data.p = p;
388+
walk_ctx.comp_func = add_pipeline_cps_consumption;
389+
390+
if(!clocks_handled)
391+
ret = walk_ctx.comp_func(p->source_comp, NULL, &walk_ctx, PPL_DIR_DOWNSTREAM);
297392
ret = pipeline_trigger_list(p, host, cmd);
298393
if (ret < 0)
299394
return ret;

0 commit comments

Comments
 (0)