[PATCH 0/4] ASoC: SOF: Intel: improve and extend HDaudio-based wakes
For LunarLake, the SoundWire in-band wake detection is reported with the HDAudio WAKE_EN/WAKE_STS registers. In the existing code, these registers are only handled for HDaudio codecs. Now the same registers have to be handled with care as shared resources.
The in-band wake detection mainly used for jack detection. Without this patchset, the SoundWire headset codecs signal an event that would be ignored and not reported.
Pierre-Louis Bossart (4): ASoC: SOF: Intel: hda-ctrl: add missing WAKE_STS clear ASoC: SOF: Intel: lnl: add helper to detect SoundWire wakes ASoC: SOF: Intel: hda-codec: preserve WAKEEN values ASoC: SOF: Intel: hda-ctrl: only clear WAKESTS for HDaudio codecs
sound/soc/sof/intel/hda-codec.c | 15 ++++++++++++--- sound/soc/sof/intel/hda-ctrl.c | 9 ++++++++- sound/soc/sof/intel/lnl.c | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-)
For some reason, the programming sequences in the SOF driver do not include a clear of the WAKE_STS bits before resetting the controller.
This clear is not formally required by the HDaudio specification, but was added to harden the snd-hda-reset back in 2007. Adding this sequence back avoids an issue reported by the Intel CI.
Closes: https://github.com/thesofproject/linux/issues/4889 Reviewed-by: Péter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/sof/intel/hda-ctrl.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/sound/soc/sof/intel/hda-ctrl.c b/sound/soc/sof/intel/hda-ctrl.c index 84bf01bd360a..b4f0756e21f6 100644 --- a/sound/soc/sof/intel/hda-ctrl.c +++ b/sound/soc/sof/intel/hda-ctrl.c @@ -184,6 +184,7 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev) struct hdac_bus *bus = sof_to_bus(sdev); struct hdac_stream *stream; int sd_offset, ret = 0; + u32 gctl;
if (bus->chip_init) return 0; @@ -192,6 +193,12 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev)
hda_dsp_ctrl_misc_clock_gating(sdev, false);
+ /* clear WAKE_STS if not in reset */ + gctl = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_GCTL); + if (gctl & SOF_HDA_GCTL_RESET) + snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, + SOF_HDA_WAKESTS, SOF_HDA_WAKESTS_INT_MASK); + /* reset HDA controller */ ret = hda_dsp_ctrl_link_reset(sdev, true); if (ret < 0) {
The global STATESTS register will provide information on all links. Rather than iterate on all possible links, the helpers only filters the range of possible bits for a quick lookup. The process_wakeen() helper will walk through all the links and deal with wakes.
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Rander Wang rander.wang@intel.com --- sound/soc/sof/intel/lnl.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/sound/soc/sof/intel/lnl.c b/sound/soc/sof/intel/lnl.c index 95da0c626832..c3ee507e2e21 100644 --- a/sound/soc/sof/intel/lnl.c +++ b/sound/soc/sof/intel/lnl.c @@ -205,6 +205,23 @@ static int lnl_dsp_disable_interrupts(struct snd_sof_dev *sdev) return mtl_enable_interrupts(sdev, false); }
+static bool lnl_sdw_check_wakeen_irq(struct snd_sof_dev *sdev) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + u16 wake_sts; + + /* + * we need to use the global HDaudio WAKEEN/STS to be able to + * detect wakes in low-power modes. The link-specific information + * is handled in the process_wakeen() helper, this helper only + * detects a SoundWire wake without identifying the link. + */ + wake_sts = snd_hdac_chip_readw(bus, STATESTS); + + /* filter out the range of SDIs that can be set for SoundWire */ + return wake_sts & GENMASK(SDW_MAX_DEVICES, SDW_INTEL_DEV_NUM_IDA_MIN); +} + const struct sof_intel_dsp_desc lnl_chip_info = { .cores_num = 5, .init_core_mask = BIT(0), @@ -221,6 +238,7 @@ const struct sof_intel_dsp_desc lnl_chip_info = { .read_sdw_lcount = hda_sdw_check_lcount_ext, .enable_sdw_irq = lnl_enable_sdw_irq, .check_sdw_irq = lnl_dsp_check_sdw_irq, + .check_sdw_wakeen_irq = lnl_sdw_check_wakeen_irq, .check_ipc_irq = mtl_dsp_check_ipc_irq, .cl_init = mtl_dsp_cl_init, .power_down_dsp = mtl_power_down_dsp,
Since LunarLake, we use the HDadio WAKEEN/WAKESTS to detect wakes for SoundWire codecs. Unfortunately, the existing code in hda_codec_jack_wake_enable() unconditionally resets the WAKEEN bits.
This patch changes the initialization to preserve SoundWire WAKEEN bits. For HDAudio codecs the same strategy is used, WAKEEN is only set when the jacktbl.used property is set.
Closes: https://github.com/thesofproject/linux/issues/4687 Co-developed-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Keqiao Zhang keqiao.zhang@intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/intel/hda-codec.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c index 9f84b0d287a5..6a13f38a8d21 100644 --- a/sound/soc/sof/intel/hda-codec.c +++ b/sound/soc/sof/intel/hda-codec.c @@ -79,18 +79,27 @@ void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable) struct hdac_bus *bus = sof_to_bus(sdev); struct hda_codec *codec; unsigned int mask = 0; + unsigned int val = 0;
if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) return;
if (enable) { - list_for_each_codec(codec, hbus) + list_for_each_codec(codec, hbus) { + /* only set WAKEEN when needed for HDaudio codecs */ + mask |= BIT(codec->core.addr); if (codec->jacktbl.used) - mask |= BIT(codec->core.addr); + val |= BIT(codec->core.addr); + } + } else { + list_for_each_codec(codec, hbus) { + /* reset WAKEEN only HDaudio codecs */ + mask |= BIT(codec->core.addr); + } }
- snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask); + snd_hdac_chip_updatew(bus, WAKEEN, mask & STATESTS_INT_MASK, val); } EXPORT_SYMBOL_NS_GPL(hda_codec_jack_wake_enable, SND_SOC_SOF_HDA_AUDIO_CODEC);
When a PME wake happens due to a SoundWire wake, we currently clear all WAKESTS bits during the resume operation initiated by the PCI subsystem. As a result, we are unable to identify which SoundWire links need to be resumed and don't properly handle jack detection.
This patch only clears the WAKESTS bits for the HDaudio codecs detected earlier.
Note that we still clear all WAKESTS bits unconditionally in hda_dsp_ctrl_stop_chip(). The existing behavior is potentially racy if e.g. a jack event happens during a suspend routine, but there's a risk of breaking shutdown or reboot sequences so the code is left as is for now.
Closes: https://github.com/thesofproject/linux/issues/4687 Co-developed-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Keqiao Zhang keqiao.zhang@intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/intel/hda-ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/sof/intel/hda-ctrl.c b/sound/soc/sof/intel/hda-ctrl.c index b4f0756e21f6..6d941209847f 100644 --- a/sound/soc/sof/intel/hda-ctrl.c +++ b/sound/soc/sof/intel/hda-ctrl.c @@ -228,7 +228,7 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev)
/* clear WAKESTS */ snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS, - SOF_HDA_WAKESTS_INT_MASK); + bus->codec_mask);
hda_codec_rirb_status_clear(sdev);
On Thu, 04 Apr 2024 14:03:53 -0500, Pierre-Louis Bossart wrote:
For LunarLake, the SoundWire in-band wake detection is reported with the HDAudio WAKE_EN/WAKE_STS registers. In the existing code, these registers are only handled for HDaudio codecs. Now the same registers have to be handled with care as shared resources.
The in-band wake detection mainly used for jack detection. Without this patchset, the SoundWire headset codecs signal an event that would be ignored and not reported.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/4] ASoC: SOF: Intel: hda-ctrl: add missing WAKE_STS clear commit: bd5863f9ef12e26c2cfdce9c0adbf0222c731a3c [2/4] ASoC: SOF: Intel: lnl: add helper to detect SoundWire wakes commit: ab9182441ee5a94dd6f47743ed1b7b6b07b63cb2 [3/4] ASoC: SOF: Intel: hda-codec: preserve WAKEEN values commit: b69480edf4eb71c6f754e3c4020e8dd72a330558 [4/4] ASoC: SOF: Intel: hda-ctrl: only clear WAKESTS for HDaudio codecs commit: 35b5806e2edee1741f6bd2de2a5c149a876c4a60
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Mark Brown
-
Pierre-Louis Bossart