From d53cc3b3fb9e5a0468e15ac931a8c33e05e1d93f Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Fri, 5 Feb 2021 11:23:19 +0800 Subject: [PATCH 01/47] topology: sof-tgl-nocodec-ci: use 38.4MHz MCLK Define to use 38.4MHz MCLK for DSM, to align with other SSP ports. Signed-off-by: Keyon Jie --- tools/topology/development/sof-tgl-nocodec-ci.m4 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/topology/development/sof-tgl-nocodec-ci.m4 b/tools/topology/development/sof-tgl-nocodec-ci.m4 index fa65f2240909..1429e2f80d0c 100644 --- a/tools/topology/development/sof-tgl-nocodec-ci.m4 +++ b/tools/topology/development/sof-tgl-nocodec-ci.m4 @@ -84,6 +84,8 @@ define(`SMART_SSP_NAME', `NoCodec-2') define(`SMART_BE_ID', 2) #define SSP QUIRK define(`SMART_SSP_QUIRK', `SSP_QUIRK_LBM') +#define SSP_MCLK +define(`SSP_MCLK', 38400000) # Playback related define(`SMART_PB_PPL_ID', 5) From 961f7252693cfb13ea609c633299e9b7eed9dc26 Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Mon, 1 Feb 2021 17:36:34 +0200 Subject: [PATCH 02/47] schedule: dma_multi_chan: do not skip tasks for dma_domain scheduler Add a full_sync attribute to ll_schedule domain. This is set to true, for a full synchronous dma_domain scheduler, which is not time dependent. By default, it is false. In full_sync case we use the ratio between the task period and the registrable task period to do the scheduling, not the task.start time. We do this because for the DMA_DOMAIN there are no guarantees for the accuracy of the period of the registrable task which drives the entire scheduling. An example is the mixer topology where we have 3 pipelines for playback scenario: - 1 pipeline for pcm1.0 (task 0); - 1 pipeline for pcm1.1 (task 1); - 1 pipeline for DAI (task 2). Task 2 is the registrable task and this is always scheduled. The other tasks (task 0 and task 1) are scheduled based on task->start. The problem is that, at some point, the DMA transfer from DAI is finished earlier than task->start for one of the task 0 or task 1 and this is not scheduled anymore. And, task 2 ends up depleting one of the source buffers, thus blocking the entire data flow. Fixes: #3802 Signed-off-by: Iuliana Prodan --- src/include/sof/schedule/ll_schedule.h | 2 + src/include/sof/schedule/ll_schedule_domain.h | 2 + src/include/sof/schedule/task.h | 3 ++ src/schedule/dma_multi_chan_domain.c | 29 +++++++++--- src/schedule/ll_schedule.c | 44 +++++++++++++++++++ 5 files changed, 75 insertions(+), 5 deletions(-) diff --git a/src/include/sof/schedule/ll_schedule.h b/src/include/sof/schedule/ll_schedule.h index 4f8c9633f1c2..b231625aeeb4 100644 --- a/src/include/sof/schedule/ll_schedule.h +++ b/src/include/sof/schedule/ll_schedule.h @@ -30,6 +30,8 @@ extern struct tr_ctx ll_tr; struct ll_task_pdata { uint64_t period; + uint16_t ratio; /**< ratio of periods compared to the registrable task */ + uint16_t skip_cnt; /**< how many times the task was skipped for execution */ }; int scheduler_init_ll(struct ll_schedule_domain *domain); diff --git a/src/include/sof/schedule/ll_schedule_domain.h b/src/include/sof/schedule/ll_schedule_domain.h index 756b0a488824..11eb09f49f68 100644 --- a/src/include/sof/schedule/ll_schedule_domain.h +++ b/src/include/sof/schedule/ll_schedule_domain.h @@ -50,6 +50,7 @@ struct ll_schedule_domain { int type; /**< domain type */ int clk; /**< source clock */ bool synchronous; /**< are tasks should be synchronous */ + bool full_sync; /**< tasks should be full synchronous, no time dependent */ void *priv_data; /**< pointer to private data */ bool registered[CONFIG_CORE_COUNT]; /**< registered cores */ bool enabled[CONFIG_CORE_COUNT]; /**< enabled cores */ @@ -80,6 +81,7 @@ static inline struct ll_schedule_domain *domain_init domain->type = type; domain->clk = clk; domain->synchronous = synchronous; + domain->full_sync = false; domain->ticks_per_ms = clock_ms_to_ticks(clk, 1); domain->ops = ops; diff --git a/src/include/sof/schedule/task.h b/src/include/sof/schedule/task.h index ed242502e50f..510569689f3d 100644 --- a/src/include/sof/schedule/task.h +++ b/src/include/sof/schedule/task.h @@ -31,6 +31,9 @@ struct sof; #define SOF_TASK_DEADLINE_ALMOST_IDLE (SOF_TASK_DEADLINE_IDLE - 1) #define SOF_TASK_DEADLINE_NOW 0 +/** \brief Task counter initial value. */ +#define SOF_TASK_SKIP_COUNT 0xFFFFu + /** \brief Task states. */ enum task_state { SOF_TASK_STATE_INIT = 0, diff --git a/src/schedule/dma_multi_chan_domain.c b/src/schedule/dma_multi_chan_domain.c index 4fd37d7ebf45..0ee88d3234f4 100644 --- a/src/schedule/dma_multi_chan_domain.c +++ b/src/schedule/dma_multi_chan_domain.c @@ -280,6 +280,7 @@ static bool dma_multi_chan_domain_is_pending(struct ll_schedule_domain *domain, struct dma_domain *dma_domain = ll_sch_domain_get_pdata(domain); struct pipeline_task *pipe_task = pipeline_task_get(task); struct dma *dmas = dma_domain->dma_array; + struct ll_task_pdata *pdata; uint32_t status; int i; int j; @@ -303,11 +304,29 @@ static bool dma_multi_chan_domain_is_pending(struct ll_schedule_domain *domain, pipe_task->sched_comp) continue; - /* it's too soon for this task */ - if (!pipe_task->registrable && - pipe_task->task.start > - platform_timer_get_atomic(timer_get())) - continue; + /* Schedule task based on the frequency they + * were configured with, not time (task.start) + * + * There are cases when a DMA transfer from a DAI + * is finished earlier than task.start and, + * without full_sync mode, this task will not + * be scheduled + */ + if (domain->full_sync) { + pdata = ll_sch_get_pdata(&pipe_task->task); + pdata->skip_cnt++; + if (pdata->skip_cnt == pdata->ratio) + pdata->skip_cnt = 0; + + if (pdata->skip_cnt != 0) + continue; + } else { + /* it's too soon for this task */ + if (!pipe_task->registrable && + pipe_task->task.start > + platform_timer_get_atomic(timer_get())) + continue; + } notifier_event(&dmas[i].chan[j], NOTIFIER_ID_DMA_IRQ, NOTIFIER_TARGET_CORE_LOCAL, diff --git a/src/schedule/ll_schedule.c b/src/schedule/ll_schedule.c index baffe1268f5a..36c90e546b0c 100644 --- a/src/schedule/ll_schedule.c +++ b/src/schedule/ll_schedule.c @@ -324,8 +324,11 @@ static int schedule_ll_task(void *data, struct task *task, uint64_t start, { struct ll_schedule_data *sch = data; struct ll_task_pdata *pdata; + struct ll_task_pdata *reg_pdata; struct list_item *tlist; struct task *curr_task; + struct task *registrable_task = NULL; + struct pipeline_task *pipe_task; uint32_t flags; int ret = 0; @@ -353,6 +356,47 @@ static int schedule_ll_task(void *data, struct task *task, uint64_t start, pdata->period = period; + /* for full synchronous domain, calculate ratio and initialize skip_cnt for task */ + if (sch->domain->full_sync) { + pdata->ratio = 1; + pdata->skip_cnt = (uint16_t)SOF_TASK_SKIP_COUNT; + + /* get the registrable task */ + list_for_item(tlist, &sch->tasks) { + curr_task = container_of(tlist, struct task, list); + pipe_task = pipeline_task_get(curr_task); + + /* registrable task found */ + if (pipe_task->registrable) { + registrable_task = curr_task; + break; + } + } + + /* we found a registrable task */ + if (registrable_task) { + reg_pdata = ll_sch_get_pdata(registrable_task); + + /* update ratio for all tasks */ + list_for_item(tlist, &sch->tasks) { + curr_task = container_of(tlist, struct task, list); + pdata = ll_sch_get_pdata(curr_task); + + /* the assumption is that the registrable + * task has the smallest period + */ + if (pdata->period >= reg_pdata->period) { + pdata->ratio = period / reg_pdata->period; + } else { + tr_err(&ll_tr, + "schedule_ll_task(): registrable task has a period longer than current task"); + ret = -EINVAL; + goto out; + } + } + } + } + /* insert task into the list */ schedule_ll_task_insert(task, &sch->tasks); From f155cf10328cd661ee21ff3100bc49bf7299ac5e Mon Sep 17 00:00:00 2001 From: Iuliana Prodan Date: Mon, 1 Feb 2021 19:58:22 +0200 Subject: [PATCH 03/47] platform: imx: use DMA_DOMAIN in full synchronous mode Use the full_sync attribute from dma_domain to schedule tasks based on period ratio between the registrable task and the current one. Do not make it time dependent anymore. Fixes: #3802 Signed-off-by: Iuliana Prodan --- src/platform/imx8/platform.c | 3 +++ src/platform/imx8m/platform.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/platform/imx8/platform.c b/src/platform/imx8/platform.c index e5232549feb8..aa3cd0a68a41 100644 --- a/src/platform/imx8/platform.c +++ b/src/platform/imx8/platform.c @@ -176,6 +176,9 @@ int platform_init(struct sof *sof) sof->platform_dma_domain = dma_multi_chan_domain_init (&sof->dma_info->dma_array[0], 1, PLATFORM_DEFAULT_CLOCK, false); + + /* i.MX platform DMA domain will be full synchronous, no time dependent */ + sof->platform_dma_domain->full_sync = true; scheduler_init_ll(sof->platform_dma_domain); /* initialize the host IPC mechanims */ diff --git a/src/platform/imx8m/platform.c b/src/platform/imx8m/platform.c index 9175e742cf86..e57fb84077ea 100644 --- a/src/platform/imx8m/platform.c +++ b/src/platform/imx8m/platform.c @@ -175,6 +175,9 @@ int platform_init(struct sof *sof) sof->platform_dma_domain = dma_multi_chan_domain_init(&sof->dma_info->dma_array[1], 1, PLATFORM_DEFAULT_CLOCK, true); + + /* i.MX platform DMA domain will be full synchronous, no time dependent */ + sof->platform_dma_domain->full_sync = true; scheduler_init_ll(sof->platform_dma_domain); /* initialize the host IPC mechanims */ From f1a6740935fa9aca7bf19a62c8981927ebde0273 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Fri, 15 Jan 2021 14:30:41 -0800 Subject: [PATCH 04/47] probe: fix ret type cppcheck points out the uselessness of checking <0 checks on unsigned types Signed-off-by: Curtis Malainey --- src/probe/probe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/probe/probe.c b/src/probe/probe.c index 3b75f3481c13..2eb1261bb2a3 100644 --- a/src/probe/probe.c +++ b/src/probe/probe.c @@ -755,7 +755,8 @@ static void probe_cb_produce(void *arg, enum notify_id type, void *data) uint32_t head, tail; uint32_t free_bytes = 0; int32_t copy_bytes = 0; - uint32_t ret, i, j; + int ret; + uint32_t i, j; uint32_t format; buffer_id = buffer->id; @@ -897,7 +898,7 @@ static void probe_cb_free(void *arg, enum notify_id type, void *data) { struct buffer_cb_free *cb_data = data; uint32_t buffer_id = cb_data->buffer->id; - uint32_t ret; + int ret; tr_dbg(&pr_tr, "probe_cb_free() buffer_id = %u", buffer_id); From bace002097efc8f235535f305b11b7ccab2333cb Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Fri, 15 Jan 2021 14:40:19 -0800 Subject: [PATCH 05/47] smart_amp_test: fix redundent check and double free not sure how this happened but this check is pointless and also results in a double free, found by cppcheck Signed-off-by: Curtis Malainey --- src/samples/audio/smart_amp_test.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/samples/audio/smart_amp_test.c b/src/samples/audio/smart_amp_test.c index 4fb631b708cd..a131cfd4d984 100644 --- a/src/samples/audio/smart_amp_test.c +++ b/src/samples/audio/smart_amp_test.c @@ -74,8 +74,6 @@ static struct comp_dev *smart_amp_new(const struct comp_driver *drv, if ((bs > 0) && (bs < sizeof(struct sof_smart_amp_config))) { comp_err(dev, "smart_amp_new(): failed to apply config"); - if (sad) - rfree(sad); rfree(sad); return NULL; } From d1b0df926077acf54f138ef3465ab222f5f895ff Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Fri, 15 Jan 2021 14:45:50 -0800 Subject: [PATCH 06/47] library: edf_schedule: fix naming collision sch is global and local, rename local, found via cppcheck Signed-off-by: Curtis Malainey --- src/platform/library/schedule/edf_schedule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/library/schedule/edf_schedule.c b/src/platform/library/schedule/edf_schedule.c index db3106456bec..4bd938701f18 100644 --- a/src/platform/library/schedule/edf_schedule.c +++ b/src/platform/library/schedule/edf_schedule.c @@ -40,9 +40,9 @@ static int schedule_edf_task_complete(struct task *task) static int schedule_edf_task(void *data, struct task *task, uint64_t start, uint64_t period) { - struct edf_schedule_data *sch = data; + struct edf_schedule_data *sched = data; (void)period; - list_item_prepend(&task->list, &sch->list); + list_item_prepend(&task->list, &sched->list); task->state = SOF_TASK_STATE_QUEUED; if (task->ops.run) From af91fde82887c5a6102fa735db576715c716f95c Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Fri, 15 Jan 2021 14:56:35 -0800 Subject: [PATCH 07/47] pipeline: fix data structure linking cppcheck was being confused as we were passing in hw_param_ctx which has linking in the following order hw_param_ctx->data->hw_params. Cppcheck was being confused as it failed to realize that hw_params was a writeback method and to be honest the way it was written they way the structures were linked was hard to see as well. Lets do all the linking upfront so its easier to read. Cppcheck doesn't seem to complain about this method so lets use it. Signed-off-by: Curtis Malainey --- src/audio/pipeline.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c index 1b51f994253a..f3f06b3bccd0 100644 --- a/src/audio/pipeline.c +++ b/src/audio/pipeline.c @@ -517,7 +517,10 @@ int pipeline_params(struct pipeline *p, struct comp_dev *host, struct sof_ipc_pcm_params *params) { struct sof_ipc_pcm_params hw_params; - struct pipeline_data data; + struct pipeline_data data = { + .start = host, + .params = &hw_params, + }; struct pipeline_walk_context hw_param_ctx = { .comp_func = pipeline_comp_hw_params, .comp_data = &data, @@ -541,10 +544,6 @@ int pipeline_params(struct pipeline *p, struct comp_dev *host, params->params.sample_valid_bytes, params->params.sample_container_bytes); - /* settin hw params */ - data.start = host; - data.params = &hw_params; - ret = hw_param_ctx.comp_func(host, NULL, &hw_param_ctx, dir); if (ret < 0) { pipe_err(p, "pipeline_params(): ret = %d, dev->comp.id = %u", From 958ff4a451c6572412258a020bf48120903bc877 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Wed, 10 Feb 2021 17:30:44 -0800 Subject: [PATCH 08/47] codec_adapter: stop leaking memory on prepare we should free before we clear the pointer found via cppcheck Signed-off-by: Curtis Malainey --- src/audio/codec_adapter/codec/generic.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/audio/codec_adapter/codec/generic.c b/src/audio/codec_adapter/codec/generic.c index d295b8d0b7f5..2f3904af91b1 100644 --- a/src/audio/codec_adapter/codec/generic.c +++ b/src/audio/codec_adapter/codec/generic.c @@ -229,10 +229,6 @@ int codec_prepare(struct comp_dev *dev) goto end; } - codec->s_cfg.avail = false; - codec->r_cfg.avail = false; - codec->r_cfg.data = NULL; - /* After prepare is done we no longer need runtime configuration * as it has been applied during the procedure - it is safe to * free it. @@ -240,6 +236,10 @@ int codec_prepare(struct comp_dev *dev) if (codec->r_cfg.data) rfree(codec->r_cfg.data); + codec->s_cfg.avail = false; + codec->r_cfg.avail = false; + codec->r_cfg.data = NULL; + codec->state = CODEC_PREPARED; comp_dbg(dev, "codec_prepare() done"); end: From e492d51d8c1ca794ba328d5224f76eb8594d9612 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Wed, 10 Feb 2021 17:39:07 -0800 Subject: [PATCH 09/47] crossover: dont set values where it doesn't matter if we aren't going to use the value, dont set it. Cppcheck complaint Signed-off-by: Curtis Malainey --- src/audio/crossover/crossover.c | 2 +- src/audio/crossover/crossover_generic.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/audio/crossover/crossover.c b/src/audio/crossover/crossover.c index 5f8b564b765f..3e087eb4e64d 100644 --- a/src/audio/crossover/crossover.c +++ b/src/audio/crossover/crossover.c @@ -223,7 +223,7 @@ int crossover_init_coef_ch(struct sof_eq_iir_biquad_df2t *coef, int32_t i; int32_t j = 0; int32_t num_lr4s = num_sinks == CROSSOVER_2WAY_NUM_SINKS ? 1 : 3; - int err = 0; + int err; for (i = 0; i < num_lr4s; i++) { /* Get the low pass coefficients */ diff --git a/src/audio/crossover/crossover_generic.c b/src/audio/crossover/crossover_generic.c index 9631c076d85e..2ec350434238 100644 --- a/src/audio/crossover/crossover_generic.c +++ b/src/audio/crossover/crossover_generic.c @@ -147,7 +147,7 @@ static void crossover_s16_default(const struct comp_dev *dev, struct audio_stream *sink_stream; int16_t *x, *y; int ch, i, j; - int idx = 0; + int idx; int nch = source_stream->channels; int32_t out[num_sinks]; @@ -186,7 +186,7 @@ static void crossover_s24_default(const struct comp_dev *dev, struct audio_stream *sink_stream; int32_t *x, *y; int ch, i, j; - int idx = 0; + int idx; int nch = source_stream->channels; int32_t out[num_sinks]; @@ -225,7 +225,7 @@ static void crossover_s32_default(const struct comp_dev *dev, struct audio_stream *sink_stream; int32_t *x, *y; int ch, i, j; - int idx = 0; + int idx; int nch = source_stream->channels; int32_t out[num_sinks]; From 2a292a81b363a2bdeaa3cb0ea06afd7faf7f68c3 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 27 Nov 2020 13:00:26 -0500 Subject: [PATCH 10/47] zephyr: reference local Kconfig Reference Kconfig in zephyr module file which is evaluated by Zephyr directly. This will eliminate the need for including the SOF Kconfig directly. Signed-off-by: Anas Nashif --- zephyr/Kconfig | 3 +++ zephyr/module.yml | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 zephyr/Kconfig diff --git a/zephyr/Kconfig b/zephyr/Kconfig new file mode 100644 index 000000000000..f4fceb3e48be --- /dev/null +++ b/zephyr/Kconfig @@ -0,0 +1,3 @@ +if SOF +rsource "../Kconfig" +endif diff --git a/zephyr/module.yml b/zephyr/module.yml index 7ac5323a3c8c..9c43bc6e5fd6 100644 --- a/zephyr/module.yml +++ b/zephyr/module.yml @@ -1,2 +1,3 @@ build: - cmake: ./zephyr + cmake: ./zephyr + kconfig: ./zephyr/Kconfig From c70acedd9504609c2aab5e0429e9eef4b1102d9d Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 18 Dec 2020 12:09:35 -0500 Subject: [PATCH 11/47] trace: do not set trace_ctx section for Zephyr [REVERTME] This section is generating warnings when build with Zephyr, so remove for now. Signed-off-by: Anas Nashif --- src/include/sof/trace/trace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/sof/trace/trace.h b/src/include/sof/trace/trace.h index b5f410fa3474..0ff9989c1676 100644 --- a/src/include/sof/trace/trace.h +++ b/src/include/sof/trace/trace.h @@ -296,7 +296,7 @@ struct tr_ctx { uint32_t level; /**< Default log level */ }; -#if defined(UNIT_TEST) +#if defined(UNIT_TEST) || defined(__ZEPHYR__) #define TRACE_CONTEXT_SECTION #else #define TRACE_CONTEXT_SECTION __section(".trace_ctx") From 89af7b50da3419011bb171b25fe57c5db3b8e063 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 10 Feb 2021 09:58:48 -0500 Subject: [PATCH 12/47] Revert "zephyr: fixed cached rimage path" This reverts commit f4c9c28bc55242c4dcf71a6aa987e764671d6ea3. This is no longer needed as we removed local copy of rimage from zephyr/ext. Signed-off-by: Anas Nashif --- zephyr/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 196ae2b4025d..e882274fd41f 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -53,7 +53,7 @@ set(SOF_TRACE_PATH "${SOF_SRC_PATH}/trace") # Save path to rimage configuration files in cmake cache for later use by # rimage during the "west sign" stage -get_filename_component(RIMAGE_CONFIG "ext/rimage/config" ABSOLUTE) +get_filename_component(RIMAGE_CONFIG "../rimage/config" ABSOLUTE) set(RIMAGE_CONFIG_PATH ${RIMAGE_CONFIG} CACHE PATH " Path to rimage board configuration files") From 538c2e8b6d836cf4b41a0a256604992f7742b444 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 18 Dec 2020 12:10:30 -0500 Subject: [PATCH 13/47] trace: fix formatting Getting formatting warnings when building with Zephyr which prevents successful build in CI. Signed-off-by: Anas Nashif --- src/audio/kpb.c | 4 ++-- src/trace/trace.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/audio/kpb.c b/src/audio/kpb.c index 2b6b1ce6244f..0c173c3f210f 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -521,8 +521,8 @@ static int kpb_prepare(struct comp_dev *dev) } if (!kpb->sel_sink || !kpb->host_sink) { - comp_info(dev, "kpb_prepare(): could not find sinks: sel_sink %d host_sink %d", - (uintptr_t)kpb->sel_sink, (uintptr_t)kpb->host_sink); + comp_info(dev, "kpb_prepare(): could not find sinks: sel_sink %p host_sink %p", + kpb->sel_sink, kpb->host_sink); ret = -EIO; } diff --git a/src/trace/trace.c b/src/trace/trace.c index 3dd9caa5b25e..b7b9d09ccf7c 100644 --- a/src/trace/trace.c +++ b/src/trace/trace.c @@ -139,7 +139,7 @@ static void emit_recent_entry(struct recent_log_entry *entry) _log_message(trace_log_unfiltered, false, LOG_LEVEL_INFO, _TRACE_INV_CLASS, &dt_tr, _TRACE_INV_ID, _TRACE_INV_ID, "Suppressed %u similar messages: %pQ", entry->trigger_count - CONFIG_TRACE_BURST_COUNT, - entry->entry_id); + (void *)entry->entry_id); memset(entry, 0, sizeof(*entry)); } From 04b237c5ebc275ec99dfa268373773ad4bee0c0b Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Thu, 11 Feb 2021 12:52:32 -0800 Subject: [PATCH 14/47] smart_amp: clarify order of operations ternary isn't entirely clear what order happens on the left, add brackets to clarify. Cppcheck complaint Signed-off-by: Curtis Malainey --- src/audio/smart_amp/smart_amp_maxim_dsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/smart_amp/smart_amp_maxim_dsm.c b/src/audio/smart_amp/smart_amp_maxim_dsm.c index e83d3b4fe78b..4b1810c20093 100644 --- a/src/audio/smart_amp/smart_amp_maxim_dsm.c +++ b/src/audio/smart_amp/smart_amp_maxim_dsm.c @@ -243,7 +243,7 @@ int maxim_dsm_set_param(struct smart_amp_mod_struct_t *hspk, value[DSM_SET_VALUE_IDX] = param->param.value; id = DSM_CH_MASK(param->param.id); - ch = param->param.id & DSM_CH1_BITMASK ? 0 : 1; + ch = (param->param.id & DSM_CH1_BITMASK) ? 0 : 1; /* 2nd channel has (hspk->param.max_param * DSM_PARAM_MAX) sized offset */ db[(id + ch * hspk->param.max_param) * DSM_PARAM_MAX + DSM_PARAM_VALUE] = From 09ecfe481ffcfc426c369732a494dbcd932ac789 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Thu, 11 Feb 2021 12:54:53 -0800 Subject: [PATCH 15/47] smart_amp: remove initial set Ret is unconditionally set later, so initialization is irrelevant. Cppcheck find. Signed-off-by: Curtis Malainey --- src/audio/smart_amp/smart_amp_maxim_dsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/smart_amp/smart_amp_maxim_dsm.c b/src/audio/smart_amp/smart_amp_maxim_dsm.c index 4b1810c20093..1efabe8adb4b 100644 --- a/src/audio/smart_amp/smart_amp_maxim_dsm.c +++ b/src/audio/smart_amp/smart_amp_maxim_dsm.c @@ -163,7 +163,7 @@ int maxim_dsm_get_param(struct smart_amp_mod_struct_t *hspk, { struct smart_amp_caldata *caldata = &hspk->param.caldata; size_t bs; - int ret = 0; + int ret; if (caldata->data) { /* reset data_pos variable in case of copying first element */ From 848e7215bcab1affb8226ef29159e52ab2e2584c Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Tue, 16 Feb 2021 15:11:56 -0800 Subject: [PATCH 16/47] intel: dmic: remove unused struct cppcheck complaint Signed-off-by: Curtis Malainey --- src/drivers/intel/dmic.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/drivers/intel/dmic.c b/src/drivers/intel/dmic.c index 6bc1ac80fa28..c471f2d07004 100644 --- a/src/drivers/intel/dmic.c +++ b/src/drivers/intel/dmic.c @@ -85,24 +85,6 @@ struct dmic_configuration { int32_t fir_b_scale; }; -struct pdm_controllers_configuration { - uint32_t cic_control; - uint32_t cic_config; - uint32_t mic_control; - uint32_t fir_control_a; - uint32_t fir_config_a; - uint32_t dc_offset_left_a; - uint32_t dc_offset_right_a; - uint32_t out_gain_left_a; - uint32_t out_gain_right_a; - uint32_t fir_control_b; - uint32_t fir_config_b; - uint32_t dc_offset_left_b; - uint32_t dc_offset_right_b; - uint32_t out_gain_left_b; - uint32_t out_gain_right_b; -}; - /* Configuration ABI version, increment if not compatible with previous * version. */ From 2fd92bef7636c3b764a22818d35eaa17bc3224c3 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Tue, 16 Feb 2021 15:16:10 -0800 Subject: [PATCH 17/47] imx: edma: remove unused variable Cppcheck complaint Related to #3843 Signed-off-by: Curtis Malainey --- src/drivers/imx/edma.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/drivers/imx/edma.c b/src/drivers/imx/edma.c index 0b35f9acdf21..ab99412412f3 100644 --- a/src/drivers/imx/edma.c +++ b/src/drivers/imx/edma.c @@ -346,16 +346,9 @@ static int edma_setup_tcd(struct dma_chan_data *channel, int16_t soff, static int edma_set_config(struct dma_chan_data *channel, struct dma_sg_config *config) { - int handshake, irq; int16_t soff = 0; int16_t doff = 0; - /* We may need to pass some data through the handshake in the - * future, so we just have them here, even if unused for now - */ - (void)handshake; - (void)irq; - tr_info(&edma_tr, "EDMA: set config"); channel->is_scheduling_source = config->is_scheduling_source; @@ -365,12 +358,10 @@ static int edma_set_config(struct dma_chan_data *channel, case DMA_DIR_MEM_TO_DEV: soff = config->src_width; doff = 0; - handshake = config->dest_dev; break; case DMA_DIR_DEV_TO_MEM: soff = 0; doff = config->dest_width; - handshake = config->src_dev; break; default: tr_err(&edma_tr, "edma_set_config() unsupported config direction"); From eba28d78081b354635596a280c658173d7bb882c Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Tue, 16 Feb 2021 15:49:11 -0800 Subject: [PATCH 18/47] cppcheck: imx: suppress divide by sizeof There is a bug in upstream cppcheck where dereferencing a pointer does not result in a type check in sizeof as far as cppcheck is concerned. This results in a false divide by sizeof(pointer) error. See https://trac.cppcheck.net/ticket/10179 Signed-off-by: Curtis Malainey --- src/drivers/imx/sdma.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/drivers/imx/sdma.c b/src/drivers/imx/sdma.c index 2a2f22fa8b59..344a536e5bde 100644 --- a/src/drivers/imx/sdma.c +++ b/src/drivers/imx/sdma.c @@ -255,7 +255,11 @@ static int sdma_upload_context(struct dma_chan_data *chan) */ return sdma_run_c0(chan->dma, SDMA_CMD_C0_SET_DM, (uint32_t)pdata->ctx, SDMA_SRAM_CONTEXTS_BASE + + /* https://trac.cppcheck.net/ticket/10179 */ + /* cppcheck-suppress divideSizeof */ chan->index * sizeof(*pdata->ctx) / 4, + /* https://trac.cppcheck.net/ticket/10179 */ + /* cppcheck-suppress divideSizeof */ sizeof(*pdata->ctx) / 4); } @@ -272,6 +276,8 @@ static int sdma_upload_contexts_all(struct dma *dma) return sdma_run_c0(dma, SDMA_CMD_C0_SET_DM, (uint32_t)pdata->contexts, SDMA_SRAM_CONTEXTS_BASE, dma->plat_data.channels * + /* https://trac.cppcheck.net/ticket/10179 */ + /* cppcheck-suppress divideSizeof */ sizeof(*pdata->contexts) / 4); } @@ -288,6 +294,8 @@ static int sdma_download_contexts_all(struct dma *dma) ret = sdma_run_c0(dma, SDMA_CMD_C0_GET_DM, (uint32_t)pdata->contexts, SDMA_SRAM_CONTEXTS_BASE, dma->plat_data.channels * + /* https://trac.cppcheck.net/ticket/10179 */ + /* cppcheck-suppress divideSizeof */ sizeof(*pdata->contexts) / 4); dcache_invalidate_region(pdata->contexts, sizeof(*pdata->contexts)); From 3522723edc034afee26bd556560f0b77225277cf Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Fri, 19 Feb 2021 13:06:58 -0800 Subject: [PATCH 19/47] codec_adapter: don't error on free(NULL) libc doesn't return a type, so it just no-ops silently on null, lets to the same having this error makes walk back patterns more annoying Signed-off-by: Curtis Malainey --- src/audio/codec_adapter/codec/generic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/audio/codec_adapter/codec/generic.c b/src/audio/codec_adapter/codec/generic.c index 2f3904af91b1..8c1259f8805b 100644 --- a/src/audio/codec_adapter/codec/generic.c +++ b/src/audio/codec_adapter/codec/generic.c @@ -182,8 +182,7 @@ int codec_free_memory(struct comp_dev *dev, void *ptr) struct list_item *_mem_list; if (!ptr) { - comp_err(dev, "codec_free_memory: error: NULL pointer passed."); - return -EINVAL; + return 0; } /* Find which container keeps this memory */ list_for_item_safe(mem_list, _mem_list, &cd->codec.memory.mem_list) { From d4e13fe7602f83bf094d242ee43c4151a26276e0 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Fri, 19 Feb 2021 14:37:03 -0800 Subject: [PATCH 20/47] trace: remove unused code based on build The current version of the code effectively relies on the compiler to optimize out the loop, this both trusts the compiler, annoys cppcheck which also not being entirely clear to the reader. Solution is to use the compile switch to remove all relevant code. Signed-off-by: Curtis Malainey --- src/trace/trace.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/trace/trace.c b/src/trace/trace.c index b7b9d09ccf7c..e7a5053b6595 100644 --- a/src/trace/trace.c +++ b/src/trace/trace.c @@ -371,15 +371,12 @@ struct sof_ipc_trace_filter_elem *trace_filter_fill(struct sof_ipc_trace_filter_ /* update global components, which tr_ctx is stored inside special section */ static int trace_filter_update_global(int32_t log_level, uint32_t uuid_id) { + int cnt = 0; #if !defined(__ZEPHYR__) && !defined(CONFIG_LIBRARY) extern void *_trace_ctx_start; extern void *_trace_ctx_end; struct tr_ctx *ptr = (struct tr_ctx *)&_trace_ctx_start; struct tr_ctx *end = (struct tr_ctx *)&_trace_ctx_end; -#else - struct tr_ctx *ptr = NULL, *end = ptr; -#endif - int cnt = 0; /* iterate over global `tr_ctx` entries located in their own section */ while (ptr < end) { @@ -398,6 +395,7 @@ static int trace_filter_update_global(int32_t log_level, uint32_t uuid_id) } ++ptr; } +#endif return cnt; } From 9c2b205a7f501b1b5e9aba095fe108a026059903 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Fri, 19 Feb 2021 14:39:56 -0800 Subject: [PATCH 21/47] trace: suppress cppcheck comparison error Cppcheck check doesn't understand the relationship between trace section start and end so it is giving a false positive because it thinks they are two separate objects, not two pointers to the same region. Signed-off-by: Curtis Malainey --- src/trace/trace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/trace/trace.c b/src/trace/trace.c index e7a5053b6595..2afe926db34b 100644 --- a/src/trace/trace.c +++ b/src/trace/trace.c @@ -379,6 +379,7 @@ static int trace_filter_update_global(int32_t log_level, uint32_t uuid_id) struct tr_ctx *end = (struct tr_ctx *)&_trace_ctx_end; /* iterate over global `tr_ctx` entries located in their own section */ + /* cppcheck-suppress comparePointers */ while (ptr < end) { /* * when looking for specific uuid element, From b2dab66fbf105e8b7923db4d2ae1bd1a925f37f2 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Fri, 19 Feb 2021 14:48:53 -0800 Subject: [PATCH 22/47] math: don't use implicit types in fixed point math Cppcheck is complaining that we are running a 32bit int off the end. This shouldn't happen here in any arch. Looking at the math and comments, it looks like idx should be a 64 type or cast to a larger container before the bit shift. Therefore I am enforcing a strict type on it. Signed-off-by: Curtis Malainey --- src/math/trig.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/math/trig.c b/src/math/trig.c index fe325e13b21e..98602ceb0d5a 100644 --- a/src/math/trig.c +++ b/src/math/trig.c @@ -552,17 +552,17 @@ static inline int32_t sine_lookup(int idx) /* Compute fixed point sine with table lookup and interpolation */ int32_t sin_fixed(int32_t w) { - int idx; int32_t frac; int32_t s0; int32_t s1; int32_t delta; + int64_t idx; int64_t sine; int64_t idx_tmp; /* Q4.28 x Q12.20 -> Q16.48 */ idx_tmp = (int64_t)w * SINE_C_Q20; - idx = (int)(idx_tmp >> 48); /* Shift to Q0 */ + idx = (idx_tmp >> 48); /* Shift to Q0 */ idx_tmp = idx_tmp >> 17; /* Shift to Q16.31 */ idx_tmp = idx_tmp - (idx << 31); /* Get fraction */ frac = (int32_t)idx_tmp; /* Q1.31 */ From 0ae3fa5cabe3697cd938c3766f59a90d86f88daf Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Fri, 19 Feb 2021 14:53:35 -0800 Subject: [PATCH 23/47] math: clarify order of operations with ternary minor cppcheck style violation Signed-off-by: Curtis Malainey --- src/math/numbers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/math/numbers.c b/src/math/numbers.c index 92606aad0a6a..0a983b5f3e6a 100644 --- a/src/math/numbers.c +++ b/src/math/numbers.c @@ -170,7 +170,7 @@ uint32_t crc32(uint32_t base, const void *data, uint32_t bytes) cur = (crc ^ ((const uint8_t *)data)[i]) & 0xFF; for (j = 0; j < 8; ++j) - cur = cur & 1 ? (cur >> 1) ^ 0xEDB88320 : cur >> 1; + cur = (cur & 1) ? (cur >> 1) ^ 0xEDB88320 : cur >> 1; crc = cur ^ (crc >> 8); } From a861efb576b7201a32ac53b41654b1ce77d2b9dd Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Thu, 7 Jan 2021 14:42:54 -0800 Subject: [PATCH 24/47] codec_adapter: delete empty header if its unused, then its uneeded Signed-off-by: Curtis Malainey --- src/include/sof/audio/codec_adapter/codec/interfaces.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/include/sof/audio/codec_adapter/codec/interfaces.h diff --git a/src/include/sof/audio/codec_adapter/codec/interfaces.h b/src/include/sof/audio/codec_adapter/codec/interfaces.h deleted file mode 100644 index e69de29bb2d1..000000000000 From 71e02a9d841eab3e1667d4e0f2f1daabf075ae05 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Thu, 7 Jan 2021 14:56:07 -0800 Subject: [PATCH 25/47] codec_adapter: fix documentation for apply config Comment is incorrect. There are multiple cases when a config is pushed by userspace that will result in no callback. Signed-off-by: Curtis Malainey --- src/include/sof/audio/codec_adapter/codec/generic.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/include/sof/audio/codec_adapter/codec/generic.h b/src/include/sof/audio/codec_adapter/codec/generic.h index 6a7f804a6526..32b7f38346ad 100644 --- a/src/include/sof/audio/codec_adapter/codec/generic.h +++ b/src/include/sof/audio/codec_adapter/codec/generic.h @@ -57,7 +57,8 @@ struct codec_interface { int (*process)(struct comp_dev *dev); /** * Codec specific apply config procedure, called by codec_adapter every time - * new configuration has been loaded. + * a new RUNTIME configuration has been sent if the adapter has been + * prepared. This will not be called for SETUP cfg. */ int (*apply_config)(struct comp_dev *dev); /** From 7ba1e3716fbabaa86b93b87dadf8eb404e4d1767 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Thu, 4 Feb 2021 10:23:49 +0800 Subject: [PATCH 26/47] ll_schedule: rename last_tick to next_tick rename the last_tick to next_tick, which means the one already set to the timer, for more easy to understand. Signed-off-by: Keyon Jie --- src/include/sof/schedule/ll_schedule_domain.h | 2 +- src/schedule/dma_single_chan_domain.c | 6 ++--- src/schedule/ll_schedule.c | 22 +++++++++---------- src/schedule/timer_domain.c | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/include/sof/schedule/ll_schedule_domain.h b/src/include/sof/schedule/ll_schedule_domain.h index 11eb09f49f68..68bf165660d9 100644 --- a/src/include/sof/schedule/ll_schedule_domain.h +++ b/src/include/sof/schedule/ll_schedule_domain.h @@ -42,7 +42,7 @@ struct ll_schedule_domain_ops { }; struct ll_schedule_domain { - uint64_t last_tick; /**< timestamp of last run */ + uint64_t next_tick; /**< ticks just set for next run */ spinlock_t lock; /**< standard lock */ atomic_t total_num_tasks; /**< total number of registered tasks */ atomic_t num_clients; /**< number of registered cores */ diff --git a/src/schedule/dma_single_chan_domain.c b/src/schedule/dma_single_chan_domain.c index da72a30fba4d..d660d1f09bc1 100644 --- a/src/schedule/dma_single_chan_domain.c +++ b/src/schedule/dma_single_chan_domain.c @@ -459,7 +459,7 @@ static void dma_single_chan_domain_disable(struct ll_schedule_domain *domain, } /** - * \brief Calculates domain's last tick. + * \brief Calculates domain's next tick. * \param[in,out] domain Pointer to schedule domain. * \param[in] start Offset of last calculated tick. */ @@ -475,14 +475,14 @@ static void dma_single_chan_domain_set(struct ll_schedule_domain *domain, goto out; if (dma_domain->channel_changed) { - domain->last_tick = platform_timer_get_atomic(timer_get()); + domain->next_tick = platform_timer_get_atomic(timer_get()); dma_domain->channel_changed = false; } else { ticks = domain->ticks_per_ms * data->channel->period / 1000 + start; - domain->last_tick = domain->last_tick ? ticks : start; + domain->next_tick = domain->next_tick ? ticks : start; } out: diff --git a/src/schedule/ll_schedule.c b/src/schedule/ll_schedule.c index 36c90e546b0c..dce2df18ea60 100644 --- a/src/schedule/ll_schedule.c +++ b/src/schedule/ll_schedule.c @@ -80,7 +80,7 @@ static bool schedule_ll_is_pending(struct ll_schedule_data *sch) } static void schedule_ll_task_update_start(struct ll_schedule_data *sch, - struct task *task, uint64_t last_tick) + struct task *task, uint64_t next_tick) { struct ll_task_pdata *pdata = ll_sch_get_pdata(task); uint64_t next; @@ -90,11 +90,11 @@ static void schedule_ll_task_update_start(struct ll_schedule_data *sch, if (sch->domain->synchronous) task->start += next; else - task->start = next + last_tick; + task->start = next + next_tick; } static void schedule_ll_tasks_execute(struct ll_schedule_data *sch, - uint64_t last_tick) + uint64_t next_tick) { struct list_item *wlist; struct list_item *tlist; @@ -127,7 +127,7 @@ static void schedule_ll_tasks_execute(struct ll_schedule_data *sch, atomic_read(&sch->domain->total_num_tasks)); } else { /* update task's start time */ - schedule_ll_task_update_start(sch, task, last_tick); + schedule_ll_task_update_start(sch, task, next_tick); } } @@ -151,7 +151,7 @@ static void schedule_ll_clients_reschedule(struct ll_schedule_data *sch) { /* rearm only if there is work to do */ if (atomic_read(&sch->domain->total_num_tasks)) { - domain_set(sch->domain, sch->domain->last_tick); + domain_set(sch->domain, sch->domain->next_tick); schedule_ll_clients_enable(sch); } @@ -162,7 +162,7 @@ static void schedule_ll_tasks_run(void *data) { struct ll_schedule_data *sch = data; uint32_t num_clients = 0; - uint64_t last_tick; + uint64_t next_tick; uint32_t flags; domain_disable(sch->domain, cpu_get_id()); @@ -173,7 +173,7 @@ static void schedule_ll_tasks_run(void *data) sch->domain->enabled[cpu_get_id()] = false; - last_tick = sch->domain->last_tick; + next_tick = sch->domain->next_tick; /* clear domain only if all clients are done */ /* TODO: no need for atomic operations, @@ -194,7 +194,7 @@ static void schedule_ll_tasks_run(void *data) /* run tasks if there are any pending */ if (schedule_ll_is_pending(sch)) - schedule_ll_tasks_execute(sch, last_tick); + schedule_ll_tasks_execute(sch, next_tick); notifier_event(sch, NOTIFIER_ID_LL_POST_RUN, NOTIFIER_TARGET_CORE_LOCAL, NULL, 0); @@ -268,7 +268,7 @@ static void schedule_ll_domain_clear(struct ll_schedule_data *sch, count = atomic_sub(&sch->domain->total_num_tasks, 1); if (count == 1) { domain_clear(sch->domain); - sch->domain->last_tick = 0; + sch->domain->next_tick = 0; } count = atomic_sub(&sch->num_tasks, 1); @@ -412,7 +412,7 @@ static int schedule_ll_task(void *data, struct task *task, uint64_t start, if (sch->domain->synchronous) task->start += platform_timer_get_atomic(timer_get()); else - task->start += sch->domain->last_tick; + task->start += sch->domain->next_tick; platform_shared_commit(sch->domain, sizeof(*sch->domain)); @@ -513,7 +513,7 @@ static int reschedule_ll_task(void *data, struct task *task, uint64_t start) if (sch->domain->synchronous) time += platform_timer_get_atomic(timer_get()); else - time += sch->domain->last_tick; + time += sch->domain->next_tick; irq_local_disable(flags); diff --git a/src/schedule/timer_domain.c b/src/schedule/timer_domain.c index b42cb0c4cf26..1d6a22320ae8 100644 --- a/src/schedule/timer_domain.c +++ b/src/schedule/timer_domain.c @@ -238,7 +238,7 @@ static void timer_domain_set(struct ll_schedule_domain *domain, uint64_t start) #else uint64_t current = platform_timer_get_atomic(timer_domain->timer); uint64_t earliest_next = current + 1 + ZEPHYR_SCHED_COST; - uint64_t ticks_req = domain->last_tick ? start + ticks_tout : + uint64_t ticks_req = domain->next_tick ? start + ticks_tout : MAX(start, earliest_next); int ret, core = cpu_get_id(); uint64_t ticks_delta; @@ -283,7 +283,7 @@ static void timer_domain_set(struct ll_schedule_domain *domain, uint64_t start) timer_report_delay(timer_domain->timer->id, ticks_set - ticks_req); - domain->last_tick = ticks_set; + domain->next_tick = ticks_set; platform_shared_commit(timer_domain, sizeof(*timer_domain)); } From 0a176aa87cf67cd6cebb7d8ba9fd63d08300a06c Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Thu, 4 Feb 2021 10:44:12 +0800 Subject: [PATCH 27/47] timer_domain: refine the timer_domain_set() logic Do timer_domain refining as below: Use unified LL_TIMER_SET_OVERHEAD_TICKS=1000 which denote the max overhead that the timer_domain_set() will take, and remove the definition from each platforms. Don't add any overhead if no needed(e.g. if the start > current + overhead). This will help to schedule the task ASAP, and make the catching up (of the previous delay) possible. Signed-off-by: Keyon Jie --- src/include/sof/schedule/ll_schedule_domain.h | 3 +- src/platform/baytrail/platform.c | 3 +- src/platform/haswell/platform.c | 3 +- src/platform/imx8/platform.c | 3 +- src/platform/imx8m/platform.c | 3 +- src/platform/intel/cavs/platform.c | 3 +- src/schedule/timer_domain.c | 28 ++++++++++--------- 7 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/include/sof/schedule/ll_schedule_domain.h b/src/include/sof/schedule/ll_schedule_domain.h index 68bf165660d9..d7b41a17f209 100644 --- a/src/include/sof/schedule/ll_schedule_domain.h +++ b/src/include/sof/schedule/ll_schedule_domain.h @@ -165,8 +165,7 @@ static inline bool domain_is_pending(struct ll_schedule_domain *domain, return ret; } -struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk, - uint64_t timeout); +struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk); struct ll_schedule_domain *dma_multi_chan_domain_init(struct dma *dma_array, uint32_t num_dma, int clk, diff --git a/src/platform/baytrail/platform.c b/src/platform/baytrail/platform.c index c0e54fb3eefc..863b077af8bc 100644 --- a/src/platform/baytrail/platform.c +++ b/src/platform/baytrail/platform.c @@ -219,8 +219,7 @@ int platform_init(struct sof *sof) /* init low latency timer domain and scheduler */ sof->platform_timer_domain = - timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK, - CONFIG_SYSTICK_PERIOD); + timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK); scheduler_init_ll(sof->platform_timer_domain); /* init the system agent */ diff --git a/src/platform/haswell/platform.c b/src/platform/haswell/platform.c index 6bcd0e36819d..857a6e223a1b 100644 --- a/src/platform/haswell/platform.c +++ b/src/platform/haswell/platform.c @@ -192,8 +192,7 @@ int platform_init(struct sof *sof) /* init low latency timer domain and scheduler */ sof->platform_timer_domain = - timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK, - CONFIG_SYSTICK_PERIOD); + timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK); scheduler_init_ll(sof->platform_timer_domain); /* init the system agent */ diff --git a/src/platform/imx8/platform.c b/src/platform/imx8/platform.c index aa3cd0a68a41..da86a3179803 100644 --- a/src/platform/imx8/platform.c +++ b/src/platform/imx8/platform.c @@ -158,8 +158,7 @@ int platform_init(struct sof *sof) /* init low latency domains and schedulers */ sof->platform_timer_domain = - timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK, - CONFIG_SYSTICK_PERIOD); + timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK); scheduler_init_ll(sof->platform_timer_domain); platform_timer_start(sof->platform_timer); diff --git a/src/platform/imx8m/platform.c b/src/platform/imx8m/platform.c index e57fb84077ea..238a6ebc1b37 100644 --- a/src/platform/imx8m/platform.c +++ b/src/platform/imx8m/platform.c @@ -157,8 +157,7 @@ int platform_init(struct sof *sof) /* init low latency domains and schedulers */ sof->platform_timer_domain = - timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK, - CONFIG_SYSTICK_PERIOD); + timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK); scheduler_init_ll(sof->platform_timer_domain); platform_timer_start(sof->platform_timer); diff --git a/src/platform/intel/cavs/platform.c b/src/platform/intel/cavs/platform.c index 098deddf61d4..c5b5762c2731 100644 --- a/src/platform/intel/cavs/platform.c +++ b/src/platform/intel/cavs/platform.c @@ -386,8 +386,7 @@ int platform_init(struct sof *sof) /* init low latency timer domain and scheduler */ sof->platform_timer_domain = - timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK, - CONFIG_SYSTICK_PERIOD); + timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK); scheduler_init_ll(sof->platform_timer_domain); /* init the system agent */ diff --git a/src/schedule/timer_domain.c b/src/schedule/timer_domain.c index 1d6a22320ae8..9df53e9ca801 100644 --- a/src/schedule/timer_domain.c +++ b/src/schedule/timer_domain.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,8 @@ K_THREAD_STACK_DEFINE(ll_workq_stack3, ZEPHYR_LL_WORKQ_SIZE); #endif #endif +#define LL_TIMER_SET_OVERHEAD_TICKS 1000 /* overhead/delay to set the tick, in ticks */ + struct timer_domain { #ifdef __ZEPHYR__ struct k_work_q ll_workq[CONFIG_CORE_COUNT]; @@ -60,7 +63,7 @@ struct timer_domain { #endif struct timer *timer; void *arg[CONFIG_CORE_COUNT]; - uint64_t timeout; /* in microseconds */ + uint64_t timeout; /* in ticks */ }; #ifdef __ZEPHYR__ @@ -228,11 +231,13 @@ static void timer_domain_disable(struct ll_schedule_domain *domain, int core) static void timer_domain_set(struct ll_schedule_domain *domain, uint64_t start) { struct timer_domain *timer_domain = ll_sch_domain_get_pdata(domain); - uint64_t ticks_tout = domain->ticks_per_ms * timer_domain->timeout / - 1000; + uint64_t ticks_tout = timer_domain->timeout; uint64_t ticks_set; #ifndef __ZEPHYR__ - uint64_t ticks_req = start + ticks_tout; + uint64_t ticks_req; + + /* make sure to require for ticks later than tout from now */ + ticks_req = MAX(start, platform_timer_get_atomic(timer_domain->timer) + ticks_tout); ticks_set = platform_timer_set(timer_domain->timer, ticks_req); #else @@ -276,6 +281,10 @@ static void timer_domain_set(struct ll_schedule_domain *domain, uint64_t start) current - current % CYC_PER_TICK; #endif + tr_dbg(&ll_tr, "timer_domain_set(): ticks_set %u ticks_req %u current %u", + (unsigned int)ticks_set, (unsigned int)ticks_req, + (unsigned int)platform_timer_get_atomic(timer_get())); + /* Was timer set to the value we requested? If no it means some * delay occurred and we should report that in error log. */ @@ -305,24 +314,17 @@ static bool timer_domain_is_pending(struct ll_schedule_domain *domain, return task->start <= platform_timer_get_atomic(timer_get()); } -struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk, - uint64_t timeout) +struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk) { struct ll_schedule_domain *domain; struct timer_domain *timer_domain; - if (timeout <= UINT_MAX) - tr_info(&ll_tr, "timer_domain_init clk %d timeout %u", clk, - (unsigned int)timeout); - else - tr_info(&ll_tr, "timer_domain_init clk %d timeout > %u", clk, UINT_MAX); - domain = domain_init(SOF_SCHEDULE_LL_TIMER, clk, false, &timer_domain_ops); timer_domain = rzalloc(SOF_MEM_ZONE_SYS_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*timer_domain)); timer_domain->timer = timer; - timer_domain->timeout = timeout; + timer_domain->timeout = LL_TIMER_SET_OVERHEAD_TICKS; ll_sch_domain_set_pdata(domain, timer_domain); From 7102012c9a77d2f4ef018852f72898a20b370d16 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Thu, 4 Feb 2021 11:15:22 +0800 Subject: [PATCH 28/47] ll_schedule: refine the _domain_set/clear() logic Refine and simplify the domain_set/clear() part: 1. Use UINT64_MAX to denote that the domain is not set. 2. For _domain_set(), set only when needed. e.g. the first task over all cores being added, or a task asking for earlier timer being added. The _domain_set() logic is refined as below: a. For first task, set domain according to the required start, else b. for one shot task, set domain if it is earlier, else c. for earlier periodic task, try to make it cadence-aligned with the existed task, else d. for later periodic task, simply cover it by the coming interrupt. 3. For _domain_clear() logic, simplify to call it when the last client is freed. Signed-off-by: Keyon Jie --- src/include/sof/schedule/ll_schedule_domain.h | 9 +++ src/schedule/dma_single_chan_domain.c | 3 +- src/schedule/ll_schedule.c | 67 ++++++++++++------- 3 files changed, 52 insertions(+), 27 deletions(-) diff --git a/src/include/sof/schedule/ll_schedule_domain.h b/src/include/sof/schedule/ll_schedule_domain.h index d7b41a17f209..f113e09bae6b 100644 --- a/src/include/sof/schedule/ll_schedule_domain.h +++ b/src/include/sof/schedule/ll_schedule_domain.h @@ -84,6 +84,8 @@ static inline struct ll_schedule_domain *domain_init domain->full_sync = false; domain->ticks_per_ms = clock_ms_to_ticks(clk, 1); domain->ops = ops; + /* maximum value means no tick has been set to timer */ + domain->next_tick = UINT64_MAX; spinlock_init(&domain->lock); atomic_init(&domain->total_num_tasks, 0); @@ -135,19 +137,26 @@ static inline void domain_disable(struct ll_schedule_domain *domain, int core) platform_shared_commit(domain, sizeof(*domain)); } +/* configure the next interrupt for domain */ static inline void domain_set(struct ll_schedule_domain *domain, uint64_t start) { if (domain->ops->domain_set) domain->ops->domain_set(domain, start); + else + domain->next_tick = start; platform_shared_commit(domain, sizeof(*domain)); } +/* clear the interrupt for domain */ static inline void domain_clear(struct ll_schedule_domain *domain) { if (domain->ops->domain_clear) domain->ops->domain_clear(domain); + /* reset to denote no tick/interrupt is set */ + domain->next_tick = UINT64_MAX; + platform_shared_commit(domain, sizeof(*domain)); } diff --git a/src/schedule/dma_single_chan_domain.c b/src/schedule/dma_single_chan_domain.c index d660d1f09bc1..69abec97cea1 100644 --- a/src/schedule/dma_single_chan_domain.c +++ b/src/schedule/dma_single_chan_domain.c @@ -482,7 +482,8 @@ static void dma_single_chan_domain_set(struct ll_schedule_domain *domain, ticks = domain->ticks_per_ms * data->channel->period / 1000 + start; - domain->next_tick = domain->next_tick ? ticks : start; + domain->next_tick = domain->next_tick != UINT64_MAX ? + ticks : start; } out: diff --git a/src/schedule/ll_schedule.c b/src/schedule/ll_schedule.c index dce2df18ea60..95ee298cfcc0 100644 --- a/src/schedule/ll_schedule.c +++ b/src/schedule/ll_schedule.c @@ -213,10 +213,15 @@ static void schedule_ll_tasks_run(void *data) } static int schedule_ll_domain_set(struct ll_schedule_data *sch, - struct task *task, uint64_t period) + struct task *task, uint64_t start, + uint64_t period) { int core = cpu_get_id(); unsigned int total; + uint64_t task_start_us; + uint64_t task_start_ticks; + uint64_t task_start; + uint64_t offset; bool registered; int ret; @@ -230,16 +235,41 @@ static int schedule_ll_domain_set(struct ll_schedule_data *sch, spin_lock(&sch->domain->lock); + tr_dbg(&ll_tr, "task->start %u next_tick %u", + (unsigned int)task->start, + (unsigned int)sch->domain->next_tick); + + task_start_us = period ? period : start; + task_start_ticks = sch->domain->ticks_per_ms * task_start_us / 1000; + task_start = task_start_ticks + platform_timer_get_atomic(timer_get()); + + if (sch->domain->next_tick == UINT64_MAX) { + /* first task, set domain */ + domain_set(sch->domain, task_start); + task->start = sch->domain->next_tick; + } else if (!period) { + /* one shot task, set domain if it is earlier */ + task->start = task_start; + if (task->start < sch->domain->next_tick) + domain_set(sch->domain, task_start); + } else if (task_start < sch->domain->next_tick) { + /* earlier periodic task, try to make it cadence-aligned with the existed task */ + offset = (sch->domain->next_tick - task_start) % + (sch->domain->ticks_per_ms * period / 1000); + task_start = task_start - task_start_ticks + offset; + domain_set(sch->domain, task_start); + task->start = sch->domain->next_tick; + } else { + /* later periodic task, simplify and cover it by the coming interrupt */ + task->start = sch->domain->next_tick; + } + registered = sch->domain->registered[core]; total = atomic_add(&sch->num_tasks, 1); if (total == 0) sch->domain->registered[core] = true; total = atomic_add(&sch->domain->total_num_tasks, 1); - if (total == 0) - /* First task in domain over all cores: actiivate it */ - domain_set(sch->domain, platform_timer_get_atomic(timer_get())); - if (total == 0 || !registered) { /* First task on core: count and enable it */ atomic_add(&sch->domain->num_clients, 1); @@ -247,6 +277,7 @@ static int schedule_ll_domain_set(struct ll_schedule_data *sch, sch->domain->enabled[core] = true; } + tr_info(&ll_tr, "new added task->start %u", (unsigned int)task->start); tr_info(&ll_tr, "num_tasks %d total_num_tasks %d", atomic_read(&sch->num_tasks), atomic_read(&sch->domain->total_num_tasks)); @@ -265,24 +296,15 @@ static void schedule_ll_domain_clear(struct ll_schedule_data *sch, spin_lock(&sch->domain->lock); - count = atomic_sub(&sch->domain->total_num_tasks, 1); - if (count == 1) { - domain_clear(sch->domain); - sch->domain->next_tick = 0; - } + atomic_sub(&sch->domain->total_num_tasks, 1); count = atomic_sub(&sch->num_tasks, 1); if (count == 1) { sch->domain->registered[cpu_get_id()] = false; - /* reschedule if we are the last client */ - if (atomic_read(&sch->domain->num_clients)) { - count = atomic_sub(&sch->domain->num_clients, 1); - if (count == 1) { - domain_clear(sch->domain); - schedule_ll_clients_reschedule(sch); - } - } + count = atomic_sub(&sch->domain->num_clients, 1); + if (count == 1) + domain_clear(sch->domain); } tr_info(&ll_tr, "num_tasks %d total_num_tasks %d", @@ -401,19 +423,12 @@ static int schedule_ll_task(void *data, struct task *task, uint64_t start, schedule_ll_task_insert(task, &sch->tasks); /* set schedule domain */ - ret = schedule_ll_domain_set(sch, task, period); + ret = schedule_ll_domain_set(sch, task, start, period); if (ret < 0) { list_item_del(&task->list); goto out; } - task->start = sch->domain->ticks_per_ms * start / 1000; - - if (sch->domain->synchronous) - task->start += platform_timer_get_atomic(timer_get()); - else - task->start += sch->domain->next_tick; - platform_shared_commit(sch->domain, sizeof(*sch->domain)); out: From a5752888354bb10c04a329a00b743e025db30146 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Thu, 4 Feb 2021 13:08:54 +0800 Subject: [PATCH 29/47] ll_schedule: _tasks_run() refining At interrupt handling & tasks_run(): run each pending task of the core, e.g. for period tasks: previously: update task->start based on last_tick(asynchronized), if the last_tick was delayed, the delay will be accumulated to the subsequent periods! new: update task->start based on last task->start, to try to make the task's running follow the pipeline requirement as more as possible. Add lock/unlock for domain accessing and updating while keep task can run simultaneously on multiple cores. Signed-off-by: Keyon Jie --- src/schedule/ll_schedule.c | 40 ++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/schedule/ll_schedule.c b/src/schedule/ll_schedule.c index 95ee298cfcc0..4547b0a0a7d3 100644 --- a/src/schedule/ll_schedule.c +++ b/src/schedule/ll_schedule.c @@ -62,6 +62,8 @@ static bool schedule_ll_is_pending(struct ll_schedule_data *sch) uint32_t pending_count = 0; struct comp_dev *sched_comp; + spin_lock(&sch->domain->lock); + do { sched_comp = NULL; @@ -76,25 +78,23 @@ static bool schedule_ll_is_pending(struct ll_schedule_data *sch) } } while (sched_comp); + spin_unlock(&sch->domain->lock); + return pending_count > 0; } static void schedule_ll_task_update_start(struct ll_schedule_data *sch, - struct task *task, uint64_t next_tick) + struct task *task) { struct ll_task_pdata *pdata = ll_sch_get_pdata(task); uint64_t next; next = sch->domain->ticks_per_ms * pdata->period / 1000; - if (sch->domain->synchronous) - task->start += next; - else - task->start = next + next_tick; + task->start += next; } -static void schedule_ll_tasks_execute(struct ll_schedule_data *sch, - uint64_t next_tick) +static void schedule_ll_tasks_execute(struct ll_schedule_data *sch) { struct list_item *wlist; struct list_item *tlist; @@ -106,12 +106,15 @@ static void schedule_ll_tasks_execute(struct ll_schedule_data *sch, list_for_item_safe(wlist, tlist, &sch->tasks) { task = container_of(wlist, struct task, list); - /* run task if its pending and remove from the list */ if (task->state != SOF_TASK_STATE_PENDING) continue; + tr_dbg(&ll_tr, "task %p %pU being started...", task, task->uid); + task->state = task_run(task); + spin_lock(&sch->domain->lock); + /* do we need to reschedule this task */ if (task->state == SOF_TASK_STATE_COMPLETED) { list_item_del(&task->list); @@ -127,11 +130,16 @@ static void schedule_ll_tasks_execute(struct ll_schedule_data *sch, atomic_read(&sch->domain->total_num_tasks)); } else { /* update task's start time */ - schedule_ll_task_update_start(sch, task, next_tick); + schedule_ll_task_update_start(sch, task); + tr_dbg(&ll_tr, "task %p uid %pU finished, next period ticks %u, domain->next_tick %u", + task, task->uid, (uint32_t)task->start, + (uint32_t)sch->domain->next_tick); } - } - platform_shared_commit(sch->domain, sizeof(*sch->domain)); + platform_shared_commit(sch->domain, sizeof(*sch->domain)); + + spin_unlock(&sch->domain->lock); + } } static void schedule_ll_clients_enable(struct ll_schedule_data *sch) @@ -162,9 +170,13 @@ static void schedule_ll_tasks_run(void *data) { struct ll_schedule_data *sch = data; uint32_t num_clients = 0; - uint64_t next_tick; uint32_t flags; + tr_dbg(&ll_tr, "timer interrupt on core %d, at %u, previous next_tick %u", + cpu_get_id(), + (unsigned int)platform_timer_get_atomic(timer_get()), + (unsigned int)sch->domain->next_tick); + domain_disable(sch->domain, cpu_get_id()); irq_local_disable(flags); @@ -173,8 +185,6 @@ static void schedule_ll_tasks_run(void *data) sch->domain->enabled[cpu_get_id()] = false; - next_tick = sch->domain->next_tick; - /* clear domain only if all clients are done */ /* TODO: no need for atomic operations, * already protected by spin_lock @@ -194,7 +204,7 @@ static void schedule_ll_tasks_run(void *data) /* run tasks if there are any pending */ if (schedule_ll_is_pending(sch)) - schedule_ll_tasks_execute(sch, next_tick); + schedule_ll_tasks_execute(sch); notifier_event(sch, NOTIFIER_ID_LL_POST_RUN, NOTIFIER_TARGET_CORE_LOCAL, NULL, 0); From 71faa3e2d5dc17d312f4898464ab0a32c5d0b2f1 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Thu, 4 Feb 2021 13:30:10 +0800 Subject: [PATCH 30/47] ll_schedule: reschedule logic refining Reschedule once interrupt is handled by all cores(clients) according to the earlist task of the list, and enable interrupt on cores that have tasks to run. Signed-off-by: Keyon Jie --- src/schedule/ll_schedule.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/schedule/ll_schedule.c b/src/schedule/ll_schedule.c index 4547b0a0a7d3..ac72a810ef90 100644 --- a/src/schedule/ll_schedule.c +++ b/src/schedule/ll_schedule.c @@ -157,10 +157,27 @@ static void schedule_ll_clients_enable(struct ll_schedule_data *sch) static void schedule_ll_clients_reschedule(struct ll_schedule_data *sch) { + struct list_item *wlist; + struct list_item *tlist; + struct task *task, *task_take; + uint64_t next_tick = UINT64_MAX; + /* rearm only if there is work to do */ if (atomic_read(&sch->domain->total_num_tasks)) { - domain_set(sch->domain, sch->domain->next_tick); - schedule_ll_clients_enable(sch); + /* traverse to set timer according to the earliest task */ + list_for_item_safe(wlist, tlist, &sch->tasks) { + task = container_of(wlist, struct task, list); + + /* update to use the earlier tick */ + if (task->start < next_tick) { + next_tick = task->start; + task_take = task; + } + } + + tr_dbg(&ll_tr, "schedule_ll_clients_reschedule next_tick %u task_take %p", + (unsigned int)next_tick, task_take); + domain_set(sch->domain, next_tick); } platform_shared_commit(sch->domain, sizeof(*sch->domain)); @@ -213,9 +230,11 @@ static void schedule_ll_tasks_run(void *data) spin_lock(&sch->domain->lock); - /* reschedule only if all clients are done */ + schedule_ll_clients_reschedule(sch); + + /* re-enable domain only if all clients are done */ if (!num_clients) - schedule_ll_clients_reschedule(sch); + schedule_ll_clients_enable(sch); spin_unlock(&sch->domain->lock); @@ -535,10 +554,7 @@ static int reschedule_ll_task(void *data, struct task *task, uint64_t start) time = sch->domain->ticks_per_ms * start / 1000; - if (sch->domain->synchronous) - time += platform_timer_get_atomic(timer_get()); - else - time += sch->domain->next_tick; + time += platform_timer_get_atomic(timer_get()); irq_local_disable(flags); From 622f1c8e342200641c63bf6b3c1ba9351efc94f8 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Thu, 25 Feb 2021 11:20:09 +0800 Subject: [PATCH 31/47] Kconfig: update the description of SYSTICK_PERIOD The SYSTICK_PERIOD is used for system agent only now, remove the schedule part from the description. Signed-off-by: Keyon Jie --- src/platform/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/platform/Kconfig b/src/platform/Kconfig index 071a0f645484..9f60f6e09d88 100644 --- a/src/platform/Kconfig +++ b/src/platform/Kconfig @@ -375,8 +375,7 @@ config SYSTICK_PERIOD int "System tick period in microseconds" default 1000 help - Defines platform system tick period. It is used to - drive timer based low latency scheduler and also + Defines platform system tick period. It is used as a timeout check value for system agent. Value should be provided in microseconds. From dde4ef6e11ce1d7642a1d13e8c331685d8efc4f2 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Tue, 23 Feb 2021 14:27:00 +0800 Subject: [PATCH 32/47] cavs: clk: do TGL specific HW recommended flow unconditionally We need to follow TGL specific HW recommended flow to get/put PM_RUNTIME_DSP, even for not release_unused clocks requirement. This will address the PM_GATE IPC failure issue: https://github.com/thesofproject/sof/issues/3823 Signed-off-by: Keyon Jie --- src/platform/intel/cavs/lib/clk.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/platform/intel/cavs/lib/clk.c b/src/platform/intel/cavs/lib/clk.c index 7ab3e337fbf9..956e2923ac64 100644 --- a/src/platform/intel/cavs/lib/clk.c +++ b/src/platform/intel/cavs/lib/clk.c @@ -57,12 +57,13 @@ static inline void select_cpu_clock_hw(int freq_idx, bool release_unused) io_reg_write(SHIM_BASE + SHIM_CLKCTL, (io_reg_read(SHIM_BASE + SHIM_CLKCTL) & ~SHIM_CLKCTL_OSC_REQUEST_MASK) | enc); + } + #if CONFIG_TIGERLAKE - /* TGL specific HW recommended flow */ - if (freq_idx != CPU_HPRO_FREQ_IDX) - pm_runtime_put(PM_RUNTIME_DSP, PWRD_BY_HPRO | (CONFIG_CORE_COUNT - 1)); + /* TGL specific HW recommended flow */ + if (freq_idx != CPU_HPRO_FREQ_IDX) + pm_runtime_put(PM_RUNTIME_DSP, PWRD_BY_HPRO | (CONFIG_CORE_COUNT - 1)); #endif - } #if CONFIG_DSP_RESIDENCY_COUNTERS if (get_dsp_r_state() != r2_r_state) { From 8fe313a501a1c1396e96076bd1616c7ee42e706a Mon Sep 17 00:00:00 2001 From: Oleksandr Strelchenko Date: Mon, 1 Mar 2021 21:32:40 -0800 Subject: [PATCH 33/47] fix norm_int32 implementation New implementation does not rely on left shift of signed value and has no code duplication. Output is the same as original. found by cppcheck Signed-off-by: Oleksandr Strelchenko --- src/math/numbers.c | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/src/math/numbers.c b/src/math/numbers.c index 0a983b5f3e6a..0233bfd93187 100644 --- a/src/math/numbers.c +++ b/src/math/numbers.c @@ -130,28 +130,16 @@ int32_t find_max_abs_int32(int32_t vec[], int vec_length) */ int norm_int32(int32_t val) { - int s; - int32_t n; - - if (!val) - return 31; - - if (val > 0) { - n = val << 1; - s = 0; - while (n > 0) { - n = n << 1; - s++; - } - } else { - n = val << 1; - s = 0; - while (n < 0) { - n = n << 1; - s++; - } - } - return s; + int c = 0; + + /* count number of bits c that val can be right-shifted arithmetically + * until there is -1 (if val is negative) or 0 (if val is positive) + * norm of val will be 31-c + */ + for (; val != -1 && val != 0; c++) + val >>= 1; + + return 31 - c; } /** From 386871d5b1fe54acfe14bae0060e2ec8aefd9704 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 4 Nov 2020 21:06:04 -0800 Subject: [PATCH 34/47] ipc: fix logic for buffer free A buffer should be prevented from being freed only if both the sink and the source widgets are active. In the case of dynamic pipeline loading, a buffer belonging to a pipeline will need to freed when that pipeline is no longer active but the other end of the buffer might still be active. So, change the logic to check if both the sink and source widget states are invalid to prevent the buffer from being freed. Also make sure that the buffer is disconnected from the active comp before it is freed. Signed-off-by: Ranjani Sridharan --- src/audio/pipeline.c | 15 ++++++++++++++ src/include/sof/audio/pipeline.h | 3 ++- src/ipc/ipc.c | 34 ++++++++++++++++++++++++++++---- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c index f3f06b3bccd0..81c0a4d799e3 100644 --- a/src/audio/pipeline.c +++ b/src/audio/pipeline.c @@ -136,6 +136,21 @@ int pipeline_connect(struct comp_dev *comp, struct comp_buffer *buffer, return 0; } +void pipeline_disconnect(struct comp_dev *comp, struct comp_buffer *buffer, int dir) +{ + uint32_t flags; + + if (dir == PPL_CONN_DIR_COMP_TO_BUFFER) + comp_info(comp, "disconnect buffer %d as sink", buffer->id); + else + comp_info(comp, "disconnect buffer %d as source", buffer->id); + + irq_local_disable(flags); + list_item_del(buffer_comp_list(buffer, dir)); + comp_writeback(comp); + irq_local_enable(flags); +} + struct pipeline_walk_context { int (*comp_func)(struct comp_dev *, struct comp_buffer *, struct pipeline_walk_context *, int); diff --git a/src/include/sof/audio/pipeline.h b/src/include/sof/audio/pipeline.h index 58d2f8aba20e..730e5d38f160 100644 --- a/src/include/sof/audio/pipeline.h +++ b/src/include/sof/audio/pipeline.h @@ -221,9 +221,10 @@ struct pipeline *pipeline_new(struct sof_ipc_pipe_new *pipe_desc, struct comp_dev *cd); int pipeline_free(struct pipeline *p); -/* insert component in pipeline */ +/* insert/remove component in pipeline */ int pipeline_connect(struct comp_dev *comp, struct comp_buffer *buffer, int dir); +void pipeline_disconnect(struct comp_dev *comp, struct comp_buffer *buffer, int dir); /* complete the pipeline */ int pipeline_complete(struct pipeline *p, struct comp_dev *source, diff --git a/src/ipc/ipc.c b/src/ipc/ipc.c index 35aefb45c6fb..16cea90be793 100644 --- a/src/ipc/ipc.c +++ b/src/ipc/ipc.c @@ -291,6 +291,9 @@ int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id) struct ipc_comp_dev *ibd; struct ipc_comp_dev *icd; struct list_item *clist; + struct comp_dev *sink = NULL, *source = NULL; + bool sink_active = false; + bool source_active = false; /* check whether buffer exists */ ibd = ipc_get_comp_by_id(ipc, buffer_id); @@ -309,13 +312,36 @@ int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id) /* check comp state if sink and source are valid */ if (ibd->cb->sink == icd->cd && - ibd->cb->sink->state != COMP_STATE_READY) - return -EINVAL; + ibd->cb->sink->state != COMP_STATE_READY) { + sink = ibd->cb->sink; + sink_active = true; + } + if (ibd->cb->source == icd->cd && - ibd->cb->source->state != COMP_STATE_READY) - return -EINVAL; + ibd->cb->source->state != COMP_STATE_READY) { + source = ibd->cb->source; + source_active = true; + } } + /* + * A buffer could be connected to 2 different pipelines. When one pipeline is freed, the + * buffer comp that belongs in this pipeline will need to be freed even when the other + * pipeline that the buffer is connected to is active. Check if both ends are active before + * freeing the buffer. + */ + if (sink_active && source_active) + return -EINVAL; + + /* + * Disconnect the buffer from the active component before freeing it. + */ + if (sink) + pipeline_disconnect(sink, ibd->cb, PPL_CONN_DIR_BUFFER_TO_COMP); + + if (source) + pipeline_disconnect(source, ibd->cb, PPL_CONN_DIR_COMP_TO_BUFFER); + /* free buffer and remove from list */ buffer_free(ibd->cb); list_item_del(&ibd->list); From 9b88fdf446ffd0a49be05d6a3b4488990f80ba97 Mon Sep 17 00:00:00 2001 From: Jaska Uimonen Date: Wed, 3 Mar 2021 16:03:20 +0200 Subject: [PATCH 35/47] host: fix buffer size alignment In buffer_size calculation period_bytes should be aligned with dma before multiplying with period_count. This is an issue for example when period_bytes could be smaller than the dma alignment size like with 8khz 16 bit mono stream. Signed-off-by: Jaska Uimonen --- src/audio/host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/host.c b/src/audio/host.c index 5c5ca53d80c6..f42b2cd4338a 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -721,7 +721,7 @@ static int host_params(struct comp_dev *dev, } /* calculate DMA buffer size */ - buffer_size = ALIGN_UP(period_count * period_bytes, align); + buffer_size = ALIGN_UP(period_bytes, align) * period_count; /* alloc DMA buffer or change its size if exists */ if (hd->dma_buffer) { From 1ff0e813287f53cb98eaf646abc6586df7497196 Mon Sep 17 00:00:00 2001 From: Oleksandr Strelchenko Date: Tue, 9 Feb 2021 13:41:22 -0800 Subject: [PATCH 36/47] audio: codec_adapter: Waves custom codec added codec_adapter API implementation for Waves MaxxEffect API Signed-off-by: Oleksandr Strelchenko --- src/audio/codec_adapter/CMakeLists.txt | 6 + src/audio/codec_adapter/Kconfig | 9 + src/audio/codec_adapter/codec/waves.c | 746 ++++++++++++++++++ .../sof/audio/codec_adapter/codec/waves.h | 17 + .../sof/audio/codec_adapter/interfaces.h | 17 + src/include/sof/debug/debug.h | 38 + 6 files changed, 833 insertions(+) create mode 100644 src/audio/codec_adapter/codec/waves.c create mode 100644 src/include/sof/audio/codec_adapter/codec/waves.h diff --git a/src/audio/codec_adapter/CMakeLists.txt b/src/audio/codec_adapter/CMakeLists.txt index b1200b797002..c4963dc844f3 100644 --- a/src/audio/codec_adapter/CMakeLists.txt +++ b/src/audio/codec_adapter/CMakeLists.txt @@ -1,6 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause add_local_sources(sof codec_adapter.c codec/generic.c) + if(CONFIG_CADENCE_CODEC) add_local_sources(sof codec/cadence.c) endif() @@ -8,3 +9,8 @@ endif() if(CONFIG_DUMMY_CODEC) add_local_sources(sof codec/dummy.c) endif() + +if(CONFIG_WAVES_CODEC) +add_local_sources(sof codec/waves.c) +sof_add_static_library(MaxxChrome ${CMAKE_CURRENT_LIST_DIR}/lib/release/libMaxxChrome.a) +endif() diff --git a/src/audio/codec_adapter/Kconfig b/src/audio/codec_adapter/Kconfig index 6d0c6cb8969b..86cb19e5733d 100644 --- a/src/audio/codec_adapter/Kconfig +++ b/src/audio/codec_adapter/Kconfig @@ -18,4 +18,13 @@ menu "Codec Adapter codecs" Select for a dummy API codec implementation. This will cause codec adapter component to include header files specific to DUMMY base codecs. + + config WAVES_CODEC + bool "Waves codec" + default n + help + Select to include Waves codec. Waves codec implements MaxxEffect API. + API definition together with pre-compiled library is shared by Waves Audio Ltd. + If library is not provided will result in compilation error. + For more information, contact consumer@waves.com. endmenu diff --git a/src/audio/codec_adapter/codec/waves.c b/src/audio/codec_adapter/codec/waves.c new file mode 100644 index 000000000000..497c81d9c071 --- /dev/null +++ b/src/audio/codec_adapter/codec/waves.c @@ -0,0 +1,746 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2020 Waves Audio Ltd. All rights reserved. +// +// Author: Oleksandr Strelchenko +// +#include +#include +#include +#include + +#include "MaxxEffect/MaxxEffect.h" +#include "MaxxEffect/MaxxStream.h" +#include "MaxxEffect/MaxxStatus.h" +#include "MaxxEffect/Initialize/MaxxEffect_Initialize.h" +#include "MaxxEffect/Process/MaxxEffect_Process.h" +#include "MaxxEffect/Process/MaxxEffect_Reset.h" +#include "MaxxEffect/Control/RPC/MaxxEffect_RPC_Server.h" +#include "MaxxEffect/Control/Direct/MaxxEffect_Revision.h" + +#define MAX_CONFIG_SIZE_BYTES (8192) +#define NUM_IO_STREAMS (1) + +struct waves_codec_data { + uint32_t sample_rate; + uint32_t buffer_bytes; + uint32_t buffer_samples; + uint32_t sample_size_in_bytes; + uint64_t reserved; + + MaxxEffect_t *effect; + uint32_t effect_size; + MaxxStreamFormat_t i_format; + MaxxStreamFormat_t o_format; + MaxxStream_t i_stream; + MaxxStream_t o_stream; + MaxxBuffer_t i_buffer; + MaxxBuffer_t o_buffer; + uint32_t response_max_bytes; + uint32_t request_max_bytes; + void *response; +}; + +enum waves_codec_params { + PARAM_NOP = 0, + PARAM_MESSAGE = 1, + PARAM_REVISION = 2 +}; + +/* convert MaxxBuffer_Format_t to number of bytes it requires */ +static int32_t sample_format_convert_to_bytes(MaxxBuffer_Format_t format) +{ + int32_t res; + + switch (format) { + case MAXX_BUFFER_FORMAT_Q1_15: + res = sizeof(uint16_t); + break; + case MAXX_BUFFER_FORMAT_Q1_23: + res = 3; /* 3 bytes */ + break; + case MAXX_BUFFER_FORMAT_Q9_23: + COMPILER_FALLTHROUGH + case MAXX_BUFFER_FORMAT_Q1_31: + COMPILER_FALLTHROUGH + case MAXX_BUFFER_FORMAT_Q5_27: + res = sizeof(uint32_t); + break; + case MAXX_BUFFER_FORMAT_FLOAT: + res = sizeof(float); + break; + default: + res = -EINVAL; + break; + } + return res; +} + +/* convert enum sof_ipc_frame to MaxxBuffer_Format_t */ +static MaxxBuffer_Format_t format_convert_sof_to_me(enum sof_ipc_frame format) +{ + MaxxBuffer_Format_t res; + + switch (format) { + case SOF_IPC_FRAME_S16_LE: + res = MAXX_BUFFER_FORMAT_Q1_15; + break; + case SOF_IPC_FRAME_S24_4LE: + res = MAXX_BUFFER_FORMAT_Q9_23; + break; + case SOF_IPC_FRAME_S32_LE: + res = MAXX_BUFFER_FORMAT_Q1_31; + break; + case SOF_IPC_FRAME_FLOAT: + res = MAXX_BUFFER_FORMAT_FLOAT; + break; + default: + res = -EINVAL; + break; + } + return res; +} + +/* convert sof frame format to MaxxBuffer_Layout_t */ +static MaxxBuffer_Layout_t layout_convert_sof_to_me(uint32_t layout) +{ + MaxxBuffer_Layout_t res; + + switch (layout) { + case SOF_IPC_BUFFER_INTERLEAVED: + res = MAXX_BUFFER_LAYOUT_INTERLEAVED; + break; + case SOF_IPC_BUFFER_NONINTERLEAVED: + res = MAXX_BUFFER_LAYOUT_DEINTERLEAVED; + break; + default: + res = -EINVAL; + break; + } + return res; +} + +/* check if sample format supported by codec */ +static bool format_is_supported(enum sof_ipc_frame format) +{ + bool supported; + + switch (format) { + case SOF_IPC_FRAME_S16_LE: + COMPILER_FALLTHROUGH + case SOF_IPC_FRAME_S24_4LE: + COMPILER_FALLTHROUGH + case SOF_IPC_FRAME_S32_LE: + supported = true; + break; + case SOF_IPC_FRAME_FLOAT: + COMPILER_FALLTHROUGH + default: + supported = false; + break; + } + return supported; +} + +/* check if buffer layout supported by codec */ +static bool layout_is_supported(uint32_t layout) +{ + bool supported; + + switch (layout) { + case SOF_IPC_BUFFER_INTERLEAVED: + supported = true; + break; + case SOF_IPC_BUFFER_NONINTERLEAVED: + COMPILER_FALLTHROUGH + default: + supported = false; + break; + } + return supported; +} + +/* check if sample rate supported by codec */ +static bool rate_is_supported(uint32_t rate) +{ + bool supported; + + switch (rate) { + case 44100: + COMPILER_FALLTHROUGH + case 48000: + supported = true; + break; + default: + supported = false; + break; + } + return supported; +} + +/* allocate memory for MaxxEffect object */ +static int waves_effect_allocate(struct comp_dev *dev) +{ + struct codec_data *codec = comp_get_codec(dev); + struct waves_codec_data *waves_codec = codec->private; + MaxxStatus_t status; + + comp_dbg(dev, "waves_effect_allocate() start"); + + status = MaxxEffect_GetEffectSize(&waves_codec->effect_size); + if (status) { + comp_err(dev, "waves_effect_allocate() MaxxEffect_GetEffectSize returned %d", + status); + return -EINVAL; + } + + waves_codec->effect = (MaxxEffect_t *)codec_allocate_memory(dev, + waves_codec->effect_size, 16); + + if (!waves_codec->effect) { + comp_err(dev, "waves_effect_allocate() failed to allocate %d bytes for effect", + waves_codec->effect_size); + return -ENOMEM; + } + + comp_info(dev, "waves_codec_init() allocated %d bytes for effect", + waves_codec->effect_size); + + comp_dbg(dev, "waves_codec_init() done"); + return 0; +} + +/* checks if sink/source parameters fit MaxxEffect */ +static int waves_effect_check(struct comp_dev *dev) +{ + struct comp_data *component = comp_get_drvdata(dev); + const struct audio_stream *src_fmt = &component->ca_source->stream; + const struct audio_stream *snk_fmt = &component->ca_sink->stream; + + comp_dbg(dev, "waves_effect_check() start"); + + /* todo use fallback to comp_verify_params when ready */ + + /* resampling not supported */ + if (src_fmt->rate != snk_fmt->rate) { + comp_err(dev, "waves_effect_check() source %d sink %d rate mismatch", + src_fmt->rate, snk_fmt->rate); + return -EINVAL; + } + + /* upmix/downmix not supported */ + if (src_fmt->channels != snk_fmt->channels) { + comp_err(dev, "waves_effect_check() source %d sink %d channels mismatch", + src_fmt->channels, snk_fmt->channels); + return -EINVAL; + } + + /* different frame format not supported */ + if (src_fmt->frame_fmt != snk_fmt->frame_fmt) { + comp_err(dev, "waves_effect_check() source %d sink %d sample format mismatch", + src_fmt->frame_fmt, snk_fmt->frame_fmt); + return -EINVAL; + } + + /* different interleaving is not supported */ + if (component->ca_source->buffer_fmt != component->ca_sink->buffer_fmt) { + comp_err(dev, "waves_effect_check() source %d sink %d buffer format mismatch"); + return -EINVAL; + } + + if (!format_is_supported(src_fmt->frame_fmt)) { + comp_err(dev, "waves_effect_check() float samples not supported"); + return -EINVAL; + } + + if (!layout_is_supported(component->ca_source->buffer_fmt)) { + comp_err(dev, "waves_effect_check() non interleaved format not supported"); + return -EINVAL; + } + + if (!rate_is_supported(src_fmt->rate)) { + comp_err(dev, "waves_effect_check() rate %d not supported", src_fmt->rate); + return -EINVAL; + } + + if (src_fmt->channels != 2) { + comp_err(dev, "waves_effect_check() channels %d not supported", src_fmt->channels); + return -EINVAL; + } + + comp_dbg(dev, "waves_effect_check() done"); + return 0; +} + +/* initializes MaxxEffect based on stream parameters */ +static int waves_effect_init(struct comp_dev *dev) +{ + struct codec_data *codec = comp_get_codec(dev); + struct waves_codec_data *waves_codec = codec->private; + struct comp_data *component = comp_get_drvdata(dev); + + const struct audio_stream *src_fmt = &component->ca_source->stream; + + MaxxStatus_t status; + MaxxBuffer_Format_t sample_format; + MaxxBuffer_Layout_t buffer_format; + int32_t sample_bytes; + MaxxStreamFormat_t *i_formats[NUM_IO_STREAMS] = { &waves_codec->i_format }; + MaxxStreamFormat_t *o_formats[NUM_IO_STREAMS] = { &waves_codec->o_format }; + + comp_dbg(dev, "waves_effect_init() start"); + + sample_format = format_convert_sof_to_me(src_fmt->frame_fmt); + if (sample_format < 0) { + comp_err(dev, "waves_effect_init() sof sample format %d not supported", + src_fmt->frame_fmt); + return -EINVAL; + } + + buffer_format = layout_convert_sof_to_me(component->ca_source->buffer_fmt); + if (buffer_format < 0) { + comp_err(dev, "waves_effect_init() sof buffer format %d not supported", + component->ca_source->buffer_fmt); + return -EINVAL; + } + + sample_bytes = sample_format_convert_to_bytes(sample_format); + if (sample_bytes < 0) { + comp_err(dev, "waves_effect_init() sample_format %d not supported", + sample_format); + return -EINVAL; + } + + waves_codec->request_max_bytes = 0; + waves_codec->response_max_bytes = 0; + waves_codec->response = 0; + waves_codec->i_buffer = 0; + waves_codec->o_buffer = 0; + + waves_codec->i_format.sampleRate = src_fmt->rate; + waves_codec->i_format.numChannels = src_fmt->channels; + waves_codec->i_format.samplesFormat = sample_format; + waves_codec->i_format.samplesLayout = buffer_format; + + waves_codec->o_format = waves_codec->i_format; + + waves_codec->sample_size_in_bytes = sample_bytes; + waves_codec->buffer_samples = (src_fmt->rate * 2) / 1000; /* 2 ms io buffers */ + waves_codec->buffer_bytes = waves_codec->buffer_samples * src_fmt->channels * + waves_codec->sample_size_in_bytes; + + // trace allows printing only up-to 4 words at a time + // logging all the information in two calls + comp_info(dev, "waves_effect_init() rate %d, channels %d", waves_codec->i_format.sampleRate, + waves_codec->i_format.numChannels); + + comp_info(dev, "waves_effect_init() format %d, layout %d, frame %d", + waves_codec->i_format.samplesFormat, waves_codec->i_format.samplesLayout, + waves_codec->buffer_samples); + + status = MaxxEffect_Initialize(waves_codec->effect, i_formats, 1, o_formats, 1); + + if (status) { + comp_err(dev, "waves_effect_init() MaxxEffect_Initialize returned %d", status); + return -EINVAL; + } + + comp_dbg(dev, "waves_effect_init() done"); + return 0; +} + +/* allocate additional buffers for MaxxEffect */ +static int waves_effect_buffers(struct comp_dev *dev) +{ + struct codec_data *codec = comp_get_codec(dev); + struct waves_codec_data *waves_codec = codec->private; + MaxxStatus_t status; + int ret; + void *i_buffer = NULL, *o_buffer = NULL, *response = NULL; + + comp_dbg(dev, "waves_effect_buffers() start"); + + status = MaxxEffect_GetMessageMaxSize(waves_codec->effect, &waves_codec->request_max_bytes, + &waves_codec->response_max_bytes); + + if (status) { + comp_err(dev, "waves_effect_buffers() MaxxEffect_GetMessageMaxSize returned %d", + status); + ret = -EINVAL; + goto err; + } + + response = codec_allocate_memory(dev, waves_codec->response_max_bytes, 16); + if (!response) { + comp_err(dev, "waves_effect_buffers() failed to allocate %d bytes for response", + waves_codec->response_max_bytes); + ret = -ENOMEM; + goto err; + } + + i_buffer = codec_allocate_memory(dev, waves_codec->buffer_bytes, 16); + if (!i_buffer) { + comp_err(dev, "waves_effect_buffers() failed to allocate %d bytes for i_buffer", + waves_codec->buffer_bytes); + ret = -ENOMEM; + goto err; + } + + o_buffer = codec_allocate_memory(dev, waves_codec->buffer_bytes, 16); + if (!o_buffer) { + comp_err(dev, "waves_effect_buffers() failed to allocate %d bytes for o_buffer", + waves_codec->buffer_bytes); + ret = -ENOMEM; + goto err; + } + + waves_codec->i_buffer = i_buffer; + waves_codec->o_buffer = o_buffer; + waves_codec->response = response; + codec->cpd.in_buff = waves_codec->i_buffer; + codec->cpd.in_buff_size = waves_codec->buffer_bytes; + codec->cpd.out_buff = waves_codec->o_buffer; + codec->cpd.out_buff_size = waves_codec->buffer_bytes; + + comp_info(dev, "waves_effect_buffers() size response %d, i_buffer %d, o_buffer %d", + waves_codec->response_max_bytes, waves_codec->buffer_bytes, + waves_codec->buffer_bytes); + + comp_dbg(dev, "waves_effect_buffers() done"); + return 0; + +err: + if (i_buffer) + codec_free_memory(dev, i_buffer); + if (o_buffer) + codec_free_memory(dev, o_buffer); + if (response) + codec_free_memory(dev, response); + return ret; +} + +/* get MaxxEffect revision */ +static int waves_effect_revision(struct comp_dev *dev) +{ + struct codec_data *codec = comp_get_codec(dev); + struct waves_codec_data *waves_codec = codec->private; + const char *revision = NULL; + uint32_t revision_len; + MaxxStatus_t status; + + comp_info(dev, "waves_effect_revision() start"); + + status = MaxxEffect_Revision_Get(waves_codec->effect, &revision, &revision_len); + + if (status) { + comp_err(dev, "waves_effect_revision() MaxxEffect_Revision_Get returned %d", + status); + return -EINVAL; + } + +#if CONFIG_TRACEV + if (revision_len) { + const uint32_t *ptr = (uint32_t *)revision; + uint32_t len = revision_len / sizeof(uint32_t); + uint32_t idx = 0; + + /* get requests from codec_adapter are not supported + * printing strings is not supported + * so dumping revision string to trace log as ascii values + * if simply write a for loop here then depending on trace filtering settings + * some parts of revision might not be printed - this is highly unwanted + */ + dump_hex(ptr, idx, len); + dump_hex(ptr, idx, len); + dump_hex(ptr, idx, len); + dump_hex(ptr, idx, len); + dump_hex(ptr, idx, len); + dump_hex(ptr, idx, len); + dump_hex(ptr, idx, len); + dump_hex(ptr, idx, len); + dump_hex(ptr, idx, len); + dump_hex(ptr, idx, len); + } +#endif + + comp_info(dev, "waves_effect_revision() done"); + return 0; +} + +/* apply MaxxEffect message */ +static int waves_effect_message(struct comp_dev *dev, void *data, uint32_t size) +{ + struct codec_data *codec = comp_get_codec(dev); + struct waves_codec_data *waves_codec = codec->private; + MaxxStatus_t status; + uint32_t response_size = 0; + + comp_info(dev, "waves_effect_message() start data %p size %d", data, size); + + status = MaxxEffect_Message(waves_codec->effect, data, size, + waves_codec->response, &response_size); + + if (status) { + comp_err(dev, "waves_effect_message() MaxxEffect_Message returned %d", status); + return -EINVAL; + } + +#if CONFIG_TRACEV + /* at time of writing codec adapter does not support getting something from codec + * so response is stored to internal structure and dumped into trace messages + */ + if (response_size) { + uint32_t idx; + uint32_t len = response_size / sizeof(uint32_t); + const uint32_t *ptr = (uint32_t *)waves_codec->response; + + for (idx = 0; idx < len; ) + dump_hex(ptr, idx, len); + } +#endif + + return 0; +} + +/* apply codec config */ +static int waves_effect_config(struct comp_dev *dev, enum codec_cfg_type type) +{ + struct codec_config *cfg; + struct codec_data *codec = comp_get_codec(dev); + struct codec_param *param; + uint32_t index; + uint32_t param_number = 0; + int ret = 0; + + comp_info(dev, "waves_codec_configure() start type %d", type); + + cfg = (type == CODEC_CFG_SETUP) ? &codec->s_cfg : &codec->r_cfg; + + comp_info(dev, "waves_codec_configure() config %p, size %d, avail %d", + cfg->data, cfg->size, cfg->avail); + + if (!cfg->avail || !cfg->size) { + comp_err(dev, "waves_codec_configure() no config for type %d, avail %d, size %d", + type, cfg->avail, cfg->size); + return -EINVAL; + } + + if (cfg->size > MAX_CONFIG_SIZE_BYTES) { + comp_err(dev, "waves_codec_configure() provided config is too big, size %d", + cfg->size); + return -EINVAL; + } + + /* incoming data in cfg->data is arranged according to struct codec_param + * there migh be more than one struct codec_param inside cfg->data, glued back to back + */ + for (index = 0; index < cfg->size && (!ret); param_number++) { + uint32_t param_data_size; + + param = (struct codec_param *)((char *)cfg->data + index); + param_data_size = param->size - sizeof(param->size) - sizeof(param->id); + + comp_info(dev, "waves_codec_configure() param num %d id %d size %d", + param_number, param->id, param->size); + + switch (param->id) { + case PARAM_NOP: + comp_info(dev, "waves_codec_configure() NOP"); + break; + case PARAM_MESSAGE: + ret = waves_effect_message(dev, param->data, param_data_size); + break; + case PARAM_REVISION: + ret = waves_effect_revision(dev); + break; + default: + ret = -EINVAL; + break; + } + + index += param->size; + } + + if (ret) + comp_err(dev, "waves_codec_configure() failed %d", ret); + + comp_dbg(dev, "waves_codec_configure() done"); + return ret; +} + +/* apply setup config */ +static int waves_effect_setup_config(struct comp_dev *dev) +{ + struct codec_data *codec = comp_get_codec(dev); + int ret; + + comp_dbg(dev, "waves_effect_setup_config() start"); + + if (!codec->s_cfg.avail && !codec->s_cfg.size) { + comp_err(dev, "waves_effect_startup_config() setup config is not provided"); + return -EINVAL; + } + + if (!codec->s_cfg.avail) { + comp_warn(dev, "waves_effect_startup_config() using old setup config"); + codec->s_cfg.avail = true; + } + + ret = waves_effect_config(dev, CODEC_CFG_SETUP); + codec->s_cfg.avail = false; + + comp_dbg(dev, "waves_effect_setup_config() done"); + return ret; +} + +int waves_codec_init(struct comp_dev *dev) +{ + struct codec_data *codec = comp_get_codec(dev); + struct waves_codec_data *waves_codec; + int ret = 0; + + comp_dbg(dev, "waves_codec_init() start"); + + waves_codec = codec_allocate_memory(dev, sizeof(struct waves_codec_data), 16); + if (!waves_codec) { + comp_err(dev, "waves_codec_init() failed to allocate %d bytes for waves_codec_data", + sizeof(struct waves_codec_data)); + ret = -ENOMEM; + } else { + memset(waves_codec, 0, sizeof(struct waves_codec_data)); + codec->private = waves_codec; + + ret = waves_effect_allocate(dev); + if (ret) { + codec_free_memory(dev, waves_codec); + codec->private = NULL; + } + } + + if (ret) + comp_err(dev, "waves_codec_init() failed %d", ret); + + comp_dbg(dev, "waves_codec_init() done"); + return ret; +} + +int waves_codec_prepare(struct comp_dev *dev) +{ + int ret; + + comp_dbg(dev, "waves_codec_prepare() start"); + + ret = waves_effect_check(dev); + + if (!ret) + ret = waves_effect_init(dev); + + if (!ret) + ret = waves_effect_buffers(dev); + + if (!ret) + ret = waves_effect_setup_config(dev); + + if (ret) + comp_err(dev, "waves_codec_prepare() failed %d", ret); + + comp_dbg(dev, "waves_codec_prepare() done"); + return ret; +} + +int waves_codec_process(struct comp_dev *dev) +{ + int ret; + struct codec_data *codec = comp_get_codec(dev); + struct waves_codec_data *waves_codec = codec->private; + + comp_dbg(dev, "waves_codec_process() start"); + + MaxxStream_t *i_streams[NUM_IO_STREAMS] = { &waves_codec->i_stream }; + MaxxStream_t *o_streams[NUM_IO_STREAMS] = { &waves_codec->o_stream }; + MaxxStatus_t status; + uint32_t num_input_samples = waves_codec->buffer_samples; + + /* here input buffer should always be filled up as requested + * since no one updates it`s size except code in prepare. + * on the other hand there is available/produced counters in cpd, check them anyways + */ + if (codec->cpd.avail != waves_codec->buffer_bytes) { + comp_warn(dev, "waves_codec_process() input buffer %d is not full %d", + codec->cpd.avail, waves_codec->buffer_bytes); + num_input_samples = codec->cpd.avail / + (waves_codec->sample_size_in_bytes * waves_codec->i_format.numChannels); + } + + waves_codec->i_stream.buffersArray = &waves_codec->i_buffer; + waves_codec->i_stream.numAvailableSamples = num_input_samples; + waves_codec->i_stream.numProcessedSamples = 0; + waves_codec->i_stream.maxNumSamples = waves_codec->buffer_samples; + + waves_codec->o_stream.buffersArray = &waves_codec->o_buffer; + waves_codec->o_stream.numAvailableSamples = 0; + waves_codec->o_stream.numProcessedSamples = 0; + waves_codec->o_stream.maxNumSamples = waves_codec->buffer_samples; + + status = MaxxEffect_Process(waves_codec->effect, i_streams, o_streams); + if (status) { + comp_err(dev, "waves_codec_process() MaxxEffect_Process returned %d", status); + ret = -EINVAL; + } else { + codec->cpd.produced = waves_codec->o_stream.numAvailableSamples * + waves_codec->o_format.numChannels * waves_codec->sample_size_in_bytes; + ret = 0; + } + + if (ret) + comp_err(dev, "waves_codec_process() failed %d", ret); + + comp_dbg(dev, "waves_codec_process() done"); + return ret; +} + +int waves_codec_apply_config(struct comp_dev *dev) +{ + int ret; + + comp_dbg(dev, "waves_codec_apply_config() start"); + ret = waves_effect_config(dev, CODEC_CFG_RUNTIME); + + if (ret) + comp_err(dev, "waves_codec_apply_config() failed %d", ret); + + comp_dbg(dev, "waves_codec_apply_config() done"); + return ret; +} + +int waves_codec_reset(struct comp_dev *dev) +{ + MaxxStatus_t status; + int ret = 0; + struct codec_data *codec = comp_get_codec(dev); + struct waves_codec_data *waves_codec = codec->private; + + comp_dbg(dev, "waves_codec_reset() start"); + + status = MaxxEffect_Reset(waves_codec->effect); + if (status) { + comp_err(dev, "waves_codec_reset() MaxxEffect_Reset returned %d", status); + ret = -EINVAL; + } + + if (ret) + comp_err(dev, "waves_codec_reset() failed %d", ret); + + comp_dbg(dev, "waves_codec_reset() done"); + return ret; +} + +int waves_codec_free(struct comp_dev *dev) +{ + /* codec is using codec_adapter method codec_allocate_memory for all allocations + * codec_adapter will free it all on component free call + * nothing to do here + */ + comp_dbg(dev, "waves_codec_free()"); + return 0; +} diff --git a/src/include/sof/audio/codec_adapter/codec/waves.h b/src/include/sof/audio/codec_adapter/codec/waves.h new file mode 100644 index 000000000000..4b82a3fe4551 --- /dev/null +++ b/src/include/sof/audio/codec_adapter/codec/waves.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2020 Waves Audio Ltd. All rights reserved. + * + * Author: Oleksandr Strelchenko + */ +#ifndef __SOF_AUDIO_WAVES_CODEC__ +#define __SOF_AUDIO_WAVES_CODEC__ + +int waves_codec_init(struct comp_dev *dev); +int waves_codec_prepare(struct comp_dev *dev); +int waves_codec_process(struct comp_dev *dev); +int waves_codec_apply_config(struct comp_dev *dev); +int waves_codec_reset(struct comp_dev *dev); +int waves_codec_free(struct comp_dev *dev); + +#endif /* __SOF_AUDIO_WAVES_CODEC__ */ diff --git a/src/include/sof/audio/codec_adapter/interfaces.h b/src/include/sof/audio/codec_adapter/interfaces.h index ccf265d5454b..4787ef4d72f4 100644 --- a/src/include/sof/audio/codec_adapter/interfaces.h +++ b/src/include/sof/audio/codec_adapter/interfaces.h @@ -19,8 +19,13 @@ #include #endif +#if CONFIG_WAVES_CODEC +#include +#endif + #define CADENCE_ID 0xCADE01 #define DUMMY_ID 0xD03311 +#define WAVES_ID 0x574101 /*****************************************************************************/ /* Linked codecs interfaces */ @@ -49,6 +54,18 @@ static struct codec_interface interfaces[] = { .free = dummy_codec_free }, #endif /* CONFIG_DUMMY_CODEC */ + +#if CONFIG_WAVES_CODEC + { + .id = WAVES_ID, + .init = waves_codec_init, + .prepare = waves_codec_prepare, + .process = waves_codec_process, + .apply_config = waves_codec_apply_config, + .reset = waves_codec_reset, + .free = waves_codec_free + }, +#endif /* CONFIG_WAVES_CODEC */ }; #endif /* __SOF_AUDIO_CODEC_INTERFACES__ */ diff --git a/src/include/sof/debug/debug.h b/src/include/sof/debug/debug.h index 2e29077163db..0712c482ac9a 100644 --- a/src/include/sof/debug/debug.h +++ b/src/include/sof/debug/debug.h @@ -138,4 +138,42 @@ #define dump_object_ptr(__o) do {} while (0) #endif +/* swap an endianness of 32-bit word */ +#define bswap32(N) ({ \ + typeof(N) n = (N); \ + ((n & 0x000000FF) << 24) | \ + ((n & 0x0000FF00) << 8) | \ + ((n & 0x00FF0000) >> 8) | \ + ((n & 0xFF000000) >> 24); }) + +#if CONFIG_TRACE +/* dump up to 4 32-bit words into trace starting in ptr, idx is incremented inside + * unconditionally swaps endianness of data + * todo: use cpu_to_endianness so trace data will be independent of platform + */ +#define dump_hex(ptr, idx, len) \ + do { \ + typeof(idx) __i = (idx); \ + typeof(ptr) __p = (ptr) + __i; \ + typeof(idx) __l = (len) - __i; \ + typeof(idx) __n = __l > 4 ? 4 : __l; \ + if (__n == 4) { \ + comp_info(dev, "%08x%08x%08x%08x", bswap32(__p[0]), bswap32(__p[1]), \ + bswap32(__p[2]), bswap32(__p[3])); \ + } else if (__n == 3) { \ + comp_info(dev, "%08x%08x%08x", bswap32(__p[0]), bswap32(__p[1]), \ + bswap32(__p[2])); \ + } else if (__n == 2) { \ + comp_info(dev, "%08x%08x", bswap32(__p[0]), bswap32(__p[1])); \ + } else if (__n == 1) { \ + comp_info(dev, "%08x", bswap32(__p[0])); \ + } \ + idx += __n; \ + } while (0) +#else + +#define dump_hex() do {} while (0) + +#endif + #endif /* __SOF_DEBUG_DEBUG_H__ */ From 74b2caebbaf121829649440919e7edee26f6cd79 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Fri, 26 Feb 2021 21:48:23 +0200 Subject: [PATCH 37/47] codec_adapter: Bail out only on fatal errors When setting parameters some API calls might not be fatal, so there is no need to fail the apply config phase in this case. For example, in case of Cadence MP3 codec the only supported PCM output word size is 16 and 24. Trying to set a PCM word size of 32 will result in a non-fatal error and the word size would be adjusted to 24. Signed-off-by: Daniel Baluta --- src/audio/codec_adapter/codec/cadence.c | 6 ++++-- src/include/sof/audio/codec_adapter/codec/cadence.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/audio/codec_adapter/codec/cadence.c b/src/audio/codec_adapter/codec/cadence.c index 1a889bf9d1a9..1aecef978b1a 100644 --- a/src/audio/codec_adapter/codec/cadence.c +++ b/src/audio/codec_adapter/codec/cadence.c @@ -97,7 +97,7 @@ int cadence_codec_init(struct comp_dev *dev) static int apply_config(struct comp_dev *dev, enum codec_cfg_type type) { - int ret; + int ret = 0; int size; struct codec_config *cfg; void *data; @@ -133,7 +133,8 @@ static int apply_config(struct comp_dev *dev, enum codec_cfg_type type) if (ret != LIB_NO_ERROR) { comp_err(dev, "apply_config() error %x: failed to apply parameter %d value %d", ret, param->id, *(int32_t *)param->data); - goto ret; + if (LIB_IS_FATAL_ERROR(ret)) + goto ret; } /* Obtain next parameter, it starts right after the preceding one */ data = (char *)data + param->size; @@ -141,6 +142,7 @@ static int apply_config(struct comp_dev *dev, enum codec_cfg_type type) } comp_dbg(dev, "apply_config() done"); + ret = 0; ret: return ret; } diff --git a/src/include/sof/audio/codec_adapter/codec/cadence.h b/src/include/sof/audio/codec_adapter/codec/cadence.h index 5c12924b1876..f16c23e4c360 100644 --- a/src/include/sof/audio/codec_adapter/codec/cadence.h +++ b/src/include/sof/audio/codec_adapter/codec/cadence.h @@ -15,6 +15,7 @@ #define LIB_NAME_MAX_LEN 30 #define LIB_NO_ERROR XA_NO_ERROR +#define LIB_IS_FATAL_ERROR(e) ((e) & XA_FATAL_ERROR) /*****************************************************************************/ /* Cadence API functions */ From b1ee8464b171811b7e83f7571df799f90103aad4 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Fri, 26 Feb 2021 15:42:40 +0200 Subject: [PATCH 38/47] codec_adapter: cadence: Fix API func search Existing code returns every time the API function at index 0, which works now because we support only a single API function. But, this will break when patches adding multiple Cadence codec types will be merged. Signed-off-by: Daniel Baluta --- src/audio/codec_adapter/codec/cadence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/codec_adapter/codec/cadence.c b/src/audio/codec_adapter/codec/cadence.c index 1aecef978b1a..9524a1738c9a 100644 --- a/src/audio/codec_adapter/codec/cadence.c +++ b/src/audio/codec_adapter/codec/cadence.c @@ -50,7 +50,7 @@ int cadence_codec_init(struct comp_dev *dev) /* Find and assign API function */ for (i = 0; i < no_of_api; i++) { if (cadence_api_table[i].id == api_id) { - cd->api = cadence_api_table[0].api; + cd->api = cadence_api_table[i].api; break; } } From 86eabe12b316b94f44f159dfd06cf80b86c6cee2 Mon Sep 17 00:00:00 2001 From: Adrian Bonislawski Date: Tue, 19 Jan 2021 09:11:36 +0100 Subject: [PATCH 39/47] clk: do not release clock only for LPRO->HPRO transition This will allow to switch to HPRO much faster when needed in s0 Signed-off-by: Adrian Bonislawski --- src/platform/intel/cavs/lib/clk.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/platform/intel/cavs/lib/clk.c b/src/platform/intel/cavs/lib/clk.c index 956e2923ac64..9405ba215579 100644 --- a/src/platform/intel/cavs/lib/clk.c +++ b/src/platform/intel/cavs/lib/clk.c @@ -168,7 +168,12 @@ static void platform_clock_low_power_mode(int clock, bool enable) int freq_idx = *cache_to_uncache(&active_freq_idx); if (enable && current_freq_idx > CPU_LPRO_FREQ_IDX) - select_cpu_clock(CPU_LPRO_FREQ_IDX, true); + /* LPRO requests are fast, but requests for other ROs + * can take a lot of time. That's why it's better to + * not release active clock just for waiti, + * so they can be switched without delay on wake up. + */ + select_cpu_clock(CPU_LPRO_FREQ_IDX, false); else if (!enable && current_freq_idx != freq_idx) select_cpu_clock(freq_idx, true); } From c549e5434136e8aff60b919244c650765e1a5045 Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Fri, 5 Mar 2021 17:36:44 +0200 Subject: [PATCH 40/47] Drivers: DMIC: Fix FW panic when stopping both paused FIFO streams The error can be replicated with two interactive mode arecord commands. After launch press space key to pause both captures and then ctrl-c to stop both. E.g. arecord -i -Dhw:0,6 -f S16_LE -c 4 -r 48000 rec06.wav arecord -i -Dhw:0,7 -f S16_LE -c 4 -r 16000 rec07.wav The error happened due to no handling for pause state in DMIC DAI type. The device was set to prepared state instead of pause that conflicted with power management when resumed. The patch updates dmic_start() to properly track the active FIFOs count with check of dmic->state before setting it to COMP_STATE_ACTIVE. Start for active DMIC should no increase it. The dmic_stop() is updated to handle pause by removal of state setting. The set of state is moved to dmic_trigger() to be able to use same stop function. The dmic_irq_handler() FIFO stop is edit to set prepared state for stopping it. The patch alters the external PDM bus function when paused. The clocks as feature of this patch remain active. Previously stop and pause were the same. Since the pause is not used for capture so the small additional power consumption of active microphone is no issue. Signed-off-by: Ranjani Sridharan Signed-off-by: Seppo Ingalsuo --- src/drivers/intel/dmic.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/drivers/intel/dmic.c b/src/drivers/intel/dmic.c index c471f2d07004..ef55e55a4d84 100644 --- a/src/drivers/intel/dmic.c +++ b/src/drivers/intel/dmic.c @@ -1269,7 +1269,6 @@ static void dmic_start(struct dai *dai) /* enable port */ spin_lock(&dai->lock); dai_dbg(dai, "dmic_start()"); - dmic->state = COMP_STATE_ACTIVE; dmic->startcount = 0; /* Initial gain value, convert Q12.20 to Q2.30 */ @@ -1368,7 +1367,10 @@ static void dmic_start(struct dai *dai) CIC_CONTROL_SOFT_RESET_BIT, 0); } - dmic_active_fifos++; + if (dmic->state == COMP_STATE_PREPARE) + dmic_active_fifos++; + + dmic->state = COMP_STATE_ACTIVE; spin_unlock(&dai->lock); @@ -1396,13 +1398,6 @@ static void dmic_stop(struct dai *dai) dai_dbg(dai, "dmic_stop()"); spin_lock(&dai->lock); - if (dmic->state != COMP_STATE_ACTIVE) { - dai_info(dai, "dmic_stop(), already stopped"); - goto out; - } - - dmic->state = COMP_STATE_PREPARE; - /* Stop FIFO packers and set FIFO initialize bits */ switch (dai->index) { case 0: @@ -1445,10 +1440,10 @@ static void dmic_stop(struct dai *dai) } } - dmic_active_fifos--; + if (dmic->state == COMP_STATE_PREPARE) + dmic_active_fifos--; schedule_task_cancel(&dmic->dmicwork); -out: platform_shared_commit(dmic, sizeof(*dmic)); spin_unlock(&dai->lock); } @@ -1496,7 +1491,11 @@ static int dmic_trigger(struct dai *dai, int cmd, int direction) } break; case COMP_TRIGGER_STOP: + dmic->state = COMP_STATE_PREPARE; + dmic_stop(dai); + break; case COMP_TRIGGER_PAUSE: + dmic->state = COMP_STATE_PAUSED; dmic_stop(dai); break; case COMP_TRIGGER_RESUME: @@ -1520,6 +1519,7 @@ static int dmic_trigger(struct dai *dai, int cmd, int direction) static void dmic_irq_handler(void *data) { struct dai *dai = data; + struct dmic_pdata *dmic = dai_get_drvdata(dai); uint32_t val0; uint32_t val1; @@ -1532,12 +1532,14 @@ static void dmic_irq_handler(void *data) if (val0 & OUTSTAT0_ROR_BIT) { dai_err(dai, "dmic_irq_handler(): full fifo A or PDM overrun"); dai_write(dai, OUTSTAT0, val0); + dmic->state = COMP_STATE_PREPARE; dmic_stop(dai); } if (val1 & OUTSTAT1_ROR_BIT) { dai_err(dai, "dmic_irq_handler(): full fifo B or PDM overrun"); dai_write(dai, OUTSTAT1, val1); + dmic->state = COMP_STATE_PREPARE; dmic_stop(dai); } } From 2d43c77e1d34cd61efac85bbb739687f6e1ddc70 Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Thu, 5 Nov 2020 18:48:26 +0200 Subject: [PATCH 41/47] Drivers: Intel: Updates to DMIC for runtime instantiate and remove DAI This patch separates from function configure_registers() the write of FIFO A, FIFO B, and common functions initialization. The change allows the DMIC DAI type to be instantiated when the streaming starts and removed after streaming ends. The driver for was designed to configure the HW in firmware initialization. It didn't support DAI initialization at streaming start and remove at end. The start of second DAI stopped the first. Also the decimation factors selection made choices those prevented the second DAI to find suitable integer decimation factors. The key change is that common functions like CIC are programmed for first instantiating. The FIR A and the FIFO are set up for FIFO A connected DAI and FIR B related for FIFO B connected DAI. The dmic_remove() is changed to pass the common resources stop and free if there's still a running FIFO left. The traced registers configuration are changed to 32 bit hex for easier manual decode of bit fields when debugging. Signed-off-by: Seppo Ingalsuo Signed-off-by: Ranjani Sridharan --- src/drivers/intel/dmic.c | 419 +++++++++++++++++---------------- src/include/sof/drivers/dmic.h | 7 + 2 files changed, 223 insertions(+), 203 deletions(-) diff --git a/src/drivers/intel/dmic.c b/src/drivers/intel/dmic.c index ef55e55a4d84..38a5cabb2a09 100644 --- a/src/drivers/intel/dmic.c +++ b/src/drivers/intel/dmic.c @@ -770,6 +770,7 @@ static int configure_registers(struct dai *dai, int stereo[DMIC_HW_CONTROLLERS]; int swap[DMIC_HW_CONTROLLERS]; uint32_t val; + uint32_t ref; int32_t ci; uint32_t cu; int ipm; @@ -779,31 +780,24 @@ static int configure_registers(struct dai *dai, int fir_length; int length; int edge; - int dccomp; - int cic_start_a; - int cic_start_b; - int fir_start_a; - int fir_start_b; int soft_reset; + int cic_mute; + int fir_mute; int i; int j; int ret; int di = dai->index; struct dmic_pdata *pdata = dai_get_drvdata(dai); + int dccomp = 1; int array_a = 0; int array_b = 0; - int cic_mute = 1; - int fir_mute = 1; int bfth = 3; /* Should be 3 for 8 entries, 1 is 2 entries */ int th = 0; /* Used with TIE=1 */ /* Normal start sequence */ - dccomp = 1; soft_reset = 1; - cic_start_a = 0; - cic_start_b = 0; - fir_start_a = 0; - fir_start_b = 0; + cic_mute = 1; + fir_mute = 1; #if (DMIC_HW_VERSION == 2 && DMIC_HW_CONTROLLERS > 2) || DMIC_HW_VERSION == 3 int source[OUTCONTROLX_IPM_NUMSOURCES]; @@ -827,63 +821,67 @@ static int configure_registers(struct dai *dai, #endif #if DMIC_HW_VERSION == 1 || (DMIC_HW_VERSION == 2 && DMIC_HW_CONTROLLERS <= 2) - ipm_helper1(&ipm, 0); - val = OUTCONTROL0_TIE(0) | - OUTCONTROL0_SIP(0) | - OUTCONTROL0_FINIT(1) | - OUTCONTROL0_FCI(0) | - OUTCONTROL0_BFTH(bfth) | - OUTCONTROL0_OF(of0) | - OUTCONTROL0_IPM(ipm) | - OUTCONTROL0_TH(th); - dai_write(dai, OUTCONTROL0, val); - dai_dbg(dai, "configure_registers(), OUTCONTROL0 = %u", val); - - ipm_helper1(&ipm, 1); - val = OUTCONTROL1_TIE(0) | - OUTCONTROL1_SIP(0) | - OUTCONTROL1_FINIT(1) | - OUTCONTROL1_FCI(0) | - OUTCONTROL1_BFTH(bfth) | - OUTCONTROL1_OF(of1) | - OUTCONTROL1_IPM(ipm) | - OUTCONTROL1_TH(th); - dai_write(dai, OUTCONTROL1, val); - dai_dbg(dai, "configure_registers(), OUTCONTROL1 = %u", val); + if (di == 0) { + ipm_helper1(&ipm, 0); + val = OUTCONTROL0_TIE(0) | + OUTCONTROL0_SIP(0) | + OUTCONTROL0_FINIT(1) | + OUTCONTROL0_FCI(0) | + OUTCONTROL0_BFTH(bfth) | + OUTCONTROL0_OF(of0) | + OUTCONTROL0_IPM(ipm) | + OUTCONTROL0_TH(th); + dai_write(dai, OUTCONTROL0, val); + dai_dbg(dai, "configure_registers(), OUTCONTROL0 = %08x", val); + } else { + ipm_helper1(&ipm, 1); + val = OUTCONTROL1_TIE(0) | + OUTCONTROL1_SIP(0) | + OUTCONTROL1_FINIT(1) | + OUTCONTROL1_FCI(0) | + OUTCONTROL1_BFTH(bfth) | + OUTCONTROL1_OF(of1) | + OUTCONTROL1_IPM(ipm) | + OUTCONTROL1_TH(th); + dai_write(dai, OUTCONTROL1, val); + dai_dbg(dai, "configure_registers(), OUTCONTROL1 = %08x", val); + } #endif #if DMIC_HW_VERSION == 3 || (DMIC_HW_VERSION == 2 && DMIC_HW_CONTROLLERS > 2) - ipm_helper2(source, &ipm, 0); - val = OUTCONTROL0_TIE(0) | - OUTCONTROL0_SIP(0) | - OUTCONTROL0_FINIT(1) | - OUTCONTROL0_FCI(0) | - OUTCONTROL0_BFTH(bfth) | - OUTCONTROL0_OF(of0) | - OUTCONTROL0_IPM(ipm) | - OUTCONTROL0_IPM_SOURCE_1(source[0]) | - OUTCONTROL0_IPM_SOURCE_2(source[1]) | - OUTCONTROL0_IPM_SOURCE_3(source[2]) | - OUTCONTROL0_IPM_SOURCE_4(source[3]) | - OUTCONTROL0_TH(th); - dai_write(dai, OUTCONTROL0, val); - dai_dbg(dai, "configure_registers(), OUTCONTROL0 = %u", val); - - ipm_helper2(source, &ipm, 1); - val = OUTCONTROL1_TIE(0) | - OUTCONTROL1_SIP(0) | - OUTCONTROL1_FINIT(1) | - OUTCONTROL1_FCI(0) | - OUTCONTROL1_BFTH(bfth) | - OUTCONTROL1_OF(of1) | - OUTCONTROL1_IPM(ipm) | - OUTCONTROL1_IPM_SOURCE_1(source[0]) | - OUTCONTROL1_IPM_SOURCE_2(source[1]) | - OUTCONTROL1_IPM_SOURCE_3(source[2]) | - OUTCONTROL1_IPM_SOURCE_4(source[3]) | - OUTCONTROL1_TH(th); - dai_write(dai, OUTCONTROL1, val); - dai_dbg(dai, "configure_registers(), OUTCONTROL1 = %u", val); + if (di == 0) { + ipm_helper2(source, &ipm, 0); + val = OUTCONTROL0_TIE(0) | + OUTCONTROL0_SIP(0) | + OUTCONTROL0_FINIT(1) | + OUTCONTROL0_FCI(0) | + OUTCONTROL0_BFTH(bfth) | + OUTCONTROL0_OF(of0) | + OUTCONTROL0_IPM(ipm) | + OUTCONTROL0_IPM_SOURCE_1(source[0]) | + OUTCONTROL0_IPM_SOURCE_2(source[1]) | + OUTCONTROL0_IPM_SOURCE_3(source[2]) | + OUTCONTROL0_IPM_SOURCE_4(source[3]) | + OUTCONTROL0_TH(th); + dai_write(dai, OUTCONTROL0, val); + dai_dbg(dai, "configure_registers(), OUTCONTROL0 = %08x", val); + } else { + ipm_helper2(source, &ipm, 1); + val = OUTCONTROL1_TIE(0) | + OUTCONTROL1_SIP(0) | + OUTCONTROL1_FINIT(1) | + OUTCONTROL1_FCI(0) | + OUTCONTROL1_BFTH(bfth) | + OUTCONTROL1_OF(of1) | + OUTCONTROL1_IPM(ipm) | + OUTCONTROL1_IPM_SOURCE_1(source[0]) | + OUTCONTROL1_IPM_SOURCE_2(source[1]) | + OUTCONTROL1_IPM_SOURCE_3(source[2]) | + OUTCONTROL1_IPM_SOURCE_4(source[3]) | + OUTCONTROL1_TH(th); + dai_write(dai, OUTCONTROL1, val); + dai_dbg(dai, "configure_registers(), OUTCONTROL1 = %08x", val); + } #endif /* Mark enabled microphones into private data to be later used @@ -903,139 +901,148 @@ static int configure_registers(struct dai *dai, } for (i = 0; i < DMIC_HW_CONTROLLERS; i++) { - /* CIC */ - val = CIC_CONTROL_SOFT_RESET(soft_reset) | - CIC_CONTROL_CIC_START_B(cic_start_b) | - CIC_CONTROL_CIC_START_A(cic_start_a) | - CIC_CONTROL_MIC_B_POLARITY(dmic_prm[di]->pdm[i].polarity_mic_a) | - CIC_CONTROL_MIC_A_POLARITY(dmic_prm[di]->pdm[i].polarity_mic_b) | - CIC_CONTROL_MIC_MUTE(cic_mute) | - CIC_CONTROL_STEREO_MODE(stereo[i]); - dai_write(dai, base[i] + CIC_CONTROL, val); - dai_dbg(dai, "configure_registers(), CIC_CONTROL = %u", - val); - - val = CIC_CONFIG_CIC_SHIFT(cfg->cic_shift + 8) | - CIC_CONFIG_COMB_COUNT(cfg->mcic - 1); - dai_write(dai, base[i] + CIC_CONFIG, val); - dai_dbg(dai, "configure_registers(), CIC_CONFIG = %u", - val); - - /* Mono right channel mic usage requires swap of PDM channels - * since the mono decimation is done with only left channel - * processing active. - */ - edge = dmic_prm[di]->pdm[i].clk_edge; - if (swap[i]) - edge = !edge; - - val = MIC_CONTROL_PDM_CLKDIV(cfg->clkdiv - 2) | - MIC_CONTROL_PDM_SKEW(dmic_prm[di]->pdm[i].skew) | - MIC_CONTROL_CLK_EDGE(edge) | - MIC_CONTROL_PDM_EN_B(cic_start_b) | - MIC_CONTROL_PDM_EN_A(cic_start_a); - dai_write(dai, base[i] + MIC_CONTROL, val); - dai_dbg(dai, "configure_registers(), MIC_CONTROL = %u", - val); - - /* FIR A */ - fir_decim = MAX(cfg->mfir_a - 1, 0); - fir_length = MAX(cfg->fir_a_length - 1, 0); - val = FIR_CONTROL_A_START(fir_start_a) | - FIR_CONTROL_A_ARRAY_START_EN(array_a) | - FIR_CONTROL_A_DCCOMP(dccomp) | - FIR_CONTROL_A_MUTE(fir_mute) | - FIR_CONTROL_A_STEREO(stereo[i]); - dai_write(dai, base[i] + FIR_CONTROL_A, val); - dai_dbg(dai, "configure_registers(), FIR_CONTROL_A = %u", - val); - - val = FIR_CONFIG_A_FIR_DECIMATION(fir_decim) | - FIR_CONFIG_A_FIR_SHIFT(cfg->fir_a_shift) | - FIR_CONFIG_A_FIR_LENGTH(fir_length); - dai_write(dai, base[i] + FIR_CONFIG_A, val); - dai_dbg(dai, "configure_registers(), FIR_CONFIG_A = %u", - val); - - val = DC_OFFSET_LEFT_A_DC_OFFS(DCCOMP_TC0); - dai_write(dai, base[i] + DC_OFFSET_LEFT_A, val); - dai_dbg(dai, "configure_registers(), DC_OFFSET_LEFT_A = %u", - val); - - val = DC_OFFSET_RIGHT_A_DC_OFFS(DCCOMP_TC0); - dai_write(dai, base[i] + DC_OFFSET_RIGHT_A, val); - dai_dbg(dai, "configure_registers(), DC_OFFSET_RIGHT_A = %u", - val); - - val = OUT_GAIN_LEFT_A_GAIN(0); - dai_write(dai, base[i] + OUT_GAIN_LEFT_A, val); - dai_dbg(dai, "configure_registers(), OUT_GAIN_LEFT_A = %u", - val); - - val = OUT_GAIN_RIGHT_A_GAIN(0); - dai_write(dai, base[i] + OUT_GAIN_RIGHT_A, val); - dai_dbg(dai, "configure_registers(), OUT_GAIN_RIGHT_A = %u", - val); - - /* FIR B */ - fir_decim = MAX(cfg->mfir_b - 1, 0); - fir_length = MAX(cfg->fir_b_length - 1, 0); - val = FIR_CONTROL_B_START(fir_start_b) | - FIR_CONTROL_B_ARRAY_START_EN(array_b) | - FIR_CONTROL_B_DCCOMP(dccomp) | - FIR_CONTROL_B_MUTE(fir_mute) | - FIR_CONTROL_B_STEREO(stereo[i]); - dai_write(dai, base[i] + FIR_CONTROL_B, val); - dai_dbg(dai, "configure_registers(), FIR_CONTROL_B = %u", - val); - - val = FIR_CONFIG_B_FIR_DECIMATION(fir_decim) | - FIR_CONFIG_B_FIR_SHIFT(cfg->fir_b_shift) | - FIR_CONFIG_B_FIR_LENGTH(fir_length); - dai_write(dai, base[i] + FIR_CONFIG_B, val); - dai_dbg(dai, "configure_registers(), FIR_CONFIG_B = %u", - val); - - val = DC_OFFSET_LEFT_B_DC_OFFS(DCCOMP_TC0); - dai_write(dai, base[i] + DC_OFFSET_LEFT_B, val); - dai_dbg(dai, "configure_registers(), DC_OFFSET_LEFT_B = %u", - val); - - val = DC_OFFSET_RIGHT_B_DC_OFFS(DCCOMP_TC0); - dai_write(dai, base[i] + DC_OFFSET_RIGHT_B, val); - dai_dbg(dai, "configure_registers(), DC_OFFSET_RIGHT_B = %u", - val); - - val = OUT_GAIN_LEFT_B_GAIN(0); - dai_write(dai, base[i] + OUT_GAIN_LEFT_B, val); - dai_dbg(dai, "configure_registers(), OUT_GAIN_LEFT_B = %u", - val); - - val = OUT_GAIN_RIGHT_B_GAIN(0); - dai_write(dai, base[i] + OUT_GAIN_RIGHT_B, val); - dai_dbg(dai, "configure_registers(), OUT_GAIN_RIGHT_B = %u", - val); - - /* Write coef RAM A with scaled coefficient in reverse order */ - length = cfg->fir_a_length; - for (j = 0; j < length; j++) { - ci = (int32_t)Q_MULTSR_32X32( - (int64_t)cfg->fir_a->coef[j], cfg->fir_a_scale, - 31, DMIC_FIR_SCALE_Q, DMIC_HW_FIR_COEF_Q); - cu = FIR_COEF_A(ci); - dai_write(dai, coef_base_a[i] - + ((length - j - 1) << 2), cu); + if (dmic_active_fifos == 0) { + /* CIC */ + val = CIC_CONTROL_SOFT_RESET(soft_reset) | + CIC_CONTROL_CIC_START_B(0) | + CIC_CONTROL_CIC_START_A(0) | + CIC_CONTROL_MIC_B_POLARITY(dmic_prm[di]->pdm[i].polarity_mic_a) | + CIC_CONTROL_MIC_A_POLARITY(dmic_prm[di]->pdm[i].polarity_mic_b) | + CIC_CONTROL_MIC_MUTE(cic_mute) | + CIC_CONTROL_STEREO_MODE(stereo[i]); + dai_write(dai, base[i] + CIC_CONTROL, val); + dai_dbg(dai, "configure_registers(), CIC_CONTROL = %08x", val); + + val = CIC_CONFIG_CIC_SHIFT(cfg->cic_shift + 8) | + CIC_CONFIG_COMB_COUNT(cfg->mcic - 1); + dai_write(dai, base[i] + CIC_CONFIG, val); + dai_dbg(dai, "configure_registers(), CIC_CONFIG = %08x", val); + + /* Mono right channel mic usage requires swap of PDM channels + * since the mono decimation is done with only left channel + * processing active. + */ + edge = dmic_prm[di]->pdm[i].clk_edge; + if (swap[i]) + edge = !edge; + + val = MIC_CONTROL_PDM_CLKDIV(cfg->clkdiv - 2) | + MIC_CONTROL_PDM_SKEW(dmic_prm[di]->pdm[i].skew) | + MIC_CONTROL_CLK_EDGE(edge) | + MIC_CONTROL_PDM_EN_B(0) | + MIC_CONTROL_PDM_EN_A(0); + dai_write(dai, base[i] + MIC_CONTROL, val); + dai_dbg(dai, "configure_registers(), MIC_CONTROL = %08x", val); + } else { + /* Check that request is compatible with running configuration: + * CIC decimation factor and shift value check + */ + val = dai_read(dai, base[i] + CIC_CONFIG); + ref = CIC_CONFIG_CIC_SHIFT(cfg->cic_shift + 8) | + CIC_CONFIG_COMB_COUNT(cfg->mcic - 1); + if ((val & + (CIC_CONFIG_CIC_SHIFT_MASK | CIC_CONFIG_COMB_COUNT_MASK)) != ref) { + dai_err(dai, "configure_registers(): CIC_CONFIG %08x block", val); + return -EINVAL; + } + + /* Clock divider check */ + val = dai_read(dai, base[i] + MIC_CONTROL); + ref = MIC_CONTROL_PDM_CLKDIV(cfg->clkdiv - 2); + if ((val & MIC_CONTROL_PDM_CLKDIV_MASK) != ref) { + dai_err(dai, "configure_registers(): MIC_CONTROL %08x block", val); + return -EINVAL; + } } - /* Write coef RAM B with scaled coefficient in reverse order */ - length = cfg->fir_b_length; - for (j = 0; j < length; j++) { - ci = (int32_t)Q_MULTSR_32X32( - (int64_t)cfg->fir_b->coef[j], cfg->fir_b_scale, - 31, DMIC_FIR_SCALE_Q, DMIC_HW_FIR_COEF_Q); - cu = FIR_COEF_B(ci); - dai_write(dai, coef_base_b[i] - + ((length - j - 1) << 2), cu); + if (di == 0) { + /* FIR A */ + fir_decim = MAX(cfg->mfir_a - 1, 0); + fir_length = MAX(cfg->fir_a_length - 1, 0); + val = FIR_CONTROL_A_START(0) | + FIR_CONTROL_A_ARRAY_START_EN(array_a) | + FIR_CONTROL_A_DCCOMP(dccomp) | + FIR_CONTROL_A_MUTE(fir_mute) | + FIR_CONTROL_A_STEREO(stereo[i]); + dai_write(dai, base[i] + FIR_CONTROL_A, val); + dai_dbg(dai, "configure_registers(), FIR_CONTROL_A = %08x", val); + + val = FIR_CONFIG_A_FIR_DECIMATION(fir_decim) | + FIR_CONFIG_A_FIR_SHIFT(cfg->fir_a_shift) | + FIR_CONFIG_A_FIR_LENGTH(fir_length); + dai_write(dai, base[i] + FIR_CONFIG_A, val); + dai_dbg(dai, "configure_registers(), FIR_CONFIG_A = %08x", val); + + val = DC_OFFSET_LEFT_A_DC_OFFS(DCCOMP_TC0); + dai_write(dai, base[i] + DC_OFFSET_LEFT_A, val); + dai_dbg(dai, "configure_registers(), DC_OFFSET_LEFT_A = %08x", val); + + val = DC_OFFSET_RIGHT_A_DC_OFFS(DCCOMP_TC0); + dai_write(dai, base[i] + DC_OFFSET_RIGHT_A, val); + dai_dbg(dai, "configure_registers(), DC_OFFSET_RIGHT_A = %08x", val); + + val = OUT_GAIN_LEFT_A_GAIN(0); + dai_write(dai, base[i] + OUT_GAIN_LEFT_A, val); + dai_dbg(dai, "configure_registers(), OUT_GAIN_LEFT_A = %08x", val); + + val = OUT_GAIN_RIGHT_A_GAIN(0); + dai_write(dai, base[i] + OUT_GAIN_RIGHT_A, val); + dai_dbg(dai, "configure_registers(), OUT_GAIN_RIGHT_A = %08x", val); + + /* Write coef RAM A with scaled coefficient in reverse order */ + length = cfg->fir_a_length; + for (j = 0; j < length; j++) { + ci = (int32_t)Q_MULTSR_32X32((int64_t)cfg->fir_a->coef[j], + cfg->fir_a_scale, 31, + DMIC_FIR_SCALE_Q, DMIC_HW_FIR_COEF_Q); + cu = FIR_COEF_A(ci); + dai_write(dai, coef_base_a[i] + ((length - j - 1) << 2), cu); + } + } + + if (di == 1) { + /* FIR B */ + fir_decim = MAX(cfg->mfir_b - 1, 0); + fir_length = MAX(cfg->fir_b_length - 1, 0); + val = FIR_CONTROL_B_START(0) | + FIR_CONTROL_B_ARRAY_START_EN(array_b) | + FIR_CONTROL_B_DCCOMP(dccomp) | + FIR_CONTROL_B_MUTE(fir_mute) | + FIR_CONTROL_B_STEREO(stereo[i]); + dai_write(dai, base[i] + FIR_CONTROL_B, val); + dai_dbg(dai, "configure_registers(), FIR_CONTROL_B = %08x", val); + + val = FIR_CONFIG_B_FIR_DECIMATION(fir_decim) | + FIR_CONFIG_B_FIR_SHIFT(cfg->fir_b_shift) | + FIR_CONFIG_B_FIR_LENGTH(fir_length); + dai_write(dai, base[i] + FIR_CONFIG_B, val); + dai_dbg(dai, "configure_registers(), FIR_CONFIG_B = %08x", val); + + val = DC_OFFSET_LEFT_B_DC_OFFS(DCCOMP_TC0); + dai_write(dai, base[i] + DC_OFFSET_LEFT_B, val); + dai_dbg(dai, "configure_registers(), DC_OFFSET_LEFT_B = %08x", val); + + val = DC_OFFSET_RIGHT_B_DC_OFFS(DCCOMP_TC0); + dai_write(dai, base[i] + DC_OFFSET_RIGHT_B, val); + dai_dbg(dai, "configure_registers(), DC_OFFSET_RIGHT_B = %08x", val); + + val = OUT_GAIN_LEFT_B_GAIN(0); + dai_write(dai, base[i] + OUT_GAIN_LEFT_B, val); + dai_dbg(dai, "configure_registers(), OUT_GAIN_LEFT_B = %08x", val); + + val = OUT_GAIN_RIGHT_B_GAIN(0); + dai_write(dai, base[i] + OUT_GAIN_RIGHT_B, val); + dai_dbg(dai, "configure_registers(), OUT_GAIN_RIGHT_B = %08x", val); + + /* Write coef RAM B with scaled coefficient in reverse order */ + length = cfg->fir_b_length; + for (j = 0; j < length; j++) { + ci = (int32_t)Q_MULTSR_32X32((int64_t)cfg->fir_b->coef[j], + cfg->fir_b_scale, 31, + DMIC_FIR_SCALE_Q, DMIC_HW_FIR_COEF_Q); + cu = FIR_COEF_B(ci); + dai_write(dai, coef_base_b[i] + ((length - j - 1) << 2), cu); + } } } @@ -1603,12 +1610,7 @@ static int dmic_remove(struct dai *dai) struct dmic_pdata *dmic = dai_get_drvdata(dai); int i; - interrupt_disable(dmic->irq, dai); - interrupt_unregister(dmic->irq, dai); - - pm_runtime_put_sync(DMIC_CLK, dai->index); - /* Disable DMIC power */ - pm_runtime_put_sync(DMIC_POW, dai->index); + dai_info(dai, "dmic_remove()"); /* remove scheduling */ schedule_task_free(&dmic->dmicwork); @@ -1616,6 +1618,17 @@ static int dmic_remove(struct dai *dai) rfree(dai_get_drvdata(dai)); dai_set_drvdata(dai, NULL); + interrupt_disable(dmic->irq, dai); + interrupt_unregister(dmic->irq, dai); + + /* The next end tasks must be passed if another DAI FIFO still runs */ + if (dmic_active_fifos) + return 0; + + pm_runtime_put_sync(DMIC_CLK, dai->index); + /* Disable DMIC power */ + pm_runtime_put_sync(DMIC_POW, dai->index); + rfree(dmic_prm[0]); for (i = 0; i < DMIC_HW_FIFOS; i++) dmic_prm[i] = NULL; diff --git a/src/include/sof/drivers/dmic.h b/src/include/sof/drivers/dmic.h index 09b21d947203..8404e6fb1261 100644 --- a/src/include/sof/drivers/dmic.h +++ b/src/include/sof/drivers/dmic.h @@ -230,6 +230,10 @@ #define CIC_CONFIG_CIC_SHIFT(x) SET_BITS(27, 24, x) #define CIC_CONFIG_COMB_COUNT(x) SET_BITS(15, 8, x) +/* CIC_CONFIG masks */ +#define CIC_CONFIG_CIC_SHIFT_MASK MASK(27, 24) +#define CIC_CONFIG_COMB_COUNT_MASK MASK(15, 8) + /* MIC_CONTROL bits */ #define MIC_CONTROL_PDM_EN_B_BIT BIT(1) #define MIC_CONTROL_PDM_EN_A_BIT BIT(0) @@ -239,6 +243,9 @@ #define MIC_CONTROL_PDM_EN_B(x) SET_BIT(1, x) #define MIC_CONTROL_PDM_EN_A(x) SET_BIT(0, x) +/* MIC_CONTROL masks */ +#define MIC_CONTROL_PDM_CLKDIV_MASK MASK(15, 8) + /* FIR_CONTROL_A bits */ #define FIR_CONTROL_A_START_BIT BIT(7) #define FIR_CONTROL_A_ARRAY_START_EN_BIT BIT(6) From 1ee1b4a33841809ed001ec30210dcdf4aac7fb56 Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Mon, 9 Nov 2020 19:22:20 +0200 Subject: [PATCH 42/47] Drivers: DMIC: Fix a mistake in FIR length and update the entire set The maximum length supported by HW is 250 while the existing decimate by 5 set is 251. Load attempt of it failed always. However it was needed only in a rare 8 and 16 kHz FIFOs configuration request. The new coefficients set fixes the issue. Also an alternate decimate by 3 set is removed as unnecessary and a decimate by 10 set is added. The DMIC filters design tool was updated for including to SOF tools. The specification adjust iteration in FIR design was improved to use finer step for bandwidth (the two four digits numbers in file name are band frequencies relative to sample rate) so many of the coefficients are changed. The CIC response estimation gives slightly different result depending on for which sample rate the decimation factor is. That is another reason for changed coefficients. This set is used to have the reference generate script available that creates these coefficients exactly. Signed-off-by: Seppo Ingalsuo --- src/drivers/intel/Kconfig | 11 + .../pdm_decim_int32_02_4288_5100_010_095.h | 107 ------ .../pdm_decim_int32_02_4323_5100_010_095.h | 109 ++++++ .../pdm_decim_int32_02_4375_5100_010_095.h | 140 ++++---- .../pdm_decim_int32_03_3850_5100_010_095.h | 109 ------ .../pdm_decim_int32_03_4375_5100_010_095.h | 316 +++++++++--------- .../pdm_decim_int32_04_4318_5100_010_095.h | 209 ++++++++++++ .../pdm_decim_int32_04_4375_5100_010_095.h | 227 ------------- .../pdm_decim_int32_05_4325_5100_010_095.h | 263 +++++++++++++++ .../pdm_decim_int32_05_4331_5100_010_095.h | 267 --------------- .../pdm_decim_int32_06_4156_5100_010_095.h | 265 --------------- .../pdm_decim_int32_06_4172_5100_010_095.h | 261 +++++++++++++++ .../pdm_decim_int32_08_4156_5301_010_090.h | 263 +++++++++++++++ .../pdm_decim_int32_08_4156_5380_010_090.h | 263 --------------- .../pdm_decim_int32_10_4156_5345_010_090.h | 264 +++++++++++++++ .../pdm_decim_int32_12_4156_5345_010_090.h | 264 +++++++++++++++ .../pdm_decim_int32_12_4156_6018_010_090.h | 255 -------------- .../coefficients/pdm_decim/pdm_decim_table.h | 32 +- 18 files changed, 1888 insertions(+), 1737 deletions(-) delete mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_02_4288_5100_010_095.h create mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_02_4323_5100_010_095.h delete mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_03_3850_5100_010_095.h create mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_04_4318_5100_010_095.h delete mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_04_4375_5100_010_095.h create mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_05_4325_5100_010_095.h delete mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_05_4331_5100_010_095.h delete mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_06_4156_5100_010_095.h create mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_06_4172_5100_010_095.h create mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_08_4156_5301_010_090.h delete mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_08_4156_5380_010_090.h create mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_10_4156_5345_010_090.h create mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_12_4156_5345_010_090.h delete mode 100644 src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_12_4156_6018_010_090.h diff --git a/src/drivers/intel/Kconfig b/src/drivers/intel/Kconfig index aad635124ae9..6c2f7a496640 100644 --- a/src/drivers/intel/Kconfig +++ b/src/drivers/intel/Kconfig @@ -61,6 +61,7 @@ config INTEL_DMIC_FIR_FULL select INTEL_DMIC_FIR_DECIMATE_BY_5 select INTEL_DMIC_FIR_DECIMATE_BY_6 select INTEL_DMIC_FIR_DECIMATE_BY_8 + select INTEL_DMIC_FIR_DECIMATE_BY_10 select INTEL_DMIC_FIR_DECIMATE_BY_12 help This option adds to previous all currently defined FIR @@ -146,6 +147,16 @@ config INTEL_DMIC_FIR_DECIMATE_BY_8 FIFO configurations may need for one FIR decimation such high decimation factor. +config INTEL_DMIC_FIR_DECIMATE_BY_10 + bool "FIR decimate by 10" + default n + help + This includes FIR coefficients to decimate by 10 into the build. + The high FIR decimation factors are needed for high microphone clock + rates due to max. decimation factor limitation of CIC. Also dual + FIFO configurations may need for one FIR decimation such high + decimation factor. + config INTEL_DMIC_FIR_DECIMATE_BY_12 bool "FIR decimate by 12" default n diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_02_4288_5100_010_095.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_02_4288_5100_010_095.h deleted file mode 100644 index 7baea26f967a..000000000000 --- a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_02_4288_5100_010_095.h +++ /dev/null @@ -1,107 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2019 Intel Corporation. All rights reserved. - * - * Author: Seppo Ingalsuo - */ - -#include - -const int32_t fir_int32_02_4288_5100_010_095[91] = { - -193886, - 104552, - 2140521, - 5355562, - 5945318, - 1216991, - -4511367, - -3527243, - 3415937, - 5526880, - -1935806, - -7515849, - -386524, - 9252379, - 3862172, - -10093681, - -8251552, - 9738620, - 13536988, - -7464432, - -19100785, - 2935187, - 24375729, - 4314479, - -28271418, - -14141458, - 29999307, - 26636531, - -28180625, - -41208987, - 21649022, - 57264356, - -8757879, - -73520802, - -12043366, - 88868414, - 43784598, - -101162825, - -91853580, - 106519993, - 169110273, - -94206010, - -317139630, - 5894310, - 739661049, - 1132200744, - 739661049, - 5894310, - -317139630, - -94206010, - 169110273, - 106519993, - -91853580, - -101162825, - 43784598, - 88868414, - -12043366, - -73520802, - -8757879, - 57264356, - 21649022, - -41208987, - -28180625, - 26636531, - 29999307, - -14141458, - -28271418, - 4314479, - 24375729, - 2935187, - -19100785, - -7464432, - 13536988, - 9738620, - -8251552, - -10093681, - 3862172, - 9252379, - -386524, - -7515849, - -1935806, - 5526880, - 3415937, - -3527243, - -4511367, - 1216991, - 5945318, - 5355562, - 2140521, - 104552, - -193886 - -}; - -struct pdm_decim pdm_decim_int32_02_4288_5100_010_095 = { - 2, 91, 0, 4288, 5100, 10, 95, fir_int32_02_4288_5100_010_095 -}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_02_4323_5100_010_095.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_02_4323_5100_010_095.h new file mode 100644 index 000000000000..957e9334cf83 --- /dev/null +++ b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_02_4323_5100_010_095.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + */ + +#include + +const int32_t fir_int32_02_4323_5100_010_095[95] = { + 178179, + -158757, + -2195582, + -5296650, + -5737416, + -1057695, + 4405719, + 3336648, + -3249588, + -5061179, + 1984305, + 6895125, + 68826, + -8433396, + -2933479, + 9499107, + 6882087, + -9330152, + -11397510, + 7807097, + 16376076, + -4402338, + -21239788, + -1118085, + 25423993, + 9062534, + -27935015, + -19203927, + 28049586, + 31500423, + -24524863, + -45191501, + 16582731, + 59861920, + -2808306, + -74639091, + -18696113, + 88054673, + 50505898, + -98266320, + -97865783, + 101816481, + 173879965, + -88042495, + -320187025, + -1193013, + 740698712, + 1139586920, + 740698712, + -1193013, + -320187025, + -88042495, + 173879965, + 101816481, + -97865783, + -98266320, + 50505898, + 88054673, + -18696113, + -74639091, + -2808306, + 59861920, + 16582731, + -45191501, + -24524863, + 31500423, + 28049586, + -19203927, + -27935015, + 9062534, + 25423993, + -1118085, + -21239788, + -4402338, + 16376076, + 7807097, + -11397510, + -9330152, + 6882087, + 9499107, + -2933479, + -8433396, + 68826, + 6895125, + 1984305, + -5061179, + -3249588, + 3336648, + 4405719, + -1057695, + -5737416, + -5296650, + -2195582, + -158757, + 178179 + +}; + +struct pdm_decim pdm_decim_int32_02_4323_5100_010_095 = { + 2, 95, 0, 4323, 5100, 10, 95, fir_int32_02_4323_5100_010_095 +}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_02_4375_5100_010_095.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_02_4375_5100_010_095.h index 1e31919fb569..d4d480b5a41e 100644 --- a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_02_4375_5100_010_095.h +++ b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_02_4375_5100_010_095.h @@ -1,8 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * * Copyright(c) 2019 Intel Corporation. All rights reserved. - * - * Author: Seppo Ingalsuo */ #include @@ -12,99 +10,99 @@ const int32_t fir_int32_02_4375_5100_010_095[101] = { -2653881, -5154608, -4845367, - -226473, + -226474, 4220832, 2571159, - -3184701, + -3184700, -4043579, 2206821, 5554546, - -750496, - -6923900, - -1268584, - 8073360, - 4085183, - -8546477, - -7505364, - 8176185, + -750495, + -6923897, + -1268580, + 8073364, + 4085184, + -8546479, + -7505366, + 8176184, 11533751, -6471060, - -15704256, - 3359707, - 19852409, - 1635593, + -15704257, + 3359705, + 19852407, + 1635592, -23144509, -8252640, - 25285013, - 16574479, + 25285011, + 16574477, -25723227, - -26663304, + -26663303, 23549736, - 38139664, - -17943366, - -50446983, - 8141043, - 63090267, - 7051351, - -75166959, - -29039894, - 85772627, - 60568979, - -93167356, - -106799776, - 94198973, - 180962815, - -78385592, - -324820245, + 38139662, + -17943368, + -50446982, + 8141045, + 63090266, + 7051348, + -75166961, + -29039893, + 85772628, + 60568976, + -93167361, + -106799777, + 94198977, + 180962817, + -78385599, + -324820256, -12243140, - 742491441, - 1151461281, - 742491441, + 742491464, + 1151461314, + 742491464, -12243140, - -324820245, - -78385592, - 180962815, - 94198973, - -106799776, - -93167356, - 60568979, - 85772627, - -29039894, - -75166959, - 7051351, - 63090267, - 8141043, - -50446983, - -17943366, - 38139664, + -324820256, + -78385599, + 180962817, + 94198977, + -106799777, + -93167361, + 60568976, + 85772628, + -29039893, + -75166961, + 7051348, + 63090266, + 8141045, + -50446982, + -17943368, + 38139662, 23549736, - -26663304, + -26663303, -25723227, - 16574479, - 25285013, + 16574477, + 25285011, -8252640, -23144509, - 1635593, - 19852409, - 3359707, - -15704256, + 1635592, + 19852407, + 3359705, + -15704257, -6471060, 11533751, - 8176185, - -7505364, - -8546477, - 4085183, - 8073360, - -1268584, - -6923900, - -750496, + 8176184, + -7505366, + -8546479, + 4085184, + 8073364, + -1268580, + -6923897, + -750495, 5554546, 2206821, -4043579, - -3184701, + -3184700, 2571159, 4220832, - -226473, + -226474, -4845367, -5154608, -2653881, diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_03_3850_5100_010_095.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_03_3850_5100_010_095.h deleted file mode 100644 index 9c18842584ed..000000000000 --- a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_03_3850_5100_010_095.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2019 Intel Corporation. All rights reserved. - * - * Author: Seppo Ingalsuo - */ - -#include - -const int32_t fir_int32_03_3850_5100_010_095[93] = { - 44212, - -302176, - -1360920, - -3291119, - -5495374, - -6588668, - -5102927, - -753403, - 4644861, - 7677973, - 5490212, - -1618066, - -9302333, - -11445730, - -4732005, - 7709057, - 17063964, - 14699335, - -457541, - -18980508, - -26202607, - -13319132, - 13695670, - 35545996, - 32740745, - 1994202, - -37267233, - -54079734, - -29355959, - 25448678, - 71128406, - 67328423, - 5964667, - -74773313, - -111583346, - -62643893, - 52737606, - 154899783, - 153311689, - 16759099, - -184962926, - -304661987, - -201939017, - 160731847, - 673585388, - 1122541471, - 1300561761, - 1122541471, - 673585388, - 160731847, - -201939017, - -304661987, - -184962926, - 16759099, - 153311689, - 154899783, - 52737606, - -62643893, - -111583346, - -74773313, - 5964667, - 67328423, - 71128406, - 25448678, - -29355959, - -54079734, - -37267233, - 1994202, - 32740745, - 35545996, - 13695670, - -13319132, - -26202607, - -18980508, - -457541, - 14699335, - 17063964, - 7709057, - -4732005, - -11445730, - -9302333, - -1618066, - 5490212, - 7677973, - 4644861, - -753403, - -5102927, - -6588668, - -5495374, - -3291119, - -1360920, - -302176, - 44212 - -}; - -struct pdm_decim pdm_decim_int32_03_3850_5100_010_095 = { - 3, 93, 1, 3850, 5100, 10, 95, fir_int32_03_3850_5100_010_095 -}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_03_4375_5100_010_095.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_03_4375_5100_010_095.h index a65a15a0481e..a4a4337b3f13 100644 --- a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_03_4375_5100_010_095.h +++ b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_03_4375_5100_010_095.h @@ -1,170 +1,168 @@ /* SPDX-License-Identifier: BSD-3-Clause * * Copyright(c) 2019 Intel Corporation. All rights reserved. - * - * Author: Seppo Ingalsuo */ #include const int32_t fir_int32_03_4375_5100_010_095[157] = { - 350904, - 1127891, - 2233546, - 3059556, - 2752177, - 818057, - -2252661, - -4944515, - -5550704, - -3466227, - 53089, - 2496755, - 1904111, - -1421730, - -4818556, - -5204443, - -1721082, - 3155305, - 5311444, - 2454515, - -3518616, - -7589471, - -5713308, - 1327821, - 7901341, - 7958087, - 527903, - -8633996, - -11354795, - -4214518, - 7627116, - 13970242, - 8263364, - -5861946, - -16549651, - -13529964, - 2213919, - 17870757, - 19056207, - 2854066, - -18029728, - -24979102, - -9860164, - 16175117, - 30545984, - 18605951, - -11894271, - -35172531, - -28918160, - 4746528, - 38201092, - 40590666, - 5825429, - -38712951, - -53159148, - -20283384, - 35723256, - 66120531, - 39265868, - -27910967, - -78795928, - -63663750, - 13458962, - 90416047, - 95193346, - 10755142, - -99897049, - -137497231, - -51075841, - 105457455, - 200047804, - 124561003, - -101612190, - -313384381, - -297343743, - 53701878, - 639681661, - 1187800564, - 1411050887, - 1187800564, - 639681661, - 53701878, - -297343743, - -313384381, - -101612190, - 124561003, - 200047804, - 105457455, - -51075841, - -137497231, - -99897049, - 10755142, - 95193346, - 90416047, - 13458962, - -63663750, - -78795928, - -27910967, - 39265868, - 66120531, - 35723256, - -20283384, - -53159148, - -38712951, - 5825429, - 40590666, - 38201092, - 4746528, - -28918160, - -35172531, - -11894271, - 18605951, - 30545984, - 16175117, - -9860164, - -24979102, - -18029728, - 2854066, - 19056207, - 17870757, - 2213919, - -13529964, - -16549651, - -5861946, - 8263364, - 13970242, - 7627116, - -4214518, - -11354795, - -8633996, - 527903, - 7958087, - 7901341, - 1327821, - -5713308, - -7589471, - -3518616, - 2454515, - 5311444, - 3155305, - -1721082, - -5204443, - -4818556, - -1421730, - 1904111, - 2496755, - 53089, - -3466227, - -5550704, - -4944515, - -2252661, - 818057, - 2752177, - 3059556, - 2233546, - 1127891, - 350904 + 350908, + 1127906, + 2233575, + 3059598, + 2752218, + 818077, + -2252677, + -4944563, + -5550761, + -3466262, + 53093, + 2496787, + 1904133, + -1421749, + -4818616, + -5204506, + -1721103, + 3155344, + 5311508, + 2454543, + -3518663, + -7589567, + -5713379, + 1327838, + 7901439, + 7958184, + 527907, + -8634105, + -11354937, + -4214569, + 7627213, + 13970417, + 8263468, + -5862019, + -16549858, + -13530131, + 2213952, + 17870989, + 19056458, + 2854116, + -18029944, + -24979416, + -9860304, + 16175288, + 30546328, + 18606151, + -11894439, + -35172976, + -28918520, + 4746588, + 38201563, + 40591159, + 5825487, + -38713444, + -53159813, + -20283635, + 35723701, + 66121349, + 39266346, + -27911327, + -78796917, + -63664545, + 13459132, + 90417174, + 95194527, + 10755265, + -99898306, + -137498952, + -51076476, + 105458775, + 200050300, + 124562550, + -101613472, + -313388303, + -297347454, + 53702567, + 639689683, + 1187815441, + 1411068556, + 1187815441, + 639689683, + 53702567, + -297347454, + -313388303, + -101613472, + 124562550, + 200050300, + 105458775, + -51076476, + -137498952, + -99898306, + 10755265, + 95194527, + 90417174, + 13459132, + -63664545, + -78796917, + -27911327, + 39266346, + 66121349, + 35723701, + -20283635, + -53159813, + -38713444, + 5825487, + 40591159, + 38201563, + 4746588, + -28918520, + -35172976, + -11894439, + 18606151, + 30546328, + 16175288, + -9860304, + -24979416, + -18029944, + 2854116, + 19056458, + 17870989, + 2213952, + -13530131, + -16549858, + -5862019, + 8263468, + 13970417, + 7627213, + -4214569, + -11354937, + -8634105, + 527907, + 7958184, + 7901439, + 1327838, + -5713379, + -7589567, + -3518663, + 2454543, + 5311508, + 3155344, + -1721103, + -5204506, + -4818616, + -1421749, + 1904133, + 2496787, + 53093, + -3466262, + -5550761, + -4944563, + -2252677, + 818077, + 2752218, + 3059598, + 2233575, + 1127906, + 350908 }; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_04_4318_5100_010_095.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_04_4318_5100_010_095.h new file mode 100644 index 000000000000..fc0eb0be8dac --- /dev/null +++ b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_04_4318_5100_010_095.h @@ -0,0 +1,209 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + */ + +#include + +const int32_t fir_int32_04_4318_5100_010_095[195] = { + 111466, + 733409, + 1749250, + 3319696, + 5129378, + 6676209, + 7309490, + 6506584, + 4154756, + 734975, + -2729377, + -4998637, + -5126868, + -2945573, + 726080, + 4306371, + 6084832, + 5022201, + 1343898, + -3405897, + -6962146, + -7384707, + -4083477, + 1706504, + 7322247, + 9858386, + 7634375, + 1218279, + -6584983, + -11909667, + -11705999, + -5426216, + 4387589, + 13057254, + 15953274, + 10914694, + -336708, + -12649310, + -19740590, + -17350504, + -5691816, + 10168034, + 22423979, + 24315225, + 13770305, + -5012695, + -23099234, + -30992981, + -23541145, + -3074594, + 21044646, + 36602258, + 34627991, + 14410179, + -15304906, + -39942350, + -46136506, + -28837515, + 5227124, + 39904111, + 57125295, + 46160603, + 9951610, + -35069112, + -66221384, + -65802058, + -30833475, + 23892424, + 71729303, + 86873627, + 57925919, + -4643620, + -71630929, + -108312985, + -91957579, + -25024430, + 63233146, + 128873180, + 134384678, + 69003997, + -42277605, + -146972769, + -188542432, + -135065835, + 625004, + 160544910, + 263771211, + 243538822, + 83417905, + -164654723, + -391259178, + -468017530, + -299941690, + 129616412, + 741218294, + 1378462855, + 1858765025, + 2037199780, + 1858765025, + 1378462855, + 741218294, + 129616412, + -299941690, + -468017530, + -391259178, + -164654723, + 83417905, + 243538822, + 263771211, + 160544910, + 625004, + -135065835, + -188542432, + -146972769, + -42277605, + 69003997, + 134384678, + 128873180, + 63233146, + -25024430, + -91957579, + -108312985, + -71630929, + -4643620, + 57925919, + 86873627, + 71729303, + 23892424, + -30833475, + -65802058, + -66221384, + -35069112, + 9951610, + 46160603, + 57125295, + 39904111, + 5227124, + -28837515, + -46136506, + -39942350, + -15304906, + 14410179, + 34627991, + 36602258, + 21044646, + -3074594, + -23541145, + -30992981, + -23099234, + -5012695, + 13770305, + 24315225, + 22423979, + 10168034, + -5691816, + -17350504, + -19740590, + -12649310, + -336708, + 10914694, + 15953274, + 13057254, + 4387589, + -5426216, + -11705999, + -11909667, + -6584983, + 1218279, + 7634375, + 9858386, + 7322247, + 1706504, + -4083477, + -7384707, + -6962146, + -3405897, + 1343898, + 5022201, + 6084832, + 4306371, + 726080, + -2945573, + -5126868, + -4998637, + -2729377, + 734975, + 4154756, + 6506584, + 7309490, + 6676209, + 5129378, + 3319696, + 1749250, + 733409, + 111466 + +}; + +struct pdm_decim pdm_decim_int32_04_4318_5100_010_095 = { + 4, 195, 2, 4318, 5100, 10, 95, fir_int32_04_4318_5100_010_095 +}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_04_4375_5100_010_095.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_04_4375_5100_010_095.h deleted file mode 100644 index ece85fabaf74..000000000000 --- a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_04_4375_5100_010_095.h +++ /dev/null @@ -1,227 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2019 Intel Corporation. All rights reserved. - * - * Author: Seppo Ingalsuo - */ - -#include - -const int32_t fir_int32_04_4375_5100_010_095[211] = { - 126017, - 745791, - 1735783, - 3250059, - 4963537, - 6400069, - 6949502, - 6142229, - 3902336, - 705842, - -2485787, - -4540607, - -4626085, - -2636100, - 646448, - 3784383, - 5275090, - 4259502, - 1015665, - -3045153, - -5950963, - -6099091, - -3115593, - 1807814, - 6342508, - 8093924, - 5838000, - 296533, - -6011752, - -9879686, - -9013045, - -3339610, - 4700101, - 11152288, - 12461593, - 7387989, - -2085667, - -11448775, - -15769545, - -12252662, - -1940150, - 10437445, - 18576639, - 17768944, - 7550319, - -7626200, - -20251921, - -23428157, - -14572076, - 2797464, - 20329234, - 28790530, - 22864155, - 4330980, - -18201801, - -33211863, - -32081436, - -13923851, - 13233081, - 35870337, - 41620943, - 25914222, - -4896316, - -35895437, - -50712381, - -40042952, - -7212823, - 32428935, - 58525317, - 56015029, - 23582638, - -24374765, - -63897455, - -73234460, - -44550852, - 10604843, - 65540282, - 91054416, - 70624752, - 10408242, - -61706258, - -108584856, - -102490195, - -40744453, - 50090298, - 124919090, - 141743373, - 84173003, - -26760833, - -138851415, - -191966143, - -148464813, - -16173880, - 148695193, - 262835505, - 254088691, - 100293640, - -149816104, - -385869984, - -474827254, - -315628113, - 112831849, - 731720961, - 1381072959, - 1872325415, - 2055132469, - 1872325415, - 1381072959, - 731720961, - 112831849, - -315628113, - -474827254, - -385869984, - -149816104, - 100293640, - 254088691, - 262835505, - 148695193, - -16173880, - -148464813, - -191966143, - -138851415, - -26760833, - 84173003, - 141743373, - 124919090, - 50090298, - -40744453, - -102490195, - -108584856, - -61706258, - 10408242, - 70624752, - 91054416, - 65540282, - 10604843, - -44550852, - -73234460, - -63897455, - -24374765, - 23582638, - 56015029, - 58525317, - 32428935, - -7212823, - -40042952, - -50712381, - -35895437, - -4896316, - 25914222, - 41620943, - 35870337, - 13233081, - -13923851, - -32081436, - -33211863, - -18201801, - 4330980, - 22864155, - 28790530, - 20329234, - 2797464, - -14572076, - -23428157, - -20251921, - -7626200, - 7550319, - 17768944, - 18576639, - 10437445, - -1940150, - -12252662, - -15769545, - -11448775, - -2085667, - 7387989, - 12461593, - 11152288, - 4700101, - -3339610, - -9013045, - -9879686, - -6011752, - 296533, - 5838000, - 8093924, - 6342508, - 1807814, - -3115593, - -6099091, - -5950963, - -3045153, - 1015665, - 4259502, - 5275090, - 3784383, - 646448, - -2636100, - -4626085, - -4540607, - -2485787, - 705842, - 3902336, - 6142229, - 6949502, - 6400069, - 4963537, - 3250059, - 1735783, - 745791, - 126017 - -}; - -struct pdm_decim pdm_decim_int32_04_4375_5100_010_095 = { - 4, 211, 2, 4375, 5100, 10, 95, fir_int32_04_4375_5100_010_095 -}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_05_4325_5100_010_095.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_05_4325_5100_010_095.h new file mode 100644 index 000000000000..4e5bf169a025 --- /dev/null +++ b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_05_4325_5100_010_095.h @@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + */ + +#include + +const int32_t fir_int32_05_4325_5100_010_095[249] = { + -207469, + -340409, + -498144, + -558705, + -409384, + 55040, + 891125, + 2067198, + 3439775, + 4759611, + 5714914, + 6006588, + 5438767, + 3999938, + 1904139, + -429386, + -2461501, + -3672469, + -3715731, + -2543409, + -455850, + 1949813, + 3931230, + 4816572, + 4223058, + 2208032, + -705100, + -3649781, + -5664341, + -5997954, + -4379534, + -1155856, + 2760627, + 6138124, + 7803235, + 7038238, + 3865643, + -886573, + -5783539, + -9205487, + -9873081, + -7309023, + -2074085, + 4324112, + 9849851, + 12575185, + 11338304, + 6203771, + -1449001, + -9273272, + -14659745, + -15592551, + -11379919, + -3001447, + 7079011, + 15617750, + 19618936, + 17365380, + 9103870, + -2875883, + -14845719, + -22779047, + -23684744, + -16699479, + -3549687, + 11824128, + 24420688, + 29781202, + 25536278, + 12369331, + -5975020, + -23715313, + -34825066, + -35046780, + -23465500, + -3076561, + 19921841, + 37971240, + 44596949, + 36675890, + 15750350, + -12128842, + -38090537, + -53213360, + -51529430, + -32269554, + -535756, + 33948414, + 59741809, + 67400482, + 52822241, + 19070165, + -24058950, + -62761384, + -83526757, + -77707237, + -44854657, + 6391470, + 60372631, + 99010031, + 107635426, + 80237884, + 22341840, + -49653145, + -112793869, + -144502927, + -130123093, + -68698546, + 25049444, + 123586766, + 193887099, + 207405271, + 149914650, + 28201854, + -128717667, + -274782040, + -357589632, + -332094228, + -173714910, + 112793207, + 491412574, + 900833942, + 1267184732, + 1520519220, + 1610979079, + 1520519220, + 1267184732, + 900833942, + 491412574, + 112793207, + -173714910, + -332094228, + -357589632, + -274782040, + -128717667, + 28201854, + 149914650, + 207405271, + 193887099, + 123586766, + 25049444, + -68698546, + -130123093, + -144502927, + -112793869, + -49653145, + 22341840, + 80237884, + 107635426, + 99010031, + 60372631, + 6391470, + -44854657, + -77707237, + -83526757, + -62761384, + -24058950, + 19070165, + 52822241, + 67400482, + 59741809, + 33948414, + -535756, + -32269554, + -51529430, + -53213360, + -38090537, + -12128842, + 15750350, + 36675890, + 44596949, + 37971240, + 19921841, + -3076561, + -23465500, + -35046780, + -34825066, + -23715313, + -5975020, + 12369331, + 25536278, + 29781202, + 24420688, + 11824128, + -3549687, + -16699479, + -23684744, + -22779047, + -14845719, + -2875883, + 9103870, + 17365380, + 19618936, + 15617750, + 7079011, + -3001447, + -11379919, + -15592551, + -14659745, + -9273272, + -1449001, + 6203771, + 11338304, + 12575185, + 9849851, + 4324112, + -2074085, + -7309023, + -9873081, + -9205487, + -5783539, + -886573, + 3865643, + 7038238, + 7803235, + 6138124, + 2760627, + -1155856, + -4379534, + -5997954, + -5664341, + -3649781, + -705100, + 2208032, + 4223058, + 4816572, + 3931230, + 1949813, + -455850, + -2543409, + -3715731, + -3672469, + -2461501, + -429386, + 1904139, + 3999938, + 5438767, + 6006588, + 5714914, + 4759611, + 3439775, + 2067198, + 891125, + 55040, + -409384, + -558705, + -498144, + -340409, + -207469 + +}; + +struct pdm_decim pdm_decim_int32_05_4325_5100_010_095 = { + 5, 249, 2, 4325, 5100, 10, 95, fir_int32_05_4325_5100_010_095 +}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_05_4331_5100_010_095.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_05_4331_5100_010_095.h deleted file mode 100644 index 9c746b0ab1fc..000000000000 --- a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_05_4331_5100_010_095.h +++ /dev/null @@ -1,267 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2019 Intel Corporation. All rights reserved. - * - * Author: Seppo Ingalsuo - */ - -#include - -const int32_t fir_int32_05_4331_5100_010_095[251] = { - -250963, - -530472, - -956449, - -1440505, - -1861966, - -2058350, - -1862594, - -1155766, - 78930, - 1719645, - 3501958, - 5061143, - 6013975, - 6066039, - 5113131, - 3303104, - 1032343, - -1135681, - -2614668, - -2968117, - -2057986, - -118896, - 2276521, - 4363476, - 5409644, - 4953617, - 2982225, - -20415, - -3181416, - -5487913, - -6107986, - -4685208, - -1505051, - 2535666, - 6167372, - 8134966, - 7619351, - 4554012, - -280001, - -5435156, - -9220394, - -10246686, - -7922490, - -2726786, - 3853867, - 9734139, - 12878468, - 11991508, - 7020539, - -717311, - -8859727, - -14705610, - -16097433, - -12195790, - -3874308, - 6431337, - 15415517, - 19946809, - 18139792, - 10093658, - -1980159, - -14334496, - -22829097, - -24298020, - -17696570, - -4621840, - 11019276, - 24149376, - 30144976, - 26434112, - 13524367, - -4930822, - -23124320, - -34892082, - -35768599, - -24626114, - -4311380, - 19011680, - 37690383, - 45054463, - 37744852, - 17102968, - -10919933, - -37416293, - -53300866, - -52364722, - -33596881, - -1935268, - 32928131, - 59438198, - 67925581, - 54022129, - 20569914, - -22737901, - -62048140, - -83661289, - -78659667, - -46330665, - 4859442, - 59276671, - 98707953, - 108233225, - 81552245, - 23955872, - -48257755, - -112070264, - -144691658, - -131171943, - -70276392, - 23448172, - 122479978, - 193637242, - 208100323, - 151336952, - 29895897, - -127299559, - -274102498, - -357874627, - -333256339, - -175377009, - 111180608, - 490397234, - 900786668, - 1268179136, - 1522305381, - 1613059887, - 1522305381, - 1268179136, - 900786668, - 490397234, - 111180608, - -175377009, - -333256339, - -357874627, - -274102498, - -127299559, - 29895897, - 151336952, - 208100323, - 193637242, - 122479978, - 23448172, - -70276392, - -131171943, - -144691658, - -112070264, - -48257755, - 23955872, - 81552245, - 108233225, - 98707953, - 59276671, - 4859442, - -46330665, - -78659667, - -83661289, - -62048140, - -22737901, - 20569914, - 54022129, - 67925581, - 59438198, - 32928131, - -1935268, - -33596881, - -52364722, - -53300866, - -37416293, - -10919933, - 17102968, - 37744852, - 45054463, - 37690383, - 19011680, - -4311380, - -24626114, - -35768599, - -34892082, - -23124320, - -4930822, - 13524367, - 26434112, - 30144976, - 24149376, - 11019276, - -4621840, - -17696570, - -24298020, - -22829097, - -14334496, - -1980159, - 10093658, - 18139792, - 19946809, - 15415517, - 6431337, - -3874308, - -12195790, - -16097433, - -14705610, - -8859727, - -717311, - 7020539, - 11991508, - 12878468, - 9734139, - 3853867, - -2726786, - -7922490, - -10246686, - -9220394, - -5435156, - -280001, - 4554012, - 7619351, - 8134966, - 6167372, - 2535666, - -1505051, - -4685208, - -6107986, - -5487913, - -3181416, - -20415, - 2982225, - 4953617, - 5409644, - 4363476, - 2276521, - -118896, - -2057986, - -2968117, - -2614668, - -1135681, - 1032343, - 3303104, - 5113131, - 6066039, - 6013975, - 5061143, - 3501958, - 1719645, - 78930, - -1155766, - -1862594, - -2058350, - -1861966, - -1440505, - -956449, - -530472, - -250963 - -}; - -struct pdm_decim pdm_decim_int32_05_4331_5100_010_095 = { - 5, 251, 2, 4331, 5100, 10, 95, fir_int32_05_4331_5100_010_095 -}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_06_4156_5100_010_095.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_06_4156_5100_010_095.h deleted file mode 100644 index b949ff23ed90..000000000000 --- a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_06_4156_5100_010_095.h +++ /dev/null @@ -1,265 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2019 Intel Corporation. All rights reserved. - * - * Author: Seppo Ingalsuo - */ - -#include - -const int32_t fir_int32_06_4156_5100_010_095[249] = { - -145670, - -159762, - -183049, - -132077, - 40047, - 375196, - 897258, - 1599108, - 2433074, - 3308273, - 4097062, - 4651618, - 4829700, - 4525669, - 3700263, - 2402258, - 776038, - -950161, - -2496541, - -3579851, - -3970442, - -3547641, - -2337956, - -529617, - 1547925, - 3476297, - 4827277, - 5253398, - 4572039, - 2823110, - 284249, - -2564887, - -5127174, - -6808166, - -7148614, - -5940791, - -3300873, - 324045, - 4222816, - 7553233, - 9518313, - 9550081, - 7459490, - 3515883, - -1570147, - -6764980, - -10915019, - -12995804, - -12355318, - -8895306, - -3143626, - 3808819, - 10504528, - 15416643, - 17288185, - 15439779, - 9973227, - 1815303, - -7421871, - -15747713, - -21211963, - -22349384, - -18551421, - -10274491, - 976318, - 12902423, - 22867792, - 28468157, - 28093650, - 21356476, - 9275878, - -5840836, - -20818261, - -32262581, - -37311768, - -34324420, - -23346677, - -6234152, - 13625405, - 31957173, - 44495096, - 47945809, - 40808741, - 23856504, - 140921, - -25513494, - -47455167, - -60412143, - -60710132, - -47229950, - -21869611, - 10631696, - 43519737, - 69370312, - 81696614, - 76484113, - 53307373, - 15747228, - -29042608, - -71597234, - -102026296, - -112167649, - -97565632, - -58831316, - -2036750, - 62029440, - 119693403, - 157031723, - 162840122, - 131357475, - 64171528, - -29147598, - -131921532, - -222701994, - -278742412, - -280032642, - -213184166, - -74440208, - 128790505, - 378234661, - 646928572, - 902966510, - 1114231037, - 1253321369, - 1301843153, - 1253321369, - 1114231037, - 902966510, - 646928572, - 378234661, - 128790505, - -74440208, - -213184166, - -280032642, - -278742412, - -222701994, - -131921532, - -29147598, - 64171528, - 131357475, - 162840122, - 157031723, - 119693403, - 62029440, - -2036750, - -58831316, - -97565632, - -112167649, - -102026296, - -71597234, - -29042608, - 15747228, - 53307373, - 76484113, - 81696614, - 69370312, - 43519737, - 10631696, - -21869611, - -47229950, - -60710132, - -60412143, - -47455167, - -25513494, - 140921, - 23856504, - 40808741, - 47945809, - 44495096, - 31957173, - 13625405, - -6234152, - -23346677, - -34324420, - -37311768, - -32262581, - -20818261, - -5840836, - 9275878, - 21356476, - 28093650, - 28468157, - 22867792, - 12902423, - 976318, - -10274491, - -18551421, - -22349384, - -21211963, - -15747713, - -7421871, - 1815303, - 9973227, - 15439779, - 17288185, - 15416643, - 10504528, - 3808819, - -3143626, - -8895306, - -12355318, - -12995804, - -10915019, - -6764980, - -1570147, - 3515883, - 7459490, - 9550081, - 9518313, - 7553233, - 4222816, - 324045, - -3300873, - -5940791, - -7148614, - -6808166, - -5127174, - -2564887, - 284249, - 2823110, - 4572039, - 5253398, - 4827277, - 3476297, - 1547925, - -529617, - -2337956, - -3547641, - -3970442, - -3579851, - -2496541, - -950161, - 776038, - 2402258, - 3700263, - 4525669, - 4829700, - 4651618, - 4097062, - 3308273, - 2433074, - 1599108, - 897258, - 375196, - 40047, - -132077, - -183049, - -159762, - -145670 - -}; - -struct pdm_decim pdm_decim_int32_06_4156_5100_010_095 = { - 6, 249, 2, 4156, 5100, 10, 95, fir_int32_06_4156_5100_010_095 -}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_06_4172_5100_010_095.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_06_4172_5100_010_095.h new file mode 100644 index 000000000000..b34905dc3bba --- /dev/null +++ b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_06_4172_5100_010_095.h @@ -0,0 +1,261 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + */ + +#include + +const int32_t fir_int32_06_4172_5100_010_095[247] = { + -128632, + -59497, + 27046, + 238561, + 615381, + 1180391, + 1925670, + 2802557, + 3718091, + 4541067, + 5118546, + 5302088, + 4979296, + 4105097, + 2725202, + 985340, + -879509, + -2576724, + -3805615, + -4316339, + -3968132, + -2772637, + -910841, + 1284350, + 3378797, + 4918713, + 5524148, + 4978750, + 3294285, + 731418, + -2230825, + -4978575, + -6884637, + -7446661, + -6411304, + -3856078, + -204820, + 3832851, + 7392855, + 9635554, + 9937191, + 8050966, + 4198476, + -936294, + -6318030, + -10761631, + -13186246, + -12869044, + -9641051, + -3974915, + 3065409, + 10013209, + 15296510, + 17584632, + 16110734, + 10893393, + 2799042, + -6583403, + -15242334, + -21164579, + -22791637, + -19410411, + -11383563, + -154458, + 11993186, + 22385766, + 28535081, + 28717126, + 22423602, + 10572914, + -4585854, + -19878539, + -31852959, + -37539801, + -35162895, + -24634855, + -7708109, + 12278651, + 31033082, + 44206560, + 48374146, + 41881953, + 25360406, + 1761722, + -24123604, + -46603137, + -60296121, + -61373509, + -48548023, + -23572693, + 8903015, + 42138419, + 68642074, + 81792054, + 77398921, + 54859810, + 17614341, + -27257528, + -70279853, + -101467545, + -112499312, + -98729567, + -60589492, + -4020371, + 60241948, + 118486175, + 156668601, + 163407087, + 132743110, + 66089855, + -27096695, + -130167425, + -221612366, + -278546163, + -280773282, + -214713860, + -76455494, + 126679457, + 376416772, + 645705969, + 902489232, + 1114466646, + 1254066162, + 1302772250, + 1254066162, + 1114466646, + 902489232, + 645705969, + 376416772, + 126679457, + -76455494, + -214713860, + -280773282, + -278546163, + -221612366, + -130167425, + -27096695, + 66089855, + 132743110, + 163407087, + 156668601, + 118486175, + 60241948, + -4020371, + -60589492, + -98729567, + -112499312, + -101467545, + -70279853, + -27257528, + 17614341, + 54859810, + 77398921, + 81792054, + 68642074, + 42138419, + 8903015, + -23572693, + -48548023, + -61373509, + -60296121, + -46603137, + -24123604, + 1761722, + 25360406, + 41881953, + 48374146, + 44206560, + 31033082, + 12278651, + -7708109, + -24634855, + -35162895, + -37539801, + -31852959, + -19878539, + -4585854, + 10572914, + 22423602, + 28717126, + 28535081, + 22385766, + 11993186, + -154458, + -11383563, + -19410411, + -22791637, + -21164579, + -15242334, + -6583403, + 2799042, + 10893393, + 16110734, + 17584632, + 15296510, + 10013209, + 3065409, + -3974915, + -9641051, + -12869044, + -13186246, + -10761631, + -6318030, + -936294, + 4198476, + 8050966, + 9937191, + 9635554, + 7392855, + 3832851, + -204820, + -3856078, + -6411304, + -7446661, + -6884637, + -4978575, + -2230825, + 731418, + 3294285, + 4978750, + 5524148, + 4918713, + 3378797, + 1284350, + -910841, + -2772637, + -3968132, + -4316339, + -3805615, + -2576724, + -879509, + 985340, + 2725202, + 4105097, + 4979296, + 5302088, + 5118546, + 4541067, + 3718091, + 2802557, + 1925670, + 1180391, + 615381, + 238561, + 27046, + -59497, + -128632 + +}; + +struct pdm_decim pdm_decim_int32_06_4172_5100_010_095 = { + 6, 247, 2, 4172, 5100, 10, 95, fir_int32_06_4172_5100_010_095 +}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_08_4156_5301_010_090.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_08_4156_5301_010_090.h new file mode 100644 index 000000000000..aa15e7b741ab --- /dev/null +++ b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_08_4156_5301_010_090.h @@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + */ + +#include + +const int32_t fir_int32_08_4156_5301_010_090[249] = { + -436533, + -30097, + 185136, + 599151, + 1249127, + 2156309, + 3316125, + 4690126, + 6201703, + 7736149, + 9146691, + 10266194, + 10924643, + 10970009, + 10291237, + 8839410, + 6645091, + 3827796, + 595625, + -2767301, + -5925074, + -8524488, + -10235869, + -10797193, + -10055131, + -7997758, + -4771108, + -678235, + 3841448, + 8252025, + 11985305, + 14503017, + 15375105, + 14342998, + 11370408, + 6669744, + 697166, + -5883789, + -12270613, + -17614188, + -21126754, + -22191034, + -20457484, + -15913860, + -8916788, + -176408, + 9306801, + 18349873, + 25728753, + 30337331, + 31343834, + 28324134, + 21351665, + 11028693, + -1551253, + -14908738, + -27343830, + -37144407, + -42813431, + -43283070, + -38091954, + -27492154, + -12471488, + 5321162, + 23744416, + 40410795, + 52985294, + 59498920, + 58637630, + 49965561, + 34048834, + 12455105, + -12379340, + -37407904, + -59331472, + -75016381, + -81921345, + -78477412, + -64367569, + -40661743, + -9779029, + 24730505, + 58569248, + 87201632, + 106433026, + 112987295, + 105007254, + 82406938, + 47020690, + 2512109, + -45960354, + -92298012, + -130180961, + -153871591, + -159007197, + -143278921, + -106903512, + -52811885, + 13489989, + 84396518, + 150980417, + 204001696, + 235041565, + 237634873, + 208265018, + 147093489, + 58319704, + -49897266, + -165975625, + -275876513, + -364417203, + -416806765, + -420248734, + -365439450, + -247794421, + -68258347, + 166406038, + 443903891, + 747260153, + 1056170460, + 1348727100, + 1603354585, + 1800763975, + 1925728602, + 1968501522, + 1925728602, + 1800763975, + 1603354585, + 1348727100, + 1056170460, + 747260153, + 443903891, + 166406038, + -68258347, + -247794421, + -365439450, + -420248734, + -416806765, + -364417203, + -275876513, + -165975625, + -49897266, + 58319704, + 147093489, + 208265018, + 237634873, + 235041565, + 204001696, + 150980417, + 84396518, + 13489989, + -52811885, + -106903512, + -143278921, + -159007197, + -153871591, + -130180961, + -92298012, + -45960354, + 2512109, + 47020690, + 82406938, + 105007254, + 112987295, + 106433026, + 87201632, + 58569248, + 24730505, + -9779029, + -40661743, + -64367569, + -78477412, + -81921345, + -75016381, + -59331472, + -37407904, + -12379340, + 12455105, + 34048834, + 49965561, + 58637630, + 59498920, + 52985294, + 40410795, + 23744416, + 5321162, + -12471488, + -27492154, + -38091954, + -43283070, + -42813431, + -37144407, + -27343830, + -14908738, + -1551253, + 11028693, + 21351665, + 28324134, + 31343834, + 30337331, + 25728753, + 18349873, + 9306801, + -176408, + -8916788, + -15913860, + -20457484, + -22191034, + -21126754, + -17614188, + -12270613, + -5883789, + 697166, + 6669744, + 11370408, + 14342998, + 15375105, + 14503017, + 11985305, + 8252025, + 3841448, + -678235, + -4771108, + -7997758, + -10055131, + -10797193, + -10235869, + -8524488, + -5925074, + -2767301, + 595625, + 3827796, + 6645091, + 8839410, + 10291237, + 10970009, + 10924643, + 10266194, + 9146691, + 7736149, + 6201703, + 4690126, + 3316125, + 2156309, + 1249127, + 599151, + 185136, + -30097, + -436533 + +}; + +struct pdm_decim pdm_decim_int32_08_4156_5301_010_090 = { + 8, 249, 3, 4156, 5301, 10, 90, fir_int32_08_4156_5301_010_090 +}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_08_4156_5380_010_090.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_08_4156_5380_010_090.h deleted file mode 100644 index 7d2a880b15f8..000000000000 --- a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_08_4156_5380_010_090.h +++ /dev/null @@ -1,263 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2019 Intel Corporation. All rights reserved. - * - * Author: Seppo Ingalsuo - */ - -#include - -const int32_t fir_int32_08_4156_5380_010_090[247] = { - -337052, - -90075, - 37780, - 310298, - 762602, - 1418014, - 2279975, - 3324413, - 4495298, - 5703536, - 6831280, - 7740936, - 8289504, - 8346168, - 7812523, - 6641741, - 4854841, - 2549644, - -98570, - -2847418, - -5407472, - -7472951, - -8758755, - -9040926, - -8192669, - -6213693, - -3246278, - 424677, - 4395972, - 8180309, - 11265189, - 13176475, - 13545386, - 12170147, - 9059463, - 4454447, - -1180491, - -7196755, - -12830960, - -17296055, - -19885729, - -20077500, - -17621714, - -12601266, - -5452197, - 3062539, - 11925735, - 19980775, - 26075722, - 29220338, - 28734576, - 24368837, - 16375791, - 5519930, - -6982346, - -19587960, - -30609997, - -38433685, - -41741838, - -39718804, - -32202058, - -19758650, - -3667506, - 14195787, - 31565234, - 46060011, - 55497992, - 58207057, - 53292128, - 40817642, - 21874421, - -1487369, - -26460171, - -49799428, - -68227825, - -78875217, - -79697543, - -69816864, - -49730377, - -21350328, - 12143051, - 46630130, - 77532435, - 100390923, - 111473843, - 108334402, - 90240198, - 58408793, - 16001822, - -32138446, - -79996329, - -121085165, - -149268412, - -159601418, - -149086287, - -117235239, - -66355092, - -1494553, - 69965597, - 139055884, - 196228005, - 232526458, - 240790250, - 216740138, - 159811182, - 73611998, - -34070591, - -151754583, - -265210746, - -358796902, - -417052464, - -426388521, - -376691518, - -262659116, - -84707915, - 150664267, - 431125422, - 739363099, - 1054476937, - 1353781691, - 1614844650, - 1817552687, - 1945997296, - 1989982406, - 1945997296, - 1817552687, - 1614844650, - 1353781691, - 1054476937, - 739363099, - 431125422, - 150664267, - -84707915, - -262659116, - -376691518, - -426388521, - -417052464, - -358796902, - -265210746, - -151754583, - -34070591, - 73611998, - 159811182, - 216740138, - 240790250, - 232526458, - 196228005, - 139055884, - 69965597, - -1494553, - -66355092, - -117235239, - -149086287, - -159601418, - -149268412, - -121085165, - -79996329, - -32138446, - 16001822, - 58408793, - 90240198, - 108334402, - 111473843, - 100390923, - 77532435, - 46630130, - 12143051, - -21350328, - -49730377, - -69816864, - -79697543, - -78875217, - -68227825, - -49799428, - -26460171, - -1487369, - 21874421, - 40817642, - 53292128, - 58207057, - 55497992, - 46060011, - 31565234, - 14195787, - -3667506, - -19758650, - -32202058, - -39718804, - -41741838, - -38433685, - -30609997, - -19587960, - -6982346, - 5519930, - 16375791, - 24368837, - 28734576, - 29220338, - 26075722, - 19980775, - 11925735, - 3062539, - -5452197, - -12601266, - -17621714, - -20077500, - -19885729, - -17296055, - -12830960, - -7196755, - -1180491, - 4454447, - 9059463, - 12170147, - 13545386, - 13176475, - 11265189, - 8180309, - 4395972, - 424677, - -3246278, - -6213693, - -8192669, - -9040926, - -8758755, - -7472951, - -5407472, - -2847418, - -98570, - 2549644, - 4854841, - 6641741, - 7812523, - 8346168, - 8289504, - 7740936, - 6831280, - 5703536, - 4495298, - 3324413, - 2279975, - 1418014, - 762602, - 310298, - 37780, - -90075, - -337052 - -}; - -struct pdm_decim pdm_decim_int32_08_4156_5380_010_090 = { - 8, 247, 3, 4156, 5380, 10, 90, fir_int32_08_4156_5380_010_090 -}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_10_4156_5345_010_090.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_10_4156_5345_010_090.h new file mode 100644 index 000000000000..40b73ee3c2f2 --- /dev/null +++ b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_10_4156_5345_010_090.h @@ -0,0 +1,264 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + */ + +#include + +const int32_t fir_int32_10_4156_5345_010_090[250] = { + 1523665, + 1033186, + 1237912, + 1334775, + 1259136, + 945771, + 330804, + -639430, + -2007230, + -3782603, + -5951062, + -8464725, + -11233139, + -14135396, + -17013193, + -19685639, + -21953913, + -23620153, + -24499971, + -24438406, + -23328862, + -21124651, + -17851431, + -13614282, + -8597813, + -3061758, + 2673313, + 8241850, + 13260214, + 17352951, + 20183225, + 21483036, + 21079871, + 18918865, + 15076270, + 9764507, + 3325641, + -3786831, + -11034844, + -17834361, + -23598518, + -27786005, + -29948197, + -29773031, + -27120493, + -22045821, + -14809184, + -5868041, + 4147420, + 14474606, + 24273606, + 32691772, + 38934943, + 42337380, + 42426833, + 38977193, + 32043932, + 21978645, + 9419218, + -4744590, + -19429341, + -33436251, + -45544284, + -54611932, + -59678078, + -60055175, + -55404949, + -45789928, + -31694490, + -14011800, + 6004287, + 26821132, + 46737621, + 64015881, + 77024918, + 84384267, + 85096503, + 78655977, + 65124057, + 45161629, + 20014065, + -8553289, + -38367257, + -66999907, + -91952963, + -110860336, + -121693302, + -122951962, + -113826153, + -94311463, + -65267325, + -28409399, + 13767679, + 58135590, + 101138413, + 139047421, + 168247614, + 185536046, + 188409622, + 175319624, + 145872050, + 100954938, + 42779310, + -25174601, + -98307054, + -171138928, + -237629824, + -291555223, + -326919157, + -338374861, + -321624361, + -273768560, + -193581379, + -81686484, + 59379271, + 225223665, + 409778420, + 605591661, + 804217132, + 996677146, + 1173970423, + 1327592623, + 1450036054, + 1535235882, + 1578933611, + 1578933611, + 1535235882, + 1450036054, + 1327592623, + 1173970423, + 996677146, + 804217132, + 605591661, + 409778420, + 225223665, + 59379271, + -81686484, + -193581379, + -273768560, + -321624361, + -338374861, + -326919157, + -291555223, + -237629824, + -171138928, + -98307054, + -25174601, + 42779310, + 100954938, + 145872050, + 175319624, + 188409622, + 185536046, + 168247614, + 139047421, + 101138413, + 58135590, + 13767679, + -28409399, + -65267325, + -94311463, + -113826153, + -122951962, + -121693302, + -110860336, + -91952963, + -66999907, + -38367257, + -8553289, + 20014065, + 45161629, + 65124057, + 78655977, + 85096503, + 84384267, + 77024918, + 64015881, + 46737621, + 26821132, + 6004287, + -14011800, + -31694490, + -45789928, + -55404949, + -60055175, + -59678078, + -54611932, + -45544284, + -33436251, + -19429341, + -4744590, + 9419218, + 21978645, + 32043932, + 38977193, + 42426833, + 42337380, + 38934943, + 32691772, + 24273606, + 14474606, + 4147420, + -5868041, + -14809184, + -22045821, + -27120493, + -29773031, + -29948197, + -27786005, + -23598518, + -17834361, + -11034844, + -3786831, + 3325641, + 9764507, + 15076270, + 18918865, + 21079871, + 21483036, + 20183225, + 17352951, + 13260214, + 8241850, + 2673313, + -3061758, + -8597813, + -13614282, + -17851431, + -21124651, + -23328862, + -24438406, + -24499971, + -23620153, + -21953913, + -19685639, + -17013193, + -14135396, + -11233139, + -8464725, + -5951062, + -3782603, + -2007230, + -639430, + 330804, + 945771, + 1259136, + 1334775, + 1237912, + 1033186, + 1523665 + +}; + +struct pdm_decim pdm_decim_int32_10_4156_5345_010_090 = { + 10, 250, 3, 4156, 5345, 10, 90, fir_int32_10_4156_5345_010_090 +}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_12_4156_5345_010_090.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_12_4156_5345_010_090.h new file mode 100644 index 000000000000..bb8de44010b6 --- /dev/null +++ b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_12_4156_5345_010_090.h @@ -0,0 +1,264 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + */ + +#include + +const int32_t fir_int32_12_4156_5345_010_090[250] = { + 3388064, + 2103678, + 2588621, + 3003201, + 3289311, + 3375616, + 3187681, + 2654590, + 1715972, + 309000, + -1610211, + -4055571, + -7035886, + -10511174, + -14426105, + -18683424, + -23158811, + -27697959, + -32125744, + -36244313, + -39850668, + -42739502, + -44716782, + -45614286, + -45293362, + -43663492, + -40685637, + -36382432, + -30840569, + -24214188, + -16719141, + -8631481, + -273616, + 7996830, + 15802429, + 22766807, + 28531588, + 32779134, + 35250465, + 35763733, + 34227329, + 30653000, + 25158397, + 17970176, + 9416017, + -86479, + -10047026, + -19926252, + -29162149, + -37200047, + -43523733, + -47686853, + -49340539, + -48260145, + -44362718, + -37720992, + -28567244, + -17289156, + -4416600, + 9400589, + 23423041, + 36858656, + 48904650, + 58793401, + 65836995, + 69472264, + 69298737, + 65111461, + 56923398, + 44977350, + 29744904, + 11913285, + -7641844, + -27894994, + -47720356, + -65950400, + -81438916, + -93127908, + -100112283, + -101700449, + -97465921, + -87287745, + -71375413, + -50277965, + -24873838, + 3657557, + 33882414, + 64176403, + 92802029, + 117997525, + 138071930, + 151502587, + 157029100, + 153740023, + 141145505, + 119233461, + 88503690, + 49978361, + 5186664, + -43876910, + -94819563, + -144940463, + -191340721, + -231048840, + -261155504, + -278952672, + -282068987, + -268596392, + -237200378, + -187208906, + -118674579, + -32406655, + 70029801, + 186348178, + 313607557, + 448310730, + 586528751, + 724047761, + 856530828, + 979688864, + 1089452098, + 1182135271, + 1254588364, + 1304326765, + 1329634160, + 1329634160, + 1304326765, + 1254588364, + 1182135271, + 1089452098, + 979688864, + 856530828, + 724047761, + 586528751, + 448310730, + 313607557, + 186348178, + 70029801, + -32406655, + -118674579, + -187208906, + -237200378, + -268596392, + -282068987, + -278952672, + -261155504, + -231048840, + -191340721, + -144940463, + -94819563, + -43876910, + 5186664, + 49978361, + 88503690, + 119233461, + 141145505, + 153740023, + 157029100, + 151502587, + 138071930, + 117997525, + 92802029, + 64176403, + 33882414, + 3657557, + -24873838, + -50277965, + -71375413, + -87287745, + -97465921, + -101700449, + -100112283, + -93127908, + -81438916, + -65950400, + -47720356, + -27894994, + -7641844, + 11913285, + 29744904, + 44977350, + 56923398, + 65111461, + 69298737, + 69472264, + 65836995, + 58793401, + 48904650, + 36858656, + 23423041, + 9400589, + -4416600, + -17289156, + -28567244, + -37720992, + -44362718, + -48260145, + -49340539, + -47686853, + -43523733, + -37200047, + -29162149, + -19926252, + -10047026, + -86479, + 9416017, + 17970176, + 25158397, + 30653000, + 34227329, + 35763733, + 35250465, + 32779134, + 28531588, + 22766807, + 15802429, + 7996830, + -273616, + -8631481, + -16719141, + -24214188, + -30840569, + -36382432, + -40685637, + -43663492, + -45293362, + -45614286, + -44716782, + -42739502, + -39850668, + -36244313, + -32125744, + -27697959, + -23158811, + -18683424, + -14426105, + -10511174, + -7035886, + -4055571, + -1610211, + 309000, + 1715972, + 2654590, + 3187681, + 3375616, + 3289311, + 3003201, + 2588621, + 2103678, + 3388064 + +}; + +struct pdm_decim pdm_decim_int32_12_4156_5345_010_090 = { + 12, 250, 3, 4156, 5345, 10, 90, fir_int32_12_4156_5345_010_090 +}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_12_4156_6018_010_090.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_12_4156_6018_010_090.h deleted file mode 100644 index 8662af709b07..000000000000 --- a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_int32_12_4156_6018_010_090.h +++ /dev/null @@ -1,255 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2019 Intel Corporation. All rights reserved. - * - * Author: Seppo Ingalsuo - */ - -const int32_t fir_int32_12_4156_6018_010_090[241] = { - 314962, - 709564, - 816474, - 1395294, - 1841297, - 2523842, - 3198174, - 3983930, - 4760567, - 5540984, - 6242495, - 6830948, - 7236018, - 7409213, - 7294862, - 6855241, - 6062372, - 4910076, - 3412857, - 1611207, - -429417, - -2618584, - -4844101, - -6976185, - -8874470, - -10396503, - -11407299, - -11789121, - -11451868, - -10342980, - -8455043, - -5831394, - -2568927, - 1181866, - 5222520, - 9314693, - 13192098, - 16575721, - 19192718, - 20794900, - 21178214, - 20201702, - 17803225, - 14010668, - 8949436, - 2842879, - -3994726, - -11170475, - -18232780, - -24697913, - -30079321, - -33921136, - -35832583, - -35519729, - -32814338, - -27696482, - -20307627, - -10955587, - -107030, - 11631605, - 23543158, - 34839849, - 44711664, - 52378576, - 57147364, - 58464306, - 55964858, - 49513162, - 39229018, - 25500353, - 8978376, - -9446673, - -28685271, - -47507955, - -64615363, - -78721214, - -88638504, - -93366828, - -92173696, - -84664063, - -70832479, - -51094971, - -26293298, - 2325527, - 33160341, - 64331225, - 93780584, - 119392064, - 139122267, - 151138511, - 153952683, - 146544581, - 128465090, - 99912102, - 61773380, - 15630736, - -36276081, - -91126422, - -145634732, - -196199513, - -239081694, - -270597744, - -287325458, - -286302172, - -265212584, - -222548033, - -157732643, - -71204480, - 35552627, - 160030161, - 298770593, - 447493387, - 601268344, - 754725438, - 902293927, - 1038455989, - 1158003615, - 1256284590, - 1329424450, - 1374513457, - 1389746873, - 1374513457, - 1329424450, - 1256284590, - 1158003615, - 1038455989, - 902293927, - 754725438, - 601268344, - 447493387, - 298770593, - 160030161, - 35552627, - -71204480, - -157732643, - -222548033, - -265212584, - -286302172, - -287325458, - -270597744, - -239081694, - -196199513, - -145634732, - -91126422, - -36276081, - 15630736, - 61773380, - 99912102, - 128465090, - 146544581, - 153952683, - 151138511, - 139122267, - 119392064, - 93780584, - 64331225, - 33160341, - 2325527, - -26293298, - -51094971, - -70832479, - -84664063, - -92173696, - -93366828, - -88638504, - -78721214, - -64615363, - -47507955, - -28685271, - -9446673, - 8978376, - 25500353, - 39229018, - 49513162, - 55964858, - 58464306, - 57147364, - 52378576, - 44711664, - 34839849, - 23543158, - 11631605, - -107030, - -10955587, - -20307627, - -27696482, - -32814338, - -35519729, - -35832583, - -33921136, - -30079321, - -24697913, - -18232780, - -11170475, - -3994726, - 2842879, - 8949436, - 14010668, - 17803225, - 20201702, - 21178214, - 20794900, - 19192718, - 16575721, - 13192098, - 9314693, - 5222520, - 1181866, - -2568927, - -5831394, - -8455043, - -10342980, - -11451868, - -11789121, - -11407299, - -10396503, - -8874470, - -6976185, - -4844101, - -2618584, - -429417, - 1611207, - 3412857, - 4910076, - 6062372, - 6855241, - 7294862, - 7409213, - 7236018, - 6830948, - 6242495, - 5540984, - 4760567, - 3983930, - 3198174, - 2523842, - 1841297, - 1395294, - 816474, - 709564, - 314962 - -}; - -struct pdm_decim pdm_decim_int32_12_4156_6018_010_090 = { - 12, 241, 3, 4156, 6018, 10, 90, fir_int32_12_4156_6018_010_090 -}; diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_table.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_table.h index bbb850a7fa4d..d2c51afe5d3e 100644 --- a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_table.h +++ b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_table.h @@ -15,27 +15,29 @@ #include #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_2 -#include "pdm_decim_int32_02_4288_5100_010_095.h" +#include "pdm_decim_int32_02_4323_5100_010_095.h" #include "pdm_decim_int32_02_4375_5100_010_095.h" #endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_3 -#include "pdm_decim_int32_03_3850_5100_010_095.h" #include "pdm_decim_int32_03_4375_5100_010_095.h" #endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_4 -#include "pdm_decim_int32_04_4375_5100_010_095.h" +#include "pdm_decim_int32_04_4318_5100_010_095.h" #endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_5 -#include "pdm_decim_int32_05_4331_5100_010_095.h" +#include "pdm_decim_int32_05_4325_5100_010_095.h" #endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_6 -#include "pdm_decim_int32_06_4156_5100_010_095.h" +#include "pdm_decim_int32_06_4172_5100_010_095.h" #endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_8 -#include "pdm_decim_int32_08_4156_5380_010_090.h" +#include "pdm_decim_int32_08_4156_5301_010_090.h" +#endif +#if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_10 +#include "pdm_decim_int32_10_4156_5345_010_090.h" #endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_12 -#include "pdm_decim_int32_12_4156_6018_010_090.h" +#include "pdm_decim_int32_12_4156_5345_010_090.h" #endif /* Note: Higher spec filter must be before lower spec filter @@ -46,26 +48,28 @@ struct pdm_decim *fir_list[] = { #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_2 &pdm_decim_int32_02_4375_5100_010_095, - &pdm_decim_int32_02_4288_5100_010_095, + &pdm_decim_int32_02_4323_5100_010_095, #endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_3 &pdm_decim_int32_03_4375_5100_010_095, - &pdm_decim_int32_03_3850_5100_010_095, #endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_4 - &pdm_decim_int32_04_4375_5100_010_095, + &pdm_decim_int32_04_4318_5100_010_095, #endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_5 - &pdm_decim_int32_05_4331_5100_010_095, + &pdm_decim_int32_05_4325_5100_010_095, #endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_6 - &pdm_decim_int32_06_4156_5100_010_095, + &pdm_decim_int32_06_4172_5100_010_095, #endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_8 - &pdm_decim_int32_08_4156_5380_010_090, + &pdm_decim_int32_08_4156_5301_010_090, +#endif +#if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_10 + &pdm_decim_int32_10_4156_5345_010_090, #endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_12 - &pdm_decim_int32_12_4156_6018_010_090, + &pdm_decim_int32_12_4156_5345_010_090, #endif NULL, /* This marks the end of coefficients */ }; From e4dbc06d35d878bf5c93b919042a253a82cd6078 Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Mon, 9 Nov 2020 20:54:22 +0200 Subject: [PATCH 43/47] Drivers: DMIC: Make FIR decimation factor preference order configurable This patch changes the logic in function select_mode() to use the defined FIR decimation filters as order of preference for FIR decimation factors. The earlier logic was simply to select the lowest decimation factor. It can be used to e.g. prefer decimation factor 6 over 5 when both are possible. The driver mode select behavior is not yet changed in this patch. The filters are presented in increasing decimation factor order in the header file. The preference order is changed in other patch. Signed-off-by: Seppo Ingalsuo --- src/drivers/intel/dmic.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/drivers/intel/dmic.c b/src/drivers/intel/dmic.c index 38a5cabb2a09..36785ac9d476 100644 --- a/src/drivers/intel/dmic.c +++ b/src/drivers/intel/dmic.c @@ -533,14 +533,13 @@ static int select_mode(struct dai *dai, int32_t gain_to_fir; int16_t idx[DMIC_MAX_MODES]; int16_t *mfir; - int n = 1; - int mmin; - int count; int mcic; int bits_cic; int ret; + int n; + int found = 0; - /* If there are more than one possibilities select a mode with lowest + /* If there are more than one possibilities select a mode with a preferred * FIR decimation factor. If there are several select mode with highest * ioclk divider to minimize microphone power consumption. The highest * clock divisors are in the end of list so select the last of list. @@ -561,9 +560,21 @@ static int select_mode(struct dai *dai, else mfir = modes->mfir_b; - mmin = find_min_int16(mfir, modes->num_of_modes); - count = find_equal_int16(idx, mfir, mmin, modes->num_of_modes, 0); - n = idx[count - 1]; + /* Search fir_list[] decimation factors from start towards end. The found + * last configuration entry with searched decimation factor will be used. + */ + for (n = 0; fir_list[n]; n++) { + found = find_equal_int16(idx, mfir, fir_list[n]->decim_factor, + modes->num_of_modes, 0); + if (found) + break; + } + + if (!found) { + dai_err(dai, "select_mode(): No filter for decimation found"); + return -EINVAL; + } + n = idx[found - 1]; /* Option with highest clock divisor and lowest mic clock rate */ /* Get microphone clock and decimation parameters for used mode from * the list. From 4ec856405c5cc00b4438afdcf1f2f38c5f3b1524 Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Tue, 10 Nov 2020 15:43:06 +0200 Subject: [PATCH 44/47] Drivers: DMIC: Move decimation factors 5 and 10 to less preferred This patch changes FIR decimation factors preference from "2, 3, 4, 5, 6, 8, 10, 12" to "2, 3, 4, 6, 5, 8, 12, 10". The prime number factor 5 and 10 (2*5) are less preferred because when used for decimate for fist started FIR they restrict more the configuration choices for the second FIR. If e.g. capture at 16 kHz is started first with decimation factor 6, the 48 kHz stream can be decimated from common 96 kHz CIC rate by 2. Earlier the driver selected decimation by 5 to 16 kHz. There is no integer decimation factor to decimate from 80 kHz to 48 kHz. Similarly if decimate to 8 kHz programmed FIR to decimate by 10, the same 80 kHz rate prevents 48 kHz for the other DAI. Decimation factor 12 sets up CIC to 96 kHz that is compatible with many other sample rates. Signed-off-by: Seppo Ingalsuo --- .../coefficients/pdm_decim/pdm_decim_table.h | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_table.h b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_table.h index d2c51afe5d3e..cfd4368bba3e 100644 --- a/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_table.h +++ b/src/include/sof/audio/coefficients/pdm_decim/pdm_decim_table.h @@ -40,9 +40,17 @@ #include "pdm_decim_int32_12_4156_5345_010_090.h" #endif -/* Note: Higher spec filter must be before lower spec filter - * if there are multiple filters for a decimation factor. The naming - * scheme of coefficients set is: +/* Note 1: Higher spec filter must be before lower spec filter + * if there are multiple filters for a decimation factor. The first + * filter is skipped if the length is too much vs. overrun limit. If + * other order the better filter would be never selected. + * + * Note 2: The introduction order of FIR decimation factors is the selection + * preference order. The decimation factor 5 and 10 (2*5) cause a often less + * compatible output sample rate for CIC so they are not used if there other + * suitable nearby values. + * + * The naming scheme of coefficients set is: * _____ */ struct pdm_decim *fir_list[] = { @@ -56,20 +64,20 @@ struct pdm_decim *fir_list[] = { #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_4 &pdm_decim_int32_04_4318_5100_010_095, #endif -#if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_5 - &pdm_decim_int32_05_4325_5100_010_095, -#endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_6 &pdm_decim_int32_06_4172_5100_010_095, #endif +#if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_5 + &pdm_decim_int32_05_4325_5100_010_095, +#endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_8 &pdm_decim_int32_08_4156_5301_010_090, #endif -#if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_10 - &pdm_decim_int32_10_4156_5345_010_090, -#endif #if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_12 &pdm_decim_int32_12_4156_5345_010_090, +#endif +#if CONFIG_INTEL_DMIC_FIR_DECIMATE_BY_10 + &pdm_decim_int32_10_4156_5345_010_090, #endif NULL, /* This marks the end of coefficients */ }; From b7f2da6094148794cc5707bbad6d86d60b9a8581 Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Fri, 6 Nov 2020 18:11:07 +0200 Subject: [PATCH 45/47] Topology: Change minimum bus clock to 2.4 MHz for 48 kHz DMIC DAI The driver configures a lowest feasible bus clock to save power. Since the 48 kHz and 16 kHz DMIC DAI can now be instantiated in the runtime there is possibility that the min. 500 kHz clock allowed could be too low for a new 48 kHz capture when existing 16 kHz capture is running. The topologies those define a 48 kHz DMIC DAI need to increase the min. clock to a sufficient rate. This patch changes every 500 kHz value to 2.4 MHz. This change does not change the external microphone clock in any platform. The lower than 2.4 MHz clock rates never happened in previous version to due to the 48 kHz DAI request in these topologies. Signed-off-by: Seppo Ingalsuo --- tools/topology/development/sof-tgl-nocodec-ci.m4 | 2 +- tools/topology/platform/intel/intel-generic-dmic-kwd.m4 | 6 +++--- tools/topology/platform/intel/intel-generic-dmic.m4 | 8 ++++---- tools/topology/sof-apl-asrc-pcm512x.m4 | 4 ++-- tools/topology/sof-apl-da7219.m4 | 2 +- tools/topology/sof-apl-dmic-a96k-b16k.m4 | 4 ++-- tools/topology/sof-apl-dmic-asymmetric.m4 | 4 ++-- tools/topology/sof-apl-dmic.m4 | 4 ++-- tools/topology/sof-apl-nocodec.m4 | 2 +- tools/topology/sof-cml-demux-rt5682.m4 | 2 +- tools/topology/sof-cml-rt5682-kwd.m4 | 4 ++-- tools/topology/sof-cml-rt5682.m4 | 4 ++-- tools/topology/sof-cml-src-rt5682.m4 | 2 +- tools/topology/sof-cnl-nocodec.m4 | 2 +- tools/topology/sof-ehl-rt5660.m4 | 4 ++-- tools/topology/sof-glk-da7219-kwd.m4 | 4 ++-- tools/topology/sof-glk-da7219.m4 | 2 +- tools/topology/sof-glk-rt5682.m4 | 2 +- tools/topology/sof-icl-dmic-4ch.m4 | 2 +- tools/topology/sof-tgl-nocodec.m4 | 2 +- 20 files changed, 33 insertions(+), 33 deletions(-) diff --git a/tools/topology/development/sof-tgl-nocodec-ci.m4 b/tools/topology/development/sof-tgl-nocodec-ci.m4 index 1429e2f80d0c..b36af14f9fea 100644 --- a/tools/topology/development/sof-tgl-nocodec-ci.m4 +++ b/tools/topology/development/sof-tgl-nocodec-ci.m4 @@ -244,7 +244,7 @@ DAI_CONFIG(DMIC, 0, 6, NoCodec-6, dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, dnl sample_rate, fifo word length, unmute time, type, dnl dai_index, pdm controller config) - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, dnl PDM_CONFIG(type, dai_index, num pdm active, pdm tuples list) dnl STEREO_PDM0 is a pre-defined pdm config for stereo capture diff --git a/tools/topology/platform/intel/intel-generic-dmic-kwd.m4 b/tools/topology/platform/intel/intel-generic-dmic-kwd.m4 index 1ffcfcd2efc8..a370c193364e 100644 --- a/tools/topology/platform/intel/intel-generic-dmic-kwd.m4 +++ b/tools/topology/platform/intel/intel-generic-dmic-kwd.m4 @@ -135,16 +135,16 @@ SectionGraph."pipe-sof-generic-keyword-detect" { dnl DAI_CONFIG(type, dai_index, link_id, name, ssp_config/dmic_config) ifelse(CHANNELS, 4, `DAI_CONFIG(DMIC, 0, DMIC_DAI_LINK_48k_ID, DMIC_DAI_LINK_48k_NAME, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 200, DMIC, 0, PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1)))', `DAI_CONFIG(DMIC, 0, DMIC_DAI_LINK_48k_ID, DMIC_DAI_LINK_48k_NAME, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 200, DMIC, 0, PDM_CONFIG(DMIC, 0, STEREO_PDM0)))') # dmic16k (ID: 2) DAI_CONFIG(DMIC, 1, DMIC_DAI_LINK_16k_ID, DMIC_DAI_LINK_16k_NAME, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 16000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, PDM_CONFIG(DMIC, 1, STEREO_PDM0))) diff --git a/tools/topology/platform/intel/intel-generic-dmic.m4 b/tools/topology/platform/intel/intel-generic-dmic.m4 index c919c33a435a..78345ea5a2e8 100644 --- a/tools/topology/platform/intel/intel-generic-dmic.m4 +++ b/tools/topology/platform/intel/intel-generic-dmic.m4 @@ -114,20 +114,20 @@ PCM_CAPTURE_ADD(DMIC16kHz, DMIC_DAI_LINK_16k_ID, concat(`PIPELINE_PCM_', DMIC_PI dnl DAI_CONFIG(type, dai_index, link_id, name, ssp_config/dmic_config) ifelse(DMIC_DAI_CHANNELS, 4, `DAI_CONFIG(DMIC, 0, DMIC_DAI_LINK_48k_ID, DMIC_DAI_LINK_48k_NAME, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 200, DMIC, 0, PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1)))', `DAI_CONFIG(DMIC, 0, DMIC_DAI_LINK_48k_ID, DMIC_DAI_LINK_48k_NAME, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 200, DMIC, 0, PDM_CONFIG(DMIC, 0, STEREO_PDM0)))') ifelse(DMIC16K_DAI_CHANNELS, 4, `DAI_CONFIG(DMIC, 1, DMIC_DAI_LINK_16k_ID, DMIC_DAI_LINK_16k_NAME, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 16000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, PDM_CONFIG(DMIC, 1, FOUR_CH_PDM0_PDM1)))', `DAI_CONFIG(DMIC, 1, DMIC_DAI_LINK_16k_ID, DMIC_DAI_LINK_16k_NAME, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 16000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, PDM_CONFIG(DMIC, 1, STEREO_PDM0)))') diff --git a/tools/topology/sof-apl-asrc-pcm512x.m4 b/tools/topology/sof-apl-asrc-pcm512x.m4 index 08c055312099..4c545791d591 100644 --- a/tools/topology/sof-apl-asrc-pcm512x.m4 +++ b/tools/topology/sof-apl-asrc-pcm512x.m4 @@ -104,13 +104,13 @@ DAI_CONFIG(SSP, 5, 0, SSP5-Codec, # DMIC (ID: 1) DAI_CONFIG(DMIC, 0, 1, dmic01, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, STEREO_PDM0))) # DMIC16kHz (ID: 2) DAI_CONFIG(DMIC, 1, 2, dmic16k, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 16000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, PDM_CONFIG(DMIC, 1, STEREO_PDM0))) diff --git a/tools/topology/sof-apl-da7219.m4 b/tools/topology/sof-apl-da7219.m4 index 20ce7eab5aab..dabfd6592a1e 100644 --- a/tools/topology/sof-apl-da7219.m4 +++ b/tools/topology/sof-apl-da7219.m4 @@ -175,7 +175,7 @@ DAI_CONFIG(SSP, 1, 1, SSP1-Codec, # dmic01 (id: 2) DAI_CONFIG(DMIC, 0, 2, dmic01, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, # FIXME: what is the right configuration # PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) diff --git a/tools/topology/sof-apl-dmic-a96k-b16k.m4 b/tools/topology/sof-apl-dmic-a96k-b16k.m4 index 0c58c616dba7..7254dd85736a 100644 --- a/tools/topology/sof-apl-dmic-a96k-b16k.m4 +++ b/tools/topology/sof-apl-dmic-a96k-b16k.m4 @@ -89,7 +89,7 @@ DAI_CONFIG(DMIC, 0, 6, NoCodec-6, dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, dnl sample_rate, fifo word length, unmute time, type, dnl dai_index, pdm controller config) - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 96000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 96000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, STEREO_PDM0))) @@ -97,7 +97,7 @@ DAI_CONFIG(DMIC, 1, 7, NoCodec-7, dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, dnl sample_rate, fifo word length, unmute time, type, dnl dai_index, pdm controller config) - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 16000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, PDM_CONFIG(DMIC, 1, STEREO_PDM0))) diff --git a/tools/topology/sof-apl-dmic-asymmetric.m4 b/tools/topology/sof-apl-dmic-asymmetric.m4 index 5e6ad22b2730..7065bc989b03 100644 --- a/tools/topology/sof-apl-dmic-asymmetric.m4 +++ b/tools/topology/sof-apl-dmic-asymmetric.m4 @@ -90,7 +90,7 @@ DAI_CONFIG(DMIC, 0, 6, NoCodec-6, dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, dnl sample_rate, fifo word length, unmute time, type, dnl dai_index, pdm controller config) - DMIC_CONFIG(1, 500000, 4800000, 40, 60, ARATE, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, ARATE, DMIC_WORD_LENGTH(AFORMAT), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, APDM))) @@ -98,6 +98,6 @@ DAI_CONFIG(DMIC, 1, 7, NoCodec-7, dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, dnl sample_rate, fifo word length, unmute time, type, dnl dai_index, pdm controller config) - DMIC_CONFIG(1, 500000, 4800000, 40, 60, BRATE, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, BRATE, DMIC_WORD_LENGTH(BFORMAT), 400, DMIC, 1, PDM_CONFIG(DMIC, 1, BPDM))) diff --git a/tools/topology/sof-apl-dmic.m4 b/tools/topology/sof-apl-dmic.m4 index ee0bfa1151bc..e9ba9d73c105 100644 --- a/tools/topology/sof-apl-dmic.m4 +++ b/tools/topology/sof-apl-dmic.m4 @@ -95,7 +95,7 @@ DAI_CONFIG(DMIC, 0, 6, NoCodec-6, dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, dnl sample_rate, fifo word length, unmute time, type, dnl dai_index, pdm controller config) - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, DMIC_PDM_CONFIG))) @@ -103,6 +103,6 @@ DAI_CONFIG(DMIC, 1, 7, NoCodec-7, dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, dnl sample_rate, fifo word length, unmute time, type, dnl dai_index, pdm controller config) - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 16000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, DMIC_WORD_LENGTH(s16le), 400, DMIC, 1, PDM_CONFIG(DMIC, 1, DMIC_PDM_CONFIG))) diff --git a/tools/topology/sof-apl-nocodec.m4 b/tools/topology/sof-apl-nocodec.m4 index aa0f24e91c20..6679ddecd7f4 100644 --- a/tools/topology/sof-apl-nocodec.m4 +++ b/tools/topology/sof-apl-nocodec.m4 @@ -313,7 +313,7 @@ DAI_CONFIG(DMIC, 0, 6, NoCodec-6, dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, dnl sample_rate, fifo word length, unmute time, type, dnl dai_index, pdm controller config) - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, dnl PDM_CONFIG(type, dai_index, num pdm active, pdm tuples list) dnl STEREO_PDM0 is a pre-defined pdm config for stereo capture diff --git a/tools/topology/sof-cml-demux-rt5682.m4 b/tools/topology/sof-cml-demux-rt5682.m4 index 0d9f910ba858..9fe1e4009725 100644 --- a/tools/topology/sof-cml-demux-rt5682.m4 +++ b/tools/topology/sof-cml-demux-rt5682.m4 @@ -212,7 +212,7 @@ DAI_CONFIG(SSP, SSP_INDEX, 0, SSP_NAME, # dmic01 (ID: 1) DAI_CONFIG(DMIC, 0, 1, dmic01, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) diff --git a/tools/topology/sof-cml-rt5682-kwd.m4 b/tools/topology/sof-cml-rt5682-kwd.m4 index c9bd645dc1db..4f88709b1de9 100644 --- a/tools/topology/sof-cml-rt5682-kwd.m4 +++ b/tools/topology/sof-cml-rt5682-kwd.m4 @@ -211,13 +211,13 @@ DAI_CONFIG(SSP, SSP_INDEX, 0, SSP_NAME, # dmic01 (ID: 1) DAI_CONFIG(DMIC, 0, 1, dmic01, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) # dmic16k (ID: 2) DAI_CONFIG(DMIC, 1, 2, dmic16k, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 16000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, PDM_CONFIG(DMIC, 1, STEREO_PDM0))) diff --git a/tools/topology/sof-cml-rt5682.m4 b/tools/topology/sof-cml-rt5682.m4 index 6b1426e1d36e..edbfd7fd702e 100644 --- a/tools/topology/sof-cml-rt5682.m4 +++ b/tools/topology/sof-cml-rt5682.m4 @@ -175,13 +175,13 @@ DAI_CONFIG(SSP, SSP_INDEX, 0, SSP_NAME, # dmic01 (ID: 1) DAI_CONFIG(DMIC, 0, 1, dmic01, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) # dmic16k (ID: 2) DAI_CONFIG(DMIC, 1, 2, dmic16k, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 16000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 1, PDM_CONFIG(DMIC, 1, STEREO_PDM0))) diff --git a/tools/topology/sof-cml-src-rt5682.m4 b/tools/topology/sof-cml-src-rt5682.m4 index 43e6cada0986..1c5f91c36b92 100644 --- a/tools/topology/sof-cml-src-rt5682.m4 +++ b/tools/topology/sof-cml-src-rt5682.m4 @@ -152,7 +152,7 @@ DAI_CONFIG(SSP, 1, 0, SSP1-Codec, # dmic01 (ID: 1) DAI_CONFIG(DMIC, 0, 1, dmic01, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) diff --git a/tools/topology/sof-cnl-nocodec.m4 b/tools/topology/sof-cnl-nocodec.m4 index b786abf3a8d1..4c71e57c27e6 100644 --- a/tools/topology/sof-cnl-nocodec.m4 +++ b/tools/topology/sof-cnl-nocodec.m4 @@ -176,6 +176,6 @@ DAI_CONFIG(SSP, 2, 2, NoCodec-2, SSP_CONFIG_DATA(SSP, 2, 24, 0, SSP_QUIRK_LBM))) DAI_CONFIG(DMIC, 0, 3, NoCodec-3, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) diff --git a/tools/topology/sof-ehl-rt5660.m4 b/tools/topology/sof-ehl-rt5660.m4 index 8f45304619c9..e9667627b34d 100644 --- a/tools/topology/sof-ehl-rt5660.m4 +++ b/tools/topology/sof-ehl-rt5660.m4 @@ -196,13 +196,13 @@ DAI_CONFIG(SSP, 0, 0, SSP0-Codec, # dmic48k (ID: 1) DAI_CONFIG(DMIC, 0, 1, dmic48k, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) # dmic16k (ID: 2) DAI_CONFIG(DMIC, 1, 2, dmic16k, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 16000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, DMIC_WORD_LENGTH(s16le), 400, DMIC, 1, PDM_CONFIG(DMIC, 1, STEREO_PDM0))) diff --git a/tools/topology/sof-glk-da7219-kwd.m4 b/tools/topology/sof-glk-da7219-kwd.m4 index 5e5019263dac..fcc3ee1528e9 100644 --- a/tools/topology/sof-glk-da7219-kwd.m4 +++ b/tools/topology/sof-glk-da7219-kwd.m4 @@ -219,7 +219,7 @@ DAI_CONFIG(SSP, SSP_INDEX, 1, SSP_NAME, # dmic01 (ID: 2) DAI_CONFIG(DMIC, 0, 2, dmic01, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(DMIC01_FMT), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) @@ -233,7 +233,7 @@ DAI_CONFIG(HDA, HDMI2_INDEX, 5, iDisp3, # dmic16k (ID: 6) DAI_CONFIG(DMIC, 1, 6, dmic16k, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 16000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 16000, DMIC_WORD_LENGTH(DMIC01_FMT), 400, DMIC, 1, PDM_CONFIG(DMIC, 1, STEREO_PDM0))) diff --git a/tools/topology/sof-glk-da7219.m4 b/tools/topology/sof-glk-da7219.m4 index 14f8f9cfbded..a0a067bf6651 100644 --- a/tools/topology/sof-glk-da7219.m4 +++ b/tools/topology/sof-glk-da7219.m4 @@ -179,7 +179,7 @@ DAI_CONFIG(SSP, 2, 1, SSP2-Codec, # dmic01 (id: 2) DAI_CONFIG(DMIC, 0, 2, dmic01, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) diff --git a/tools/topology/sof-glk-rt5682.m4 b/tools/topology/sof-glk-rt5682.m4 index 0a3ded31d446..0864c74a5a6d 100644 --- a/tools/topology/sof-glk-rt5682.m4 +++ b/tools/topology/sof-glk-rt5682.m4 @@ -179,7 +179,7 @@ DAI_CONFIG(SSP, 2, 1, SSP2-Codec, # dmic01 (id: 2) DAI_CONFIG(DMIC, 0, 2, dmic01, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s16le), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) diff --git a/tools/topology/sof-icl-dmic-4ch.m4 b/tools/topology/sof-icl-dmic-4ch.m4 index ba95b4de3f93..03dea7201f96 100644 --- a/tools/topology/sof-icl-dmic-4ch.m4 +++ b/tools/topology/sof-icl-dmic-4ch.m4 @@ -64,6 +64,6 @@ PCM_CAPTURE_ADD(DMIC, 1, PIPELINE_PCM_1) dnl DAI_CONFIG(type, dai_index, link_id, name, ssp_config/dmic_config) DAI_CONFIG(DMIC, 0, 1, dmic01, - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, PDM_CONFIG(DMIC, 0, FOUR_CH_PDM0_PDM1))) diff --git a/tools/topology/sof-tgl-nocodec.m4 b/tools/topology/sof-tgl-nocodec.m4 index df16a327c3dd..cd6d5c007068 100644 --- a/tools/topology/sof-tgl-nocodec.m4 +++ b/tools/topology/sof-tgl-nocodec.m4 @@ -178,7 +178,7 @@ DAI_CONFIG(DMIC, 0, 6, NoCodec-6, dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, dnl sample_rate, fifo word length, unmute time, type, dnl dai_index, pdm controller config) - DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000, + DMIC_CONFIG(1, 2400000, 4800000, 40, 60, 48000, DMIC_WORD_LENGTH(s32le), 400, DMIC, 0, dnl PDM_CONFIG(type, dai_index, num pdm active, pdm tuples list) dnl STEREO_PDM0 is a pre-defined pdm config for stereo capture From fdaa092a71c50daf7bd04beaf8b9934321508113 Mon Sep 17 00:00:00 2001 From: Jaska Uimonen Date: Tue, 15 Dec 2020 18:13:24 +0200 Subject: [PATCH 46/47] mux: enable playback of multiple simultaneous streams Currently you can't play multiple simultaneous streams at the same time into mux. Fix this by copying the trigger and reset mechanism from audio mixer. Signed-off-by: Jaska Uimonen --- src/audio/mux/mux.c | 94 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 13 deletions(-) diff --git a/src/audio/mux/mux.c b/src/audio/mux/mux.c index 7be529c1824b..829644792f46 100644 --- a/src/audio/mux/mux.c +++ b/src/audio/mux/mux.c @@ -610,48 +610,116 @@ static int mux_copy(struct comp_dev *dev) static int mux_reset(struct comp_dev *dev) { + int dir = dev->pipeline->source_comp->direction; + struct list_item *blist; + struct comp_buffer *source; + comp_info(dev, "mux_reset()"); - return comp_set_state(dev, COMP_TRIGGER_RESET); + if (dir == SOF_IPC_STREAM_PLAYBACK) { + list_for_item(blist, &dev->bsource_list) { + source = container_of(blist, struct comp_buffer, + sink_list); + /* only mux the sources with the same state with mux */ + if (source->source->state > COMP_STATE_READY) + /* should not reset the downstream components */ + return PPL_STATUS_PATH_STOP; + } + } + + comp_set_state(dev, COMP_TRIGGER_RESET); + return 0; } static int mux_prepare(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); + struct list_item *blist; + struct comp_buffer *source; + int downstream = 0; int ret; comp_info(dev, "mux_prepare()"); - if (dev->comp.type == SOF_COMP_MUX) - cd->mux = mux_get_processing_function(dev); - else - cd->demux = demux_get_processing_function(dev); + if (dev->state != COMP_STATE_ACTIVE) { + if (dev->comp.type == SOF_COMP_MUX) + cd->mux = mux_get_processing_function(dev); + else + cd->demux = demux_get_processing_function(dev); - if (!cd->mux && !cd->demux) { - comp_err(dev, "mux_prepare(): Invalid configuration, couldn't find suitable processing function."); - return -EINVAL; + if (!cd->mux && !cd->demux) { + comp_err(dev, "mux_prepare(): Invalid configuration, couldn't find suitable processing function."); + return -EINVAL; + } + + ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); + if (ret) { + comp_info(dev, "mux_prepare() comp_set_state() returned non-zero."); + return ret; + } } - ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); - if (ret) { - comp_info(dev, "mux_prepare() comp_set_state() returned non-zero."); - return ret; + /* check each mux source state */ + list_for_item(blist, &dev->bsource_list) { + source = container_of(blist, struct comp_buffer, sink_list); + + /* only prepare downstream if we have no active sources */ + if (source->source->state == COMP_STATE_PAUSED || + source->source->state == COMP_STATE_ACTIVE) { + downstream = 1; + } } - return 0; + /* prepare downstream */ + return downstream; +} + +static int mux_source_status_count(struct comp_dev *mux, uint32_t status) +{ + struct comp_buffer *source; + struct list_item *blist; + int count = 0; + + /* count source with state == status */ + list_for_item(blist, &mux->bsource_list) { + source = container_of(blist, struct comp_buffer, sink_list); + if (source->source->state == status) + count++; + } + + return count; } static int mux_trigger(struct comp_dev *dev, int cmd) { + int dir = dev->pipeline->source_comp->direction; int ret = 0; comp_info(dev, "mux_trigger(), command = %u", cmd); ret = comp_set_state(dev, cmd); + if (ret < 0) + return ret; if (ret == COMP_STATUS_STATE_ALREADY_SET) ret = PPL_STATUS_PATH_STOP; + /* nothing else to check for capture streams */ + if (dir == SOF_IPC_STREAM_CAPTURE) + return ret; + + /* don't stop mux if at least one source is active */ + if (mux_source_status_count(dev, COMP_STATE_ACTIVE) && + (cmd == COMP_TRIGGER_PAUSE || cmd == COMP_TRIGGER_STOP)) { + dev->state = COMP_STATE_ACTIVE; + ret = PPL_STATUS_PATH_STOP; + /* don't stop mux if at least one source is paused */ + } else if (mux_source_status_count(dev, COMP_STATE_PAUSED) && + cmd == COMP_TRIGGER_STOP) { + dev->state = COMP_STATE_PAUSED; + ret = PPL_STATUS_PATH_STOP; + } + return ret; } From 02175a78cdb43ccfb6df5e295b52406118d701ca Mon Sep 17 00:00:00 2001 From: Bartosz Kokoszko Date: Wed, 17 Feb 2021 12:42:25 +0100 Subject: [PATCH 47/47] mux/demux: update mux/demux documentation. This commit adds description of mux/demux config structure and format. Signed-off-by: Bartosz Kokoszko --- src/include/sof/audio/mux.h | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/include/sof/audio/mux.h b/src/include/sof/audio/mux.h index 7afb83127b4f..656afd64dabc 100644 --- a/src/include/sof/audio/mux.h +++ b/src/include/sof/audio/mux.h @@ -67,6 +67,45 @@ typedef void(*mux_func)(struct comp_dev *dev, struct audio_stream *sink, const struct audio_stream **sources, uint32_t frames, struct mux_look_up *look_up); +/** + * \brief Mux/Demux component config structure. + * + * The multiplexer/demultiplexer component copies its input audio channels + * into output audio channels according to a specific routing matrix. + * Multiplexer has multiple input audio streams and a single audio output + * stream. Demultiplexer has a single input stream and multiple output streams. + * + * Struct sof_mux_config includes array of mux_stream_data struct elements - + * streams[]. Each element of streams[] array refers to streams on "many" side + * of mux/demux component i.e. input streams for mux and output streams for + * demux. + * + * Struct mux_stream_data consists mask[] array. + * In the mux case, one mask[] element per input channel - each mask shows, to + * which output channel data should be copied. + * In the demux case, one mask[] element per output channel - each mask shows, + * from which input channel data should be taken. + * + * Mux example: + * Assuming that below mask array refers to x input stream: + * mask[] = { 0b00000001, + * 0b00000100 } + * it means that: + * - first input channel of stream x (mask[0]) will be copied to first output + * channel (0b00000001 & BIT(0)); + * - second input channel of stream x (mask[1]) will be copied to third output + * channel (0b00000100 & BIT(2)). + * + * Demux example: + * Assuming that below mask array refers to x output stream: + * mask[] = { 0b00000001, + * 0b00000100 } + * it means that: + * - first input channel (0b00000001 & BIT(0)) will be copied to first output + * (mask[0]) channel of stream x; + * - third input channel (0b00000100 & BIT(2)) will be copied to second output + * (mask[1]) channel of stream x. + */ struct sof_mux_config { uint16_t frame_format_deprecated; /* deprecated in ABI 3.15 */ uint16_t num_channels_deprecated; /* deprecated in ABI 3.15 */