summaryrefslogtreecommitdiffstats
path: root/sound/soc/sof/intel
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof/intel')
-rw-r--r--sound/soc/sof/intel/hda-dai.c10
-rw-r--r--sound/soc/sof/intel/hda-dsp.c50
-rw-r--r--sound/soc/sof/intel/hda-pcm.c2
3 files changed, 51 insertions, 11 deletions
diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c
index 3934cd6bf87a..df1c6997cb4e 100644
--- a/sound/soc/sof/intel/hda-dai.c
+++ b/sound/soc/sof/intel/hda-dai.c
@@ -56,7 +56,7 @@ static struct hdac_ext_stream *
hda_link_stream_assign(struct hdac_bus *bus,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct sof_intel_hda_stream *hda_stream;
struct hdac_ext_stream *res = NULL;
struct hdac_stream *stream = NULL;
@@ -203,7 +203,7 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
struct hdac_stream *hstream = substream->runtime->private_data;
struct hdac_bus *bus = hstream->bus;
struct hdac_ext_stream *link_dev;
- struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
struct sof_intel_hda_stream *hda_stream;
struct hda_pipe_params p_params = {0};
@@ -264,7 +264,7 @@ static int hda_link_pcm_prepare(struct snd_pcm_substream *substream,
snd_soc_dai_get_dma_data(dai, substream);
struct snd_sof_dev *sdev =
snd_soc_component_get_drvdata(dai->component);
- struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
int stream = substream->stream;
if (link_dev->link_prepared)
@@ -291,7 +291,7 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
hstream = substream->runtime->private_data;
bus = hstream->bus;
- rtd = snd_pcm_substream_chip(substream);
+ rtd = asoc_substream_to_rtd(substream);
link = snd_hdac_ext_bus_get_link(bus, asoc_rtd_to_codec(rtd, 0)->component->name);
if (!link)
@@ -357,7 +357,7 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream,
hstream = substream->runtime->private_data;
bus = hstream->bus;
- rtd = snd_pcm_substream_chip(substream);
+ rtd = asoc_substream_to_rtd(substream);
link_dev = snd_soc_dai_get_dma_data(dai, substream);
if (!link_dev) {
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index 9e5ff8c18f99..ed4d65a29d3a 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -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);
@@ -846,7 +886,7 @@ int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
* explicitly during suspend.
*/
if (stream->link_substream) {
- rtd = snd_pcm_substream_chip(stream->link_substream);
+ rtd = asoc_substream_to_rtd(stream->link_substream);
name = asoc_rtd_to_codec(rtd, 0)->component->name;
link = snd_hdac_ext_bus_get_link(bus, name);
if (!link)
diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c
index 53a875ac52d6..b527d5958ae5 100644
--- a/sound/soc/sof/intel/hda-pcm.c
+++ b/sound/soc/sof/intel/hda-pcm.c
@@ -147,7 +147,7 @@ int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev,
snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_component *scomp = sdev->component;
struct hdac_stream *hstream = substream->runtime->private_data;
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;