Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIx for DP + multicore with IPC4 #4705

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sound/soc/sof/ipc3-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ static int sof_ipc3_widget_setup_comp_mixer(struct snd_sof_widget *swidget)
static int sof_ipc3_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
{
struct snd_soc_component *scomp = swidget->scomp;
struct snd_sof_pipeline *spipe = swidget->spipe;
ranj063 marked this conversation as resolved.
Show resolved Hide resolved
struct sof_ipc_pipe_new *pipeline;
struct snd_sof_widget *comp_swidget;
int ret;
Expand Down Expand Up @@ -557,6 +558,7 @@ static int sof_ipc3_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
swidget->dynamic_pipeline_widget);

swidget->core = pipeline->core;
spipe->core_mask |= BIT(pipeline->core);

return 0;

Expand Down
9 changes: 9 additions & 0 deletions sound/soc/sof/ipc4-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
{
struct snd_soc_component *scomp = swidget->scomp;
struct sof_ipc4_pipeline *pipeline;
struct snd_sof_pipeline *spipe = swidget->spipe;
int ret;

pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL);
Expand All @@ -692,6 +693,7 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
}

swidget->core = pipeline->core_id;
spipe->core_mask |= BIT(pipeline->core_id);
plbossart marked this conversation as resolved.
Show resolved Hide resolved

if (pipeline->use_chain_dma) {
dev_dbg(scomp->dev, "Set up chain DMA for %s\n", swidget->widget->name);
Expand Down Expand Up @@ -819,6 +821,7 @@ static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget)
static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget)
{
struct snd_soc_component *scomp = swidget->scomp;
struct snd_sof_pipeline *spipe = swidget->spipe;
struct sof_ipc4_src *src;
int ret;

Expand All @@ -842,6 +845,8 @@ static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget)
goto err;
}

spipe->core_mask |= BIT(swidget->core);

dev_dbg(scomp->dev, "SRC sink rate %d\n", src->data.sink_rate);

ret = sof_ipc4_widget_setup_msg(swidget, &src->msg);
Expand Down Expand Up @@ -887,6 +892,7 @@ static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget)
{
struct snd_soc_component *scomp = swidget->scomp;
struct sof_ipc4_fw_module *fw_module;
struct snd_sof_pipeline *spipe = swidget->spipe;
struct sof_ipc4_process *process;
void *cfg;
int ret;
Expand Down Expand Up @@ -943,6 +949,9 @@ static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget)

sof_ipc4_widget_update_kcontrol_module_id(swidget);

/* set pipeline core mask to keep track of the core the module is scheduled to run on */
spipe->core_mask |= BIT(swidget->core);
plbossart marked this conversation as resolved.
Show resolved Hide resolved

return 0;
free_base_cfg_ext:
kfree(process->base_config_ext);
Expand Down
65 changes: 41 additions & 24 deletions sound/soc/sof/sof-audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
struct snd_sof_widget *swidget)
{
const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
struct snd_sof_pipeline *spipe = swidget->spipe;
ranj063 marked this conversation as resolved.
Show resolved Hide resolved
struct snd_sof_widget *pipe_widget;
int err = 0;
int ret;
Expand Down Expand Up @@ -86,15 +87,22 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
}

/*
* disable widget core. continue to route setup status and complete flag
* even if this fails and return the appropriate error
* decrement ref count for cores associated with all modules in the pipeline and clear
* the complete flag
*/
ret = snd_sof_dsp_core_put(sdev, swidget->core);
if (ret < 0) {
dev_err(sdev->dev, "error: failed to disable target core: %d for widget %s\n",
swidget->core, swidget->widget->name);
if (!err)
err = ret;
if (swidget->id == snd_soc_dapm_scheduler) {
int i;

for_each_set_bit(i, &spipe->core_mask, sdev->num_cores) {
ret = snd_sof_dsp_core_put(sdev, i);
plbossart marked this conversation as resolved.
Show resolved Hide resolved
if (ret < 0) {
dev_err(sdev->dev, "failed to disable target core: %d for pipeline %s\n",
i, swidget->widget->name);
if (!err)
err = ret;
}
}
swidget->spipe->complete = 0;
}

/*
Expand All @@ -107,10 +115,6 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
err = ret;
}

/* clear pipeline complete */
if (swidget->id == snd_soc_dapm_scheduler)
swidget->spipe->complete = 0;

if (!err)
dev_dbg(sdev->dev, "widget %s freed\n", swidget->widget->name);

Expand All @@ -133,8 +137,10 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
struct snd_sof_widget *swidget)
{
const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
struct snd_sof_pipeline *spipe = swidget->spipe;
bool use_count_decremented = false;
int ret;
int i;

/* skip if there is no private data */
if (!swidget->private)
Expand Down Expand Up @@ -165,19 +171,23 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
goto use_count_dec;
}

/* enable widget core */
ret = snd_sof_dsp_core_get(sdev, swidget->core);
if (ret < 0) {
dev_err(sdev->dev, "error: failed to enable target core for widget %s\n",
swidget->widget->name);
goto pipe_widget_free;
/* update ref count for cores associated with all modules in the pipeline */
if (swidget->id == snd_soc_dapm_scheduler) {
for_each_set_bit(i, &spipe->core_mask, sdev->num_cores) {
ret = snd_sof_dsp_core_get(sdev, i);
if (ret < 0) {
dev_err(sdev->dev, "failed to enable target core %d for pipeline %s\n",
i, swidget->widget->name);
goto pipe_widget_free;
}
}
}

/* setup widget in the DSP */
if (tplg_ops && tplg_ops->widget_setup) {
ret = tplg_ops->widget_setup(sdev, swidget);
if (ret < 0)
goto core_put;
goto pipe_widget_free;
}

/* send config for DAI components */
Expand Down Expand Up @@ -207,15 +217,22 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
return 0;

widget_free:
/* widget use_count and core ref_count will both be decremented by sof_widget_free() */
/* widget use_count will be decremented by sof_widget_free() */
sof_widget_free_unlocked(sdev, swidget);
use_count_decremented = true;
core_put:
if (!use_count_decremented)
snd_sof_dsp_core_put(sdev, swidget->core);
pipe_widget_free:
if (swidget->id != snd_soc_dapm_scheduler)
if (swidget->id != snd_soc_dapm_scheduler) {
sof_widget_free_unlocked(sdev, swidget->spipe->pipe_widget);
} else {
int j;

/* decrement ref count for all cores that were updated previously */
for_each_set_bit(j, &spipe->core_mask, sdev->num_cores) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if it would work, but in theory

for_each_set_bit(j, &spipe->core_mask, i + 1) {

might work as well?

if (j >= i)
break;
snd_sof_dsp_core_put(sdev, j);
}
}
use_count_dec:
if (!use_count_decremented)
swidget->use_count--;
Expand Down
2 changes: 2 additions & 0 deletions sound/soc/sof/sof-audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,13 +481,15 @@ struct snd_sof_widget {
* @paused_count: Count of number of PCM's that have started and have currently paused this
pipeline
* @complete: flag used to indicate that pipeline set up is complete.
* @core_mask: Mask containing target cores for all modules in the pipeline
* @list: List item in sdev pipeline_list
*/
struct snd_sof_pipeline {
struct snd_sof_widget *pipe_widget;
int started_count;
int paused_count;
int complete;
unsigned long core_mask;
struct list_head list;
};

Expand Down