ASoC: SOF: Intel: hda: Allow trace DMA in S0 when DSP is in D0I3 for debug
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Wed, 29 Jan 2020 22:07:26 +0000 (16:07 -0600)
committerMark Brown <broonie@kernel.org>
Tue, 11 Feb 2020 11:48:08 +0000 (11:48 +0000)
Trace DMA is disabled by default when the DSP is in D0I3.
Add a debug option to keep trace DMA enabled when the DSP
is in D0I3 during S0.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200129220726.31792-10-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/intel/hda-dsp.c

index ee604be..14228b4 100644 (file)
@@ -15,6 +15,7 @@
  * Hardware interface for generic Intel audio DSP HDA IP
  */
 
+#include <linux/module.h>
 #include <sound/hdaudio_ext.h>
 #include <sound/hda_register.h>
 #include "../sof-audio.h"
 #include "hda.h"
 #include "hda-ipc.h"
 
+static bool hda_enable_trace_D0I3_S0;
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG)
+module_param_named(enable_trace_D0I3_S0, hda_enable_trace_D0I3_S0, bool, 0444);
+MODULE_PARM_DESC(enable_trace_D0I3_S0,
+                "SOF HDA enable trace when the DSP is in D0I3 in S0");
+#endif
+
 /*
  * DSP Core control.
  */
@@ -399,8 +407,14 @@ static int hda_dsp_set_D0_state(struct snd_sof_dev *sdev,
        if (target_state->substate == SOF_HDA_DSP_PM_D0I3) {
                value = SOF_HDA_VS_D0I3C_I3;
 
-               /* disable DMA trace in D0I3 */
-               flags = HDA_PM_NO_DMA_TRACE;
+               /*
+                * 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.
+                */
+               if (hda_enable_trace_D0I3_S0 &&
+                   sdev->system_suspend_target != SOF_SUSPEND_NONE)
+                       flags = HDA_PM_NO_DMA_TRACE;
        } else {
                /* prevent power gating in D0I0 */
                flags = HDA_PM_PPG;
@@ -450,11 +464,26 @@ int hda_dsp_set_power_state(struct snd_sof_dev *sdev,
 {
        int ret = 0;
 
-       /* Nothing to do if the DSP is already in the requested 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)
+               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);