drm/i915: FBC flush nuke for BDW
authorRodrigo Vivi <rodrigo.vivi@intel.com>
Mon, 4 Aug 2014 10:51:38 +0000 (03:51 -0700)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 3 Sep 2014 09:04:40 +0000 (11:04 +0200)
According to spec FBC on BDW and HSW are identical without any gaps.
So let's copy the nuke and let FBC really start compressing stuff.

Without this patch we can verify with false color that nothing is being
compressed. With the nuke in place and false color it is possible
to see false color debugs.

Unfortunatelly on some rings like BCS on BDW we have to avoid Bits 22:18 on
LRIs due to a high risk of hung. So, when using Blt ring for frontbuffer rend
cache would never been cleaned and FBC would stop compressing buffer.
One alternative is to cache clean on software frontbuffer tracking.

v2: Fix rebase conflict.
v3: Do not clean cache on BCS ring. Instead use sw frontbuffer tracking.

Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_ringbuffer.c

index 5957db463e2710051647ee25325ef40209d7584b..f13f30d65172a6f01c8b2ed8bb8c40ac0050114d 100644 (file)
@@ -2772,6 +2772,7 @@ extern void intel_modeset_setup_hw_state(struct drm_device *dev,
 extern void i915_redisable_vga(struct drm_device *dev);
 extern void i915_redisable_vga_power_on(struct drm_device *dev);
 extern bool intel_fbc_enabled(struct drm_device *dev);
+extern void gen8_fbc_sw_flush(struct drm_device *dev, u32 value);
 extern void intel_disable_fbc(struct drm_device *dev);
 extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
 extern void intel_init_pch_refclk(struct drm_device *dev);
index 794aa5e611ebe6a4aa38ddd08ff74fcaf04f6dab..cbd159163722cfd5eedefe3b6aa4441578cad7b6 100644 (file)
@@ -9082,6 +9082,9 @@ void intel_frontbuffer_flush(struct drm_device *dev,
        intel_mark_fb_busy(dev, frontbuffer_bits, NULL);
 
        intel_edp_psr_flush(dev, frontbuffer_bits);
+
+       if (IS_GEN8(dev))
+               gen8_fbc_sw_flush(dev, FBC_REND_CACHE_CLEAN);
 }
 
 /**
index 2253f878adf4a914eaef38a7e4606baa302e0547..b9edfd426a19716bd3e8ee463851b7c5e1a3a581 100644 (file)
@@ -345,6 +345,16 @@ bool intel_fbc_enabled(struct drm_device *dev)
        return dev_priv->display.fbc_enabled(dev);
 }
 
+void gen8_fbc_sw_flush(struct drm_device *dev, u32 value)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       if (!IS_GEN8(dev))
+               return;
+
+       I915_WRITE(MSG_FBC_REND_STATE, value);
+}
+
 static void intel_fbc_work_fn(struct work_struct *__work)
 {
        struct intel_fbc_work *work =
index 4fb1ec95ec08ef9161eb5146b9d4661fe309933d..de7654623acc1db660cb63e41011987362b426bc 100644 (file)
@@ -444,7 +444,14 @@ gen8_render_ring_flush(struct intel_engine_cs *ring,
                        return ret;
        }
 
-       return gen8_emit_pipe_control(ring, flags, scratch_addr);
+       ret = gen8_emit_pipe_control(ring, flags, scratch_addr);
+       if (ret)
+               return ret;
+
+       if (!invalidate_domains && flush_domains)
+               return gen7_ring_fbc_flush(ring, FBC_REND_NUKE);
+
+       return 0;
 }
 
 static void ring_write_tail(struct intel_engine_cs *ring,