ASoC: SOF: Intel: CNL/ICL/APL: set core_get/core_put ops
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Fri, 19 Nov 2021 19:26:16 +0000 (21:26 +0200)
committerMark Brown <broonie@kernel.org>
Mon, 22 Nov 2021 15:40:19 +0000 (15:40 +0000)
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>
sound/soc/sof/intel/apl.c
sound/soc/sof/intel/cnl.c
sound/soc/sof/intel/hda-dsp.c
sound/soc/sof/intel/hda.h
sound/soc/sof/intel/icl.c

index 917f78cf6daf15b8b49c7242d93db274abf7edd5..569668b2186ff743e6af59c58723ff062490e20d 100644 (file)
@@ -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,
index 3957e2b3db3206f5d1274c42f66cb7a94f551eaa..be6b6500b907291c0c5269f1bb2ebc250169ab89 100644 (file)
@@ -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,
index 287dc0eb6686f52bf815cfba934d71cdd7ecb667..b2f6dcd1c23d044d5ea6665b31ce82b138a84848 100644 (file)
@@ -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;
+}
index 1195018a1f4f5695ffe92bebdbc2caf34113920c..646f5d4dc8824fbd9a5600a19b00cd28de97e02a 100644 (file)
@@ -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);
 
index 0b2cc331d55ba3a685f6623235be4084b5e0c903..e3472868f49a469853fe131e2343f1121a72eef8 100644 (file)
@@ -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,