This is a horrible layering violation; we should be doing this in the
connector/encoder ->prepare instead, but we don't always have enough
information there about the config to know whether it will actually be
necessary or just cause unnecessary flicker.

-- 
Jesse Barnes, Intel Open Source Technology Center

>From 5600b8266132dc704079757c2f513fe4fef5eb21 Mon Sep 17 00:00:00 2001
From: Jesse Barnes <jbar...@virtuousgeek.org>
Date: Wed, 2 Feb 2011 13:37:07 -0800
Subject: [PATCH 1/3] drm/i915: disable PCH ports if needed when disabling a CRTC

Disable any PCH ports associated with a pipe when disabling it.  This
should prevent transcoder disable failures due to ports still being on.

Signed-off-by: Jesse Barnes <jbar...@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |   75 ++++++++++++++++++++++++++++++----
 1 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index cc431f4..a22483e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1626,6 +1626,72 @@ static void intel_disable_plane(struct drm_i915_private 
*dev_priv,
        intel_wait_for_vblank(dev_priv->dev, pipe);
 }
 
+static void disable_pch_dp(struct drm_i915_private *dev_priv,
+                          enum pipe pipe, int reg)
+{
+       u32 val;
+       u32 sel_pipe;
+
+       val = I915_READ(reg);
+       sel_pipe = (val & DP_PIPEB_SELECT) >> 30;
+       if ((val & DP_PORT_EN) && sel_pipe == pipe) {
+               I915_WRITE(reg, val & ~DP_PORT_EN);
+               POSTING_READ(reg);
+       }
+}
+
+static void disable_pch_hdmi(struct drm_i915_private *dev_priv,
+                            enum pipe pipe, int reg)
+{
+       u32 val;
+       u32 sel_pipe;
+
+       val = I915_READ(reg);
+       sel_pipe = (val & TRANSCODER_B) >> 30;
+       if ((val & PORT_ENABLE) && sel_pipe == pipe) {
+               I915_WRITE(reg, val & ~PORT_ENABLE);
+               POSTING_READ(reg);
+       }
+}
+
+/* Disable any ports connected to this transcoder */
+static void intel_disable_pch_ports(struct drm_i915_private *dev_priv,
+                                   enum pipe pipe)
+{
+       int reg;
+       u32 val;
+       u32 sel_pipe;
+
+       val = I915_READ(PCH_PP_CONTROL);
+       I915_WRITE(PCH_PP_CONTROL, val | PANEL_UNLOCK_REGS);
+       POSTING_READ(PCH_PP_CONTROL);
+
+       disable_pch_dp(dev_priv, pipe, PCH_DP_B);
+       disable_pch_dp(dev_priv, pipe, PCH_DP_C);
+       disable_pch_dp(dev_priv, pipe, PCH_DP_D);
+
+       reg = PCH_ADPA;
+       val = I915_READ(reg);
+       sel_pipe = (val & ADPA_TRANS_B_SELECT) >> 30;
+       if ((val & ADPA_DAC_ENABLE) && sel_pipe == pipe) {
+               I915_WRITE(reg, val & ~ADPA_DAC_ENABLE);
+               POSTING_READ(reg);
+       }
+
+       reg = PCH_LVDS;
+       val = I915_READ(reg);
+       sel_pipe = (val & LVDS_PIPEB_SELECT) >> 30;
+       if ((val & LVDS_PORT_EN) && sel_pipe == pipe) {
+               I915_WRITE(reg, val & ~LVDS_PORT_EN);
+               POSTING_READ(reg);
+               udelay(100);
+       }
+
+       disable_pch_hdmi(dev_priv, pipe, HDMIB);
+       disable_pch_hdmi(dev_priv, pipe, HDMIC);
+       disable_pch_hdmi(dev_priv, pipe, HDMID);
+}
+
 static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
 {
        struct drm_device *dev = crtc->dev;
@@ -2865,14 +2931,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 
        ironlake_fdi_disable(crtc);
 
-       if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-               temp = I915_READ(PCH_LVDS);
-               if (temp & LVDS_PORT_EN) {
-                       I915_WRITE(PCH_LVDS, temp & ~LVDS_PORT_EN);
-                       POSTING_READ(PCH_LVDS);
-                       udelay(100);
-               }
-       }
+       intel_disable_pch_ports(dev_priv, pipe);
 
        intel_disable_transcoder(dev_priv, pipe);
 
-- 
1.7.2.3


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to