From 167c303875b43dc4cce6cb5081375f1c12966e64 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 7 Jun 2024 09:11:41 +0200 Subject: [PATCH 01/11] llext: fix Windows builds Under windows the Python interpreter has to be called explicitly. Without it an attempt to execute a Python script fails silently. Signed-off-by: Guennadi Liakhovetski Suggested-by: Marc Herbert --- scripts/xtensa-build-zephyr.py | 6 +++++- zephyr/CMakeLists.txt | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/xtensa-build-zephyr.py b/scripts/xtensa-build-zephyr.py index 44b9d7167902..26f00e09470d 100755 --- a/scripts/xtensa-build-zephyr.py +++ b/scripts/xtensa-build-zephyr.py @@ -962,7 +962,11 @@ def install_lib(sof_lib_dir, abs_build_dir, platform_wconfig): llext_input = entry_path / (llext_base + '.llext') llext_output = entry_path / (llext_file + '.ri') - sign_cmd = [platform_wconfig.get("rimage.path"), "-o", str(llext_output), + # See why the shlex() parsing step is required at + # https://docs.zephyrproject.org/latest/develop/west/sign.html#rimage + # and in Zephyr commit 030b740bd1ec + rimage_cmd = shlex.split(platform_wconfig.get('rimage.path'))[0] + sign_cmd = [rimage_cmd, "-o", str(llext_output), "-e", "-c", str(rimage_cfg), "-k", str(signing_key), "-l", "-r", str(llext_input)] diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index e691dff9d880..6c98bc212c68 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -90,7 +90,7 @@ function(sof_llext_build module) get_target_property(proc_out_file ${module} pkg_input) add_llext_command(TARGET ${module} POST_BUILD - COMMAND ${SOF_BASE}scripts/llext_link_helper.py + COMMAND ${PYTHON_EXECUTABLE} ${SOF_BASE}scripts/llext_link_helper.py --text-addr="${SOF_LLEXT_TEXT_ADDR}" -f ${proc_in_file} ${CMAKE_C_COMPILER} -- -o ${proc_out_file} ${EXTRA_LINKER_PARAMS} $ From d6c2b5ac2b9b5ab7359089d7c50ff670062837d1 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 7 Jun 2024 16:29:09 +0200 Subject: [PATCH 02/11] ipc4: a failure to find a driver might not be fatal When ipc4_get_drv() fails to find a driver, it might mean, that the driver needs to be linked dynamically. Printing an error in such a case wrongly fails CI testing. Signed-off-by: Guennadi Liakhovetski --- src/ipc/ipc4/helper.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index aa6505218854..cec4442c7220 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -911,11 +911,11 @@ const struct comp_driver *ipc4_get_drv(const uint8_t *uuid) } } - tr_err(&comp_tr, "get_drv(): the provided UUID (%08x %08x %08x %08x) can't be found!", - *(uint32_t *)(&uuid[0]), - *(uint32_t *)(&uuid[4]), - *(uint32_t *)(&uuid[8]), - *(uint32_t *)(&uuid[12])); + tr_warn(&comp_tr, "get_drv(): the provided UUID (%08x %08x %08x %08x) can't be found!", + *(uint32_t *)(&uuid[0]), + *(uint32_t *)(&uuid[4]), + *(uint32_t *)(&uuid[8]), + *(uint32_t *)(&uuid[12])); out: irq_local_enable(flags); From 1f3b74f05934c8a78e6d9da10af6ee26945135e5 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 13 Jun 2024 14:30:37 +0200 Subject: [PATCH 03/11] samples: (cosmetic) clean up Kconfig spacing Use consistent TABs and spaces in src/samples/audio/Kconfig Signed-off-by: Guennadi Liakhovetski --- src/samples/audio/Kconfig | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/samples/audio/Kconfig b/src/samples/audio/Kconfig index e853b0668f1a..0338ced15875 100644 --- a/src/samples/audio/Kconfig +++ b/src/samples/audio/Kconfig @@ -2,27 +2,27 @@ menu "Audio component samples" - config SAMPLE_SMART_AMP - tristate "Smart amplifier test component" - default y - help - Select for test smart amplifier component + config SAMPLE_SMART_AMP + tristate "Smart amplifier test component" + default y + help + Select for test smart amplifier component - config SAMPLE_KEYPHRASE + config SAMPLE_KEYPHRASE depends on CAVS || IMX || ACE - bool "Keyphrase test component" - default y - help - Select for Keyphrase test component. - Provides basic functionality for use in testing of keyphrase detection pipelines. + bool "Keyphrase test component" + default y + help + Select for Keyphrase test component. + Provides basic functionality for use in testing of keyphrase detection pipelines. config KWD_NN_SAMPLE_KEYPHRASE - depends on IMX - bool "KWD NN Keyphrase test component" - default n - help - Select for KWD NN Keyphrase test component based on neural network. - Provides ML functionality for use in testing of keyphrase detection pipelines. - Use KWD based on NN as alternative to the default KWD component. - Provides neural network as a library. + depends on IMX + bool "KWD NN Keyphrase test component" + default n + help + Select for KWD NN Keyphrase test component based on neural network. + Provides ML functionality for use in testing of keyphrase detection pipelines. + Use KWD based on NN as alternative to the default KWD component. + Provides neural network as a library. endmenu From ebdab32a5ce7971d62acf3d8a0ebc8df7f556f3b Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 14 Jun 2024 15:44:34 +0200 Subject: [PATCH 04/11] llext: add maximum instance count support Maximum instance count cannot be zero, they have to be supplied by respective modules. Signed-off-by: Guennadi Liakhovetski --- src/audio/eq_iir/eq_iir.c | 2 +- src/audio/mixin_mixout/mixin_mixout.c | 4 ++-- src/include/module/module/llext.h | 3 ++- src/samples/audio/smart_amp_test_ipc4.c | 1 + 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/audio/eq_iir/eq_iir.c b/src/audio/eq_iir/eq_iir.c index 6c298e4d59ff..9cfab900c9fa 100644 --- a/src/audio/eq_iir/eq_iir.c +++ b/src/audio/eq_iir/eq_iir.c @@ -271,7 +271,7 @@ SOF_MODULE_INIT(eq_iir, sys_comp_module_eq_iir_interface_init); SOF_LLEXT_MOD_ENTRY(eq_iir, &eq_iir_interface); static const struct sof_man_module_manifest mod_manifest __section(".module") __used = - SOF_LLEXT_MODULE_MANIFEST("EQIIR", eq_iir_llext_entry, 1, UUID_EQIIR); + SOF_LLEXT_MODULE_MANIFEST("EQIIR", eq_iir_llext_entry, 1, UUID_EQIIR, 40); SOF_LLEXT_BUILDINFO; diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index 5171cbda22e0..cee5140c0f6b 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -982,8 +982,8 @@ SOF_LLEXT_MOD_ENTRY(mixout, &mixout_interface); static const struct sof_man_module_manifest mod_manifest[] __section(".module") __used = { - SOF_LLEXT_MODULE_MANIFEST("MIXIN", mixin_llext_entry, 1, UUID_MIXIN), - SOF_LLEXT_MODULE_MANIFEST("MIXOUT", mixout_llext_entry, 1, UUID_MIXOUT), + SOF_LLEXT_MODULE_MANIFEST("MIXIN", mixin_llext_entry, 1, UUID_MIXIN, 30), + SOF_LLEXT_MODULE_MANIFEST("MIXOUT", mixout_llext_entry, 1, UUID_MIXOUT, 30), }; SOF_LLEXT_BUILDINFO; diff --git a/src/include/module/module/llext.h b/src/include/module/module/llext.h index 61532e3fb70f..05b8f0ffb5f5 100644 --- a/src/include/module/module/llext.h +++ b/src/include/module/module/llext.h @@ -6,12 +6,13 @@ #ifndef MODULE_LLEXT_H #define MODULE_LLEXT_H -#define SOF_LLEXT_MODULE_MANIFEST(manifest_name, entry, affinity, mod_uuid) \ +#define SOF_LLEXT_MODULE_MANIFEST(manifest_name, entry, affinity, mod_uuid, instances) \ { \ .module = { \ .name = manifest_name, \ .uuid = {mod_uuid}, \ .entry_point = (uint32_t)(entry), \ + .instance_max_count = instances, \ .type = { \ .load_type = SOF_MAN_MOD_TYPE_LLEXT, \ .domain_ll = 1, \ diff --git a/src/samples/audio/smart_amp_test_ipc4.c b/src/samples/audio/smart_amp_test_ipc4.c index c0d6acc872aa..4faa8d967030 100644 --- a/src/samples/audio/smart_amp_test_ipc4.c +++ b/src/samples/audio/smart_amp_test_ipc4.c @@ -417,6 +417,7 @@ static const struct sof_man_module_manifest main_manifest __section(".module") _ .uuid = {0x1E, 0x96, 0x7A, 0x16, 0xE4, 0x8A, 0xEA, 0x11, 0x89, 0xF1, 0x00, 0x0C, 0x29, 0xCE, 0x16, 0x35}, .entry_point = (uint32_t)smart_amp_test_llext_entry, + .instance_max_count = 1, .type = { #ifdef __SOF_MODULE_SERVICE_BUILD__ .load_type = SOF_MAN_MOD_TYPE_MODULE, From 9cc1afb12b9b69ad7a20cf54017ad48d35c15c81 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 14 Jun 2024 15:47:08 +0200 Subject: [PATCH 05/11] rimage: don't overwrite maximum module instance counts Use maximum instance count from TOML when building a manifest. Signed-off-by: Guennadi Liakhovetski --- tools/rimage/src/manifest.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/rimage/src/manifest.c b/tools/rimage/src/manifest.c index 5fb766c87173..52b328e85ca7 100644 --- a/tools/rimage/src/manifest.c +++ b/tools/rimage/src/manifest.c @@ -464,9 +464,6 @@ static int man_module_create_reloc(struct image *image, struct manifest_module * /* stack size ??? convert sizes to PAGES */ man_module->instance_bss_size = 1; - /* max number of instances of this module ?? */ - man_module->instance_max_count = 1; - module_print_zones(&module->file); /* main module */ From ccd41ba7c129a47921d620681ec3db827f58957c Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 17 Jun 2024 17:24:35 +0200 Subject: [PATCH 06/11] llext: remove logging during module freeing When pipelines are destroyed, component drivers' .reset() and .free() are called. If those drivers were loaded dynamically their memory is then unmapped. But logging takes place in a low priority task, so it is important that no logging is done from those methods. Signed-off-by: Guennadi Liakhovetski --- src/audio/eq_iir/eq_iir.c | 4 ---- src/audio/mixin_mixout/mixin_mixout.c | 8 -------- src/samples/audio/smart_amp_test_ipc4.c | 4 ---- 3 files changed, 16 deletions(-) diff --git a/src/audio/eq_iir/eq_iir.c b/src/audio/eq_iir/eq_iir.c index 9cfab900c9fa..9ba43d27993c 100644 --- a/src/audio/eq_iir/eq_iir.c +++ b/src/audio/eq_iir/eq_iir.c @@ -100,8 +100,6 @@ static int eq_iir_free(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "eq_iir_free()"); - eq_iir_free_delaylines(cd); comp_data_blob_handler_free(cd->model_handler); @@ -234,8 +232,6 @@ static int eq_iir_reset(struct processing_module *mod) struct comp_data *cd = module_get_private_data(mod); int i; - comp_info(mod->dev, "eq_iir_reset()"); - eq_iir_free_delaylines(cd); cd->eq_iir_func = NULL; diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index cee5140c0f6b..d1334fe4d399 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -175,9 +175,7 @@ static int mixout_init(struct processing_module *mod) static int mixin_free(struct processing_module *mod) { struct mixin_data *md = module_get_private_data(mod); - struct comp_dev *dev = mod->dev; - comp_dbg(dev, "mixin_free()"); rfree(md); return 0; @@ -185,7 +183,6 @@ static int mixin_free(struct processing_module *mod) static int mixout_free(struct processing_module *mod) { - comp_dbg(mod->dev, "mixout_free()"); rfree(module_get_private_data(mod)); return 0; @@ -556,9 +553,6 @@ static int mixout_process(struct processing_module *mod, static int mixin_reset(struct processing_module *mod) { struct mixin_data *mixin_data = module_get_private_data(mod); - struct comp_dev *dev = mod->dev; - - comp_dbg(dev, "mixin_reset()"); mixin_data->mix = NULL; mixin_data->gain_mix = NULL; @@ -570,8 +564,6 @@ static int mixout_reset(struct processing_module *mod) { struct comp_dev *dev = mod->dev; - comp_dbg(dev, "mixout_reset()"); - /* FIXME: move this to module_adapter_reset() */ if (dev->pipeline->source_comp->direction == SOF_IPC_STREAM_PLAYBACK) { int i; diff --git a/src/samples/audio/smart_amp_test_ipc4.c b/src/samples/audio/smart_amp_test_ipc4.c index 4faa8d967030..db81b0fa2725 100644 --- a/src/samples/audio/smart_amp_test_ipc4.c +++ b/src/samples/audio/smart_amp_test_ipc4.c @@ -159,8 +159,6 @@ static inline int smart_amp_get_config(struct processing_module *mod, static int smart_amp_free(struct processing_module *mod) { - LOG_DBG("smart_amp_free()"); - #ifndef __SOF_MODULE_SERVICE_BUILD__ struct smart_amp_data *sad = module_get_private_data(mod); @@ -322,8 +320,6 @@ static int smart_amp_process(struct processing_module *mod, static int smart_amp_reset(struct processing_module *mod) { - LOG_DBG("smart_amp_reset()"); - return 0; } From 6e848749af0faac1d99db1d70ce1ed4cbb229392 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 2 Jul 2024 10:53:07 +0200 Subject: [PATCH 07/11] llext: disable when testing reproducible builds So far we cannot build identical LLEXT modules under Linux and Windows, build a monolithic firmware for this test. Signed-off-by: Guennadi Liakhovetski --- app/overlays/repro-build.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/app/overlays/repro-build.conf b/app/overlays/repro-build.conf index d7b434c39660..25e49e619e6c 100644 --- a/app/overlays/repro-build.conf +++ b/app/overlays/repro-build.conf @@ -1,2 +1,3 @@ CONFIG_OUTPUT_DISASSEMBLY=y CONFIG_OUTPUT_DISASSEMBLY_WITH_SOURCE=n +CONFIG_MODULES=n From 6249a3bb2b2941f2d9e88042ab267baac27be7fb Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 3 Jul 2024 11:56:29 +0200 Subject: [PATCH 08/11] llext: export symbols, required for modular DRC Export additional symbols, required for building DRC as an LLEXT object. Signed-off-by: Guennadi Liakhovetski --- src/math/exp_fcn.c | 3 +++ src/math/exp_fcn_hifi.c | 2 ++ src/math/lut_trig.c | 2 ++ 3 files changed, 7 insertions(+) diff --git a/src/math/exp_fcn.c b/src/math/exp_fcn.c index 2bace8a430cc..6ada84202212 100644 --- a/src/math/exp_fcn.c +++ b/src/math/exp_fcn.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -258,6 +259,7 @@ int32_t sofm_exp_fixed(int32_t x) return y; } +EXPORT_SYMBOL(sofm_exp_fixed); #endif /* EXPONENTIAL_GENERIC */ @@ -284,3 +286,4 @@ int32_t sofm_db2lin_fixed(int32_t db) arg = (int32_t)Q_MULTSR_32X32((int64_t)db, SOFM_EXP_LOG10_DIV20_Q27, 24, 27, 27); return sofm_exp_fixed(arg); } +EXPORT_SYMBOL(sofm_db2lin_fixed); diff --git a/src/math/exp_fcn_hifi.c b/src/math/exp_fcn_hifi.c index f0a263b76873..10775133e8a4 100644 --- a/src/math/exp_fcn_hifi.c +++ b/src/math/exp_fcn_hifi.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -370,5 +371,6 @@ int32_t sofm_exp_fixed(int32_t x) return y; } +EXPORT_SYMBOL(sofm_exp_fixed); #endif diff --git a/src/math/lut_trig.c b/src/math/lut_trig.c index 5c88b957d413..a40729327932 100644 --- a/src/math/lut_trig.c +++ b/src/math/lut_trig.c @@ -6,6 +6,7 @@ #include #include +#include #include #define SOFM_LUT_SINE_C_Q20 341782638 /* 2 * SINE_NQUART / pi in Q12.20 */ @@ -106,3 +107,4 @@ int16_t sofm_lut_sin_fixed_16b(int32_t w) sine = s0 + q_mults_32x32(frac, delta, Q_SHIFT_BITS_64(31, 16, 16)); /* Q1.16 */ return sat_int16((sine + 1) >> 1); /* Round to Q1.15 */ } +EXPORT_SYMBOL(sofm_lut_sin_fixed_16b); From 701593924c1fdda0a037295dc4a40bf4aa475e0f Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 3 Jun 2024 15:26:03 +0200 Subject: [PATCH 09/11] drc: enable building as an llext module Add support for LLEXT building to drc. Since multiband DRC calls functions from DRC, we cannot so far build it if DRC is configured as a module. In the future it should be possible to build both as modules and to export symbols between them. Signed-off-by: Guennadi Liakhovetski --- app/overlays/lnl/module_overlay.conf | 1 + app/overlays/mtl/module_overlay.conf | 1 + src/audio/drc/Kconfig | 2 +- src/audio/drc/drc.c | 23 +++++++++++++++++++---- src/audio/drc/drc.toml | 6 +++++- src/audio/drc/llext/CMakeLists.txt | 13 +++++++++++++ src/audio/drc/llext/llext.toml.h | 6 ++++++ src/audio/multiband_drc/Kconfig | 2 +- zephyr/CMakeLists.txt | 22 ++++++++++++++-------- 9 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 src/audio/drc/llext/CMakeLists.txt create mode 100644 src/audio/drc/llext/llext.toml.h diff --git a/app/overlays/lnl/module_overlay.conf b/app/overlays/lnl/module_overlay.conf index 172a8ea28e82..88006880acd9 100644 --- a/app/overlays/lnl/module_overlay.conf +++ b/app/overlays/lnl/module_overlay.conf @@ -1 +1,2 @@ CONFIG_SAMPLE_SMART_AMP=m +CONFIG_COMP_DRC=m diff --git a/app/overlays/mtl/module_overlay.conf b/app/overlays/mtl/module_overlay.conf index 45babe736c53..1fb5549e9d82 100644 --- a/app/overlays/mtl/module_overlay.conf +++ b/app/overlays/mtl/module_overlay.conf @@ -1,3 +1,4 @@ CONFIG_SAMPLE_SMART_AMP=m CONFIG_COMP_MIXIN_MIXOUT=m CONFIG_COMP_IIR=m +CONFIG_COMP_DRC=m diff --git a/src/audio/drc/Kconfig b/src/audio/drc/Kconfig index 9e6aaf6388ed..56e3c4d9e6fc 100644 --- a/src/audio/drc/Kconfig +++ b/src/audio/drc/Kconfig @@ -3,7 +3,7 @@ rsource "Kconfig.simd" config COMP_DRC - bool "Dynamic Range Compressor component" + tristate "Dynamic Range Compressor component" select CORDIC_FIXED select MATH_LUT_SINE_FIXED select NUMBERS_NORM diff --git a/src/audio/drc/drc.c b/src/audio/drc/drc.c index 7080fdea55f1..9beb5112b597 100644 --- a/src/audio/drc/drc.c +++ b/src/audio/drc/drc.c @@ -203,8 +203,6 @@ static int drc_free(struct processing_module *mod) { struct drc_comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "drc_free()"); - comp_data_blob_handler_free(cd->model_handler); rfree(cd); return 0; @@ -370,8 +368,6 @@ static int drc_reset(struct processing_module *mod) { struct drc_comp_data *cd = module_get_private_data(mod); - comp_info(mod->dev, "drc_reset()"); - drc_reset_state(&cd->state); return 0; @@ -389,3 +385,22 @@ static const struct module_interface drc_interface = { DECLARE_MODULE_ADAPTER(drc_interface, drc_uuid, drc_tr); SOF_MODULE_INIT(drc, sys_comp_module_drc_interface_init); + +#if CONFIG_COMP_DRC_MODULE +/* modular: llext dynamic link */ + +#include +#include +#include + +#define UUID_DRC 0xda, 0xe4, 0x6e, 0xb3, 0x6f, 0x00, 0xf9, 0x47, \ + 0xa0, 0x6d, 0xfe, 0xcb, 0xe2, 0xd8, 0xb6, 0xce + +SOF_LLEXT_MOD_ENTRY(drc, &drc_interface); + +static const struct sof_man_module_manifest mod_manifest __section(".module") __used = + SOF_LLEXT_MODULE_MANIFEST("DRC", drc_llext_entry, 1, UUID_DRC, 40); + +SOF_LLEXT_BUILDINFO; + +#endif diff --git a/src/audio/drc/drc.toml b/src/audio/drc/drc.toml index 29ee8d856cbb..4c0b25601425 100644 --- a/src/audio/drc/drc.toml +++ b/src/audio/drc/drc.toml @@ -1,3 +1,7 @@ +#ifndef LOAD_TYPE +#define LOAD_TYPE "0" +#endif + REM # DRC module config [[module.entry]] name = "DRC" @@ -5,7 +9,7 @@ affinity_mask = "0x1" instance_count = "40" domain_types = "0" - load_type = "0" + load_type = LOAD_TYPE module_type = "9" auto_start = "0" sched_caps = [1, 0x00008000] diff --git a/src/audio/drc/llext/CMakeLists.txt b/src/audio/drc/llext/CMakeLists.txt new file mode 100644 index 000000000000..5a59b9bade98 --- /dev/null +++ b/src/audio/drc/llext/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +# Hard-coded .text address to be moved to a common place +sof_llext_build("drc" + SOURCES ../drc.c + ../drc_generic.c + ../drc_math_generic.c + ../drc_hifi3.c + ../drc_hifi4.c + ../drc_math_hifi3.c + TEXT_ADDR 0xa068a000 +) diff --git a/src/audio/drc/llext/llext.toml.h b/src/audio/drc/llext/llext.toml.h new file mode 100644 index 000000000000..89469d54fffb --- /dev/null +++ b/src/audio/drc/llext/llext.toml.h @@ -0,0 +1,6 @@ +#include +#define LOAD_TYPE "2" +#include "../drc.toml" + +[module] +count = __COUNTER__ diff --git a/src/audio/multiband_drc/Kconfig b/src/audio/multiband_drc/Kconfig index 175a6bf09c48..d9e61c915ccd 100644 --- a/src/audio/multiband_drc/Kconfig +++ b/src/audio/multiband_drc/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause config COMP_MULTIBAND_DRC - depends on COMP_IIR && COMP_CROSSOVER && COMP_DRC + depends on COMP_IIR && COMP_CROSSOVER && COMP_DRC = y bool "Multiband Dynamic Range Compressor component" select CORDIC_FIXED select COMP_BLOB diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 6c98bc212c68..b34829ad883c 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -755,14 +755,20 @@ zephyr_library_sources_ifdef(CONFIG_COMP_CROSSOVER ${SOF_AUDIO_PATH}/crossover/crossover_${ipc_suffix}.c ) -zephyr_library_sources_ifdef(CONFIG_COMP_DRC - ${SOF_AUDIO_PATH}/drc/drc.c - ${SOF_AUDIO_PATH}/drc/drc_generic.c - ${SOF_AUDIO_PATH}/drc/drc_math_generic.c - ${SOF_AUDIO_PATH}/drc/drc_hifi3.c - ${SOF_AUDIO_PATH}/drc/drc_hifi4.c - ${SOF_AUDIO_PATH}/drc/drc_math_hifi3.c -) +if(CONFIG_COMP_DRC STREQUAL "m") + add_subdirectory(${SOF_AUDIO_PATH}/drc/llext + ${PROJECT_BINARY_DIR}/drc_llext) + add_dependencies(app drc) +elseif(CONFIG_COMP_DRC) + zephyr_library_sources( + ${SOF_AUDIO_PATH}/drc/drc.c + ${SOF_AUDIO_PATH}/drc/drc_generic.c + ${SOF_AUDIO_PATH}/drc/drc_math_generic.c + ${SOF_AUDIO_PATH}/drc/drc_hifi3.c + ${SOF_AUDIO_PATH}/drc/drc_hifi4.c + ${SOF_AUDIO_PATH}/drc/drc_math_hifi3.c + ) +endif() zephyr_library_sources_ifdef(CONFIG_COMP_MULTIBAND_DRC ${SOF_AUDIO_PATH}/multiband_drc/multiband_drc.c From 95517f8b7b9535e8dbd13f7d5c437ed59a612e3a Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 Jun 2024 12:25:41 +0200 Subject: [PATCH 10/11] drc: make modular on MTL and LNL Export missing symbols for modular DRC builds and select it as a module on MTL and LNL. DRC isn't built by default, so we cannot use CONFIG_LIBRARY_DEFAULT_MODULAR for it. Signed-off-by: Guennadi Liakhovetski --- app/boards/intel_adsp_ace15_mtpm.conf | 2 +- app/boards/intel_adsp_ace20_lnl.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/boards/intel_adsp_ace15_mtpm.conf b/app/boards/intel_adsp_ace15_mtpm.conf index 0348c9da5aa9..ed4c0f596d19 100644 --- a/app/boards/intel_adsp_ace15_mtpm.conf +++ b/app/boards/intel_adsp_ace15_mtpm.conf @@ -5,7 +5,7 @@ CONFIG_IPC4_BASE_FW_INTEL=y CONFIG_COMP_SRC=y CONFIG_COMP_SRC_IPC4_FULL_MATRIX=y CONFIG_COMP_SRC_LITE=y -CONFIG_COMP_DRC=y +CONFIG_COMP_DRC=m CONFIG_COMP_CROSSOVER=y CONFIG_COMP_MULTIBAND_DRC=y diff --git a/app/boards/intel_adsp_ace20_lnl.conf b/app/boards/intel_adsp_ace20_lnl.conf index 42dea6d096ee..7fdd37ab63c4 100644 --- a/app/boards/intel_adsp_ace20_lnl.conf +++ b/app/boards/intel_adsp_ace20_lnl.conf @@ -4,7 +4,7 @@ CONFIG_IPC4_BASE_FW_INTEL=y CONFIG_COMP_SRC=y CONFIG_COMP_SRC_IPC4_FULL_MATRIX=y -CONFIG_COMP_DRC=y +CONFIG_COMP_DRC=m # power settings CONFIG_PM=y From a529d61cf51044b821235a69de9721791296aa34 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 26 Jun 2024 10:18:43 +0200 Subject: [PATCH 11/11] kcps: fix 0 module CPC case If a module contains 0 as its CPC value, the consumption calculation routine will assign a "safe" maximum value to keep the DSP running at the maximum clock rate. This works when constructing a pipeline, but when a pipeline is torn down, returning the maximum clock rate leads to the clock being reduced to a small value. Fix this by detecting such cases in pipeline termination code. Signed-off-by: Guennadi Liakhovetski --- src/audio/pipeline/pipeline-stream.c | 22 ++++++++++++++++++++-- src/include/sof/audio/component.h | 4 ++++ src/include/sof/audio/pipeline.h | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/audio/pipeline/pipeline-stream.c b/src/audio/pipeline/pipeline-stream.c index 7077f5e30251..add2dbd787b6 100644 --- a/src/audio/pipeline/pipeline-stream.c +++ b/src/audio/pipeline/pipeline-stream.c @@ -344,7 +344,15 @@ static int pipeline_calc_cps_consumption(struct comp_dev *current, if (cd->cpc == 0) { /* Use maximum clock budget, assume 1ms chunk size */ - ppl_data->kcps[comp_core] = CLK_MAX_CPU_HZ / 1000; + uint32_t core_kcps = core_kcps_get(comp_core); + + if (!current->kcps_inc[comp_core]) { + current->kcps_inc[comp_core] = core_kcps; + ppl_data->kcps[comp_core] = CLK_MAX_CPU_HZ / 1000 - core_kcps; + } else { + ppl_data->kcps[comp_core] = core_kcps - current->kcps_inc[comp_core]; + current->kcps_inc[comp_core] = 0; + } 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]); @@ -367,6 +375,9 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd) { int ret; #if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL +/* FIXME: this must be a platform-specific parameter or a Kconfig option */ +#define DSP_MIN_KCPS 50000 + struct pipeline_data data = { .start = p->source_comp, .p = p, @@ -431,8 +442,15 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd) for (int i = 0; i < arch_num_cpus(); i++) { if (data.kcps[i] > 0) { + uint32_t core_kcps = core_kcps_get(i); + + /* Tests showed, that we cannot go below 40000kcps on MTL */ + if (data.kcps[i] > core_kcps - DSP_MIN_KCPS) + data.kcps[i] = core_kcps - DSP_MIN_KCPS; + core_kcps_adjust(i, -data.kcps[i]); - tr_info(pipe, "Sum of KCPS consumption: %d, core: %d", core_kcps_get(i), i); + tr_info(pipe, "Sum of KCPS consumption: %d, core: %d", + core_kcps, i); } } } diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index 4dfa2e66a26a..e8171084087b 100644 --- a/src/include/sof/audio/component.h +++ b/src/include/sof/audio/component.h @@ -604,6 +604,10 @@ struct comp_dev { #if CONFIG_PERFORMANCE_COUNTERS struct perf_cnt_data pcd; #endif + +#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL + int32_t kcps_inc[CONFIG_CORE_COUNT]; +#endif }; /** @}*/ diff --git a/src/include/sof/audio/pipeline.h b/src/include/sof/audio/pipeline.h index 0edb3305680c..2410f774f00d 100644 --- a/src/include/sof/audio/pipeline.h +++ b/src/include/sof/audio/pipeline.h @@ -123,7 +123,7 @@ struct pipeline_data { 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 */ + int32_t kcps[CONFIG_CORE_COUNT]; /**< the max count of KCPS */ #endif };