On Tue, 11 Oct 2022, Ville Syrjala <ville.syrjala@xxxxxxxxxxxxxxx> wrote: > From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > > The spec tells us to do a bunch of vblank waits in the audio > enable/disable sequences. Make it so. > > The FIXMEs are nonsense since we do the audio disable very > early and enable very late, so vblank interrupts are in fact > enabled when we do this. > > TODO not sure we actually want these since we don't even rely > on the hw ELD buffer, and these might be there just to give > the audio side a bit of time to respond to the unsol events. > OTOH they might be really needed for some other reason. *shrug* Acked-by: Jani Nikula <jani.nikula@xxxxxxxxx> > > Cc: Chaitanya Kumar Borah <chaitanya.kumar.borah@xxxxxxxxx> > Cc: Kai Vehmanen <kai.vehmanen@xxxxxxxxxxxxxxx> > Cc: Takashi Iwai <tiwai@xxxxxxx> > Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/i915/display/intel_audio.c | 31 +++++++++++++--------- > 1 file changed, 18 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c > index 0a1ba10fc20d..4eb5589a0f89 100644 > --- a/drivers/gpu/drm/i915/display/intel_audio.c > +++ b/drivers/gpu/drm/i915/display/intel_audio.c > @@ -318,10 +318,14 @@ static void g4x_audio_codec_disable(struct intel_encoder *encoder, > const struct drm_connector_state *old_conn_state) > { > struct drm_i915_private *i915 = to_i915(encoder->base.dev); > + struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); > > /* Invalidate ELD */ > intel_de_rmw(i915, G4X_AUD_CNTL_ST, > G4X_ELD_VALID, 0); > + > + intel_crtc_wait_for_next_vblank(crtc); > + intel_crtc_wait_for_next_vblank(crtc); > } > > static void g4x_audio_codec_enable(struct intel_encoder *encoder, > @@ -329,10 +333,13 @@ static void g4x_audio_codec_enable(struct intel_encoder *encoder, > const struct drm_connector_state *conn_state) > { > struct drm_i915_private *i915 = to_i915(encoder->base.dev); > + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); > struct drm_connector *connector = conn_state->connector; > const u32 *eld = (const u32 *)connector->eld; > int eld_buffer_size, len, i; > > + intel_crtc_wait_for_next_vblank(crtc); > + > intel_de_rmw(i915, G4X_AUD_CNTL_ST, > G4X_ELD_VALID | G4X_ELD_ADDRESS_MASK, 0); > > @@ -466,6 +473,7 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder, > const struct drm_connector_state *old_conn_state) > { > struct drm_i915_private *i915 = to_i915(encoder->base.dev); > + struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); > enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; > > mutex_lock(&i915->display.audio.mutex); > @@ -483,6 +491,9 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder, > intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD, > AUDIO_ELD_VALID(cpu_transcoder), 0); > > + intel_crtc_wait_for_next_vblank(crtc); > + intel_crtc_wait_for_next_vblank(crtc); > + > /* Disable audio presence detect */ > intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD, > AUDIO_OUTPUT_ENABLE(cpu_transcoder), 0); > @@ -604,6 +615,7 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder, > const struct drm_connector_state *conn_state) > { > struct drm_i915_private *i915 = to_i915(encoder->base.dev); > + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); > struct drm_connector *connector = conn_state->connector; > enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; > const u32 *eld = (const u32 *)connector->eld; > @@ -619,17 +631,12 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder, > intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD, > 0, AUDIO_OUTPUT_ENABLE(cpu_transcoder)); > > + intel_crtc_wait_for_next_vblank(crtc); > + > /* Invalidate ELD */ > intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD, > AUDIO_ELD_VALID(cpu_transcoder), 0); > > - /* > - * FIXME: We're supposed to wait for vblank here, but we have vblanks > - * disabled during the mode set. The proper fix would be to push the > - * rest of the setup into a vblank work item, queued here, but the > - * infrastructure is not there yet. > - */ > - > /* Reset ELD address */ > intel_de_rmw(i915, HSW_AUD_DIP_ELD_CTRL(cpu_transcoder), > IBX_ELD_ADDRESS_MASK, 0); > @@ -726,6 +733,9 @@ static void ilk_audio_codec_disable(struct intel_encoder *encoder, > IBX_ELD_VALID(port), 0); > > mutex_unlock(&i915->display.audio.mutex); > + > + intel_crtc_wait_for_next_vblank(crtc); > + intel_crtc_wait_for_next_vblank(crtc); > } > > static void ilk_audio_codec_enable(struct intel_encoder *encoder, > @@ -744,12 +754,7 @@ static void ilk_audio_codec_enable(struct intel_encoder *encoder, > if (drm_WARN_ON(&i915->drm, port == PORT_A)) > return; > > - /* > - * FIXME: We're supposed to wait for vblank here, but we have vblanks > - * disabled during the mode set. The proper fix would be to push the > - * rest of the setup into a vblank work item, queued here, but the > - * infrastructure is not there yet. > - */ > + intel_crtc_wait_for_next_vblank(crtc); > > ilk_audio_regs_init(i915, pipe, ®s); -- Jani Nikula, Intel Open Source Graphics Center