Hello,

Also to change Authorship of @Vehmanen, Kai before merging.

Regards,
Mitul

> -----Original Message-----
> From: Intel-gfx <[email protected]> On Behalf Of Mitul
> Golani
> Sent: 08 July 2026 17:06
> To: [email protected]
> Cc: [email protected]; Shankar, Uma <[email protected]>;
> Lee, Shawn C <[email protected]>; Vehmanen, Kai
> <[email protected]>; Nautiyal, Ankit K <[email protected]>;
> Borah, Chaitanya Kumar <[email protected]>; Kandpal, Suraj
> <[email protected]>
> Subject: [PATCH v3] drm/i915/audio: treat UHBR SST like MST for
> cpu_transcoder signalling
> 
> Both DP MST and UHBR SST require the audio component to use a real
> cpu_transcoder (>= 0) value to identify the audio stream on a port.
> For DP MST this was already handled; for UHBR SST it was not, causing
> pin_eld_notify() to signal cpu_transcoder = -1 (the legacy SST sentinel) and
> find_audio_state() to skip the per-transcoder entry for the UHBR stream.
> 
> After suspend/resume or replug, the ELD lookup fails and audio goes silent. 
> Fix
> by detecting UHBR SST alongside DP MST when deciding whether a real
> cpu_transcoder value must be used for audio state addressing, in both the
> pin_eld_notify() signalling and the
> find_audio_state() lookup paths.
> 
> --v2:
> - Commit message and comment update. (Suraj)
> - Change function name has_mst_transcoder. (Suraj)
> - Avoid Live crtc access in find_audio_state. (Suraj)
> 
> --v3:
> - Minor comment changes to avoid MST over 128b/132b confusion. (Suraj)
> 
> Signed-off-by: Kai Vehmanen <[email protected]>
> Signed-off-by: Mitul Golani <[email protected]>
> Reviewed-by: Suraj Kandpal <[email protected]>
> ---
>  drivers/gpu/drm/i915/display/intel_audio.c    | 55 ++++++++++++++-----
>  .../gpu/drm/i915/display/intel_display_core.h |  1 +
>  2 files changed, 41 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_audio.c
> b/drivers/gpu/drm/i915/display/intel_audio.c
> index 9729f1837d2c..fb0d7ed6fbd6 100644
> --- a/drivers/gpu/drm/i915/display/intel_audio.c
> +++ b/drivers/gpu/drm/i915/display/intel_audio.c
> @@ -38,6 +38,7 @@
>  #include "intel_de.h"
>  #include "intel_display_types.h"
>  #include "intel_display_wa.h"
> +#include "intel_dp.h"
>  #include "intel_lpe_audio.h"
> 
>  /**
> @@ -696,6 +697,13 @@ static void ibx_audio_codec_enable(struct
> intel_encoder *encoder,
>       mutex_unlock(&display->audio.mutex);
>  }
> 
> +static
> +bool intel_audio_needs_cpu_transcoder_id(const struct intel_crtc_state
> +*crtc_state) {
> +     return intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) ||
> +            intel_dp_is_uhbr(crtc_state);
> +}
> +
>  bool intel_audio_compute_config(struct intel_encoder *encoder,
>                               struct intel_crtc_state *crtc_state,
>                               struct drm_connector_state *conn_state)
> @@ -762,6 +770,8 @@ void intel_audio_codec_enable(struct intel_encoder
> *encoder,
>       audio_state = &display->audio.state[cpu_transcoder];
> 
>       audio_state->encoder = encoder;
> +     audio_state->needs_cpu_transcoder_id =
> +                     intel_audio_needs_cpu_transcoder_id(crtc_state);
>       BUILD_BUG_ON(sizeof(audio_state->eld) != sizeof(crtc_state->eld));
>       memcpy(audio_state->eld, crtc_state->eld, sizeof(audio_state->eld));
> 
> @@ -769,8 +779,12 @@ void intel_audio_codec_enable(struct intel_encoder
> *encoder,
> 
>       if (acomp && acomp->base.audio_ops &&
>           acomp->base.audio_ops->pin_eld_notify) {
> -             /* audio drivers expect cpu_transcoder = -1 to indicate Non-
> MST cases */
> -             if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
> +             /*
> +              * Audio drivers expect cpu_transcoder = -1 to indicate
> +              * Non-MST/HBR cases. MST and UHBR SST are addressed by
> +              * a real cpu_transcoder.
> +              */
> +             if (!intel_audio_needs_cpu_transcoder_id(crtc_state))
>                       cpu_transcoder = -1;
>               acomp->base.audio_ops->pin_eld_notify(acomp-
> >base.audio_ops->audio_ptr,
>                                                     (int)port,
> (int)cpu_transcoder); @@ -819,14 +833,19 @@ void
> intel_audio_codec_disable(struct intel_encoder *encoder,
>       audio_state = &display->audio.state[cpu_transcoder];
> 
>       audio_state->encoder = NULL;
> +     audio_state->needs_cpu_transcoder_id = false;
>       memset(audio_state->eld, 0, sizeof(audio_state->eld));
> 
>       mutex_unlock(&display->audio.mutex);
> 
>       if (acomp && acomp->base.audio_ops &&
>           acomp->base.audio_ops->pin_eld_notify) {
> -             /* audio drivers expect cpu_transcoder = -1 to indicate Non-
> MST cases */
> -             if (!intel_crtc_has_type(old_crtc_state,
> INTEL_OUTPUT_DP_MST))
> +             /*
> +              * Audio drivers expect cpu_transcoder = -1 to indicate
> +              * Non-MST/HBR cases. MST and UHBR SST are addressed by
> +              * a real cpu_transcoder.
> +              */
> +             if (!intel_audio_needs_cpu_transcoder_id(old_crtc_state))
>                       cpu_transcoder = -1;
>               acomp->base.audio_ops->pin_eld_notify(acomp-
> >base.audio_ops->audio_ptr,
>                                                     (int)port,
> (int)cpu_transcoder); @@ -1118,18 +1137,24 @@ static int
> intel_audio_component_get_cdclk_freq(struct device *kdev)  }
> 
>  /*
> - * get the intel audio state according to the parameter port and
> cpu_transcoder
> - * MST & (cpu_transcoder >= 0): return the
> audio.state[cpu_transcoder].encoder],
> - *   when port is matched
> - * MST & (cpu_transcoder < 0): this is invalid
> - * Non-MST & (cpu_transcoder >= 0): only cpu_transcoder = 0 (the first
> device entry)
> - *   will get the right intel_encoder with port matched
> - * Non-MST & (cpu_transcoder < 0): get the right intel_encoder with port
> matched
> + * Get the intel audio state for a given (port, cpu_transcoder).
> + *
> + * Streams are addressed either by a real cpu_transcoder (DP MST and
> + UHBR SST,
> + * i.e. entries whose stored needs_cpu_transcoder_id is true) or by
> + port alone
> + * (legacy SST). Both the signalling side (pin_eld_notify()) and the
> + lookup
> + * side use the same predicate, so the two are symmetric.
> + *
> + * cpu_transcoder >= 0 & needs_cpu_transcoder_id: return
> audio.state[cpu_transcoder]
> + *   when the port matches.
> + * cpu_transcoder <  0 & !needs_cpu_transcoder_id: return the first port-
> matching
> + *   entry.
> + * cpu_transcoder =  0 & !needs_cpu_transcoder_id: falls through to the port-
> only
> + *   loop so the first device entry of a legacy SST port is still found.
>   */
>  static struct intel_audio_state *find_audio_state(struct intel_display 
> *display,
>                                                 int port, int cpu_transcoder)
>  {
> -     /* MST */
> +     /* MST, or UHBR SST. */
>       if (cpu_transcoder >= 0) {
>               struct intel_audio_state *audio_state;
>               struct intel_encoder *encoder;
> @@ -1142,11 +1167,11 @@ static struct intel_audio_state
> *find_audio_state(struct intel_display *display,
>               encoder = audio_state->encoder;
> 
>               if (encoder && encoder->port == port &&
> -                 encoder->type == INTEL_OUTPUT_DP_MST)
> +                 audio_state->needs_cpu_transcoder_id)
>                       return audio_state;
>       }
> 
> -     /* Non-MST */
> +     /* Legacy SST. */
>       if (cpu_transcoder > 0)
>               return NULL;
> 
> @@ -1158,7 +1183,7 @@ static struct intel_audio_state
> *find_audio_state(struct intel_display *display,
>               encoder = audio_state->encoder;
> 
>               if (encoder && encoder->port == port &&
> -                 encoder->type != INTEL_OUTPUT_DP_MST)
> +                 !audio_state->needs_cpu_transcoder_id)
>                       return audio_state;
>       }
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h
> b/drivers/gpu/drm/i915/display/intel_display_core.h
> index 17f7d3abdb9c..a6129d0b523f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_core.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_core.h
> @@ -97,6 +97,7 @@ struct intel_wm_funcs {  struct intel_audio_state {
>       struct intel_encoder *encoder;
>       u8 eld[MAX_ELD_BYTES];
> +     bool needs_cpu_transcoder_id;  /* MST, or SST on UHBR link */
>  };
> 
>  struct intel_audio {
> --
> 2.48.1

Reply via email to