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
