ASoC: SOF: get pipeline instance id from pipe_widget->instance_id

Merge series from Bard Liao <yung-chuan.liao@linux.intel.com>:

Currently we set pipeline instance id = swidget->pipeline_id, but
pipeline_id is from topology and can be any number. In fact, the
number of pipelines is limited. This patch use ida to allocate pipeline
instance id and will be used for pipeline instance id in the IPC
message.
This commit is contained in:
Mark Brown 2022-11-10 17:49:54 +00:00
commit 6426f56b7a
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
5 changed files with 45 additions and 14 deletions

View File

@ -478,7 +478,7 @@ static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream,
struct snd_sof_widget *pipe_widget = swidget->pipe_widget;
struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id,
ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id,
SOF_IPC4_PIPE_PAUSED);
if (ret < 0)
return ret;
@ -487,7 +487,7 @@ static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream,
snd_hdac_ext_stream_clear(hext_stream);
ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id,
ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id,
SOF_IPC4_PIPE_RESET);
if (ret < 0)
return ret;
@ -506,7 +506,7 @@ static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream,
struct snd_sof_widget *pipe_widget = swidget->pipe_widget;
struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id,
ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id,
SOF_IPC4_PIPE_PAUSED);
if (ret < 0)
return ret;
@ -721,20 +721,20 @@ static int ipc4_be_dai_common_trigger(struct snd_soc_dai *dai, int cmd, int stre
switch (cmd) {
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_STOP:
ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id,
ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id,
SOF_IPC4_PIPE_PAUSED);
if (ret < 0)
return ret;
pipeline->state = SOF_IPC4_PIPE_PAUSED;
ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id,
ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id,
SOF_IPC4_PIPE_RESET);
if (ret < 0)
return ret;
pipeline->state = SOF_IPC4_PIPE_RESET;
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id,
ret = sof_ipc4_set_pipeline_state(sdev, pipe_widget->instance_id,
SOF_IPC4_PIPE_PAUSED);
if (ret < 0)
return ret;

View File

@ -383,6 +383,17 @@ int sof_ipc4_query_fw_configuration(struct snd_sof_dev *sdev)
if (!ipc4_data->max_libs_count)
ipc4_data->max_libs_count = 1;
break;
case SOF_IPC4_FW_CFG_MAX_PPL_COUNT:
ipc4_data->max_num_pipelines = *tuple->value;
trace_sof_ipc4_fw_config(sdev, "Max PPL count %d",
ipc4_data->max_num_pipelines);
if (ipc4_data->max_num_pipelines <= 0) {
dev_err(sdev->dev, "Invalid max_num_pipelines %d",
ipc4_data->max_num_pipelines);
ret = -EINVAL;
goto out;
}
break;
default:
break;
}

View File

@ -81,7 +81,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
/* first set the pipeline to PAUSED state */
if (pipeline->state != SOF_IPC4_PIPE_PAUSED) {
ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id,
ret = sof_ipc4_set_pipeline_state(sdev, pipeline_widget->instance_id,
SOF_IPC4_PIPE_PAUSED);
if (ret < 0) {
dev_err(sdev->dev, "failed to pause pipeline %d\n",
@ -96,7 +96,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
continue;
/* then set the final state */
ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, state);
ret = sof_ipc4_set_pipeline_state(sdev, pipeline_widget->instance_id, state);
if (ret < 0) {
dev_err(sdev->dev, "failed to set state %d for pipeline %d\n",
state, swidget->pipeline_id);

View File

@ -65,6 +65,7 @@ struct sof_ipc4_fw_library {
* @nhlt: NHLT table either from the BIOS or the topology manifest
* @mtrace_type: mtrace type supported on the booted platform
* @mtrace_log_bytes: log bytes as reported by the firmware via fw_config reply
* @max_num_pipelines: max number of pipelines
* @max_libs_count: Maximum number of libraries support by the FW including the
* base firmware
*
@ -76,6 +77,7 @@ struct sof_ipc4_fw_data {
void *nhlt;
enum sof_ipc4_mtrace_type mtrace_type;
u32 mtrace_log_bytes;
int max_num_pipelines;
u32 max_libs_count;
int (*load_library)(struct snd_sof_dev *sdev,

View File

@ -20,6 +20,7 @@
#define SOF_IPC4_TPLG_ABI_SIZE 6
static DEFINE_IDA(alh_group_ida);
static DEFINE_IDA(pipeline_ida);
static const struct sof_topology_token ipc4_sched_tokens[] = {
{SOF_TKN_SCHED_LP_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
@ -280,7 +281,7 @@ static void sof_ipc4_free_audio_fmt(struct sof_ipc4_available_audio_format *avai
available_fmt->out_audio_fmt = NULL;
}
static void sof_ipc4_widget_free_comp(struct snd_sof_widget *swidget)
static void sof_ipc4_widget_free_comp_pipeline(struct snd_sof_widget *swidget)
{
kfree(swidget->private);
}
@ -317,8 +318,7 @@ static int sof_ipc4_widget_setup_msg(struct snd_sof_widget *swidget, struct sof_
msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);
msg->extension = SOF_IPC4_MOD_EXT_PPL_ID(swidget->pipeline_id);
msg->extension |= SOF_IPC4_MOD_EXT_CORE_ID(swidget->core);
msg->extension = SOF_IPC4_MOD_EXT_CORE_ID(swidget->core);
type = (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_DP) ? 1 : 0;
msg->extension |= SOF_IPC4_MOD_EXT_DOMAIN(type);
@ -625,7 +625,6 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
swidget->private = pipeline;
pipeline->msg.primary = SOF_IPC4_GLB_PIPE_PRIORITY(pipeline->priority);
pipeline->msg.primary |= SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->pipeline_id);
pipeline->msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CREATE_PIPELINE);
pipeline->msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
pipeline->msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG);
@ -1436,6 +1435,8 @@ static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_contr
static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
{
struct snd_sof_widget *pipe_widget = swidget->pipe_widget;
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
struct sof_ipc4_pipeline *pipeline;
struct sof_ipc4_msg *msg;
void *ipc_data = NULL;
@ -1451,6 +1452,16 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
msg = &pipeline->msg;
msg->primary |= pipeline->mem_usage;
swidget->instance_id = ida_alloc_max(&pipeline_ida, ipc4_data->max_num_pipelines,
GFP_KERNEL);
if (swidget->instance_id < 0) {
dev_err(sdev->dev, "failed to assign pipeline id for %s: %d\n",
swidget->widget->name, swidget->instance_id);
return swidget->instance_id;
}
msg->primary &= ~SOF_IPC4_GLB_PIPE_INSTANCE_MASK;
msg->primary |= SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id);
break;
case snd_soc_dapm_aif_in:
case snd_soc_dapm_aif_out:
@ -1524,6 +1535,9 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK;
msg->extension |= ipc_size >> 2;
msg->extension &= ~SOF_IPC4_MOD_EXT_PPL_ID_MASK;
msg->extension |= SOF_IPC4_MOD_EXT_PPL_ID(pipe_widget->instance_id);
}
dev_dbg(sdev->dev, "Create widget %s instance %d - pipe %d - core %d\n",
swidget->widget->name, swidget->instance_id, swidget->pipeline_id, swidget->core);
@ -1539,6 +1553,8 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
struct sof_ipc4_fw_module *fw_module = swidget->module_info;
ida_free(&fw_module->m_ida, swidget->instance_id);
} else {
ida_free(&pipeline_ida, swidget->instance_id);
}
}
@ -1556,7 +1572,7 @@ static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget
struct sof_ipc4_msg msg = {{ 0 }};
u32 header;
header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->pipeline_id);
header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id);
header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_DELETE_PIPELINE);
header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG);
@ -1570,6 +1586,7 @@ static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget
pipeline->mem_usage = 0;
pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED;
ida_free(&pipeline_ida, swidget->instance_id);
} else {
ida_free(&fw_module->m_ida, swidget->instance_id);
}
@ -1917,7 +1934,8 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TY
dai_token_list, ARRAY_SIZE(dai_token_list), NULL,
sof_ipc4_prepare_copier_module,
sof_ipc4_unprepare_copier_module},
[snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline, sof_ipc4_widget_free_comp,
[snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline,
sof_ipc4_widget_free_comp_pipeline,
pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL,
NULL, NULL},
[snd_soc_dapm_pga] = {sof_ipc4_widget_setup_comp_pga, sof_ipc4_widget_free_comp_pga,