OSDN Git Service

drm/i915: make the blitter report buffer modifications to the FBC unit
authorJesse Barnes <jbarnes@virtuousgeek.org>
Tue, 18 Jan 2011 19:25:41 +0000 (11:25 -0800)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 18 Jan 2011 19:30:24 +0000 (19:30 +0000)
Without this change, blits to the front buffer won't invalidate FBC
state, causing us to scan out stale data.  Make sure we update these
bits on every FBC enable, since they may get clobbered if we shut off
the display.

References: https://bugzilla.kernel.org/show_bug.cgi?id=26932
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c

index 6abb15f..5cfc689 100644 (file)
 #define   GEN6_BLITTER_SYNC_STATUS                     (1 << 24)
 #define   GEN6_BLITTER_USER_INTERRUPT                  (1 << 22)
 
+#define GEN6_BLITTER_ECOSKPD   0x221d0
+#define   GEN6_BLITTER_LOCK_SHIFT                      16
+#define   GEN6_BLITTER_FBC_NOTIFY                      (1<<3)
+
 #define GEN6_BSD_SLEEP_PSMI_CONTROL    0x12050
 #define   GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK      (1 << 16)
 #define   GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE          (1 << 0)
index d2ef1c2..d7f237d 100644 (file)
@@ -1213,6 +1213,26 @@ static bool g4x_fbc_enabled(struct drm_device *dev)
        return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN;
 }
 
+static void sandybridge_blit_fbc_update(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 blt_ecoskpd;
+
+       /* Make sure blitter notifies FBC of writes */
+       __gen6_force_wake_get(dev_priv);
+       blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD);
+       blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY <<
+               GEN6_BLITTER_LOCK_SHIFT;
+       I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
+       blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY;
+       I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
+       blt_ecoskpd &= ~(GEN6_BLITTER_FBC_NOTIFY <<
+                        GEN6_BLITTER_LOCK_SHIFT);
+       I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
+       POSTING_READ(GEN6_BLITTER_ECOSKPD);
+       __gen6_force_wake_put(dev_priv);
+}
+
 static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
 {
        struct drm_device *dev = crtc->dev;
@@ -1266,6 +1286,7 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
                I915_WRITE(SNB_DPFC_CTL_SA,
                           SNB_CPU_FENCE_ENABLE | dev_priv->cfb_fence);
                I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y);
+               sandybridge_blit_fbc_update(dev);
        }
 
        DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane);