After writing to the plane control reg we need to write to the surface
reg to trigger the double buffered register latch.

v2: write DSPADDR too to cover pre-965 chipsets
v3: use flush_display_plane instead, that's what it's for

Signed-off-by: Jesse Barnes <[email protected]>
---
 drivers/gpu/drm/i915/i915_drv.c      |    2 +-
 drivers/gpu/drm/i915/i915_drv.h      |    2 +
 drivers/gpu/drm/i915/i915_reg.h      |    7 ++
 drivers/gpu/drm/i915/intel_display.c |  144 ++++++++++++++++++++++++----------
 4 files changed, 111 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index ce045a8..60e4b9e 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -62,7 +62,7 @@ module_param_named(semaphores, i915_semaphores, int, 0600);
 MODULE_PARM_DESC(semaphores,
                "Use semaphores for inter-ring sync (default: false)");
 
-unsigned int i915_enable_rc6 __read_mostly = 0;
+unsigned int i915_enable_rc6 __read_mostly = 1;
 module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
 MODULE_PARM_DESC(i915_enable_rc6,
                "Enable power-saving render C-state 6 (default: true)");
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 78cdd15..4f24e72 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -337,6 +337,8 @@ typedef struct drm_i915_private {
        int cfb_y;
        struct intel_fbc_work *fbc_work;
 
+       int planes_enabled;
+
        struct intel_opregion opregion;
 
        /* overlay */
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 7377ae4..ae28549 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3081,6 +3081,13 @@
 #define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2)
 #define   TRANS_AUTOTRAIN_GEN_STALL_DIS        (1<<31)
 
+#define SOUTH_CHICKEN1         0xc2000
+#define  FDIA_PHASE_SYNC_OVR   (1<<19)
+#define  FDIA_PHASE_SYNC_EN    (1<<18)
+#define  FDIB_PHASE_SYNC_OVR   (1<<17)
+#define  FDIB_PHASE_SYNC_EN    (1<<16)
+#define  FDIC_PHASE_SYNC_OVR   (1<<15)
+#define  FDIC_PHASE_SYNC_EN    (1<<14)
 #define SOUTH_CHICKEN2         0xc2004
 #define  DPLS_EDP_PPS_FIX_DIS  (1<<0)
 
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 32ffde2..8bf6c6f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1309,8 +1309,8 @@ static void intel_enable_plane(struct drm_i915_private 
*dev_priv,
 static void intel_flush_display_plane(struct drm_i915_private *dev_priv,
                                      enum plane plane)
 {
-       u32 reg = DSPADDR(plane);
-       I915_WRITE(reg, I915_READ(reg));
+       I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane)));
+       I915_WRITE(DSPSURF(plane), I915_READ(DSPSURF(plane)));
 }
 
 /**
@@ -1370,7 +1370,7 @@ static void intel_disable_pch_ports(struct 
drm_i915_private *dev_priv,
        val = I915_READ(reg);
        if (ADPA_PIPE_ENABLED(val, pipe))
                I915_WRITE(reg, val & ~ADPA_DAC_ENABLE);
-
+#if 0
        reg = PCH_LVDS;
        val = I915_READ(reg);
        if (LVDS_PIPE_ENABLED(val, pipe)) {
@@ -1378,7 +1378,7 @@ static void intel_disable_pch_ports(struct 
drm_i915_private *dev_priv,
                POSTING_READ(reg);
                udelay(100);
        }
-
+#endif
        disable_pch_hdmi(dev_priv, pipe, HDMIB);
        disable_pch_hdmi(dev_priv, pipe, HDMIC);
        disable_pch_hdmi(dev_priv, pipe, HDMID);
@@ -2295,6 +2295,23 @@ static void ironlake_fdi_link_train(struct drm_crtc 
*crtc)
                I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR);
                I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR |
                           FDI_RX_PHASE_SYNC_POINTER_EN);
+       } else if (HAS_PCH_CPT(dev)) {
+               u32 flags;
+               switch (pipe) {
+               case 0:
+                       flags = FDIA_PHASE_SYNC_OVR | FDIA_PHASE_SYNC_EN;
+                       break;
+               case 2:
+                       flags = FDIA_PHASE_SYNC_OVR | FDIA_PHASE_SYNC_EN;
+                       break;
+               case 3:
+                       flags = FDIA_PHASE_SYNC_OVR | FDIA_PHASE_SYNC_EN;
+                       break;
+               default:
+                       break;
+               }
+               I915_WRITE(SOUTH_CHICKEN1, flags); /* once to unlock... */
+               I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to enable */
        }
 
        reg = FDI_RX_IIR(pipe);
@@ -2652,6 +2669,23 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc)
                I915_WRITE(FDI_RX_CHICKEN(pipe),
                           I915_READ(FDI_RX_CHICKEN(pipe) &
                                     ~FDI_RX_PHASE_SYNC_POINTER_EN));
+       } else if (HAS_PCH_CPT(dev)) {
+               u32 flags;
+               switch (pipe) {
+               case 0:
+                       flags = FDIA_PHASE_SYNC_OVR;
+                       break;
+               case 2:
+                       flags = FDIA_PHASE_SYNC_OVR;
+                       break;
+               case 3:
+                       flags = FDIA_PHASE_SYNC_OVR;
+                       break;
+               default:
+                       break;
+               }
+               I915_WRITE(SOUTH_CHICKEN1, flags); /* once to unlock... */
+               I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to enable */
        }
 
        /* still set train pattern 1 */
@@ -2919,6 +2953,10 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
                /* disable TRANS_DP_CTL */
                reg = TRANS_DP_CTL(pipe);
                temp = I915_READ(reg);
+               temp &= ~TRANS_DP_PORT_SEL_MASK;
+               temp |=  TRANS_DP_PORT_SEL_NONE;
+               I915_WRITE(reg, temp);
+               intel_wait_for_vblank(dev, pipe);
                temp &= ~(TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK);
                temp |= TRANS_DP_PORT_SEL_NONE;
                I915_WRITE(reg, temp);
@@ -4328,51 +4366,20 @@ static void ironlake_update_wm(struct drm_device *dev)
         */
 }
 
-static void sandybridge_update_wm(struct drm_device *dev)
+static void snb_disable_lpwm(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       int latency = SNB_READ_WM0_LATENCY() * 100;     /* In unit 0.1us */
-       int fbc_wm, plane_wm, cursor_wm;
-       unsigned int enabled;
 
-       enabled = 0;
-       if (g4x_compute_wm0(dev, 0,
-                           &sandybridge_display_wm_info, latency,
-                           &sandybridge_cursor_wm_info, latency,
-                           &plane_wm, &cursor_wm)) {
-               I915_WRITE(WM0_PIPEA_ILK,
-                          (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
-               DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
-                             " plane %d, " "cursor: %d\n",
-                             plane_wm, cursor_wm);
-               enabled |= 1;
-       }
-
-       if (g4x_compute_wm0(dev, 1,
-                           &sandybridge_display_wm_info, latency,
-                           &sandybridge_cursor_wm_info, latency,
-                           &plane_wm, &cursor_wm)) {
-               I915_WRITE(WM0_PIPEB_ILK,
-                          (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
-               DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
-                             " plane %d, cursor: %d\n",
-                             plane_wm, cursor_wm);
-               enabled |= 2;
-       }
-
-       /*
-        * Calculate and update the self-refresh watermark only when one
-        * display plane is used.
-        *
-        * SNB support 3 levels of watermark.
-        *
-        * WM1/WM2/WM2 watermarks have to be enabled in the ascending order,
-        * and disabled in the descending order
-        *
-        */
        I915_WRITE(WM3_LP_ILK, 0);
        I915_WRITE(WM2_LP_ILK, 0);
        I915_WRITE(WM1_LP_ILK, 0);
+}
+
+void snb_enable_lpwm(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int fbc_wm, plane_wm, cursor_wm;
+       int enabled = dev_priv->planes_enabled;
 
        if (!single_plane_enabled(enabled))
                return;
@@ -4424,6 +4431,55 @@ static void sandybridge_update_wm(struct drm_device *dev)
                   cursor_wm);
 }
 
+static void sandybridge_update_wm(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int latency = SNB_READ_WM0_LATENCY() * 100;     /* In unit 0.1us */
+       int plane_wm, cursor_wm;
+       unsigned int enabled;
+
+       enabled = 0;
+       if (g4x_compute_wm0(dev, 0,
+                           &sandybridge_display_wm_info, latency,
+                           &sandybridge_cursor_wm_info, latency,
+                           &plane_wm, &cursor_wm)) {
+               I915_WRITE(WM0_PIPEA_ILK,
+                          (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+               DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
+                             " plane %d, " "cursor: %d\n",
+                             plane_wm, cursor_wm);
+               enabled |= 1;
+       }
+
+       if (g4x_compute_wm0(dev, 1,
+                           &sandybridge_display_wm_info, latency,
+                           &sandybridge_cursor_wm_info, latency,
+                           &plane_wm, &cursor_wm)) {
+               I915_WRITE(WM0_PIPEB_ILK,
+                          (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+               DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
+                             " plane %d, cursor: %d\n",
+                             plane_wm, cursor_wm);
+               enabled |= 2;
+       }
+
+       /*
+        * Calculate and update the self-refresh watermark only when one
+        * display plane is used.
+        *
+        * SNB support 3 levels of watermark.
+        *
+        * WM1/WM2/WM2 watermarks have to be enabled in the ascending order,
+        * and disabled in the descending order
+        *
+        */
+       snb_disable_lpwm(dev);
+
+       dev_priv->planes_enabled = enabled;
+
+       snb_enable_lpwm(dev);
+}
+
 /**
  * intel_update_watermarks - update FIFO watermark values based on current 
modes
  *
@@ -5515,6 +5571,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 
        drm_vblank_post_modeset(dev, pipe);
 
+       intel_crtc->dpms_mode = DRM_MODE_DPMS_ON;
+
        return ret;
 }
 
-- 
1.7.4.1

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to