Skip to content

Commit 195f101

Browse files
mrajwabroonie
authored andcommitted
ASoC: SOF: Intel: fix the suspend procedure to support s0ix entry
This patch fixes the suspend & resume procedure to allow entry into the low power states with some streams being active as a wake source - wake on voice is a perfect example. The current implementation does not stop the CORB/RIRB DMA and does not power down the HDA links. With firmware's help, the platform has been able to still enter s0ix state on older platforms, but the sequence is still incorrect, and the additional driver actions are needed to ensure correct s0ix behaviour. Signed-off-by: Marcin Rajwa <[email protected]> Signed-off-by: Keyon Jie <[email protected]> Signed-off-by: Ranjani Sridharan <[email protected]> Reviewed-by: Pierre-Louis Bossart <[email protected]> Reviewed-by: Kai Vehmanen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 950039f commit 195f101

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

sound/soc/sof/intel/hda-dsp.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,12 +696,35 @@ int hda_dsp_resume(struct snd_sof_dev *sdev)
696696
.state = SOF_DSP_PM_D0,
697697
.substate = SOF_HDA_DSP_PM_D0I0,
698698
};
699+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
700+
struct hdac_bus *bus = sof_to_bus(sdev);
701+
struct hdac_ext_link *hlink = NULL;
702+
#endif
699703
int ret;
700704

701705
/* resume from D0I3 */
702706
if (sdev->dsp_power_state.state == SOF_DSP_PM_D0) {
703707
hda_codec_i915_display_power(sdev, true);
704708

709+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
710+
/* power up links that were active before suspend */
711+
list_for_each_entry(hlink, &bus->hlink_list, list) {
712+
if (hlink->ref_count) {
713+
ret = snd_hdac_ext_bus_link_power_up(hlink);
714+
if (ret < 0) {
715+
dev_dbg(sdev->dev,
716+
"error %x in %s: failed to power up links",
717+
ret, __func__);
718+
return ret;
719+
}
720+
}
721+
}
722+
723+
/* set up CORB/RIRB buffers if was on before suspend */
724+
if (bus->cmd_dma_state)
725+
snd_hdac_bus_init_cmd_io(bus);
726+
#endif
727+
705728
/* Set DSP power state */
706729
ret = snd_sof_dsp_set_power_state(sdev, &target_state);
707730
if (ret < 0) {
@@ -808,6 +831,21 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
808831
HDA_VS_INTEL_EM2_L1SEN,
809832
HDA_VS_INTEL_EM2_L1SEN);
810833

834+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
835+
/* stop the CORB/RIRB DMA if it is On */
836+
if (bus->cmd_dma_state)
837+
snd_hdac_bus_stop_cmd_io(bus);
838+
839+
/* no link can be powered in s0ix state */
840+
ret = snd_hdac_ext_bus_link_power_down_all(bus);
841+
if (ret < 0) {
842+
dev_dbg(sdev->dev,
843+
"error %d in %s: failed to power down links",
844+
ret, __func__);
845+
return ret;
846+
}
847+
#endif
848+
811849
/* enable the system waking up via IPC IRQ */
812850
enable_irq_wake(pci->irq);
813851
pci_save_state(pci);

0 commit comments

Comments
 (0)