Skip to content

Commit df68ff2

Browse files
committed
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. In order to enter low power state all active links as well as streams need to be power down. Signed-off-by: Marcin Rajwa <marcin.rajwa@linux.intel.com>
1 parent 156ee7a commit df68ff2

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,12 +696,27 @@ 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+
#endif
699702
int ret;
700703

701704
/* resume from D0I3 */
702705
if (sdev->dsp_power_state.state == SOF_DSP_PM_D0) {
703706
hda_codec_i915_display_power(sdev, true);
704707

708+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
709+
/* reenable CORB/RIRB */
710+
snd_hdac_bus_init_cmd_io(bus);
711+
ret = snd_hdac_ext_bus_link_power_up_all(bus);
712+
if (ret < 0) {
713+
dev_dbg(sdev->dev,
714+
"error %d in %s: failed to power up links",
715+
ret, __func__);
716+
return ret;
717+
}
718+
#endif
719+
705720
/* Set DSP power state */
706721
ret = snd_sof_dsp_set_power_state(sdev, &target_state);
707722
if (ret < 0) {
@@ -783,6 +798,8 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
783798
.substate = target_state == SOF_DSP_PM_D0 ?
784799
SOF_HDA_DSP_PM_D0I3 : 0,
785800
};
801+
struct hdac_stream *stream;
802+
int sd_offset;
786803
int ret;
787804

788805
/* cancel any attempt for DSP D0I3 */
@@ -808,6 +825,32 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
808825
HDA_VS_INTEL_EM2_L1SEN,
809826
HDA_VS_INTEL_EM2_L1SEN);
810827

828+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
829+
/* clear rirb status */
830+
snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
831+
/* disable CORB/RIRB */
832+
snd_hdac_bus_stop_cmd_io(bus);
833+
#endif
834+
/* clear stream status */
835+
list_for_each_entry(stream, &bus->stream_list, list) {
836+
sd_offset = SOF_STREAM_SD_OFFSET(stream);
837+
snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
838+
sd_offset +
839+
SOF_HDA_ADSP_REG_CL_SD_STS,
840+
SOF_HDA_CL_DMA_SD_INT_MASK);
841+
}
842+
843+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
844+
/* No link can be powered in s0ix state */
845+
ret = snd_hdac_ext_bus_link_power_down_all(bus);
846+
if (ret < 0) {
847+
dev_dbg(sdev->dev,
848+
"error %d in %s: failed to power down links",
849+
ret, __func__);
850+
return ret;
851+
}
852+
#endif
853+
811854
/* enable the system waking up via IPC IRQ */
812855
enable_irq_wake(pci->irq);
813856
pci_save_state(pci);

0 commit comments

Comments
 (0)