Unverified Commit 483e20a0 authored by Mark Brown's avatar Mark Brown
Browse files

Merge series "SOF Fixes for S0iX suspend/resume sequence" from Ranjani...

Merge series "SOF Fixes for S0iX suspend/resume sequence" from Ranjani Sridharan <ranjani.sridharan@linux.intel.com>:

This set of patches is required for facilitating system S0ix
entry when the DSP is in D0I3. This first patch adds the missing
CORB/RIRB DMA stop and restart to the suspend/resume sequence along
with powering up/down the links. The second patch ensures that the
FW traces are disabled when the system enters S0ix with the DSP in D0I3.

Marcin Rajwa (2):
  ASoC: SOF: Intel: fix the suspend procedure to support s0ix entry
  ASoC: SOF: Intel: disable traces when switching to S0Ix D0I3

 sound/soc/sof/intel/hda-dsp.c | 48 ++++++++++++++++++++++++++++++++---
 1 file changed, 44 insertions(+), 4 deletions(-)

--
2.25.1
parents e35cf9f5 79560b8a
Loading
Loading
Loading
Loading
+44 −4
Original line number Diff line number Diff line
@@ -408,11 +408,13 @@ static int hda_dsp_set_D0_state(struct snd_sof_dev *sdev,
		value = SOF_HDA_VS_D0I3C_I3;

		/*
		 * Trace DMA is disabled by default when the DSP enters D0I3.
		 * But it can be kept enabled when the DSP enters D0I3 while the
		 * system is in S0 for debug.
		 * Trace DMA need to be disabled when the DSP enters
		 * D0I3 for S0Ix suspend, but it can be kept enabled
		 * when the DSP enters D0I3 while the system is in S0
		 * for debug purpose.
		 */
		if (hda_enable_trace_D0I3_S0 &&
		if (!sdev->dtrace_is_supported ||
		    !hda_enable_trace_D0I3_S0 ||
		    sdev->system_suspend_target != SOF_SUSPEND_NONE)
			flags = HDA_PM_NO_DMA_TRACE;
	} else {
@@ -696,12 +698,35 @@ int hda_dsp_resume(struct snd_sof_dev *sdev)
		.state = SOF_DSP_PM_D0,
		.substate = SOF_HDA_DSP_PM_D0I0,
	};
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
	struct hdac_bus *bus = sof_to_bus(sdev);
	struct hdac_ext_link *hlink = NULL;
#endif
	int ret;

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

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
		/* power up links that were active before suspend */
		list_for_each_entry(hlink, &bus->hlink_list, list) {
			if (hlink->ref_count) {
				ret = snd_hdac_ext_bus_link_power_up(hlink);
				if (ret < 0) {
					dev_dbg(sdev->dev,
						"error %x in %s: failed to power up links",
						ret, __func__);
					return ret;
				}
			}
		}

		/* set up CORB/RIRB buffers if was on before suspend */
		if (bus->cmd_dma_state)
			snd_hdac_bus_init_cmd_io(bus);
#endif

		/* Set DSP power state */
		ret = snd_sof_dsp_set_power_state(sdev, &target_state);
		if (ret < 0) {
@@ -808,6 +833,21 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
						HDA_VS_INTEL_EM2_L1SEN,
						HDA_VS_INTEL_EM2_L1SEN);

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
		/* stop the CORB/RIRB DMA if it is On */
		if (bus->cmd_dma_state)
			snd_hdac_bus_stop_cmd_io(bus);

		/* no link can be powered in s0ix state */
		ret = snd_hdac_ext_bus_link_power_down_all(bus);
		if (ret < 0) {
			dev_dbg(sdev->dev,
				"error %d in %s: failed to power down links",
				ret, __func__);
			return ret;
		}
#endif

		/* enable the system waking up via IPC IRQ */
		enable_irq_wake(pci->irq);
		pci_save_state(pci);