drm/i915: Apply a workaround for transitioning from DP on pipe B to HDMI.
authorEric Anholt <eric@anholt.net>
Thu, 18 Nov 2010 01:32:59 +0000 (09:32 +0800)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 2 Dec 2010 22:31:30 +0000 (22:31 +0000)
This workaround only applies to Ironlake.

Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: stable@kernel.org
drivers/gpu/drm/i915/intel_dp.c

index 300f64b4238bdcefa89ab02ee5ff862b6aeb0f78..1d8d068bc4730ce2fec78e8207588ef289dbc5b9 100644 (file)
@@ -1374,6 +1374,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 {
        struct drm_device *dev = intel_dp->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
        uint32_t DP = intel_dp->DP;
 
        DRM_DEBUG_KMS("\n");
@@ -1398,6 +1399,26 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 
        if (is_edp(intel_dp))
                DP |= DP_LINK_TRAIN_OFF;
+
+       if (!HAS_PCH_CPT(dev) && (DP & DP_PIPEB_SELECT)) {
+               /* Hardware workaround: leaving our transcoder select
+                * set to transcoder B while it's off will prevent the
+                * corresponding HDMI output on transcoder A.
+                *
+                * Combine this with another hardware workaround:
+                * transcoder select bit can only be cleared while the
+                * port is enabled.
+                */
+               DP &= ~DP_PIPEB_SELECT;
+               I915_WRITE(intel_dp->output_reg, DP);
+
+               /* Changes to enable or select take place the vblank
+                * after being written.
+                */
+               intel_wait_for_vblank(intel_dp->base.base.dev,
+                                     intel_crtc->pipe);
+       }
+
        I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
        POSTING_READ(intel_dp->output_reg);
 }