@@ -319,10 +319,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,
@@ -330,10 +334,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);
@@ -468,6 +475,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);
@@ -485,6 +493,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);
@@ -606,6 +617,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;
@@ -621,17 +633,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);
@@ -729,6 +736,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,
@@ -747,12 +757,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);