diff options
author | Paulo Zanoni <paulo.r.zanoni@intel.com> | 2015-10-13 19:13:25 -0300 |
---|---|---|
committer | Paulo Zanoni <paulo.r.zanoni@intel.com> | 2015-12-03 11:32:13 -0200 |
commit | 754d113304aa640b9b3ffa5535a1565b95e5fdb6 (patch) | |
tree | f45e09bcc4ea029f30ca29c283717f1da24451a5 /drivers/gpu/drm/i915/intel_fbc.c | |
parent | e9c5fd26ac38ec64497b86d70472f8dd750410ad (diff) | |
download | op-kernel-dev-754d113304aa640b9b3ffa5535a1565b95e5fdb6.zip op-kernel-dev-754d113304aa640b9b3ffa5535a1565b95e5fdb6.tar.gz |
drm/i915: pass the crtc as an argument to intel_fbc_update()
There's no need to reevaluate the status of every single crtc when a
single crtc changes its state.
With this, we're cutting the case where due to a change in pipe B,
intel_fbc_update() is called, then intel_fbc_find_crtc() concludes FBC
should be enabled on pipe A, then it completely rechecks the state of
pipe A only to conclude FBC should remain enabled on pipe A. If any
change on pipe A triggers a need to recompute whether FBC is valid on
pipe A, then at some point someone is going to call
intel_fbc_update(PIPE_A).
The addition of intel_fbc_deactivate() is necessary so we keep track
of the previously selected CRTC when we do invalidate/flush. We're
also going to continue the enable/disable/activate/deactivate concept
in the next patches.
v2: Rebase.
v3: Rebase after changing the patch order.
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fbc.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_fbc.c | 68 |
1 files changed, 29 insertions, 39 deletions
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 70b55c0c..263d450 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -429,7 +429,7 @@ static void intel_fbc_schedule_enable(struct intel_crtc *crtc) schedule_delayed_work(&work->work, msecs_to_jiffies(50)); } -static void __intel_fbc_disable(struct drm_i915_private *dev_priv) +static void intel_fbc_deactivate(struct drm_i915_private *dev_priv) { WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); @@ -437,6 +437,11 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv) if (dev_priv->fbc.enabled) dev_priv->fbc.disable_fbc(dev_priv); +} + +static void __intel_fbc_disable(struct drm_i915_private *dev_priv) +{ + intel_fbc_deactivate(dev_priv); dev_priv->fbc.crtc = NULL; } @@ -501,24 +506,6 @@ static bool crtc_is_valid(struct intel_crtc *crtc) return true; } -static struct drm_crtc *intel_fbc_find_crtc(struct drm_i915_private *dev_priv) -{ - struct drm_crtc *crtc = NULL, *tmp_crtc; - enum pipe pipe; - - for_each_pipe(dev_priv, pipe) { - tmp_crtc = dev_priv->pipe_to_crtc_mapping[pipe]; - - if (crtc_is_valid(to_intel_crtc(tmp_crtc))) - crtc = tmp_crtc; - } - - if (!crtc) - return NULL; - - return crtc; -} - static bool multiple_pipes_ok(struct drm_i915_private *dev_priv) { enum pipe pipe; @@ -804,21 +791,28 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) /** * __intel_fbc_update - enable/disable FBC as needed, unlocked - * @dev_priv: i915 device instance + * @crtc: the CRTC that triggered the update * * This function completely reevaluates the status of FBC, then enables, * disables or maintains it on the same state. */ -static void __intel_fbc_update(struct drm_i915_private *dev_priv) +static void __intel_fbc_update(struct intel_crtc *crtc) { - struct drm_crtc *drm_crtc = NULL; - struct intel_crtc *crtc; + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct drm_framebuffer *fb; 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.crtc != NULL && dev_priv->fbc.crtc != crtc) + return; + if (intel_vgpu_active(dev_priv->dev)) i915.enable_fbc = 0; @@ -832,18 +826,11 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv) goto out_disable; } - drm_crtc = intel_fbc_find_crtc(dev_priv); - if (!drm_crtc) { + if (!crtc_is_valid(crtc)) { set_no_fbc_reason(dev_priv, "no output"); goto out_disable; } - if (!multiple_pipes_ok(dev_priv)) { - set_no_fbc_reason(dev_priv, "more than one pipe active"); - goto out_disable; - } - - crtc = to_intel_crtc(drm_crtc); fb = crtc->base.primary->fb; obj = intel_fb_obj(fb); adjusted_mode = &crtc->config->base.adjusted_mode; @@ -909,7 +896,8 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv) */ if (dev_priv->fbc.crtc == crtc && dev_priv->fbc.fb_id == fb->base.id && - dev_priv->fbc.y == crtc->base.y) + dev_priv->fbc.y == crtc->base.y && + dev_priv->fbc.enabled) return; if (intel_fbc_enabled(dev_priv)) { @@ -955,17 +943,19 @@ out_disable: /* * intel_fbc_update - enable/disable FBC as needed - * @dev_priv: i915 device instance + * @crtc: the CRTC that triggered the update * * This function reevaluates the overall state and enables or disables FBC. */ -void intel_fbc_update(struct drm_i915_private *dev_priv) +void intel_fbc_update(struct intel_crtc *crtc) { + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + if (!fbc_supported(dev_priv)) return; mutex_lock(&dev_priv->fbc.lock); - __intel_fbc_update(dev_priv); + __intel_fbc_update(crtc); mutex_unlock(&dev_priv->fbc.lock); } @@ -991,7 +981,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, dev_priv->fbc.busy_bits |= (fbc_bits & frontbuffer_bits); if (dev_priv->fbc.busy_bits) - __intel_fbc_disable(dev_priv); + intel_fbc_deactivate(dev_priv); mutex_unlock(&dev_priv->fbc.lock); } @@ -1009,9 +999,9 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, dev_priv->fbc.busy_bits &= ~frontbuffer_bits; - if (!dev_priv->fbc.busy_bits) { - __intel_fbc_disable(dev_priv); - __intel_fbc_update(dev_priv); + if (!dev_priv->fbc.busy_bits && dev_priv->fbc.crtc) { + intel_fbc_deactivate(dev_priv); + __intel_fbc_update(dev_priv->fbc.crtc); } mutex_unlock(&dev_priv->fbc.lock); |