[PATCH 1/3] ALSA: hda/hdmi: fix i915 silent stream programming flow

Amadeusz Sławiński amadeuszx.slawinski at linux.intel.com
Thu Dec 8 17:25:21 CET 2022


On 12/8/2022 4:43 PM, Kai Vehmanen wrote:
> The i915 display codec may not successfully transition to
> normal audio streaming mode, if the stream id is programmed
> while codec is actively transmitting data. This can happen
> when silent stream is enabled in KAE mode.
> 
> Fix the issue by implementing a i915 specific programming
> flow, where the silent streaming is temporarily stopped,
> a small delay is applied to ensure display codec becomes
> idle, and then proceed with reprogramming the stream ID.
> 
> Fixes: 15175a4f2bbb ("ALSA: hda/hdmi: add keep-alive support for ADL-P and DG2")
> Link: https://gitlab.freedesktop.org/drm/intel/-/issues/7353
> Signed-off-by: Kai Vehmanen <kai.vehmanen at linux.intel.com>
> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> Tested-by: Rodrigo Vivi <rodrigo.vivi at intel.com>
> ---
>   sound/pci/hda/patch_hdmi.c | 23 +++++++++++++++++++++--
>   1 file changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> index 7a40ddfd695a..a0ba24165ae2 100644
> --- a/sound/pci/hda/patch_hdmi.c
> +++ b/sound/pci/hda/patch_hdmi.c
> @@ -2879,9 +2879,28 @@ static int i915_hsw_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
>   				 hda_nid_t pin_nid, int dev_id, u32 stream_tag,
>   				 int format)
>   {
> +	struct hdmi_spec *spec = codec->spec;
> +	int pin_idx = pin_id_to_pin_index(codec, pin_nid, dev_id);

Shouldn't return value from pin_id_to_pin_index() be checked? It seems 
that it can return -EINVAL.

> +	struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
> +	int res;
> +
>   	haswell_verify_D0(codec, cvt_nid, pin_nid);
> -	return hdmi_setup_stream(codec, cvt_nid, pin_nid, dev_id,
> -				 stream_tag, format);
> +
> +	if (spec->silent_stream_type == SILENT_STREAM_KAE && per_pin && per_pin->silent_stream) {
> +		silent_stream_set_kae(codec, per_pin, false);
> +		/* wait for pending transfers in codec to clear */
> +		usleep_range(100, 200);
> +	}
> +
> +	res = hdmi_setup_stream(codec, cvt_nid, pin_nid, dev_id,
> +				stream_tag, format);
> +
> +	if (spec->silent_stream_type == SILENT_STREAM_KAE && per_pin && per_pin->silent_stream) {
> +		usleep_range(100, 200);
> +		silent_stream_set_kae(codec, per_pin, true);
> +	}
> +
> +	return res;
>   }
>   
>   /* pin_cvt_fixup ops override for HSW+ and VLV+ */



More information about the Alsa-devel mailing list