diff options
| author | Ranjani Sridharan <ranjani.sridharan@linux.intel.com> | 2023-04-20 13:47:14 +0300 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2023-04-20 12:52:02 +0100 |
| commit | 996b07efe49620325332081afdb0dc0bd6fe5cd0 (patch) | |
| tree | ffc793e6fc8727a87725746214e801a16c7988cf /sound/soc/sof/intel/hda-dsp.c | |
| parent | 09cda705860125ffee1b1359b1da79f8e0c77a40 (diff) | |
| download | linux-next-996b07efe49620325332081afdb0dc0bd6fe5cd0.tar.gz linux-next-996b07efe49620325332081afdb0dc0bd6fe5cd0.zip | |
ASoC: SOF: Intel: Split the set_power_op for IPC3 and IPC4
Suspending to S0iX with IPC3 requires the PM_GATE IPC to be sent again
to stop the DMA trace. But with IPC4, this is not needed as the trace is
stopped with the LARGE_CONFIG_SET IPC. Also, sending the MOD_D0IX IPC to
set the D0I3 state again when the DSP is in D0I3 already results in an
imbalance in PM runtime states in the firmware. So split the
set_power_state ops for IPC3 and IPC4 to avoid sending the MOD_D0IX IPC
when the DSP is already in D0I3 with IPC4.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20230420104714.29573-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/intel/hda-dsp.c')
| -rw-r--r-- | sound/soc/sof/intel/hda-dsp.c | 60 |
1 files changed, 38 insertions, 22 deletions
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 77df536cf901..44f39a520bb3 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -574,31 +574,11 @@ static void hda_dsp_state_log(struct snd_sof_dev *sdev) * is called again either because of a new IPC sent to the DSP or * during system suspend/resume. */ -int hda_dsp_set_power_state(struct snd_sof_dev *sdev, - const struct sof_dsp_power_state *target_state) +static int hda_dsp_set_power_state(struct snd_sof_dev *sdev, + const struct sof_dsp_power_state *target_state) { int ret = 0; - /* - * When the DSP is already in D0I3 and the target state is D0I3, - * it could be the case that the DSP is in D0I3 during S0 - * and the system is suspending to S0Ix. Therefore, - * hda_dsp_set_D0_state() must be called to disable trace DMA - * by sending the PM_GATE IPC to the FW. - */ - if (target_state->substate == SOF_HDA_DSP_PM_D0I3 && - sdev->system_suspend_target == SOF_SUSPEND_S0IX) - goto set_state; - - /* - * For all other cases, return without doing anything if - * the DSP is already in the target state. - */ - if (target_state->state == sdev->dsp_power_state.state && - target_state->substate == sdev->dsp_power_state.substate) - return 0; - -set_state: switch (target_state->state) { case SOF_DSP_PM_D0: ret = hda_dsp_set_D0_state(sdev, target_state); @@ -630,6 +610,42 @@ set_state: return ret; } +int hda_dsp_set_power_state_ipc3(struct snd_sof_dev *sdev, + const struct sof_dsp_power_state *target_state) +{ + /* + * When the DSP is already in D0I3 and the target state is D0I3, + * it could be the case that the DSP is in D0I3 during S0 + * and the system is suspending to S0Ix. Therefore, + * hda_dsp_set_D0_state() must be called to disable trace DMA + * by sending the PM_GATE IPC to the FW. + */ + if (target_state->substate == SOF_HDA_DSP_PM_D0I3 && + sdev->system_suspend_target == SOF_SUSPEND_S0IX) + return hda_dsp_set_power_state(sdev, target_state); + + /* + * For all other cases, return without doing anything if + * the DSP is already in the target state. + */ + if (target_state->state == sdev->dsp_power_state.state && + target_state->substate == sdev->dsp_power_state.substate) + return 0; + + return hda_dsp_set_power_state(sdev, target_state); +} + +int hda_dsp_set_power_state_ipc4(struct snd_sof_dev *sdev, + const struct sof_dsp_power_state *target_state) +{ + /* Return without doing anything if the DSP is already in the target state */ + if (target_state->state == sdev->dsp_power_state.state && + target_state->substate == sdev->dsp_power_state.substate) + return 0; + + return hda_dsp_set_power_state(sdev, target_state); +} + /* * Audio DSP states may transform as below:- * |
