summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>2021-11-19 22:26:16 +0300
committerMark Brown <broonie@kernel.org>2021-11-22 18:40:19 +0300
commit9cdcbc9f6788661fb02fb2340032a5c8115aaf9b (patch)
tree1307d3345f604ee2328eb42f3925a5d7af4c2bab
parent41dd63cccb42ec26f555cbb2495d85828a4b0e96 (diff)
downloadlinux-9cdcbc9f6788661fb02fb2340032a5c8115aaf9b.tar.xz
ASoC: SOF: Intel: CNL/ICL/APL: set core_get/core_put ops
Set core_get/put ops for CNL/ICL platforms. These platforms do not support enabling/disabling secondary cores dynamically. So skip sending the IPC to power off the cores in the core_put op. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Link: https://lore.kernel.org/r/20211119192621.4096077-6-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/sof/intel/apl.c1
-rw-r--r--sound/soc/sof/intel/cnl.c1
-rw-r--r--sound/soc/sof/intel/hda-dsp.c44
-rw-r--r--sound/soc/sof/intel/hda.h1
-rw-r--r--sound/soc/sof/intel/icl.c1
5 files changed, 48 insertions, 0 deletions
diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c
index 917f78cf6daf..569668b2186f 100644
--- a/sound/soc/sof/intel/apl.c
+++ b/sound/soc/sof/intel/apl.c
@@ -104,6 +104,7 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
/* dsp core power up/down */
.core_power_up = hda_dsp_enable_core,
.core_power_down = hda_dsp_core_reset_power_down,
+ .core_get = hda_dsp_core_get,
/* trace callback */
.trace_init = hda_dsp_trace_init,
diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index 3957e2b3db32..be6b6500b907 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -306,6 +306,7 @@ const struct snd_sof_dsp_ops sof_cnl_ops = {
/* dsp core power up/down */
.core_power_up = hda_dsp_enable_core,
.core_power_down = hda_dsp_core_reset_power_down,
+ .core_get = hda_dsp_core_get,
/* firmware run */
.run = hda_dsp_cl_boot_firmware,
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index 287dc0eb6686..b2f6dcd1c23d 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -962,3 +962,47 @@ void hda_dsp_d0i3_work(struct work_struct *work)
"error: failed to set DSP state %d substate %d\n",
target_state.state, target_state.substate);
}
+
+int hda_dsp_core_get(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, ret1;
+
+ /* power up core */
+ ret = hda_dsp_enable_core(sdev, BIT(core));
+ if (ret < 0) {
+ dev_err(sdev->dev, "failed to power up core %d with err: %d\n",
+ core, ret);
+ return ret;
+ }
+
+ /* No need to send IPC for primary core or if FW boot is not complete */
+ if (sdev->fw_state != SOF_FW_BOOT_COMPLETE || core == SOF_DSP_PRIMARY_CORE)
+ return 0;
+
+ /* Now notify DSP for secondary cores */
+ 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, "failed to enable secondary core '%d' failed with %d\n",
+ core, ret);
+ goto power_down;
+ }
+
+ return ret;
+
+power_down:
+ /* power down core if it is host managed and return the original error if this fails too */
+ ret1 = hda_dsp_core_reset_power_down(sdev, BIT(core));
+ if (ret1 < 0)
+ dev_err(sdev->dev, "failed to power down core: %d with err: %d\n", core, ret1);
+
+ return ret;
+}
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 1195018a1f4f..646f5d4dc882 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -496,6 +496,7 @@ int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask);
int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask);
int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev,
unsigned int core_mask);
+int hda_dsp_core_get(struct snd_sof_dev *sdev, int core);
void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev);
void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev);
diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c
index 0b2cc331d55b..e3472868f49a 100644
--- a/sound/soc/sof/intel/icl.c
+++ b/sound/soc/sof/intel/icl.c
@@ -100,6 +100,7 @@ const struct snd_sof_dsp_ops sof_icl_ops = {
/* dsp core power up/down */
.core_power_up = hda_dsp_enable_core,
.core_power_down = hda_dsp_core_reset_power_down,
+ .core_get = hda_dsp_core_get,
/* firmware run */
.run = hda_dsp_cl_boot_firmware_iccmax,