diff options
author | Paulo Zanoni <paulo.r.zanoni@intel.com> | 2014-09-19 15:04:55 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-09-23 04:28:53 -0400 |
commit | 9adccc6063d1cf6ba38a5a26b87001554105be18 (patch) | |
tree | 071fe73fc3ad629b50c746d86b143006504f0ba9 | |
parent | d2dee86cece9deee33923ee71be918f0452c8ebe (diff) |
drm/i915: add SW tracking to FBC enabling
Currently, calling intel_fbc_enabled() will trigger a register read.
And we call it a lot of times, even when FBC is disabled, so saving a
few cycles would be a good thing.
Another reason for this patch is because we currently call
intel_fbc_enabled() while the HW is runtime suspended, so the read
makes no sense and triggers a WARN. This happens even if FBC is
disabled by default. Of course one could argue that we just shouldn't
be calling intel_fbc_enabled() while the driver is runtime suspended,
and I agree that's a good argument, but I still think that the reason
explained in the first paragraph already justifies the patch.
This problem can easily be reproduced with many subtests of
igt/pm_rpm, and it is a regression introduced by:
commit c5ad011d7d256ecbe173324029e992817194d2b0
Author: Rodrigo Vivi <rodrigo.vivi@intel.com>
Date: Mon Aug 4 03:51:38 2014 -0700
drm/i915: FBC flush nuke for BDW
Testcase: igt/pm_rpm/cursor (and others)
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-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.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 31 |
2 files changed, 24 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5fce16c9d647..999bd57cab65 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -662,6 +662,10 @@ struct i915_fbc { | |||
662 | 662 | ||
663 | bool false_color; | 663 | bool false_color; |
664 | 664 | ||
665 | /* Tracks whether the HW is actually enabled, not whether the feature is | ||
666 | * possible. */ | ||
667 | bool enabled; | ||
668 | |||
665 | struct intel_fbc_work { | 669 | struct intel_fbc_work { |
666 | struct delayed_work work; | 670 | struct delayed_work work; |
667 | struct drm_crtc *crtc; | 671 | struct drm_crtc *crtc; |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 2ca9fdba7cb7..6b416201240f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -71,6 +71,8 @@ static void i8xx_disable_fbc(struct drm_device *dev) | |||
71 | struct drm_i915_private *dev_priv = dev->dev_private; | 71 | struct drm_i915_private *dev_priv = dev->dev_private; |
72 | u32 fbc_ctl; | 72 | u32 fbc_ctl; |
73 | 73 | ||
74 | dev_priv->fbc.enabled = false; | ||
75 | |||
74 | /* Disable compression */ | 76 | /* Disable compression */ |
75 | fbc_ctl = I915_READ(FBC_CONTROL); | 77 | fbc_ctl = I915_READ(FBC_CONTROL); |
76 | if ((fbc_ctl & FBC_CTL_EN) == 0) | 78 | if ((fbc_ctl & FBC_CTL_EN) == 0) |
@@ -99,6 +101,8 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc) | |||
99 | int i; | 101 | int i; |
100 | u32 fbc_ctl; | 102 | u32 fbc_ctl; |
101 | 103 | ||
104 | dev_priv->fbc.enabled = true; | ||
105 | |||
102 | cfb_pitch = dev_priv->fbc.size / FBC_LL_SIZE; | 106 | cfb_pitch = dev_priv->fbc.size / FBC_LL_SIZE; |
103 | if (fb->pitches[0] < cfb_pitch) | 107 | if (fb->pitches[0] < cfb_pitch) |
104 | cfb_pitch = fb->pitches[0]; | 108 | cfb_pitch = fb->pitches[0]; |
@@ -153,6 +157,8 @@ static void g4x_enable_fbc(struct drm_crtc *crtc) | |||
153 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 157 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
154 | u32 dpfc_ctl; | 158 | u32 dpfc_ctl; |
155 | 159 | ||
160 | dev_priv->fbc.enabled = true; | ||
161 | |||
156 | dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane) | DPFC_SR_EN; | 162 | dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane) | DPFC_SR_EN; |
157 | if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) | 163 | if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) |
158 | dpfc_ctl |= DPFC_CTL_LIMIT_2X; | 164 | dpfc_ctl |= DPFC_CTL_LIMIT_2X; |
@@ -173,6 +179,8 @@ static void g4x_disable_fbc(struct drm_device *dev) | |||
173 | struct drm_i915_private *dev_priv = dev->dev_private; | 179 | struct drm_i915_private *dev_priv = dev->dev_private; |
174 | u32 dpfc_ctl; | 180 | u32 dpfc_ctl; |
175 | 181 | ||
182 | dev_priv->fbc.enabled = false; | ||
183 | |||
176 | /* Disable compression */ | 184 | /* Disable compression */ |
177 | dpfc_ctl = I915_READ(DPFC_CONTROL); | 185 | dpfc_ctl = I915_READ(DPFC_CONTROL); |
178 | if (dpfc_ctl & DPFC_CTL_EN) { | 186 | if (dpfc_ctl & DPFC_CTL_EN) { |
@@ -224,6 +232,8 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc) | |||
224 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 232 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
225 | u32 dpfc_ctl; | 233 | u32 dpfc_ctl; |
226 | 234 | ||
235 | dev_priv->fbc.enabled = true; | ||
236 | |||
227 | dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane); | 237 | dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane); |
228 | if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) | 238 | if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) |
229 | dev_priv->fbc.threshold++; | 239 | dev_priv->fbc.threshold++; |
@@ -264,6 +274,8 @@ static void ironlake_disable_fbc(struct drm_device *dev) | |||
264 | struct drm_i915_private *dev_priv = dev->dev_private; | 274 | struct drm_i915_private *dev_priv = dev->dev_private; |
265 | u32 dpfc_ctl; | 275 | u32 dpfc_ctl; |
266 | 276 | ||
277 | dev_priv->fbc.enabled = false; | ||
278 | |||
267 | /* Disable compression */ | 279 | /* Disable compression */ |
268 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | 280 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); |
269 | if (dpfc_ctl & DPFC_CTL_EN) { | 281 | if (dpfc_ctl & DPFC_CTL_EN) { |
@@ -290,6 +302,8 @@ static void gen7_enable_fbc(struct drm_crtc *crtc) | |||
290 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 302 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
291 | u32 dpfc_ctl; | 303 | u32 dpfc_ctl; |
292 | 304 | ||
305 | dev_priv->fbc.enabled = true; | ||
306 | |||
293 | dpfc_ctl = IVB_DPFC_CTL_PLANE(intel_crtc->plane); | 307 | dpfc_ctl = IVB_DPFC_CTL_PLANE(intel_crtc->plane); |
294 | if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) | 308 | if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) |
295 | dev_priv->fbc.threshold++; | 309 | dev_priv->fbc.threshold++; |
@@ -339,16 +353,7 @@ bool intel_fbc_enabled(struct drm_device *dev) | |||
339 | { | 353 | { |
340 | struct drm_i915_private *dev_priv = dev->dev_private; | 354 | struct drm_i915_private *dev_priv = dev->dev_private; |
341 | 355 | ||
342 | /* If it wasn't never enabled by kernel parameter or platform default | 356 | return dev_priv->fbc.enabled; |
343 | * we can avoid reading registers so many times in vain | ||
344 | */ | ||
345 | if (!i915.enable_fbc) | ||
346 | return false; | ||
347 | |||
348 | if (!dev_priv->display.fbc_enabled) | ||
349 | return false; | ||
350 | |||
351 | return dev_priv->display.fbc_enabled(dev); | ||
352 | } | 357 | } |
353 | 358 | ||
354 | void gen8_fbc_sw_flush(struct drm_device *dev, u32 value) | 359 | void gen8_fbc_sw_flush(struct drm_device *dev, u32 value) |
@@ -7360,8 +7365,10 @@ void intel_fini_runtime_pm(struct drm_i915_private *dev_priv) | |||
7360 | 7365 | ||
7361 | static void intel_init_fbc(struct drm_i915_private *dev_priv) | 7366 | static void intel_init_fbc(struct drm_i915_private *dev_priv) |
7362 | { | 7367 | { |
7363 | if (!HAS_FBC(dev_priv)) | 7368 | if (!HAS_FBC(dev_priv)) { |
7369 | dev_priv->fbc.enabled = false; | ||
7364 | return; | 7370 | return; |
7371 | } | ||
7365 | 7372 | ||
7366 | if (INTEL_INFO(dev_priv)->gen >= 7) { | 7373 | if (INTEL_INFO(dev_priv)->gen >= 7) { |
7367 | dev_priv->display.fbc_enabled = ironlake_fbc_enabled; | 7374 | dev_priv->display.fbc_enabled = ironlake_fbc_enabled; |
@@ -7383,6 +7390,8 @@ static void intel_init_fbc(struct drm_i915_private *dev_priv) | |||
7383 | /* This value was pulled out of someone's hat */ | 7390 | /* This value was pulled out of someone's hat */ |
7384 | I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT); | 7391 | I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT); |
7385 | } | 7392 | } |
7393 | |||
7394 | dev_priv->fbc.enabled = dev_priv->display.fbc_enabled(dev_priv->dev); | ||
7386 | } | 7395 | } |
7387 | 7396 | ||
7388 | /* Set up chip specific power management-related functions */ | 7397 | /* Set up chip specific power management-related functions */ |