diff options
author | Paulo Zanoni <paulo.r.zanoni@intel.com> | 2016-01-19 11:35:35 -0200 |
---|---|---|
committer | Paulo Zanoni <paulo.r.zanoni@intel.com> | 2016-01-29 18:07:38 -0200 |
commit | 615b40d7e441ee10b859ccc5a3e456c823f42cfa (patch) | |
tree | a7589375923ba9153d719db81c2aeb9c83d7b8bf /drivers/gpu/drm/i915/intel_fbc.c | |
parent | ca18d51d77eba6120f56761e5a0e541dbb07fa50 (diff) | |
download | op-kernel-dev-615b40d7e441ee10b859ccc5a3e456c823f42cfa.zip op-kernel-dev-615b40d7e441ee10b859ccc5a3e456c823f42cfa.tar.gz |
drm/i915/fbc: extract intel_fbc_can_activate()
Extract all the code that checks if the FBC configuration is valid to
its own function, making __intel_fbc_update() much simpler.
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-3-git-send-email-paulo.r.zanoni@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fbc.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_fbc.c | 92 |
1 files changed, 50 insertions, 42 deletions
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 3993b43..1440bb3 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -516,17 +516,6 @@ static bool crtc_can_fbc(struct intel_crtc *crtc) return true; } -static bool crtc_is_valid(struct intel_crtc *crtc) -{ - if (!intel_crtc_active(&crtc->base)) - return false; - - if (!to_intel_plane_state(crtc->base.primary->state)->visible) - return false; - - return true; -} - static bool multiple_pipes_ok(struct drm_i915_private *dev_priv) { enum pipe pipe; @@ -752,48 +741,40 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) return effective_w <= max_w && effective_h <= max_h; } -/** - * __intel_fbc_update - activate/deactivate FBC as needed, unlocked - * @crtc: the CRTC that triggered the update - * - * This function completely reevaluates the status of FBC, then activates, - * deactivates or maintains it on the same state. - */ -static void __intel_fbc_update(struct intel_crtc *crtc) +static bool intel_fbc_can_activate(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_plane *primary; struct drm_framebuffer *fb; + struct intel_plane_state *plane_state; struct drm_i915_gem_object *obj; const struct drm_display_mode *adjusted_mode; - WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); - - if (!multiple_pipes_ok(dev_priv)) { - set_no_fbc_reason(dev_priv, "more than one pipe active"); - goto out_disable; - } - - if (!dev_priv->fbc.enabled || dev_priv->fbc.crtc != crtc) - return; - - if (!crtc_is_valid(crtc)) { - set_no_fbc_reason(dev_priv, "no output"); - goto out_disable; + if (!intel_crtc_active(&crtc->base)) { + set_no_fbc_reason(dev_priv, "CRTC not active"); + return false; } - fb = crtc->base.primary->fb; + primary = crtc->base.primary; + fb = primary->fb; obj = intel_fb_obj(fb); adjusted_mode = &crtc->config->base.adjusted_mode; + plane_state = to_intel_plane_state(primary->state); + + if (!plane_state->visible) { + set_no_fbc_reason(dev_priv, "primary plane not visible"); + return false; + } if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) || (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) { set_no_fbc_reason(dev_priv, "incompatible mode"); - goto out_disable; + return false; } if (!intel_fbc_hw_tracking_covers_screen(crtc)) { set_no_fbc_reason(dev_priv, "mode too large for compression"); - goto out_disable; + return false; } /* The use of a CPU fence is mandatory in order to detect writes @@ -802,22 +783,22 @@ static void __intel_fbc_update(struct intel_crtc *crtc) if (obj->tiling_mode != I915_TILING_X || obj->fence_reg == I915_FENCE_REG_NONE) { set_no_fbc_reason(dev_priv, "framebuffer not tiled or fenced"); - goto out_disable; + return false; } if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_G4X(dev_priv) && - crtc->base.primary->state->rotation != BIT(DRM_ROTATE_0)) { + plane_state->base.rotation != BIT(DRM_ROTATE_0)) { set_no_fbc_reason(dev_priv, "rotation unsupported"); - goto out_disable; + return false; } if (!stride_is_valid(dev_priv, fb->pitches[0])) { set_no_fbc_reason(dev_priv, "framebuffer stride not supported"); - goto out_disable; + return false; } if (!pixel_format_is_valid(fb)) { set_no_fbc_reason(dev_priv, "pixel format is invalid"); - goto out_disable; + return false; } /* WaFbcExceedCdClockThreshold:hsw,bdw */ @@ -825,7 +806,7 @@ static void __intel_fbc_update(struct intel_crtc *crtc) ilk_pipe_pixel_rate(crtc->config) >= dev_priv->cdclk_freq * 95 / 100) { set_no_fbc_reason(dev_priv, "pixel rate is too big"); - goto out_disable; + return false; } /* It is possible for the required CFB size change without a @@ -841,16 +822,43 @@ static void __intel_fbc_update(struct intel_crtc *crtc) if (intel_fbc_calculate_cfb_size(crtc, fb) > dev_priv->fbc.compressed_fb.size * dev_priv->fbc.threshold) { set_no_fbc_reason(dev_priv, "CFB requirements changed"); + return false; + } + + return true; +} + +/** + * __intel_fbc_update - activate/deactivate FBC as needed, unlocked + * @crtc: the CRTC that triggered the update + * + * This function completely reevaluates the status of FBC, then activates, + * deactivates or maintains it on the same state. + */ +static void __intel_fbc_update(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + + WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); + + if (!multiple_pipes_ok(dev_priv)) { + set_no_fbc_reason(dev_priv, "more than one pipe active"); goto out_disable; } + if (!dev_priv->fbc.enabled || dev_priv->fbc.crtc != crtc) + return; + + if (!intel_fbc_can_activate(crtc)) + goto out_disable; + /* If the scanout has not changed, don't modify the FBC settings. * Note that we make the fundamental assumption that the fb->obj * cannot be unpinned (and have its GTT offset and fence revoked) * without first being decoupled from the scanout and FBC disabled. */ if (dev_priv->fbc.crtc == crtc && - dev_priv->fbc.fb_id == fb->base.id && + dev_priv->fbc.fb_id == crtc->base.primary->fb->base.id && dev_priv->fbc.y == crtc->base.y && dev_priv->fbc.active) return; |