summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/sof/intel/apl.c4
-rw-r--r--sound/soc/sof/intel/cnl.c4
-rw-r--r--sound/soc/sof/intel/icl.c4
-rw-r--r--sound/soc/sof/intel/tgl.c4
-rw-r--r--sound/soc/sof/ops.h32
-rw-r--r--sound/soc/sof/sof-audio.c67
-rw-r--r--sound/soc/sof/sof-audio.h2
-rw-r--r--sound/soc/sof/sof-priv.h4
-rw-r--r--sound/soc/sof/topology.c83
9 files changed, 59 insertions, 145 deletions
diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c
index 569668b2186f..1baf0fddeb3d 100644
--- a/sound/soc/sof/intel/apl.c
+++ b/sound/soc/sof/intel/apl.c
@@ -101,9 +101,7 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
/* parse platform specific extended manifest */
.parse_platform_ext_manifest = hda_dsp_ext_man_get_cavs_config_data,
- /* dsp core power up/down */
- .core_power_up = hda_dsp_enable_core,
- .core_power_down = hda_dsp_core_reset_power_down,
+ /* dsp core get/put */
.core_get = hda_dsp_core_get,
/* trace callback */
diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index be6b6500b907..d455272bfc8e 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -303,9 +303,7 @@ const struct snd_sof_dsp_ops sof_cnl_ops = {
/* parse platform specific extended manifest */
.parse_platform_ext_manifest = hda_dsp_ext_man_get_cavs_config_data,
- /* dsp core power up/down */
- .core_power_up = hda_dsp_enable_core,
- .core_power_down = hda_dsp_core_reset_power_down,
+ /* dsp core get/put */
.core_get = hda_dsp_core_get,
/* firmware run */
diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c
index e3472868f49a..6c5422157ec8 100644
--- a/sound/soc/sof/intel/icl.c
+++ b/sound/soc/sof/intel/icl.c
@@ -97,9 +97,7 @@ const struct snd_sof_dsp_ops sof_icl_ops = {
/* parse platform specific extended manifest */
.parse_platform_ext_manifest = hda_dsp_ext_man_get_cavs_config_data,
- /* dsp core power up/down */
- .core_power_up = hda_dsp_enable_core,
- .core_power_down = hda_dsp_core_reset_power_down,
+ /* dsp core get/put */
.core_get = hda_dsp_core_get,
/* firmware run */
diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c
index 51011b0b8c11..237e92e790b7 100644
--- a/sound/soc/sof/intel/tgl.c
+++ b/sound/soc/sof/intel/tgl.c
@@ -133,9 +133,7 @@ const struct snd_sof_dsp_ops sof_tgl_ops = {
/* parse platform specific extended manifest */
.parse_platform_ext_manifest = hda_dsp_ext_man_get_cavs_config_data,
- /* dsp core power up/down */
- .core_power_up = hda_dsp_enable_core,
- .core_power_down = hda_dsp_core_reset_power_down,
+ /* dsp core get/put */
.core_get = tgl_dsp_core_get,
.core_put = tgl_dsp_core_put,
diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h
index 61dc2768b000..a0648a13e3eb 100644
--- a/sound/soc/sof/ops.h
+++ b/sound/soc/sof/ops.h
@@ -72,37 +72,7 @@ static inline int snd_sof_dsp_reset(struct snd_sof_dev *sdev)
return 0;
}
-/* dsp core power up/power down */
-static inline int snd_sof_dsp_core_power_up(struct snd_sof_dev *sdev,
- unsigned int core_mask)
-{
- int ret = 0;
-
- core_mask &= ~sdev->enabled_cores_mask;
- if (sof_ops(sdev)->core_power_up && core_mask) {
- ret = sof_ops(sdev)->core_power_up(sdev, core_mask);
- if (!ret)
- sdev->enabled_cores_mask |= core_mask;
- }
-
- return ret;
-}
-
-static inline int snd_sof_dsp_core_power_down(struct snd_sof_dev *sdev,
- unsigned int core_mask)
-{
- int ret = 0;
-
- core_mask &= sdev->enabled_cores_mask;
- if (sof_ops(sdev)->core_power_down && core_mask) {
- ret = sof_ops(sdev)->core_power_down(sdev, core_mask);
- if (!ret)
- sdev->enabled_cores_mask &= ~core_mask;
- }
-
- return ret;
-}
-
+/* dsp core get/put */
static inline int snd_sof_dsp_core_get(struct snd_sof_dev *sdev, int core)
{
if (core > sdev->num_cores - 1) {
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index 669d5c924f6b..0f2566f7c094 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -106,7 +106,7 @@ int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
.id = swidget->comp_id,
};
struct sof_ipc_reply reply;
- int ret;
+ int ret, ret1, core;
if (!swidget->private)
return 0;
@@ -115,10 +115,17 @@ int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
if (--swidget->use_count)
return 0;
+ core = swidget->core;
+
switch (swidget->id) {
case snd_soc_dapm_scheduler:
+ {
+ const struct sof_ipc_pipe_new *pipeline = swidget->private;
+
+ core = pipeline->core;
ipc_free.hdr.cmd |= SOF_IPC_TPLG_PIPE_FREE;
break;
+ }
case snd_soc_dapm_buffer:
ipc_free.hdr.cmd |= SOF_IPC_TPLG_BUFFER_FREE;
break;
@@ -127,20 +134,32 @@ int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
break;
}
+ /* continue to disable core even if IPC fails */
ret = sof_ipc_tx_message(sdev->ipc, ipc_free.hdr.cmd, &ipc_free, sizeof(ipc_free),
&reply, sizeof(reply));
- if (ret < 0) {
+ if (ret < 0)
dev_err(sdev->dev, "error: failed to free widget %s\n", swidget->widget->name);
- swidget->use_count++;
- return ret;
+
+ /*
+ * disable widget core. continue to route setup status and complete flag
+ * even if this fails and return the appropriate error
+ */
+ ret1 = snd_sof_dsp_core_put(sdev, core);
+ if (ret1 < 0) {
+ dev_err(sdev->dev, "error: failed to disable target core: %d for widget %s\n",
+ core, swidget->widget->name);
+ if (!ret)
+ ret = ret1;
}
/* reset route setup status for all routes that contain this widget */
sof_reset_route_setup_status(sdev, swidget);
swidget->complete = 0;
- dev_dbg(sdev->dev, "widget %s freed\n", swidget->widget->name);
- return 0;
+ if (!ret)
+ dev_dbg(sdev->dev, "widget %s freed\n", swidget->widget->name);
+
+ return ret;
}
EXPORT_SYMBOL(sof_widget_free);
@@ -153,6 +172,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
struct snd_sof_dai *dai;
size_t ipc_size;
int ret;
+ int core;
/* skip if there is no private data */
if (!swidget->private)
@@ -162,10 +182,18 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
if (++swidget->use_count > 1)
return 0;
- ret = sof_pipeline_core_enable(sdev, swidget);
+ /* set core ID */
+ core = swidget->core;
+ if (swidget->id == snd_soc_dapm_scheduler) {
+ pipeline = swidget->private;
+ core = pipeline->core;
+ }
+
+ /* enable widget core */
+ ret = snd_sof_dsp_core_get(sdev, core);
if (ret < 0) {
- dev_err(sdev->dev, "error: failed to enable target core: %d for widget %s\n",
- ret, swidget->widget->name);
+ dev_err(sdev->dev, "error: failed to enable target core for widget %s\n",
+ swidget->widget->name);
goto use_count_dec;
}
@@ -174,8 +202,10 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
case snd_soc_dapm_dai_out:
ipc_size = sizeof(struct sof_ipc_comp_dai) + sizeof(struct sof_ipc_comp_ext);
comp = kzalloc(ipc_size, GFP_KERNEL);
- if (!comp)
- return -ENOMEM;
+ if (!comp) {
+ ret = -ENOMEM;
+ goto core_put;
+ }
dai = swidget->private;
dai->configured = false;
@@ -190,13 +220,18 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
if (ret < 0) {
dev_err(sdev->dev, "error: failed to load widget %s\n",
swidget->widget->name);
- goto use_count_dec;
+ goto core_put;
}
ret = sof_dai_config_setup(sdev, dai);
if (ret < 0) {
dev_err(sdev->dev, "error: failed to load dai config for DAI %s\n",
swidget->widget->name);
+
+ /*
+ * widget use_count and core ref_count will both be decremented by
+ * sof_widget_free()
+ */
sof_widget_free(sdev, swidget);
return ret;
}
@@ -214,7 +249,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
}
if (ret < 0) {
dev_err(sdev->dev, "error: failed to load widget %s\n", swidget->widget->name);
- goto use_count_dec;
+ goto core_put;
}
/* restore kcontrols for widget */
@@ -222,6 +257,10 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
if (ret < 0) {
dev_err(sdev->dev, "error: failed to restore kcontrols for widget %s\n",
swidget->widget->name);
+ /*
+ * widget use_count and core ref_count will both be decremented by
+ * sof_widget_free()
+ */
sof_widget_free(sdev, swidget);
return ret;
}
@@ -230,6 +269,8 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
return 0;
+core_put:
+ snd_sof_dsp_core_put(sdev, core);
use_count_dec:
swidget->use_count--;
return ret;
diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h
index 6c591b7a531c..389d56ac3aba 100644
--- a/sound/soc/sof/sof-audio.h
+++ b/sound/soc/sof/sof-audio.h
@@ -184,8 +184,6 @@ void snd_sof_control_notify(struct snd_sof_dev *sdev,
int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file);
int snd_sof_complete_pipeline(struct snd_sof_dev *sdev,
struct snd_sof_widget *swidget);
-int sof_pipeline_core_enable(struct snd_sof_dev *sdev,
- const struct snd_sof_widget *swidget);
/*
* Stream IPC
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index f7c86a72ac10..a9c5197617f1 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -130,10 +130,6 @@ struct snd_sof_dsp_ops {
int (*run)(struct snd_sof_dev *sof_dev); /* mandatory */
int (*stall)(struct snd_sof_dev *sof_dev, unsigned int core_mask); /* optional */
int (*reset)(struct snd_sof_dev *sof_dev); /* optional */
- int (*core_power_up)(struct snd_sof_dev *sof_dev,
- unsigned int core_mask); /* optional */
- int (*core_power_down)(struct snd_sof_dev *sof_dev,
- unsigned int core_mask); /* optional */
int (*core_get)(struct snd_sof_dev *sof_dev, int core); /* optional */
int (*core_put)(struct snd_sof_dev *sof_dev, int core); /* optional */
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index 3a49d7910326..63948bb30710 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -1346,69 +1346,6 @@ static int sof_control_unload(struct snd_soc_component *scomp,
* DAI Topology
*/
-/* Static DSP core power management so far, should be extended in the future */
-static int sof_core_enable(struct snd_sof_dev *sdev, int core)
-{
- struct sof_ipc_pm_core_config pm_core_config = {
- .hdr = {
- .cmd = SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CORE_ENABLE,
- .size = sizeof(pm_core_config),
- },
- .enable_mask = sdev->enabled_cores_mask | BIT(core),
- };
- int ret;
-
- if (sdev->enabled_cores_mask & BIT(core))
- return 0;
-
- /* power up the core if it is host managed */
- ret = snd_sof_dsp_core_power_up(sdev, BIT(core));
- if (ret < 0) {
- dev_err(sdev->dev, "error: %d powering up core %d\n",
- ret, core);
- return ret;
- }
-
- /* Now notify DSP */
- ret = sof_ipc_tx_message(sdev->ipc, pm_core_config.hdr.cmd,
- &pm_core_config, sizeof(pm_core_config),
- &pm_core_config, sizeof(pm_core_config));
- if (ret < 0) {
- dev_err(sdev->dev, "error: core %d enable ipc failure %d\n",
- core, ret);
- goto err;
- }
- return ret;
-err:
- /* power down core if it is host managed and return the original error if this fails too */
- if (snd_sof_dsp_core_power_down(sdev, BIT(core)) < 0)
- dev_err(sdev->dev, "error: powering down core %d\n", core);
-
- return ret;
-}
-
-int sof_pipeline_core_enable(struct snd_sof_dev *sdev,
- const struct snd_sof_widget *swidget)
-{
- const struct sof_ipc_pipe_new *pipeline;
- int ret;
-
- if (swidget->id == snd_soc_dapm_scheduler) {
- pipeline = swidget->private;
- } else {
- pipeline = snd_sof_pipeline_find(sdev, swidget->pipeline_id);
- if (!pipeline)
- return -ENOENT;
- }
-
- /* First enable the pipeline core */
- ret = sof_core_enable(sdev, pipeline->core);
- if (ret < 0)
- return ret;
-
- return sof_core_enable(sdev, swidget->core);
-}
-
static int sof_connect_dai_widget(struct snd_soc_component *scomp,
struct snd_soc_dapm_widget *w,
struct snd_soc_tplg_dapm_widget *tw,
@@ -2485,10 +2422,8 @@ static int sof_route_unload(struct snd_soc_component *scomp,
static int sof_widget_unload(struct snd_soc_component *scomp,
struct snd_soc_dobj *dobj)
{
- struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
const struct snd_kcontrol_new *kc;
struct snd_soc_dapm_widget *widget;
- struct sof_ipc_pipe_new *pipeline;
struct snd_sof_control *scontrol;
struct snd_sof_widget *swidget;
struct soc_mixer_control *sm;
@@ -2515,24 +2450,6 @@ static int sof_widget_unload(struct snd_soc_component *scomp,
list_del(&dai->list);
}
break;
- case snd_soc_dapm_scheduler:
-
- /* power down the pipeline schedule core */
- pipeline = swidget->private;
-
- /*
- * Runtime PM should still function normally if topology loading fails and
- * it's components are unloaded. Do not power down the primary core so that the
- * CTX_SAVE IPC can succeed during runtime suspend.
- */
- if (pipeline->core == SOF_DSP_PRIMARY_CORE)
- break;
-
- ret = snd_sof_dsp_core_power_down(sdev, 1 << pipeline->core);
- if (ret < 0)
- dev_err(scomp->dev, "error: powering down pipeline schedule core %d\n",
- pipeline->core);
- break;
default:
break;
}