Commit 6d9d1652 authored by Mark Brown's avatar Mark Brown

Merge series "ASoC: SOF: Intel: DMI L1 power optimization for HDaudio...

Merge series "ASoC: SOF: Intel: DMI L1 power optimization for HDaudio platforms" from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>:

This patchset provides an optimization that result in significant power
savings on Intel HDAudio platforms using SOF (Sound Open Firmware).

We previously prevented the Intel DSP from enabling the DMI_L1
capability to work-around issues with pause on capture streams. It
turns out that this also prevented the platform from entering high C
states in full-duplex usages such as videoconferencing - a rather
basic use case since the start of the pandemic.

The support for pause_push/release was already a bit controversial for
Intel platforms, in theory platforms should only enable PAUSE if they
can resume on the same sample, which is not the case on any Intel
platform.

With this patchset, when the user enables DMI L1 via a kernel
parameter, the PAUSE support is disabled for capture streams. A kernel
parameter is far from ideal but it's a placeholder until we have an
API to negotiate capabilities between applications and driver, and
it's far less confusing than a Kconfig option.

Changes since v1:
Removal of SPIB support since it may conflict with Takashi's memalloc
changes. These SPIB changes will be provided after rebase.
Addition of one cleanup for cppcheck warning
Move all changes to intel/ directory, no changes in shared code
Flipped the logic: the selection of DMI L1 disables PAUSE

Pierre-Louis Bossart (4):
  ASoC: SOF: Intel: Kconfig: clarify DMI L1 option description
  ASoC: SOF: Intel: hda-stream: remove always true condition
  ASoC: SOF: Intel: simplify logic for DMI_L1 handling
  ASoC: SOF: Intel: make DMI L1 selection more robust

 sound/soc/sof/intel/Kconfig      | 10 ----------
 sound/soc/sof/intel/hda-pcm.c    | 16 ++++++++++++++--
 sound/soc/sof/intel/hda-stream.c | 11 +++++------
 3 files changed, 19 insertions(+), 18 deletions(-)

--
2.25.1
parents a1ea0572 246dd428
...@@ -249,16 +249,6 @@ config SND_SOC_SOF_HDA_PROBES ...@@ -249,16 +249,6 @@ config SND_SOC_SOF_HDA_PROBES
Say Y if you want to enable probes. Say Y if you want to enable probes.
If unsure, select "N". If unsure, select "N".
config SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1
bool "SOF enable DMI Link L1"
help
This option enables DMI L1 for both playback and capture
and disables known workarounds for specific HDAudio platforms.
Only use to look into power optimizations on platforms not
affected by DMI L1 issues. This option is not recommended.
Say Y if you want to enable DMI Link L1.
If unsure, select "N".
endif ## SND_SOC_SOF_HDA_COMMON endif ## SND_SOC_SOF_HDA_COMMON
config SND_SOC_SOF_HDA_LINK_BASELINE config SND_SOC_SOF_HDA_LINK_BASELINE
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
* Hardware interface for generic Intel audio DSP HDA IP * Hardware interface for generic Intel audio DSP HDA IP
*/ */
#include <linux/moduleparam.h>
#include <sound/hda_register.h> #include <sound/hda_register.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include "../sof-audio.h" #include "../sof-audio.h"
...@@ -27,6 +28,10 @@ ...@@ -27,6 +28,10 @@
#define SDnFMT_BITS(x) ((x) << 4) #define SDnFMT_BITS(x) ((x) << 4)
#define SDnFMT_CHAN(x) ((x) << 0) #define SDnFMT_CHAN(x) ((x) << 0)
static bool hda_always_enable_dmi_l1;
module_param_named(always_enable_dmi_l1, hda_always_enable_dmi_l1, bool, 0444);
MODULE_PARM_DESC(always_enable_dmi_l1, "SOF HDA always enable DMI l1");
u32 hda_dsp_get_mult_div(struct snd_sof_dev *sdev, int rate) u32 hda_dsp_get_mult_div(struct snd_sof_dev *sdev, int rate)
{ {
switch (rate) { switch (rate) {
...@@ -216,6 +221,7 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev, ...@@ -216,6 +221,7 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream) struct snd_pcm_substream *substream)
{ {
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_component *scomp = sdev->component; struct snd_soc_component *scomp = sdev->component;
struct hdac_ext_stream *dsp_stream; struct hdac_ext_stream *dsp_stream;
struct snd_sof_pcm *spcm; struct snd_sof_pcm *spcm;
...@@ -228,8 +234,14 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev, ...@@ -228,8 +234,14 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
return -EINVAL; return -EINVAL;
} }
/* All playback and D0i3 compatible streams are DMI L1 capable */ /*
if (direction == SNDRV_PCM_STREAM_PLAYBACK || * All playback streams are DMI L1 capable, capture streams need
* pause push/release to be disabled
*/
if (hda_always_enable_dmi_l1 && direction == SNDRV_PCM_STREAM_CAPTURE)
runtime->hw.info &= ~SNDRV_PCM_INFO_PAUSE;
if (hda_always_enable_dmi_l1 ||
spcm->stream[substream->stream].d0i3_compatible) spcm->stream[substream->stream].d0i3_compatible)
flags |= SOF_HDA_STREAM_DMI_L1_COMPATIBLE; flags |= SOF_HDA_STREAM_DMI_L1_COMPATIBLE;
......
...@@ -197,8 +197,7 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags) ...@@ -197,8 +197,7 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags)
* Workaround to address a known issue with host DMA that results * Workaround to address a known issue with host DMA that results
* in xruns during pause/release in capture scenarios. * in xruns during pause/release in capture scenarios.
*/ */
if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1)) if (!(flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE))
if (stream && !(flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE))
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
HDA_VS_INTEL_EM2, HDA_VS_INTEL_EM2,
HDA_VS_INTEL_EM2_L1SEN, 0); HDA_VS_INTEL_EM2_L1SEN, 0);
...@@ -240,7 +239,7 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag) ...@@ -240,7 +239,7 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
spin_unlock_irq(&bus->reg_lock); spin_unlock_irq(&bus->reg_lock);
/* Enable DMI L1 if permitted */ /* Enable DMI L1 if permitted */
if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1) && dmi_l1_enable) if (dmi_l1_enable)
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, HDA_VS_INTEL_EM2, snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, HDA_VS_INTEL_EM2,
HDA_VS_INTEL_EM2_L1SEN, HDA_VS_INTEL_EM2_L1SEN); HDA_VS_INTEL_EM2_L1SEN, HDA_VS_INTEL_EM2_L1SEN);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment