aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRodrigo Vivi <rodrigo.vivi@intel.com>2014-09-24 19:50:59 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-09-29 08:17:31 -0400
commit1d73c2a8f218be3e8b6aa884740fc67110660b54 (patch)
treead5adff5398fe4f3de1cae51a1c7ab0097ac915b
parent7ca5a41f4da201371e131fc0641033652f76bf30 (diff)
drm/i915: Minimize the huge amount of unecessary fbc sw cache clean.
The sw cache clean on BDW is a tempoorary workaround because we cannot set cache clean on blt ring with risk of hungs. So we are doing the cache clean on sw. However we are doing much more than needed. Not only when using blt ring. So, with this extra w/a we minimize the ammount of cache cleans and call it only on same cases that it was being called on gen7. The traditional FBC Cache clean happens over LRI on BLT ring when there is a frontbuffer touch happening. frontbuffer tracking set fbc_dirty variable to let BLT flush that it must clean FBC cache. fbc.need_sw_cache_clean works in the opposite information direction of ring->fbc_dirty telling software on frontbuffer tracking to perform the cache clean on sw side. v2: Clean it a little bit and fully check for Broadwell instead of gen8. v3: Rebase after frontbuffer organization. v4: Wiggle confused me. So fixing v3! Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h10
-rw-r--r--drivers/gpu/drm/i915/intel_frontbuffer.c6
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c2
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c9
4 files changed, 21 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 999bd57cab65..cccb7767e837 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -666,6 +666,14 @@ struct i915_fbc {
666 * possible. */ 666 * possible. */
667 bool enabled; 667 bool enabled;
668 668
669 /* On gen8 some rings cannont perform fbc clean operation so for now
670 * we are doing this on SW with mmio.
671 * This variable works in the opposite information direction
672 * of ring->fbc_dirty telling software on frontbuffer tracking
673 * to perform the cache clean on sw side.
674 */
675 bool need_sw_cache_clean;
676
669 struct intel_fbc_work { 677 struct intel_fbc_work {
670 struct delayed_work work; 678 struct delayed_work work;
671 struct drm_crtc *crtc; 679 struct drm_crtc *crtc;
@@ -2825,7 +2833,7 @@ extern void intel_modeset_setup_hw_state(struct drm_device *dev,
2825extern void i915_redisable_vga(struct drm_device *dev); 2833extern void i915_redisable_vga(struct drm_device *dev);
2826extern void i915_redisable_vga_power_on(struct drm_device *dev); 2834extern void i915_redisable_vga_power_on(struct drm_device *dev);
2827extern bool intel_fbc_enabled(struct drm_device *dev); 2835extern bool intel_fbc_enabled(struct drm_device *dev);
2828extern void gen8_fbc_sw_flush(struct drm_device *dev, u32 value); 2836extern void bdw_fbc_sw_flush(struct drm_device *dev, u32 value);
2829extern void intel_disable_fbc(struct drm_device *dev); 2837extern void intel_disable_fbc(struct drm_device *dev);
2830extern bool ironlake_set_drps(struct drm_device *dev, u8 val); 2838extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
2831extern void intel_init_pch_refclk(struct drm_device *dev); 2839extern void intel_init_pch_refclk(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c
index f74744c091cb..7eb74a62117f 100644
--- a/drivers/gpu/drm/i915/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/intel_frontbuffer.c
@@ -189,8 +189,10 @@ void intel_frontbuffer_flush(struct drm_device *dev,
189 * needs to be reworked into a proper frontbuffer tracking scheme like 189 * needs to be reworked into a proper frontbuffer tracking scheme like
190 * psr employs. 190 * psr employs.
191 */ 191 */
192 if (IS_BROADWELL(dev)) 192 if (dev_priv->fbc.need_sw_cache_clean) {
193 gen8_fbc_sw_flush(dev, FBC_REND_CACHE_CLEAN); 193 dev_priv->fbc.need_sw_cache_clean = false;
194 bdw_fbc_sw_flush(dev, FBC_REND_CACHE_CLEAN);
195 }
194} 196}
195 197
196/** 198/**
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 6b416201240f..011892d5356e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -356,7 +356,7 @@ bool intel_fbc_enabled(struct drm_device *dev)
356 return dev_priv->fbc.enabled; 356 return dev_priv->fbc.enabled;
357} 357}
358 358
359void gen8_fbc_sw_flush(struct drm_device *dev, u32 value) 359void bdw_fbc_sw_flush(struct drm_device *dev, u32 value)
360{ 360{
361 struct drm_i915_private *dev_priv = dev->dev_private; 361 struct drm_i915_private *dev_priv = dev->dev_private;
362 362
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 922d6bc1a1b3..620a89dc868b 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2237,6 +2237,7 @@ static int gen6_ring_flush(struct intel_engine_cs *ring,
2237 u32 invalidate, u32 flush) 2237 u32 invalidate, u32 flush)
2238{ 2238{
2239 struct drm_device *dev = ring->dev; 2239 struct drm_device *dev = ring->dev;
2240 struct drm_i915_private *dev_priv = dev->dev_private;
2240 uint32_t cmd; 2241 uint32_t cmd;
2241 int ret; 2242 int ret;
2242 2243
@@ -2267,8 +2268,12 @@ static int gen6_ring_flush(struct intel_engine_cs *ring,
2267 } 2268 }
2268 intel_ring_advance(ring); 2269 intel_ring_advance(ring);
2269 2270
2270 if (IS_GEN7(dev) && !invalidate && flush) 2271 if (!invalidate && flush) {
2271 return gen7_ring_fbc_flush(ring, FBC_REND_CACHE_CLEAN); 2272 if (IS_GEN7(dev))
2273 return gen7_ring_fbc_flush(ring, FBC_REND_CACHE_CLEAN);
2274 else if (IS_BROADWELL(dev))
2275 dev_priv->fbc.need_sw_cache_clean = true;
2276 }
2272 2277
2273 return 0; 2278 return 0;
2274} 2279}