]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/i915/intel_dp.c
Merge branch 'common/fbdev-mipi' of master.kernel.org:/pub/scm/linux/kernel/git/letha...
[karo-tx-linux.git] / drivers / gpu / drm / i915 / intel_dp.c
index 300f64b4238bdcefa89ab02ee5ff862b6aeb0f78..df648cb4c29641cec581307b1c40a46d812fd58b 100644 (file)
@@ -1376,6 +1376,9 @@ intel_dp_link_down(struct intel_dp *intel_dp)
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t DP = intel_dp->DP;
 
+       if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0)
+               return;
+
        DRM_DEBUG_KMS("\n");
 
        if (is_edp(intel_dp)) {
@@ -1398,6 +1401,28 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 
        if (is_edp(intel_dp))
                DP |= DP_LINK_TRAIN_OFF;
+
+       if (!HAS_PCH_CPT(dev) &&
+           I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
+               struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
+               /* 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);
 }