All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/9] ASoC: Intel: avs: PCM power management
@ 2022-10-27  8:23 Cezary Rojewski
  2022-10-27  8:23 ` [PATCH v3 1/9] ASoC: Intel: avs: Split pcm pages freeing operation from hw_free() Cezary Rojewski
                   ` (8 more replies)
  0 siblings, 9 replies; 15+ messages in thread
From: Cezary Rojewski @ 2022-10-27  8:23 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: Cezary Rojewski, pierre-louis.bossart, tiwai, hdegoede,
	amadeuszx.slawinski

Goal of the series is implementation of suspend/resume operations for a
PCM stream along with all the collaterals connected to the subject.

Start with splitting avs_dai_fe_hw_free() as ideally we would like to
reuse as much of existing code as possible but snd_pcm_lib_free_pages()
is not desired part of the function when speaking of suspend operation.

The actual implementation of suspend/resume() for component drivers
follows. For most scenarios, the PM flow is similar to standard
streaming one, except for the part where the position register are being
saved and the lack of PCM pages freeing. To reduce code duplication, all
avs_dai_suspend_XXX() and avs_dai_resume_XXX() functions reuse their
non-PM equivalents.
Order of operations is affected by the fact that path binding/unbinding
happens only in FE part of the stream.

Above essentially unlocks SX+streaming scenarios i.e.: power transitions
with an ongoing stream.

As some streams are allowed to run in low power state, support is
provided for S0iX state. The handlers check ACPI capabilities and the
number of active low-power paths before deciding between SX and S0iX
flows.

The last portion of the patchset is addition of power/clock gating
overrides. There is no single set of registers that ensures AudioDSP
firmware loads 100% of time on every single configuration. By having
them exposed, user can have the loading procedure behavior adjusted for
their configuration without having to recompile the kernel.


Changes in v3:
- fixed unused-but-set-variable warnings reported by the test robot

Changes in v2:
- moved DRSM reg polling to separate function,
  snd_hdac_stream_wait_drsm() as suggested by Pierre
- moved the acpi_gbl_FADT under AVS_S0IX_SUPPORTED macro and relocated
  the checks from pcm.c to topology.c so that the low-power streams are
  filtered as early as possible
- fixed compilation when CONFIG_ACPI is disabled as reported by the test
  robot
- simplified all the avs_dai_resume/suspend_xxx() by moving
  ->ignore_suspend check one level up, to avs_component_pm_op()
  (patch 0002)


Amadeusz Sławiński (1):
  ASoC: Intel: avs: Handle SUSPEND and RESUME triggers

Cezary Rojewski (7):
  ASoC: Intel: avs: Split pcm pages freeing operation from hw_free()
  ASoC: Intel: avs: Introduce PCM power management routines
  ALSA: hda: Introduce snd_hdac_stream_wait_drsm()
  ASoC: Intel: avs: Restart instead of resuming HDA capture streams
  ASoC: Intel: avs: Count low power streams
  ASoC: Intel: avs: Power and clock gating policy overriding
  ASoC: Intel: avs: Enact power gating policy

Piotr Maziarz (1):
  ASoC: Intel: avs: Standby power-state support

 include/sound/hdaudio.h        |   1 +
 include/sound/hdaudio_ext.h    |   5 +
 sound/hda/hdac_stream.c        |  21 ++
 sound/soc/intel/avs/avs.h      |   8 +
 sound/soc/intel/avs/core.c     |  97 +++++++--
 sound/soc/intel/avs/loader.c   |  10 +
 sound/soc/intel/avs/pcm.c      | 368 +++++++++++++++++++++++++++++----
 sound/soc/intel/avs/topology.c |  10 +
 8 files changed, 460 insertions(+), 60 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 1/9] ASoC: Intel: avs: Split pcm pages freeing operation from hw_free()
  2022-10-27  8:23 [PATCH v3 0/9] ASoC: Intel: avs: PCM power management Cezary Rojewski
@ 2022-10-27  8:23 ` Cezary Rojewski
  2022-10-27  8:23 ` [PATCH v3 2/9] ASoC: Intel: avs: Introduce PCM power management routines Cezary Rojewski
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Cezary Rojewski @ 2022-10-27  8:23 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: Cezary Rojewski, pierre-louis.bossart, tiwai, hdegoede,
	amadeuszx.slawinski

Prepare for introduction of PCM power management support. As freeing
pages during the suspend operation is not desired, separate
snd_pcm_lib_free_pages() from existing avs_dai_fe_hw_free() so that
majority of the code found within it can be reused for standard and PM
flows both.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/intel/avs/pcm.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index 293336c2fc63..fea801243d37 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -499,7 +499,7 @@ static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream,
 	return ret;
 }
 
-static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+static int __avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 {
 	struct avs_dma_data *data;
 	struct hdac_ext_stream *host_stream;
@@ -523,9 +523,15 @@ static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_so
 	snd_hdac_stream_cleanup(hdac_stream(host_stream));
 	hdac_stream(host_stream)->prepared = false;
 
-	ret = snd_pcm_lib_free_pages(substream);
-	if (ret < 0)
-		dev_dbg(dai->dev, "Failed to free pages!\n");
+	return ret;
+}
+
+static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+{
+	int ret;
+
+	ret = __avs_dai_fe_hw_free(substream, dai);
+	snd_pcm_lib_free_pages(substream);
 
 	return ret;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 2/9] ASoC: Intel: avs: Introduce PCM power management routines
  2022-10-27  8:23 [PATCH v3 0/9] ASoC: Intel: avs: PCM power management Cezary Rojewski
  2022-10-27  8:23 ` [PATCH v3 1/9] ASoC: Intel: avs: Split pcm pages freeing operation from hw_free() Cezary Rojewski
@ 2022-10-27  8:23 ` Cezary Rojewski
  2022-10-27  8:23 ` [PATCH v3 3/9] ALSA: hda: Introduce snd_hdac_stream_wait_drsm() Cezary Rojewski
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Cezary Rojewski @ 2022-10-27  8:23 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: Cezary Rojewski, pierre-louis.bossart, tiwai, hdegoede,
	amadeuszx.slawinski

Implement suspend/resume() operations for component drivers. For most
scenarios, the PM flow is similar to standard streaming one, except for
the part where the position register are being saved and the lack of PCM
pages freeing. To reduce code duplication, all avs_dai_suspend_XXX() and
avs_dai_resume_XXX() functions reuse their non-PM equivalents.

Given that path binding/unbinding happens only in FE part of the stream,
the order of suspend() goes:

1. hw_free() all FE DAIs, paths are unbound here
2. hw_free() all BE DAIs

Consequently, for resume() its:

1. hw_params() all BE DAIs
2. hw_params() all FE DAIs, paths are bound here
3. prepare() all BE DAIs
4. prepare() all FE DAIs

As component->suspend/resume() do not provide substream pointer, store
it ourselves so that the PM flow has all the necessary information to
proceed.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---

Changes in v3:
- fixed unused-but-set-variable warnings reported by the test robot

Changes in v2:
- moved DRSM reg polling to separate function,
  snd_hdac_stream_wait_drsm() as suggested by Pierre
- moved the acpi_gbl_FADT under AVS_S0IX_SUPPORTED macro and relocated
  the checks from pcm.c to topology.c so that the low-power streams are
  filtered as early as possible
- simplified all the avs_dai_resume/suspend_xxx() by moving
  ->ignore_suspend check one level up, to avs_component_pm_op()
  (patch 0002)

 include/sound/hdaudio_ext.h |   5 +
 sound/soc/intel/avs/pcm.c   | 214 +++++++++++++++++++++++++++++++++++-
 2 files changed, 215 insertions(+), 4 deletions(-)

diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
index 90fd47e05370..68ab89211de2 100644
--- a/include/sound/hdaudio_ext.h
+++ b/include/sound/hdaudio_ext.h
@@ -51,6 +51,11 @@ struct hdac_ext_stream {
 	void __iomem *pphc_addr;
 	void __iomem *pplc_addr;
 
+	u32 pphcllpl;
+	u32 pphcllpu;
+	u32 pphcldpl;
+	u32 pphcldpu;
+
 	bool decoupled:1;
 	bool link_locked:1;
 	bool link_prepared;
diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index fea801243d37..df965dbb8d12 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -28,6 +28,8 @@ struct avs_dma_data {
 	 * host stream assigned
 	 */
 	struct hdac_ext_stream *host_stream;
+
+	struct snd_pcm_substream *substream;
 };
 
 static struct avs_tplg_path_template *
@@ -55,7 +57,8 @@ avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction)
 	return dw->priv;
 }
 
-static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe)
+static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe,
+			   const struct snd_soc_dai_ops *ops)
 {
 	struct avs_tplg_path_template *template;
 	struct avs_dma_data *data;
@@ -71,6 +74,7 @@ static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_d
 	if (!data)
 		return -ENOMEM;
 
+	data->substream = substream;
 	data->template = template;
 	snd_soc_dai_set_dma_data(dai, substream, data);
 
@@ -151,9 +155,11 @@ static int avs_dai_prepare(struct avs_dev *adev, struct snd_pcm_substream *subst
 	return ret;
 }
 
+static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops;
+
 static int avs_dai_nonhda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 {
-	return avs_dai_startup(substream, dai, false);
+	return avs_dai_startup(substream, dai, false, &avs_dai_nonhda_be_ops);
 }
 
 static void avs_dai_nonhda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
@@ -245,9 +251,11 @@ static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = {
 	.trigger = avs_dai_nonhda_be_trigger,
 };
 
+static const struct snd_soc_dai_ops avs_dai_hda_be_ops;
+
 static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 {
-	return avs_dai_startup(substream, dai, false);
+	return avs_dai_startup(substream, dai, false, &avs_dai_hda_be_ops);
 }
 
 static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
@@ -407,6 +415,8 @@ static const struct snd_pcm_hw_constraint_list hw_rates = {
 	.mask = 0,
 };
 
+const struct snd_soc_dai_ops avs_dai_fe_ops;
+
 static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
@@ -416,7 +426,7 @@ static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_so
 	struct hdac_ext_stream *host_stream;
 	int ret;
 
-	ret = avs_dai_startup(substream, dai, true);
+	ret = avs_dai_startup(substream, dai, true, &avs_dai_fe_ops);
 	if (ret)
 		return ret;
 
@@ -758,6 +768,198 @@ static void avs_component_remove(struct snd_soc_component *component)
 	}
 }
 
+static int avs_dai_resume_hw_params(struct snd_soc_dai *dai, struct avs_dma_data *data)
+{
+	struct snd_pcm_substream *substream;
+	struct snd_soc_pcm_runtime *rtd;
+	int ret;
+
+	substream = data->substream;
+	rtd = snd_pcm_substream_chip(substream);
+
+	ret = dai->driver->ops->hw_params(substream, &rtd->dpcm[substream->stream].hw_params, dai);
+	if (ret)
+		dev_err(dai->dev, "hw_params on resume failed: %d\n", ret);
+
+	return ret;
+}
+
+static int avs_dai_resume_fe_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
+{
+	struct hdac_ext_stream *host_stream;
+	struct hdac_stream *hstream;
+	struct hdac_bus *bus;
+	int ret;
+
+	host_stream = data->host_stream;
+	hstream = hdac_stream(host_stream);
+	bus = hdac_stream(host_stream)->bus;
+
+	/* Set DRSM before programming stream and position registers. */
+	snd_hdac_stream_drsm_enable(bus, true, hstream->index);
+
+	ret = dai->driver->ops->prepare(data->substream, dai);
+	if (ret) {
+		dev_err(dai->dev, "prepare FE on resume failed: %d\n", ret);
+		return ret;
+	}
+
+	writel(host_stream->pphcllpl, host_stream->pphc_addr + AZX_REG_PPHCLLPL);
+	writel(host_stream->pphcllpu, host_stream->pphc_addr + AZX_REG_PPHCLLPU);
+	writel(host_stream->pphcldpl, host_stream->pphc_addr + AZX_REG_PPHCLDPL);
+	writel(host_stream->pphcldpu, host_stream->pphc_addr + AZX_REG_PPHCLDPU);
+
+	/* As per HW spec recommendation, program LPIB and DPIB to the same value. */
+	snd_hdac_stream_set_lpib(hstream, hstream->lpib);
+	snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib);
+
+	return 0;
+}
+
+static int avs_dai_resume_be_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
+{
+	int ret;
+
+	ret = dai->driver->ops->prepare(data->substream, dai);
+	if (ret)
+		dev_err(dai->dev, "prepare BE on resume failed: %d\n", ret);
+
+	return ret;
+}
+
+static int avs_dai_suspend_fe_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
+{
+	struct hdac_ext_stream *host_stream;
+	int ret;
+
+	host_stream = data->host_stream;
+
+	/* Store position addresses so we can resume from them later on. */
+	hdac_stream(host_stream)->lpib = snd_hdac_stream_get_pos_lpib(hdac_stream(host_stream));
+	host_stream->pphcllpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPL);
+	host_stream->pphcllpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPU);
+	host_stream->pphcldpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPL);
+	host_stream->pphcldpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPU);
+
+	ret = __avs_dai_fe_hw_free(data->substream, dai);
+	if (ret < 0)
+		dev_err(dai->dev, "hw_free FE on suspend failed: %d\n", ret);
+
+	return ret;
+}
+
+static int avs_dai_suspend_be_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
+{
+	int ret;
+
+	ret = dai->driver->ops->hw_free(data->substream, dai);
+	if (ret < 0)
+		dev_err(dai->dev, "hw_free BE on suspend failed: %d\n", ret);
+
+	return ret;
+}
+
+static int avs_component_pm_op(struct snd_soc_component *component, bool be,
+			       int (*op)(struct snd_soc_dai *, struct avs_dma_data *))
+{
+	struct snd_soc_pcm_runtime *rtd;
+	struct avs_dma_data *data;
+	struct snd_soc_dai *dai;
+	int ret;
+
+	for_each_component_dais(component, dai) {
+		data = dai->playback_dma_data;
+		if (data) {
+			rtd = snd_pcm_substream_chip(data->substream);
+			if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
+				ret = op(dai, data);
+				if (ret < 0)
+					return ret;
+			}
+		}
+
+		data = dai->capture_dma_data;
+		if (data) {
+			rtd = snd_pcm_substream_chip(data->substream);
+			if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
+				ret = op(dai, data);
+				if (ret < 0)
+					return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int avs_component_resume_hw_params(struct snd_soc_component *component, bool be)
+{
+	return avs_component_pm_op(component, be, &avs_dai_resume_hw_params);
+}
+
+static int avs_component_resume_prepare(struct snd_soc_component *component, bool be)
+{
+	int (*prepare_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
+
+	if (be)
+		prepare_cb = &avs_dai_resume_be_prepare;
+	else
+		prepare_cb = &avs_dai_resume_fe_prepare;
+
+	return avs_component_pm_op(component, be, prepare_cb);
+}
+
+static int avs_component_suspend_hw_free(struct snd_soc_component *component, bool be)
+{
+	int (*hw_free_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
+
+	if (be)
+		hw_free_cb = &avs_dai_suspend_be_hw_free;
+	else
+		hw_free_cb = &avs_dai_suspend_fe_hw_free;
+
+	return avs_component_pm_op(component, be, hw_free_cb);
+}
+
+static int avs_component_suspend(struct snd_soc_component *component)
+{
+	int ret;
+
+	/*
+	 * When freeing paths, FEs need to be first as they perform
+	 * path unbinding.
+	 */
+	ret = avs_component_suspend_hw_free(component, false);
+	if (ret)
+		return ret;
+
+	return avs_component_suspend_hw_free(component, true);
+}
+
+static int avs_component_resume(struct snd_soc_component *component)
+{
+	int ret;
+
+	/*
+	 * When creating paths, FEs need to be last as they perform
+	 * path binding.
+	 */
+	ret = avs_component_resume_hw_params(component, true);
+	if (ret)
+		return ret;
+
+	ret = avs_component_resume_hw_params(component, false);
+	if (ret)
+		return ret;
+
+	/* It is expected that the LINK stream is prepared first. */
+	ret = avs_component_resume_prepare(component, true);
+	if (ret)
+		return ret;
+
+	return avs_component_resume_prepare(component, false);
+}
+
 static int avs_component_open(struct snd_soc_component *component,
 			      struct snd_pcm_substream *substream)
 {
@@ -846,6 +1048,8 @@ static const struct snd_soc_component_driver avs_component_driver = {
 	.name			= "avs-pcm",
 	.probe			= avs_component_probe,
 	.remove			= avs_component_remove,
+	.suspend		= avs_component_suspend,
+	.resume			= avs_component_resume,
 	.open			= avs_component_open,
 	.pointer		= avs_component_pointer,
 	.mmap			= avs_component_mmap,
@@ -1161,6 +1365,8 @@ static const struct snd_soc_component_driver avs_hda_component_driver = {
 	.name			= "avs-hda-pcm",
 	.probe			= avs_component_hda_probe,
 	.remove			= avs_component_hda_remove,
+	.suspend		= avs_component_suspend,
+	.resume			= avs_component_resume,
 	.open			= avs_component_hda_open,
 	.close			= avs_component_hda_close,
 	.pointer		= avs_component_pointer,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 3/9] ALSA: hda: Introduce snd_hdac_stream_wait_drsm()
  2022-10-27  8:23 [PATCH v3 0/9] ASoC: Intel: avs: PCM power management Cezary Rojewski
  2022-10-27  8:23 ` [PATCH v3 1/9] ASoC: Intel: avs: Split pcm pages freeing operation from hw_free() Cezary Rojewski
  2022-10-27  8:23 ` [PATCH v3 2/9] ASoC: Intel: avs: Introduce PCM power management routines Cezary Rojewski
@ 2022-10-27  8:23 ` Cezary Rojewski
  2022-10-27 10:21   ` Takashi Iwai
  2022-10-27  8:23 ` [PATCH v3 4/9] ASoC: Intel: avs: Handle SUSPEND and RESUME triggers Cezary Rojewski
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 15+ messages in thread
From: Cezary Rojewski @ 2022-10-27  8:23 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: Cezary Rojewski, pierre-louis.bossart, tiwai, hdegoede,
	amadeuszx.slawinski

Allow for waiting for DRSM bit for specified stream to be cleared from
HDAudio library level. Drivers may utilize this optional step during the
stream resume procedure.

Suggested-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 include/sound/hdaudio.h |  1 +
 sound/hda/hdac_stream.c | 21 +++++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 78f1809a4ad6..a6872537724d 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -597,6 +597,7 @@ int snd_hdac_stream_get_spbmaxfifo(struct hdac_bus *bus,
 				   struct hdac_stream *azx_dev);
 void snd_hdac_stream_drsm_enable(struct hdac_bus *bus,
 				 bool enable, int index);
+int snd_hdac_stream_wait_drsm(struct hdac_stream *azx_dev);
 int snd_hdac_stream_set_dpibr(struct hdac_bus *bus,
 			      struct hdac_stream *azx_dev, u32 value);
 int snd_hdac_stream_set_lpib(struct hdac_stream *azx_dev, u32 value);
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index 35fe2bd582ac..59e8bfe4feca 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -821,6 +821,27 @@ void snd_hdac_stream_drsm_enable(struct hdac_bus *bus,
 }
 EXPORT_SYMBOL_GPL(snd_hdac_stream_drsm_enable);
 
+/*
+ * snd_hdac_stream_wait_drsm - wait for HW to clear RSM for a stream
+ * @azx_dev: HD-audio core stream to await RSM for
+ *
+ * Returns 0 on success and -ETIMEDOUT upon a timeout.
+ */
+int snd_hdac_stream_wait_drsm(struct hdac_stream *azx_dev)
+{
+	struct hdac_bus *bus = azx_dev->bus;
+	u32 mask, reg;
+	int ret;
+
+	mask = 1 << azx_dev->index;
+
+	ret = readb_poll_timeout(bus->drsmcap + AZX_REG_DRSM_CTL, reg, !(reg & mask), 250, 2000);
+	if (ret)
+		dev_dbg(bus->dev, "polling RSM 0x%08x failed: %d\n", mask, ret);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_stream_wait_drsm);
+
 /**
  * snd_hdac_stream_set_dpibr - sets the dpibr value of a stream
  * @bus: HD-audio core bus
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 4/9] ASoC: Intel: avs: Handle SUSPEND and RESUME triggers
  2022-10-27  8:23 [PATCH v3 0/9] ASoC: Intel: avs: PCM power management Cezary Rojewski
                   ` (2 preceding siblings ...)
  2022-10-27  8:23 ` [PATCH v3 3/9] ALSA: hda: Introduce snd_hdac_stream_wait_drsm() Cezary Rojewski
@ 2022-10-27  8:23 ` Cezary Rojewski
  2022-10-27  8:23 ` [PATCH v3 5/9] ASoC: Intel: avs: Restart instead of resuming HDA capture streams Cezary Rojewski
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Cezary Rojewski @ 2022-10-27  8:23 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: Cezary Rojewski, pierre-louis.bossart, tiwai, hdegoede,
	amadeuszx.slawinski

From: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>

With power management operations added, service SUSPEND and RESUME
trigger commands for running streams.

Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/intel/avs/pcm.c | 75 +++++++++++++++++++++++++++++++--------
 1 file changed, 60 insertions(+), 15 deletions(-)

diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index df965dbb8d12..db29496e16ab 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -208,30 +208,43 @@ static int avs_dai_nonhda_be_prepare(struct snd_pcm_substream *substream, struct
 static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd,
 				     struct snd_soc_dai *dai)
 {
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
 	struct avs_dma_data *data;
 	int ret = 0;
 
 	data = snd_soc_dai_get_dma_data(dai, substream);
 
 	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_RESUME:
+		if (rtd->dai_link->ignore_suspend)
+			break;
+		fallthrough;
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		ret = avs_path_pause(data->path);
+		if (ret < 0) {
+			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
+			break;
+		}
+
 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
 		if (ret < 0)
 			dev_err(dai->dev, "run BE path failed: %d\n", ret);
 		break;
 
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		if (rtd->dai_link->ignore_suspend)
+			break;
+		fallthrough;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 	case SNDRV_PCM_TRIGGER_STOP:
 		ret = avs_path_pause(data->path);
 		if (ret < 0)
 			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
 
-		if (cmd == SNDRV_PCM_TRIGGER_STOP) {
-			ret = avs_path_reset(data->path);
-			if (ret < 0)
-				dev_err(dai->dev, "reset BE path failed: %d\n", ret);
-		}
+		ret = avs_path_reset(data->path);
+		if (ret < 0)
+			dev_err(dai->dev, "reset BE path failed: %d\n", ret);
 		break;
 
 	default:
@@ -351,6 +364,7 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn
 static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
 				  struct snd_soc_dai *dai)
 {
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
 	struct hdac_ext_stream *link_stream;
 	struct avs_dma_data *data;
 	int ret = 0;
@@ -361,15 +375,29 @@ static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
 	link_stream = substream->runtime->private_data;
 
 	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_RESUME:
+		if (rtd->dai_link->ignore_suspend)
+			break;
+		fallthrough;
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		snd_hdac_ext_stream_start(link_stream);
 
+		ret = avs_path_pause(data->path);
+		if (ret < 0) {
+			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
+			break;
+		}
+
 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
 		if (ret < 0)
 			dev_err(dai->dev, "run BE path failed: %d\n", ret);
 		break;
 
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		if (rtd->dai_link->ignore_suspend)
+			break;
+		fallthrough;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 	case SNDRV_PCM_TRIGGER_STOP:
 		ret = avs_path_pause(data->path);
@@ -378,11 +406,9 @@ static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
 
 		snd_hdac_ext_stream_clear(link_stream);
 
-		if (cmd == SNDRV_PCM_TRIGGER_STOP) {
-			ret = avs_path_reset(data->path);
-			if (ret < 0)
-				dev_err(dai->dev, "reset BE path failed: %d\n", ret);
-		}
+		ret = avs_path_reset(data->path);
+		if (ret < 0)
+			dev_err(dai->dev, "reset BE path failed: %d\n", ret);
 		break;
 
 	default:
@@ -587,6 +613,7 @@ static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_so
 
 static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
 {
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
 	struct avs_dma_data *data;
 	struct hdac_ext_stream *host_stream;
 	struct hdac_bus *bus;
@@ -598,17 +625,36 @@ static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, stru
 	bus = hdac_stream(host_stream)->bus;
 
 	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_RESUME:
+		if (rtd->dai_link->ignore_suspend)
+			break;
+		fallthrough;
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		spin_lock_irqsave(&bus->reg_lock, flags);
 		snd_hdac_stream_start(hdac_stream(host_stream), true);
 		spin_unlock_irqrestore(&bus->reg_lock, flags);
 
+		/* Timeout on DRSM poll shall not stop the resume so ignore the result. */
+		if (cmd == SNDRV_PCM_TRIGGER_RESUME)
+			snd_hdac_stream_wait_drsm(hdac_stream(host_stream));
+
+		ret = avs_path_pause(data->path);
+		if (ret < 0) {
+			dev_err(dai->dev, "pause FE path failed: %d\n", ret);
+			break;
+		}
+
 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
 		if (ret < 0)
 			dev_err(dai->dev, "run FE path failed: %d\n", ret);
+
 		break;
 
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		if (rtd->dai_link->ignore_suspend)
+			break;
+		fallthrough;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 	case SNDRV_PCM_TRIGGER_STOP:
 		ret = avs_path_pause(data->path);
@@ -619,11 +665,9 @@ static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, stru
 		snd_hdac_stream_stop(hdac_stream(host_stream));
 		spin_unlock_irqrestore(&bus->reg_lock, flags);
 
-		if (cmd == SNDRV_PCM_TRIGGER_STOP) {
-			ret = avs_path_reset(data->path);
-			if (ret < 0)
-				dev_err(dai->dev, "reset FE path failed: %d\n", ret);
-		}
+		ret = avs_path_reset(data->path);
+		if (ret < 0)
+			dev_err(dai->dev, "reset FE path failed: %d\n", ret);
 		break;
 
 	default:
@@ -974,6 +1018,7 @@ static int avs_component_open(struct snd_soc_component *component,
 			SNDRV_PCM_INFO_MMAP_VALID |
 			SNDRV_PCM_INFO_INTERLEAVED |
 			SNDRV_PCM_INFO_PAUSE |
+			SNDRV_PCM_INFO_RESUME |
 			SNDRV_PCM_INFO_NO_PERIOD_WAKEUP;
 
 	hwparams.formats = SNDRV_PCM_FMTBIT_S16_LE |
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 5/9] ASoC: Intel: avs: Restart instead of resuming HDA capture streams
  2022-10-27  8:23 [PATCH v3 0/9] ASoC: Intel: avs: PCM power management Cezary Rojewski
                   ` (3 preceding siblings ...)
  2022-10-27  8:23 ` [PATCH v3 4/9] ASoC: Intel: avs: Handle SUSPEND and RESUME triggers Cezary Rojewski
@ 2022-10-27  8:23 ` Cezary Rojewski
  2022-10-27  8:23 ` [PATCH v3 6/9] ASoC: Intel: avs: Count low power streams Cezary Rojewski
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Cezary Rojewski @ 2022-10-27  8:23 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: Cezary Rojewski, pierre-louis.bossart, tiwai, hdegoede,
	amadeuszx.slawinski

Resuming of capture streams for HD-Audio is unsupported so remove the
relevant flag from the hardware params when assigning them during
avs_component_hda_open().

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/intel/avs/pcm.c | 50 ++++++++++++++++++++++-----------------
 1 file changed, 28 insertions(+), 22 deletions(-)

diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index db29496e16ab..660129508c08 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -1004,34 +1004,34 @@ static int avs_component_resume(struct snd_soc_component *component)
 	return avs_component_resume_prepare(component, false);
 }
 
+static const struct snd_pcm_hardware avs_pcm_hardware = {
+	.info			= SNDRV_PCM_INFO_MMAP |
+				  SNDRV_PCM_INFO_MMAP_VALID |
+				  SNDRV_PCM_INFO_INTERLEAVED |
+				  SNDRV_PCM_INFO_PAUSE |
+				  SNDRV_PCM_INFO_RESUME |
+				  SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
+	.formats		= SNDRV_PCM_FMTBIT_S16_LE |
+				  SNDRV_PCM_FMTBIT_S24_LE |
+				  SNDRV_PCM_FMTBIT_S32_LE,
+	.buffer_bytes_max	= AZX_MAX_BUF_SIZE,
+	.period_bytes_min	= 128,
+	.period_bytes_max	= AZX_MAX_BUF_SIZE / 2,
+	.periods_min		= 2,
+	.periods_max		= AZX_MAX_FRAG,
+	.fifo_size		= 0,
+};
+
 static int avs_component_open(struct snd_soc_component *component,
 			      struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
-	struct snd_pcm_hardware hwparams;
 
 	/* only FE DAI links are handled here */
 	if (rtd->dai_link->no_pcm)
 		return 0;
 
-	hwparams.info = SNDRV_PCM_INFO_MMAP |
-			SNDRV_PCM_INFO_MMAP_VALID |
-			SNDRV_PCM_INFO_INTERLEAVED |
-			SNDRV_PCM_INFO_PAUSE |
-			SNDRV_PCM_INFO_RESUME |
-			SNDRV_PCM_INFO_NO_PERIOD_WAKEUP;
-
-	hwparams.formats = SNDRV_PCM_FMTBIT_S16_LE |
-			   SNDRV_PCM_FMTBIT_S24_LE |
-			   SNDRV_PCM_FMTBIT_S32_LE;
-	hwparams.period_bytes_min = 128;
-	hwparams.period_bytes_max = AZX_MAX_BUF_SIZE / 2;
-	hwparams.periods_min = 2;
-	hwparams.periods_max = AZX_MAX_FRAG;
-	hwparams.buffer_bytes_max = AZX_MAX_BUF_SIZE;
-	hwparams.fifo_size = 0;
-
-	return snd_soc_set_runtime_hwparams(substream, &hwparams);
+	return snd_soc_set_runtime_hwparams(substream, &avs_pcm_hardware);
 }
 
 static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream)
@@ -1375,9 +1375,15 @@ static int avs_component_hda_open(struct snd_soc_component *component,
 	struct hdac_ext_stream *link_stream;
 	struct hda_codec *codec;
 
-	/* only BE DAI links are handled here */
-	if (!rtd->dai_link->no_pcm)
-		return avs_component_open(component, substream);
+	if (!rtd->dai_link->no_pcm) {
+		struct snd_pcm_hardware hwparams = avs_pcm_hardware;
+
+		/* RESUME unsupported for de-coupled HD-Audio capture. */
+		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			hwparams.info &= ~SNDRV_PCM_INFO_RESUME;
+
+		return snd_soc_set_runtime_hwparams(substream, &hwparams);
+	}
 
 	codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
 	link_stream = snd_hdac_ext_stream_assign(&codec->bus->core, substream,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 6/9] ASoC: Intel: avs: Count low power streams
  2022-10-27  8:23 [PATCH v3 0/9] ASoC: Intel: avs: PCM power management Cezary Rojewski
                   ` (4 preceding siblings ...)
  2022-10-27  8:23 ` [PATCH v3 5/9] ASoC: Intel: avs: Restart instead of resuming HDA capture streams Cezary Rojewski
@ 2022-10-27  8:23 ` Cezary Rojewski
  2022-10-27  8:23 ` [PATCH v3 7/9] ASoC: Intel: avs: Standby power-state support Cezary Rojewski
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Cezary Rojewski @ 2022-10-27  8:23 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: Cezary Rojewski, pierre-louis.bossart, tiwai, hdegoede,
	amadeuszx.slawinski

Streaming in S0iX differs from SX scenarios. Store the number of
so-called low-power streams to be able to differentiate between the two.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/intel/avs/avs.h |  1 +
 sound/soc/intel/avs/pcm.c | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h
index 91f78eb11bc1..fb73d207697f 100644
--- a/sound/soc/intel/avs/avs.h
+++ b/sound/soc/intel/avs/avs.h
@@ -127,6 +127,7 @@ struct avs_dev {
 	struct list_head fw_list;
 	int *core_refs;		/* reference count per core */
 	char **lib_names;
+	int num_lp_paths;
 
 	struct completion fw_ready;
 	struct work_struct probe_work;
diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index 660129508c08..157d25e32e16 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -60,6 +60,8 @@ avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction)
 static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe,
 			   const struct snd_soc_dai_ops *ops)
 {
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+	struct avs_dev *adev = to_avs_dev(dai->dev);
 	struct avs_tplg_path_template *template;
 	struct avs_dma_data *data;
 
@@ -78,6 +80,9 @@ static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_d
 	data->template = template;
 	snd_soc_dai_set_dma_data(dai, substream, data);
 
+	if (rtd->dai_link->ignore_suspend)
+		adev->num_lp_paths++;
+
 	return 0;
 }
 
@@ -164,8 +169,13 @@ static int avs_dai_nonhda_be_startup(struct snd_pcm_substream *substream, struct
 
 static void avs_dai_nonhda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 {
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+	struct avs_dev *adev = to_avs_dev(dai->dev);
 	struct avs_dma_data *data;
 
+	if (rtd->dai_link->ignore_suspend)
+		adev->num_lp_paths--;
+
 	data = snd_soc_dai_get_dma_data(dai, substream);
 
 	snd_soc_dai_set_dma_data(dai, substream, NULL);
@@ -479,8 +489,13 @@ static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_so
 
 static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 {
+	struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+	struct avs_dev *adev = to_avs_dev(dai->dev);
 	struct avs_dma_data *data;
 
+	if (rtd->dai_link->ignore_suspend)
+		adev->num_lp_paths--;
+
 	data = snd_soc_dai_get_dma_data(dai, substream);
 
 	snd_soc_dai_set_dma_data(dai, substream, NULL);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 7/9] ASoC: Intel: avs: Standby power-state support
  2022-10-27  8:23 [PATCH v3 0/9] ASoC: Intel: avs: PCM power management Cezary Rojewski
                   ` (5 preceding siblings ...)
  2022-10-27  8:23 ` [PATCH v3 6/9] ASoC: Intel: avs: Count low power streams Cezary Rojewski
@ 2022-10-27  8:23 ` Cezary Rojewski
  2022-10-27  8:23 ` [PATCH v3 8/9] ASoC: Intel: avs: Power and clock gating policy overriding Cezary Rojewski
  2022-10-27  8:23 ` [PATCH v3 9/9] ASoC: Intel: avs: Enact power gating policy Cezary Rojewski
  8 siblings, 0 replies; 15+ messages in thread
From: Cezary Rojewski @ 2022-10-27  8:23 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: Cezary Rojewski, tiwai, Piotr Maziarz, pierre-louis.bossart,
	hdegoede, amadeuszx.slawinski

From: Piotr Maziarz <piotrx.maziarz@linux.intel.com>

Introduce avs_suspend_standby() and avs_resume_standby() to support S0IX
streaming. The AudioDSP is not shutdown during such scenario and the PCI
device is armed for possible wake operation through an audio event.

As capability for a stream to be active during low power S0 is based off
of ->ignore_suspend, adjust the field's value according to platform
capabilities if needed.

Signed-off-by: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/intel/avs/avs.h      |  7 ++++
 sound/soc/intel/avs/core.c     | 75 ++++++++++++++++++++++++++++++----
 sound/soc/intel/avs/topology.c | 10 +++++
 3 files changed, 85 insertions(+), 7 deletions(-)

diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h
index fb73d207697f..8d05b27608fe 100644
--- a/sound/soc/intel/avs/avs.h
+++ b/sound/soc/intel/avs/avs.h
@@ -24,6 +24,13 @@ struct avs_tplg_library;
 struct avs_soc_component;
 struct avs_ipc_msg;
 
+#ifdef CONFIG_ACPI
+#define AVS_S0IX_SUPPORTED \
+	(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)
+#else
+#define AVS_S0IX_SUPPORTED false
+#endif
+
 /*
  * struct avs_dsp_ops - Platform-specific DSP operations
  *
diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
index 0aaded90a99a..6b68d926c9f4 100644
--- a/sound/soc/intel/avs/core.c
+++ b/sound/soc/intel/avs/core.c
@@ -534,12 +534,30 @@ static void avs_pci_remove(struct pci_dev *pci)
 	pm_runtime_get_noresume(&pci->dev);
 }
 
-static int __maybe_unused avs_suspend_common(struct avs_dev *adev)
+static int avs_suspend_standby(struct avs_dev *adev)
+{
+	struct hdac_bus *bus = &adev->base.core;
+	struct pci_dev *pci = adev->base.pci;
+
+	if (bus->cmd_dma_state)
+		snd_hdac_bus_stop_cmd_io(bus);
+
+	snd_hdac_ext_bus_link_power_down_all(bus);
+
+	enable_irq_wake(pci->irq);
+	pci_save_state(pci);
+
+	return 0;
+}
+
+static int __maybe_unused avs_suspend_common(struct avs_dev *adev, bool low_power)
 {
 	struct hdac_bus *bus = &adev->base.core;
 	int ret;
 
 	flush_work(&adev->probe_work);
+	if (low_power && adev->num_lp_paths)
+		return avs_suspend_standby(adev);
 
 	snd_hdac_ext_bus_link_power_down_all(bus);
 
@@ -577,11 +595,30 @@ static int __maybe_unused avs_suspend_common(struct avs_dev *adev)
 	return 0;
 }
 
-static int __maybe_unused avs_resume_common(struct avs_dev *adev, bool purge)
+static int avs_resume_standby(struct avs_dev *adev)
+{
+	struct hdac_bus *bus = &adev->base.core;
+	struct pci_dev *pci = adev->base.pci;
+
+	pci_restore_state(pci);
+	disable_irq_wake(pci->irq);
+
+	snd_hdac_ext_bus_link_power_up_all(bus);
+
+	if (bus->cmd_dma_state)
+		snd_hdac_bus_init_cmd_io(bus);
+
+	return 0;
+}
+
+static int __maybe_unused avs_resume_common(struct avs_dev *adev, bool low_power, bool purge)
 {
 	struct hdac_bus *bus = &adev->base.core;
 	int ret;
 
+	if (low_power && adev->num_lp_paths)
+		return avs_resume_standby(adev);
+
 	snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true);
 	avs_hdac_bus_init_chip(bus, true);
 
@@ -599,26 +636,50 @@ static int __maybe_unused avs_resume_common(struct avs_dev *adev, bool purge)
 
 static int __maybe_unused avs_suspend(struct device *dev)
 {
-	return avs_suspend_common(to_avs_dev(dev));
+	return avs_suspend_common(to_avs_dev(dev), true);
 }
 
 static int __maybe_unused avs_resume(struct device *dev)
 {
-	return avs_resume_common(to_avs_dev(dev), true);
+	return avs_resume_common(to_avs_dev(dev), true, true);
 }
 
 static int __maybe_unused avs_runtime_suspend(struct device *dev)
 {
-	return avs_suspend_common(to_avs_dev(dev));
+	return avs_suspend_common(to_avs_dev(dev), true);
 }
 
 static int __maybe_unused avs_runtime_resume(struct device *dev)
 {
-	return avs_resume_common(to_avs_dev(dev), true);
+	return avs_resume_common(to_avs_dev(dev), true, false);
+}
+
+static int __maybe_unused avs_freeze(struct device *dev)
+{
+	return avs_suspend_common(to_avs_dev(dev), false);
+}
+static int __maybe_unused avs_thaw(struct device *dev)
+{
+	return avs_resume_common(to_avs_dev(dev), false, true);
+}
+
+static int __maybe_unused avs_poweroff(struct device *dev)
+{
+	return avs_suspend_common(to_avs_dev(dev), false);
+}
+
+static int __maybe_unused avs_restore(struct device *dev)
+{
+	return avs_resume_common(to_avs_dev(dev), false, true);
 }
 
 static const struct dev_pm_ops avs_dev_pm = {
-	SET_SYSTEM_SLEEP_PM_OPS(avs_suspend, avs_resume)
+	.suspend = avs_suspend,
+	.resume = avs_resume,
+	.freeze = avs_freeze,
+	.thaw = avs_thaw,
+	.poweroff = avs_poweroff,
+	.restore = avs_restore,
 	SET_RUNTIME_PM_OPS(avs_runtime_suspend, avs_runtime_resume, NULL)
 };
 
diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c
index 8a9f9fc48938..e845eaf0a1e7 100644
--- a/sound/soc/intel/avs/topology.c
+++ b/sound/soc/intel/avs/topology.c
@@ -1405,6 +1405,11 @@ static int avs_widget_load(struct snd_soc_component *comp, int index,
 	if (!le32_to_cpu(dw->priv.size))
 		return 0;
 
+	if (w->ignore_suspend && !AVS_S0IX_SUPPORTED) {
+		dev_info_once(comp->dev, "Device does not support S0IX, check BIOS settings\n");
+		w->ignore_suspend = false;
+	}
+
 	tplg = acomp->tplg;
 	mach = dev_get_platdata(comp->card->dev);
 
@@ -1442,6 +1447,11 @@ static int avs_dai_load(struct snd_soc_component *comp, int index,
 static int avs_link_load(struct snd_soc_component *comp, int index, struct snd_soc_dai_link *link,
 			 struct snd_soc_tplg_link_config *cfg)
 {
+	if (link->ignore_suspend && !AVS_S0IX_SUPPORTED) {
+		dev_info_once(comp->dev, "Device does not support S0IX, check BIOS settings\n");
+		link->ignore_suspend = false;
+	}
+
 	if (!link->no_pcm) {
 		/* Stream control handled by IPCs. */
 		link->nonatomic = true;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 8/9] ASoC: Intel: avs: Power and clock gating policy overriding
  2022-10-27  8:23 [PATCH v3 0/9] ASoC: Intel: avs: PCM power management Cezary Rojewski
                   ` (6 preceding siblings ...)
  2022-10-27  8:23 ` [PATCH v3 7/9] ASoC: Intel: avs: Standby power-state support Cezary Rojewski
@ 2022-10-27  8:23 ` Cezary Rojewski
  2022-10-27  8:23 ` [PATCH v3 9/9] ASoC: Intel: avs: Enact power gating policy Cezary Rojewski
  8 siblings, 0 replies; 15+ messages in thread
From: Cezary Rojewski @ 2022-10-27  8:23 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: Cezary Rojewski, pierre-louis.bossart, tiwai, hdegoede,
	amadeuszx.slawinski

Provide pgctl/cgctl_mask module parameters for overriding power and
clock gating policies respectively. These help deal with rare firmware
loading failures on some configurations. There're no golden masks that
cover all known problems so leave the defaults as is.

While at it, update avs_hda_l1sen_enable()'s definition so it aligns
with its power/clock friends.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/intel/avs/core.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
index 6b68d926c9f4..f7bc06404dbc 100644
--- a/sound/soc/intel/avs/core.c
+++ b/sound/soc/intel/avs/core.c
@@ -27,6 +27,14 @@
 #include "avs.h"
 #include "cldma.h"
 
+static u32 pgctl_mask = AZX_PGCTL_LSRMD_MASK;
+module_param(pgctl_mask, uint, 0444);
+MODULE_PARM_DESC(pgctl_mask, "PCI PGCTL policy override");
+
+static u32 cgctl_mask = AZX_CGCTL_MISCBDCGE_MASK;
+module_param(cgctl_mask, uint, 0444);
+MODULE_PARM_DESC(cgctl_mask, "PCI CGCTL policy override");
+
 static void
 avs_hda_update_config_dword(struct hdac_bus *bus, u32 reg, u32 mask, u32 value)
 {
@@ -41,19 +49,16 @@ avs_hda_update_config_dword(struct hdac_bus *bus, u32 reg, u32 mask, u32 value)
 
 void avs_hda_power_gating_enable(struct avs_dev *adev, bool enable)
 {
-	u32 value;
+	u32 value = enable ? 0 : pgctl_mask;
 
-	value = enable ? 0 : AZX_PGCTL_LSRMD_MASK;
-	avs_hda_update_config_dword(&adev->base.core, AZX_PCIREG_PGCTL,
-				    AZX_PGCTL_LSRMD_MASK, value);
+	avs_hda_update_config_dword(&adev->base.core, AZX_PCIREG_PGCTL, pgctl_mask, value);
 }
 
 static void avs_hdac_clock_gating_enable(struct hdac_bus *bus, bool enable)
 {
-	u32 value;
+	u32 value = enable ? cgctl_mask : 0;
 
-	value = enable ? AZX_CGCTL_MISCBDCGE_MASK : 0;
-	avs_hda_update_config_dword(bus, AZX_PCIREG_CGCTL, AZX_CGCTL_MISCBDCGE_MASK, value);
+	avs_hda_update_config_dword(bus, AZX_PCIREG_CGCTL, cgctl_mask, value);
 }
 
 void avs_hda_clock_gating_enable(struct avs_dev *adev, bool enable)
@@ -63,9 +68,8 @@ void avs_hda_clock_gating_enable(struct avs_dev *adev, bool enable)
 
 void avs_hda_l1sen_enable(struct avs_dev *adev, bool enable)
 {
-	u32 value;
+	u32 value = enable ? AZX_VS_EM2_L1SEN : 0;
 
-	value = enable ? AZX_VS_EM2_L1SEN : 0;
 	snd_hdac_chip_updatel(&adev->base.core, VS_EM2, AZX_VS_EM2_L1SEN, value);
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 9/9] ASoC: Intel: avs: Enact power gating policy
  2022-10-27  8:23 [PATCH v3 0/9] ASoC: Intel: avs: PCM power management Cezary Rojewski
                   ` (7 preceding siblings ...)
  2022-10-27  8:23 ` [PATCH v3 8/9] ASoC: Intel: avs: Power and clock gating policy overriding Cezary Rojewski
@ 2022-10-27  8:23 ` Cezary Rojewski
  8 siblings, 0 replies; 15+ messages in thread
From: Cezary Rojewski @ 2022-10-27  8:23 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: Cezary Rojewski, pierre-louis.bossart, tiwai, hdegoede,
	amadeuszx.slawinski

Update all firmware loading functions to also account for the power
gating policy. As module loading routine is missing the chicken bits
manipulation entirely, add the entire set there.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/intel/avs/loader.c | 10 ++++++++++
 sound/soc/intel/avs/pcm.c    |  2 ++
 2 files changed, 12 insertions(+)

diff --git a/sound/soc/intel/avs/loader.c b/sound/soc/intel/avs/loader.c
index eb10e45790e7..56bb0a59249d 100644
--- a/sound/soc/intel/avs/loader.c
+++ b/sound/soc/intel/avs/loader.c
@@ -224,11 +224,19 @@ static int avs_cldma_load_module(struct avs_dev *adev, struct avs_module_entry *
 	if (ret < 0)
 		return ret;
 
+	avs_hda_power_gating_enable(adev, false);
+	avs_hda_clock_gating_enable(adev, false);
+	avs_hda_l1sen_enable(adev, false);
+
 	hda_cldma_set_data(cl, (void *)mod->data, mod->size);
 	hda_cldma_transfer(cl, msecs_to_jiffies(AVS_CLDMA_START_DELAY_MS));
 	ret = avs_ipc_load_modules(adev, &mentry->module_id, 1);
 	hda_cldma_stop(cl);
 
+	avs_hda_l1sen_enable(adev, true);
+	avs_hda_clock_gating_enable(adev, true);
+	avs_hda_power_gating_enable(adev, true);
+
 	if (ret) {
 		dev_err(adev->dev, "load module %d failed: %d\n", mentry->module_id, ret);
 		avs_release_last_firmware(adev);
@@ -605,6 +613,7 @@ int avs_dsp_boot_firmware(struct avs_dev *adev, bool purge)
 	for (i = 1; i < adev->fw_cfg.max_libs_count; i++)
 		memset(adev->lib_names[i], 0, AVS_LIB_NAME_SIZE);
 
+	avs_hda_power_gating_enable(adev, false);
 	avs_hda_clock_gating_enable(adev, false);
 	avs_hda_l1sen_enable(adev, false);
 
@@ -625,6 +634,7 @@ int avs_dsp_boot_firmware(struct avs_dev *adev, bool purge)
 reenable_gating:
 	avs_hda_l1sen_enable(adev, true);
 	avs_hda_clock_gating_enable(adev, true);
+	avs_hda_power_gating_enable(adev, true);
 
 	if (ret < 0)
 		return ret;
diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index 157d25e32e16..ca624fbb5c0d 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -737,6 +737,7 @@ static int avs_component_load_libraries(struct avs_soc_component *acomp)
 	if (ret < 0)
 		return ret;
 
+	avs_hda_power_gating_enable(adev, false);
 	avs_hda_clock_gating_enable(adev, false);
 	avs_hda_l1sen_enable(adev, false);
 
@@ -744,6 +745,7 @@ static int avs_component_load_libraries(struct avs_soc_component *acomp)
 
 	avs_hda_l1sen_enable(adev, true);
 	avs_hda_clock_gating_enable(adev, true);
+	avs_hda_power_gating_enable(adev, true);
 
 	if (!ret)
 		ret = avs_module_info_init(adev, false);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 3/9] ALSA: hda: Introduce snd_hdac_stream_wait_drsm()
  2022-10-27  8:23 ` [PATCH v3 3/9] ALSA: hda: Introduce snd_hdac_stream_wait_drsm() Cezary Rojewski
@ 2022-10-27 10:21   ` Takashi Iwai
  2022-10-27 10:29     ` Amadeusz Sławiński
  0 siblings, 1 reply; 15+ messages in thread
From: Takashi Iwai @ 2022-10-27 10:21 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, pierre-louis.bossart, tiwai, hdegoede, broonie,
	amadeuszx.slawinski

On Thu, 27 Oct 2022 10:23:25 +0200,
Cezary Rojewski wrote:
> --- a/sound/hda/hdac_stream.c
> +++ b/sound/hda/hdac_stream.c
> @@ -821,6 +821,27 @@ void snd_hdac_stream_drsm_enable(struct hdac_bus *bus,
>  }
>  EXPORT_SYMBOL_GPL(snd_hdac_stream_drsm_enable);
>  
> +/*
> + * snd_hdac_stream_wait_drsm - wait for HW to clear RSM for a stream
> + * @azx_dev: HD-audio core stream to await RSM for
> + *
> + * Returns 0 on success and -ETIMEDOUT upon a timeout.
> + */
> +int snd_hdac_stream_wait_drsm(struct hdac_stream *azx_dev)
> +{
> +	struct hdac_bus *bus = azx_dev->bus;
> +	u32 mask, reg;
> +	int ret;
> +
> +	mask = 1 << azx_dev->index;
> +
> +	ret = readb_poll_timeout(bus->drsmcap + AZX_REG_DRSM_CTL, reg, !(reg & mask), 250, 2000);

Remember that HD-audio bus doesn't always allow readb().  Tegra
requires the aligned access, for example.


Takashi

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 3/9] ALSA: hda: Introduce snd_hdac_stream_wait_drsm()
  2022-10-27 10:21   ` Takashi Iwai
@ 2022-10-27 10:29     ` Amadeusz Sławiński
  2022-10-27 11:05       ` Takashi Iwai
  0 siblings, 1 reply; 15+ messages in thread
From: Amadeusz Sławiński @ 2022-10-27 10:29 UTC (permalink / raw)
  To: Takashi Iwai, Cezary Rojewski
  Cc: hdegoede, alsa-devel, broonie, pierre-louis.bossart, tiwai

On 10/27/2022 12:21 PM, Takashi Iwai wrote:
> On Thu, 27 Oct 2022 10:23:25 +0200,
> Cezary Rojewski wrote:
>> --- a/sound/hda/hdac_stream.c
>> +++ b/sound/hda/hdac_stream.c
>> @@ -821,6 +821,27 @@ void snd_hdac_stream_drsm_enable(struct hdac_bus *bus,
>>   }
>>   EXPORT_SYMBOL_GPL(snd_hdac_stream_drsm_enable);
>>   
>> +/*
>> + * snd_hdac_stream_wait_drsm - wait for HW to clear RSM for a stream
>> + * @azx_dev: HD-audio core stream to await RSM for
>> + *
>> + * Returns 0 on success and -ETIMEDOUT upon a timeout.
>> + */
>> +int snd_hdac_stream_wait_drsm(struct hdac_stream *azx_dev)
>> +{
>> +	struct hdac_bus *bus = azx_dev->bus;
>> +	u32 mask, reg;
>> +	int ret;
>> +
>> +	mask = 1 << azx_dev->index;
>> +
>> +	ret = readb_poll_timeout(bus->drsmcap + AZX_REG_DRSM_CTL, reg, !(reg & mask), 250, 2000);
> 
> Remember that HD-audio bus doesn't always allow readb().  Tegra
> requires the aligned access, for example.
> 

The readb_poll_timeout macro was updated to take care of that,
https://lore.kernel.org/all/20221007084856.1638302-1-amadeuszx.slawinski@linux.intel.com/
so it should be fine?


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 3/9] ALSA: hda: Introduce snd_hdac_stream_wait_drsm()
  2022-10-27 10:29     ` Amadeusz Sławiński
@ 2022-10-27 11:05       ` Takashi Iwai
  2022-10-27 11:08         ` Amadeusz Sławiński
  2022-10-27 11:37         ` Cezary Rojewski
  0 siblings, 2 replies; 15+ messages in thread
From: Takashi Iwai @ 2022-10-27 11:05 UTC (permalink / raw)
  To: Amadeusz Sławiński
  Cc: Cezary Rojewski, alsa-devel, tiwai, pierre-louis.bossart,
	hdegoede, broonie

On Thu, 27 Oct 2022 12:29:35 +0200,
Amadeusz Sławiński wrote:
> 
> On 10/27/2022 12:21 PM, Takashi Iwai wrote:
> > On Thu, 27 Oct 2022 10:23:25 +0200,
> > Cezary Rojewski wrote:
> >> --- a/sound/hda/hdac_stream.c
> >> +++ b/sound/hda/hdac_stream.c
> >> @@ -821,6 +821,27 @@ void snd_hdac_stream_drsm_enable(struct hdac_bus *bus,
> >>   }
> >>   EXPORT_SYMBOL_GPL(snd_hdac_stream_drsm_enable);
> >>   +/*
> >> + * snd_hdac_stream_wait_drsm - wait for HW to clear RSM for a stream
> >> + * @azx_dev: HD-audio core stream to await RSM for
> >> + *
> >> + * Returns 0 on success and -ETIMEDOUT upon a timeout.
> >> + */
> >> +int snd_hdac_stream_wait_drsm(struct hdac_stream *azx_dev)
> >> +{
> >> +	struct hdac_bus *bus = azx_dev->bus;
> >> +	u32 mask, reg;
> >> +	int ret;
> >> +
> >> +	mask = 1 << azx_dev->index;
> >> +
> >> +	ret = readb_poll_timeout(bus->drsmcap + AZX_REG_DRSM_CTL, reg, !(reg & mask), 250, 2000);
> > 
> > Remember that HD-audio bus doesn't always allow readb().  Tegra
> > requires the aligned access, for example.
> > 
> 
> The readb_poll_timeout macro was updated to take care of that,
> https://lore.kernel.org/all/20221007084856.1638302-1-amadeuszx.slawinski@linux.intel.com/
> so it should be fine?

This patch doesn't use that macro...


Takashi

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 3/9] ALSA: hda: Introduce snd_hdac_stream_wait_drsm()
  2022-10-27 11:05       ` Takashi Iwai
@ 2022-10-27 11:08         ` Amadeusz Sławiński
  2022-10-27 11:37         ` Cezary Rojewski
  1 sibling, 0 replies; 15+ messages in thread
From: Amadeusz Sławiński @ 2022-10-27 11:08 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Cezary Rojewski, alsa-devel, pierre-louis.bossart, tiwai,
	hdegoede, broonie

On 10/27/2022 1:05 PM, Takashi Iwai wrote:
> On Thu, 27 Oct 2022 12:29:35 +0200,
> Amadeusz Sławiński wrote:
>>
>> On 10/27/2022 12:21 PM, Takashi Iwai wrote:
>>> On Thu, 27 Oct 2022 10:23:25 +0200,
>>> Cezary Rojewski wrote:
>>>> --- a/sound/hda/hdac_stream.c
>>>> +++ b/sound/hda/hdac_stream.c
>>>> @@ -821,6 +821,27 @@ void snd_hdac_stream_drsm_enable(struct hdac_bus *bus,
>>>>    }
>>>>    EXPORT_SYMBOL_GPL(snd_hdac_stream_drsm_enable);
>>>>    +/*
>>>> + * snd_hdac_stream_wait_drsm - wait for HW to clear RSM for a stream
>>>> + * @azx_dev: HD-audio core stream to await RSM for
>>>> + *
>>>> + * Returns 0 on success and -ETIMEDOUT upon a timeout.
>>>> + */
>>>> +int snd_hdac_stream_wait_drsm(struct hdac_stream *azx_dev)
>>>> +{
>>>> +	struct hdac_bus *bus = azx_dev->bus;
>>>> +	u32 mask, reg;
>>>> +	int ret;
>>>> +
>>>> +	mask = 1 << azx_dev->index;
>>>> +
>>>> +	ret = readb_poll_timeout(bus->drsmcap + AZX_REG_DRSM_CTL, reg, !(reg & mask), 250, 2000);
>>>
>>> Remember that HD-audio bus doesn't always allow readb().  Tegra
>>> requires the aligned access, for example.
>>>
>>
>> The readb_poll_timeout macro was updated to take care of that,
>> https://lore.kernel.org/all/20221007084856.1638302-1-amadeuszx.slawinski@linux.intel.com/
>> so it should be fine?
> 
> This patch doesn't use that macro...
> 

Ah... right, sorry for confusion, I looked at diff part instead of macro 
name.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 3/9] ALSA: hda: Introduce snd_hdac_stream_wait_drsm()
  2022-10-27 11:05       ` Takashi Iwai
  2022-10-27 11:08         ` Amadeusz Sławiński
@ 2022-10-27 11:37         ` Cezary Rojewski
  1 sibling, 0 replies; 15+ messages in thread
From: Cezary Rojewski @ 2022-10-27 11:37 UTC (permalink / raw)
  To: Takashi Iwai, Amadeusz Sławiński
  Cc: hdegoede, alsa-devel, broonie, pierre-louis.bossart, tiwai

On 2022-10-27 1:05 PM, Takashi Iwai wrote:
> On Thu, 27 Oct 2022 12:29:35 +0200,
> Amadeusz Sławiński wrote:
>>
>> On 10/27/2022 12:21 PM, Takashi Iwai wrote:
>>> On Thu, 27 Oct 2022 10:23:25 +0200,
>>> Cezary Rojewski wrote:
>>>> --- a/sound/hda/hdac_stream.c
>>>> +++ b/sound/hda/hdac_stream.c
>>>> @@ -821,6 +821,27 @@ void snd_hdac_stream_drsm_enable(struct hdac_bus *bus,
>>>>    }
>>>>    EXPORT_SYMBOL_GPL(snd_hdac_stream_drsm_enable);
>>>>    +/*
>>>> + * snd_hdac_stream_wait_drsm - wait for HW to clear RSM for a stream
>>>> + * @azx_dev: HD-audio core stream to await RSM for
>>>> + *
>>>> + * Returns 0 on success and -ETIMEDOUT upon a timeout.
>>>> + */
>>>> +int snd_hdac_stream_wait_drsm(struct hdac_stream *azx_dev)
>>>> +{
>>>> +	struct hdac_bus *bus = azx_dev->bus;
>>>> +	u32 mask, reg;
>>>> +	int ret;
>>>> +
>>>> +	mask = 1 << azx_dev->index;
>>>> +
>>>> +	ret = readb_poll_timeout(bus->drsmcap + AZX_REG_DRSM_CTL, reg, !(reg & mask), 250, 2000);
>>>
>>> Remember that HD-audio bus doesn't always allow readb().  Tegra
>>> requires the aligned access, for example.
>>>
>>
>> The readb_poll_timeout macro was updated to take care of that,
>> https://lore.kernel.org/all/20221007084856.1638302-1-amadeuszx.slawinski@linux.intel.com/
>> so it should be fine?
> 
> This patch doesn't use that macro...
Thanks for spotting this out! There's even more to that. The DRSMCTL 
register is u32 reg, not u8. Since we are using lower amount of streams 
in these tests, it works just fine but with a higher number, the 
scenario can fail.

'Just copy-paste things'. Will update the function to make use of u32 
equivalent.


Regards,
Czarek

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2022-10-27 11:38 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-27  8:23 [PATCH v3 0/9] ASoC: Intel: avs: PCM power management Cezary Rojewski
2022-10-27  8:23 ` [PATCH v3 1/9] ASoC: Intel: avs: Split pcm pages freeing operation from hw_free() Cezary Rojewski
2022-10-27  8:23 ` [PATCH v3 2/9] ASoC: Intel: avs: Introduce PCM power management routines Cezary Rojewski
2022-10-27  8:23 ` [PATCH v3 3/9] ALSA: hda: Introduce snd_hdac_stream_wait_drsm() Cezary Rojewski
2022-10-27 10:21   ` Takashi Iwai
2022-10-27 10:29     ` Amadeusz Sławiński
2022-10-27 11:05       ` Takashi Iwai
2022-10-27 11:08         ` Amadeusz Sławiński
2022-10-27 11:37         ` Cezary Rojewski
2022-10-27  8:23 ` [PATCH v3 4/9] ASoC: Intel: avs: Handle SUSPEND and RESUME triggers Cezary Rojewski
2022-10-27  8:23 ` [PATCH v3 5/9] ASoC: Intel: avs: Restart instead of resuming HDA capture streams Cezary Rojewski
2022-10-27  8:23 ` [PATCH v3 6/9] ASoC: Intel: avs: Count low power streams Cezary Rojewski
2022-10-27  8:23 ` [PATCH v3 7/9] ASoC: Intel: avs: Standby power-state support Cezary Rojewski
2022-10-27  8:23 ` [PATCH v3 8/9] ASoC: Intel: avs: Power and clock gating policy overriding Cezary Rojewski
2022-10-27  8:23 ` [PATCH v3 9/9] ASoC: Intel: avs: Enact power gating policy Cezary Rojewski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.