Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 367
pipeline: register KCPS consumption and enable dynamic clock control#8019
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
7a68ed74e3bf981572a1d577e8aa2c6483fFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -95,3 +95,5 @@ CONFIG_LOG_TIMESTAMP_64BIT=y | ||
| CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING=y | ||
| CONFIG_COMP_STUBS=y | ||
| CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL=y | ||
| ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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> | ||
| @@ -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; | ||
abonislawski marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| 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); | ||
abonislawski marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| #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 */ | ||
| @@ -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 | ||
| flags = irq_lock(); | ||
| /* setup walking ctx for removing consumption */ | ||
| if (!trigger_first) { | ||
| ret = walk_ctx.comp_func(p->source_comp, NULL, &walk_ctx, PPL_DIR_DOWNSTREAM); | ||
abonislawski marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| 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_unlock(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_unlock(flags); | ||
| #endif | ||
| /* IPC response will be sent from the task, unless it was paused */ | ||
| return PPL_STATUS_SCHEDULED; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
abonislawski marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| bool "Use KCPS budget to determine DSP clock" | ||
abonislawski marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| 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 | ||
abonislawski marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -15,6 +15,7 @@ | ||
| #include <sof/lib/cpu-clk-manager.h> | ||
| #include <sof/lib/mm_heap.h> | ||
| #include <sof/lib/watchdog.h> | ||
| #include <sof/lib/cpu-clk-manager.h> | ||
| #include <sof/schedule/edf_schedule.h> | ||
| #include <sof/schedule/dp_schedule.h> | ||
| #include <sof/schedule/ll_schedule.h> | ||
| @@ -87,11 +88,13 @@ int platform_init(struct sof *sof) | ||
| trace_point(TRACE_BOOT_PLATFORM_CLOCK); | ||
| platform_clock_init(sof); | ||
| kcps_budget_init(); | ||
abonislawski marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| /* Set DSP clock to MAX using KCPS API. Value should be lowered when KCPS API | ||
| * for modules is implemented | ||
| */ | ||
| #if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL | ||
| ret = core_kcps_adjust(cpu_get_id(), PRIMARY_CORE_BASE_CPS_USAGE); | ||
| #else | ||
| ret = core_kcps_adjust(cpu_get_id(), CLK_MAX_CPU_HZ / 1000); | ||
| #endif | ||
| if (ret < 0) | ||
| return ret; | ||
Uh oh!
There was an error while loading. Please reload this page.