Bspec Vol 3, Part 3, Section 3.8.1.1, bit 30: "[DevIBX] Writing to this bit only takes effect when port is enabled. Due to hardware issue it is required that this bit be cleared when port is disabled. To clear this bit software must temporarily enable this port on transcoder A." Unfortunately the public Bspec misses totally out on the same language for HDMIB. Internal Bspec also mentions that one of the bad side-effects is that DPx can fail to light up on transcoder A if HDMIx is disabled but using transcoder B. I've found this while reviewing Bsepc. We already implement the same workaround for the DP ports. Also replace a magic 1 with PIPE_B I've found while looking through the code. Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch> --- drivers/gpu/drm/i915/intel_hdmi.c | 29 ++++++++++++++++++++++++++++- 1 files changed, 28 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 4c6f141..4ebdcf1 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -382,7 +382,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, if (HAS_PCH_CPT(dev)) sdvox |= PORT_TRANS_SEL_CPT(intel_crtc->pipe); - else if (intel_crtc->pipe == 1) + else if (intel_crtc->pipe == PIPE_B) sdvox |= SDVO_PIPE_B_SELECT; I915_WRITE(intel_hdmi->sdvox_reg, sdvox); @@ -405,6 +405,33 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) temp = I915_READ(intel_hdmi->sdvox_reg); + /* HW workaround for IBX, we need to move the port to transcoder A + * before disabling it. */ + if (HAS_PCH_IBX(dev)) { + struct drm_crtc *crtc = encoder->crtc; + struct intel_crtc *intel_crtc; + + if (crtc) + intel_crtc = to_intel_crtc(crtc); + else + intel_crtc = NULL; + + if (mode != DRM_MODE_DPMS_ON && (temp & SDVO_PIPE_B_SELECT)) { + temp &= ~SDVO_PIPE_B_SELECT; + I915_WRITE(intel_hdmi->sdvox_reg, temp); + POSTING_READ(intel_hdmi->sdvox_reg); + + if (intel_crtc) + intel_wait_for_vblank(dev, intel_crtc->pipe); + else + msleep(50); + } else if (mode == DRM_MODE_DPMS_ON){ + /* Restore the transcoder select bit. */ + if (intel_crtc->pipe == PIPE_B) + enable_bits |= SDVO_PIPE_B_SELECT; + } + } + /* HW workaround, need to toggle enable bit off and on for 12bpc, but * we do this anyway which shows more stable in testing. */ -- 1.7.7.5