From patchwork Tue Oct 20 13:49:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zanoni, Paulo R" X-Patchwork-Id: 7447591 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 98A789F37F for ; Tue, 20 Oct 2015 13:50:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E24E02053A for ; Tue, 20 Oct 2015 13:50:53 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 1B9B520546 for ; Tue, 20 Oct 2015 13:50:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0A8036EC34; Tue, 20 Oct 2015 06:50:49 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id 264386EC2B for ; Tue, 20 Oct 2015 06:50:45 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 20 Oct 2015 06:50:27 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,707,1437462000"; d="scan'208";a="798059564" Received: from quanshi-mobl1.amr.corp.intel.com (HELO panetone.amr.corp.intel.com) ([10.254.77.241]) by orsmga001.jf.intel.com with ESMTP; 20 Oct 2015 06:50:26 -0700 From: Paulo Zanoni To: intel-gfx@lists.freedesktop.org Date: Tue, 20 Oct 2015 11:49:54 -0200 Message-Id: <1445349004-16409-9-git-send-email-paulo.r.zanoni@intel.com> X-Mailer: git-send-email 2.6.1 In-Reply-To: <1445349004-16409-1-git-send-email-paulo.r.zanoni@intel.com> References: <1445349004-16409-1-git-send-email-paulo.r.zanoni@intel.com> Subject: [Intel-gfx] [PATCH 08/18] drm/i915: pass the crtc as an argument to intel_fbc_update() X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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. Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_display.c | 3 +- drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_fbc.c | 70 ++++++++++++++++-------------------- 3 files changed, 32 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e83a428..3050bfe 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4778,7 +4778,6 @@ static void intel_post_plane_update(struct intel_crtc *crtc) { struct intel_crtc_atomic_commit *atomic = &crtc->atomic; struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_plane *plane; if (atomic->wait_vblank) @@ -4793,7 +4792,7 @@ static void intel_post_plane_update(struct intel_crtc *crtc) intel_update_watermarks(&crtc->base); if (atomic->update_fbc) - intel_fbc_update(dev_priv); + intel_fbc_update(crtc); if (atomic->post_enable_primary) intel_post_enable_primary(&crtc->base); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1e08c8a..27c8403 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1278,7 +1278,7 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev) /* intel_fbc.c */ bool intel_fbc_enabled(struct drm_i915_private *dev_priv); -void intel_fbc_update(struct drm_i915_private *dev_priv); +void intel_fbc_update(struct intel_crtc *crtc); void intel_fbc_init(struct drm_i915_private *dev_priv); void intel_fbc_disable(struct drm_i915_private *dev_priv); void intel_fbc_disable_crtc(struct intel_crtc *crtc); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 5fa4ce4..2a55c1b 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -482,13 +482,18 @@ 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)); intel_fbc_cancel_work(dev_priv); 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; } @@ -551,24 +556,6 @@ static bool crtc_is_valid(struct intel_crtc *crtc) crtc->base.primary->fb != NULL; } -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; @@ -851,21 +838,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; @@ -879,18 +873,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; @@ -962,7 +949,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)) { @@ -1008,17 +996,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); } @@ -1044,7 +1034,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); } @@ -1064,14 +1054,14 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, dev_priv->fbc.busy_bits &= ~frontbuffer_bits; - if (!dev_priv->fbc.busy_bits) { + if (!dev_priv->fbc.busy_bits && dev_priv->fbc.crtc) { if (origin == ORIGIN_FLIP) { - __intel_fbc_update(dev_priv); + __intel_fbc_update(dev_priv->fbc.crtc); } else { if (dev_priv->fbc.enabled) intel_fbc_nuke(dev_priv); else - __intel_fbc_update(dev_priv); + __intel_fbc_update(dev_priv->fbc.crtc); } } @@ -1095,7 +1085,7 @@ void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv, } else if (dev_priv->fbc.fbc_work) { fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe); if (fbc_bits & frontbuffer_bits) - __intel_fbc_disable(dev_priv); + intel_fbc_deactivate(dev_priv); } mutex_unlock(&dev_priv->fbc.lock);