Skip to content

Commit

Permalink
pipeline: Register and unregister pipelines CPS consumption on run/pause
Browse files Browse the repository at this point in the history
Register and unregister pipelines CPS consumption on run/pause

Signed-off-by: Adrian Bonislawski <adrian.bonislawski@intel.com>
Signed-off-by: Krzysztof Frydryk <krzysztofx.frydryk@intel.com>

+Squashed commits:
924f0d2 pipeline: print warning if 0 KCPS received
Signed-off-by: Adrian Bonislawski <adrian.bonislawski@intel.com>
7bb6e7e pipeline: register CPS consumption for a proper core
Signed-off-by: Adrian Bonislawski <adrian.bonislawski@intel.com>
5f0c4e4 pipeline: make CPC data "opt-in" with fallback
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
  • Loading branch information
kfrydryx authored and abonislawski committed Apr 14, 2024
1 parent 4e3bf98 commit 6bc04cd
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 3 deletions.
101 changes: 99 additions & 2 deletions src/audio/pipeline/pipeline-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
#include <sof/lib/dai.h>
#include <rtos/wait.h>
#include <sof/list.h>
#include <rtos/interrupt.h>
#include <rtos/spinlock.h>
#include <rtos/string.h>
#include <ipc/stream.h>
#include <ipc/topology.h>
#include <ipc4/module.h>
#include <rtos/kernel.h>
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/lib/cpu-clk-manager.h>

#include <errno.h>
#include <stdbool.h>
Expand Down Expand Up @@ -311,17 +314,80 @@ static void pipeline_trigger_xrun(struct pipeline *p, struct comp_dev **host)
} while (true);
}

#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
static int pipeline_calc_cps_consumption(struct comp_dev *current,
struct comp_buffer *calling_buf,
struct pipeline_walk_context *ctx, int dir)
{
struct pipeline_data *ppl_data = ctx->comp_data;
struct ipc4_base_module_cfg *cd;
int comp_core, kcps;

pipe_dbg(ppl_data->p, "pipeline_calc_cps_consumption(), current->comp.id = %u, dir = %u",
dev_comp_id(current), dir);

if (!comp_is_single_pipeline(current, ppl_data->start)) {
pipe_dbg(ppl_data->p, "pipeline_calc_cps_consumption(), current is from another pipeline");
return 0;
}
comp_core = current->ipc_config.core;

/* modules created through module adapter have different priv_data */
if (current->drv->type != SOF_COMP_MODULE_ADAPTER) {
cd = comp_get_drvdata(current);
} else {
struct processing_module *mod = comp_get_drvdata(current);
struct module_data *md = &mod->priv;

cd = &md->cfg.base_cfg;
}

if (cd->cpc == 0) {
/* Use maximum clock budget, assume 1ms chunk size */
ppl_data->kcps[comp_core] = CLK_MAX_CPU_HZ / 1000;
tr_warn(pipe,
"0 CPS requested for module: %#x, core: %d using safe max KCPS: %u",
current->ipc_config.id, comp_core, ppl_data->kcps[comp_core]);

return PPL_STATUS_PATH_STOP;
} else {
kcps = cd->cpc * 1000 / current->period;
tr_dbg(pipe, "Module: %#x KCPS consumption: %d, core: %d",
current->ipc_config.id, kcps, comp_core);

ppl_data->kcps[comp_core] += kcps;
}

return pipeline_for_each_comp(current, ctx, dir);
}
#endif

/* trigger pipeline in IPC context */
int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd)
{
int ret;

#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
struct pipeline_data data = {
.start = p->source_comp,
.p = p,
};
struct pipeline_walk_context walk_ctx = {
.comp_func = pipeline_calc_cps_consumption,
.comp_data = &data,
};
bool trigger_first = false;
uint32_t flags = 0;
#endif
pipe_info(p, "pipe trigger cmd %d", cmd);

p->trigger.aborted = false;

switch (cmd) {
case COMP_TRIGGER_PAUSE:
#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
trigger_first = true;
COMPILER_FALLTHROUGH;
#endif
case COMP_TRIGGER_STOP:
if (p->status == COMP_STATE_PAUSED || p->xrun_bytes) {
/* The task isn't running, trigger inline */
Expand All @@ -338,9 +404,40 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd)
case COMP_TRIGGER_PRE_RELEASE:
case COMP_TRIGGER_PRE_START:
/* Add all connected pipelines to the list and trigger them all */
#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
irq_local_disable(flags);
/* setup walking ctx for removing consumption */
if (!trigger_first) {
ret = walk_ctx.comp_func(p->source_comp, NULL, &walk_ctx, PPL_DIR_DOWNSTREAM);

for (int i = 0; i < arch_num_cpus(); i++) {
if (data.kcps[i] > 0) {
core_kcps_adjust(i, data.kcps[i]);
tr_info(pipe, "Sum of KCPS consumption: %d, core: %d", core_kcps_get(i), i);
}
}
}
#endif
ret = pipeline_trigger_list(p, host, cmd);
if (ret < 0)
if (ret < 0) {
#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
irq_local_enable(flags);
#endif
return ret;
}
#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
if (trigger_first) {
ret = walk_ctx.comp_func(p->source_comp, NULL, &walk_ctx, PPL_DIR_DOWNSTREAM);

for (int i = 0; i < arch_num_cpus(); i++) {
if (data.kcps[i] > 0) {
core_kcps_adjust(i, -data.kcps[i]);
tr_info(pipe, "Sum of KCPS consumption: %d, core: %d", core_kcps_get(i), i);
}
}
}
irq_local_enable(flags);
#endif
/* IPC response will be sent from the task, unless it was paused */
return PPL_STATUS_SCHEDULED;
}
Expand Down
3 changes: 3 additions & 0 deletions src/include/sof/audio/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ struct pipeline_data {
struct pipeline *p;
int cmd;
uint32_t delay_ms; /* between PRE_{START,RELEASE} and {START,RELEASE} */
#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
uint32_t kcps[CONFIG_CORE_COUNT]; /**< the max count of KCPS */
#endif
};

/** \brief Task type registered by pipelines. */
Expand Down
2 changes: 1 addition & 1 deletion src/lib/cpu-clk-manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ int core_kcps_adjust(int adjusted_core_id, int kcps_delta)

for (core_id = 0; core_id < CONFIG_CORE_COUNT; core_id++) {
/* Convert kcps to cps */
ret = request_freq_change(core_id, freq * 1000);
ret = request_freq_change(core_id, MIN(freq * 1000, CLK_MAX_CPU_HZ));
if (ret < 0)
goto out;
}
Expand Down
8 changes: 8 additions & 0 deletions src/platform/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,14 @@ config CAVS_USE_LPRO_IN_WAITI
After waiti exit clock source will be restored.
Choose n if unclear.

config KCPS_DYNAMIC_CLOCK_CONTROL
bool "Use KCPS budget to determine DSP clock"
default n
depends on IPC_MAJOR_4
help
Select if we want to use compute budget
expressed in Kilo Cycles Per Second (KCPS) to determine DSP clock.

config L3_HEAP
bool "Use L3 memory heap"
default n
Expand Down
1 change: 1 addition & 0 deletions src/platform/imx93_a55/include/platform/lib/clk.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define CPU_DEFAULT_IDX 0
#define NUM_CLOCKS 1
#define NUM_CPU_FREQ 1
#define CLK_MAX_CPU_HZ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC

struct sof;

Expand Down

0 comments on commit 6bc04cd

Please sign in to comment.