]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ASoC: SOF: topology: Make scheduler widget parsing IPC agnostic
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Mon, 14 Mar 2022 20:05:07 +0000 (13:05 -0700)
committerMark Brown <broonie@kernel.org>
Wed, 16 Mar 2022 16:38:59 +0000 (16:38 +0000)
Define the list of tokens pertaining to the scheduler widgets, parse and
save them as part of the swidget tuples array. Once topology parsing is
complete, these tokens will be applied to create the IPC structure for the
pipeline component based on the topology widget_setup op in ipc3_tplg_ops.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20220314200520.1233427-7-ranjani.sridharan@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/ipc3-topology.c
sound/soc/sof/topology.c

index 33d07b0df6401d39c5e68201a3ec3cfa34fcd196..15299ffb7b1583596b0e2a7c19c71a97ed30f934 100644 (file)
 #include "sof-audio.h"
 #include "ops.h"
 
+/* scheduling */
+static const struct sof_topology_token sched_tokens[] = {
+       {SOF_TKN_SCHED_PERIOD, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc_pipe_new, period)},
+       {SOF_TKN_SCHED_PRIORITY, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc_pipe_new, priority)},
+       {SOF_TKN_SCHED_MIPS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc_pipe_new, period_mips)},
+       {SOF_TKN_SCHED_CORE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc_pipe_new, core)},
+       {SOF_TKN_SCHED_FRAMES, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc_pipe_new, frames_per_sched)},
+       {SOF_TKN_SCHED_TIME_DOMAIN, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+               offsetof(struct sof_ipc_pipe_new, time_domain)},
+};
+
+static const struct sof_topology_token pipeline_tokens[] = {
+       {SOF_TKN_SCHED_DYNAMIC_PIPELINE, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
+               offsetof(struct snd_sof_widget, dynamic_pipeline_widget)},
+
+};
+
 /* PCM */
 static const struct sof_topology_token pcm_tokens[] = {
        {SOF_TKN_PCM_DMAC_CONFIG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
@@ -44,6 +66,8 @@ static const struct sof_topology_token comp_ext_tokens[] = {
 
 static const struct sof_token_info ipc3_token_list[SOF_TOKEN_COUNT] = {
        [SOF_PCM_TOKENS] = {"PCM tokens", pcm_tokens, ARRAY_SIZE(pcm_tokens)},
+       [SOF_PIPELINE_TOKENS] = {"Pipeline tokens", pipeline_tokens, ARRAY_SIZE(pipeline_tokens)},
+       [SOF_SCHED_TOKENS] = {"Scheduler tokens", sched_tokens, ARRAY_SIZE(sched_tokens)},
        [SOF_COMP_TOKENS] = {"Comp tokens", comp_tokens, ARRAY_SIZE(comp_tokens)},
        [SOF_CORE_TOKENS] = {"Core tokens", core_tokens, ARRAY_SIZE(core_tokens)},
        [SOF_COMP_EXT_TOKENS] = {"AFE tokens", comp_ext_tokens, ARRAY_SIZE(comp_ext_tokens)},
@@ -148,6 +172,71 @@ static void sof_ipc3_widget_free_comp(struct snd_sof_widget *swidget)
        kfree(swidget->private);
 }
 
+static int sof_ipc3_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
+{
+       struct snd_soc_component *scomp = swidget->scomp;
+       struct sof_ipc_pipe_new *pipeline;
+       struct snd_sof_widget *comp_swidget;
+       int ret;
+
+       pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL);
+       if (!pipeline)
+               return -ENOMEM;
+
+       /* configure pipeline IPC message */
+       pipeline->hdr.size = sizeof(*pipeline);
+       pipeline->hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_PIPE_NEW;
+       pipeline->pipeline_id = swidget->pipeline_id;
+       pipeline->comp_id = swidget->comp_id;
+
+       swidget->private = pipeline;
+
+       /* component at start of pipeline is our stream id */
+       comp_swidget = snd_sof_find_swidget(scomp, swidget->widget->sname);
+       if (!comp_swidget) {
+               dev_err(scomp->dev, "scheduler %s refers to non existent widget %s\n",
+                       swidget->widget->name, swidget->widget->sname);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       pipeline->sched_id = comp_swidget->comp_id;
+
+       /* parse one set of scheduler tokens */
+       ret = sof_update_ipc_object(scomp, pipeline, SOF_SCHED_TOKENS, swidget->tuples,
+                                   swidget->num_tuples, sizeof(*pipeline), 1);
+       if (ret < 0)
+               goto err;
+
+       /* parse one set of pipeline tokens */
+       ret = sof_update_ipc_object(scomp, swidget, SOF_PIPELINE_TOKENS, swidget->tuples,
+                                   swidget->num_tuples, sizeof(*swidget), 1);
+       if (ret < 0)
+               goto err;
+
+       if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE))
+               pipeline->core = SOF_DSP_PRIMARY_CORE;
+
+       if (sof_debug_check_flag(SOF_DBG_DYNAMIC_PIPELINES_OVERRIDE))
+               swidget->dynamic_pipeline_widget =
+                       sof_debug_check_flag(SOF_DBG_DYNAMIC_PIPELINES_ENABLE);
+
+       dev_dbg(scomp->dev, "pipeline %s: period %d pri %d mips %d core %d frames %d dynamic %d\n",
+               swidget->widget->name, pipeline->period, pipeline->priority,
+               pipeline->period_mips, pipeline->core, pipeline->frames_per_sched,
+               swidget->dynamic_pipeline_widget);
+
+       swidget->core = pipeline->core;
+
+       return 0;
+
+err:
+       kfree(swidget->private);
+       swidget->private = NULL;
+
+       return ret;
+}
+
 /* token list for each topology object */
 static enum sof_tokens host_token_list[] = {
        SOF_CORE_TOKENS,
@@ -156,11 +245,20 @@ static enum sof_tokens host_token_list[] = {
        SOF_COMP_TOKENS,
 };
 
+static enum sof_tokens pipeline_token_list[] = {
+       SOF_CORE_TOKENS,
+       SOF_COMP_EXT_TOKENS,
+       SOF_PIPELINE_TOKENS,
+       SOF_SCHED_TOKENS,
+};
+
 static const struct sof_ipc_tplg_widget_ops tplg_ipc3_widget_ops[SND_SOC_DAPM_TYPE_COUNT] = {
        [snd_soc_dapm_aif_in] =  {sof_ipc3_widget_setup_comp_host, sof_ipc3_widget_free_comp,
                                  host_token_list, ARRAY_SIZE(host_token_list), NULL},
        [snd_soc_dapm_aif_out] = {sof_ipc3_widget_setup_comp_host, sof_ipc3_widget_free_comp,
                                  host_token_list, ARRAY_SIZE(host_token_list), NULL},
+       [snd_soc_dapm_scheduler] = {sof_ipc3_widget_setup_comp_pipeline, sof_ipc3_widget_free_comp,
+                                   pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL},
 };
 
 static const struct sof_ipc_tplg_ops ipc3_tplg_ops = {
index 2258317d7f5709718ad0daada488eba12e50eb31..4dd4e98e87cf6078147d658efcfe323e5ec26f6e 100644 (file)
@@ -637,28 +637,6 @@ static const struct sof_topology_token dai_link_tokens[] = {
                offsetof(struct sof_ipc_dai_config, dai_index)},
 };
 
-/* scheduling */
-static const struct sof_topology_token sched_tokens[] = {
-       {SOF_TKN_SCHED_PERIOD, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc_pipe_new, period)},
-       {SOF_TKN_SCHED_PRIORITY, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc_pipe_new, priority)},
-       {SOF_TKN_SCHED_MIPS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc_pipe_new, period_mips)},
-       {SOF_TKN_SCHED_CORE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc_pipe_new, core)},
-       {SOF_TKN_SCHED_FRAMES, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc_pipe_new, frames_per_sched)},
-       {SOF_TKN_SCHED_TIME_DOMAIN, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc_pipe_new, time_domain)},
-};
-
-static const struct sof_topology_token pipeline_tokens[] = {
-       {SOF_TKN_SCHED_DYNAMIC_PIPELINE, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16,
-               offsetof(struct snd_sof_widget, dynamic_pipeline_widget)},
-
-};
-
 /* volume */
 static const struct sof_topology_token volume_tokens[] = {
        {SOF_TKN_VOLUME_RAMP_STEP_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
@@ -1873,81 +1851,6 @@ err:
        return ret;
 }
 
-/*
- * Pipeline Topology
- */
-static int sof_widget_load_pipeline(struct snd_soc_component *scomp, int index,
-                                   struct snd_sof_widget *swidget,
-                                   struct snd_soc_tplg_dapm_widget *tw)
-{
-       struct snd_soc_tplg_private *private = &tw->priv;
-       struct sof_ipc_pipe_new *pipeline;
-       struct snd_sof_widget *comp_swidget;
-       int ret;
-
-       pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL);
-       if (!pipeline)
-               return -ENOMEM;
-
-       /* configure dai IPC message */
-       pipeline->hdr.size = sizeof(*pipeline);
-       pipeline->hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_PIPE_NEW;
-       pipeline->pipeline_id = index;
-       pipeline->comp_id = swidget->comp_id;
-
-       /* component at start of pipeline is our stream id */
-       comp_swidget = snd_sof_find_swidget(scomp, tw->sname);
-       if (!comp_swidget) {
-               dev_err(scomp->dev, "error: widget %s refers to non existent widget %s\n",
-                       tw->name, tw->sname);
-               ret = -EINVAL;
-               goto err;
-       }
-
-       pipeline->sched_id = comp_swidget->comp_id;
-
-       dev_dbg(scomp->dev, "tplg: pipeline id %d comp %d scheduling comp id %d\n",
-               pipeline->pipeline_id, pipeline->comp_id, pipeline->sched_id);
-
-       ret = sof_parse_tokens(scomp, pipeline, sched_tokens,
-                              ARRAY_SIZE(sched_tokens), private->array,
-                              le32_to_cpu(private->size));
-       if (ret != 0) {
-               dev_err(scomp->dev, "error: parse pipeline tokens failed %d\n",
-                       private->size);
-               goto err;
-       }
-
-       ret = sof_parse_tokens(scomp, swidget, pipeline_tokens,
-                              ARRAY_SIZE(pipeline_tokens), private->array,
-                              le32_to_cpu(private->size));
-       if (ret != 0) {
-               dev_err(scomp->dev, "error: parse dynamic pipeline token failed %d\n",
-                       private->size);
-               goto err;
-       }
-
-       if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE))
-               pipeline->core = SOF_DSP_PRIMARY_CORE;
-
-       if (sof_debug_check_flag(SOF_DBG_DYNAMIC_PIPELINES_OVERRIDE))
-               swidget->dynamic_pipeline_widget =
-                       sof_debug_check_flag(SOF_DBG_DYNAMIC_PIPELINES_ENABLE);
-
-       dev_dbg(scomp->dev, "pipeline %s: period %d pri %d mips %d core %d frames %d dynamic %d\n",
-               swidget->widget->name, pipeline->period, pipeline->priority,
-               pipeline->period_mips, pipeline->core, pipeline->frames_per_sched,
-               swidget->dynamic_pipeline_widget);
-
-       swidget->core = pipeline->core;
-       swidget->private = pipeline;
-
-       return 0;
-err:
-       kfree(pipeline);
-       return ret;
-}
-
 /*
  * Mixer topology
  */
@@ -2579,8 +2482,6 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
                ret = sof_widget_load_buffer(scomp, index, swidget, tw);
                break;
        case snd_soc_dapm_scheduler:
-               ret = sof_widget_load_pipeline(scomp, index, swidget, tw);
-               break;
        case snd_soc_dapm_aif_out:
        case snd_soc_dapm_aif_in:
                ret = sof_widget_parse_tokens(scomp, swidget, tw,  token_list, token_list_size);