From patchwork Tue Sep 15 20:57:36 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 47765 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n8FKwSal001211 for ; Tue, 15 Sep 2009 20:58:28 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DDB059F664; Tue, 15 Sep 2009 13:58:27 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail.ffwll.ch (cable-static-49-187.intergga.ch [157.161.49.187]) by gabe.freedesktop.org (Postfix) with ESMTP id D80409E915 for ; Tue, 15 Sep 2009 13:58:24 -0700 (PDT) Received: by mail.ffwll.ch (Postfix, from userid 1000) id EE58320C4C0; Wed, 16 Sep 2009 06:52:31 +0200 (CEST) X-Spam-ASN: X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on orange.ffwll.ch X-Spam-Level: X-Spam-Hammy: 0.000-+--H*Ad:D*sourceforge.net, 0.000-+--H*Ad:D*lists.sourceforge.net, 0.000-+--HCc:D*net X-Spam-Status: No, score=-4.4 required=6.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham version=3.2.5 X-Spam-Spammy: Received: from biene (unknown [192.168.23.129]) by mail.ffwll.ch (Postfix) with ESMTP id 8E23520C4B5; Wed, 16 Sep 2009 06:52:06 +0200 (CEST) Received: from daniel by biene with local (Exim 4.69) (envelope-from ) id 1Mnf66-0002Au-HO; Tue, 15 Sep 2009 22:57:58 +0200 From: Daniel Vetter To: intel-gfx@lists.freedesktop.org Date: Tue, 15 Sep 2009 22:57:36 +0200 Message-Id: <5a82db0a8446ac3e5d15cec182504d94569521d4.1253047594.git.daniel.vetter@ffwll.ch> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: References: <0cdb434c339fd4257f9e19c0b9db4389c99c8e84.1253047594.git.daniel.vetter@ffwll.ch> <23ce9c607c40e8441e7c5650124782f150030e52.1253047594.git.daniel.vetter@ffwll.ch> <7e4800d3a495686bb3d4cea4dd9364f53c100bba.1253047594.git.daniel.vetter@ffwll.ch> In-Reply-To: References: Cc: Daniel Vetter , dri-devel@lists.sourceforge.net Subject: [Intel-gfx] [PATCH 6/8] [drm/i915] implement fastpath for overlay flip waiting X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org As long as the gpu can keep up, neither the cpu (waiting for gpu) nore the gpu (waiting for vblank to do an overlay flip) stalls. Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 3 ++ drivers/gpu/drm/i915/i915_gem.c | 4 +- drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_overlay.c | 43 ++++++++++++++++++++++++++------- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d31198b..8b17942 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -724,6 +724,9 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev); int i915_gem_do_init(struct drm_device *dev, unsigned long start, unsigned long end); int i915_gem_idle(struct drm_device *dev); +uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv, + uint32_t flush_domains); +int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible); int i915_lp_ring_sync(struct drm_device *dev); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a3d8fa8..4793766 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1518,7 +1518,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) * * Returned sequence numbers are nonzero on success. */ -static uint32_t +uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv, uint32_t flush_domains) { @@ -1738,7 +1738,7 @@ i915_gem_retire_work_handler(struct work_struct *work) mutex_unlock(&dev->struct_mutex); } -static int +int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) { drm_i915_private_t *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f84a0cf..9eea5c7 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -125,7 +125,9 @@ struct intel_overlay { u32 flip_addr; struct drm_i915_gem_object *reg_bo; void *virt_addr; + /* flip handling */ int hw_wedged; + uint32_t last_flip_req; }; struct intel_crtc { diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 4e88abb..85e07e4 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -251,7 +251,6 @@ static void intel_overlay_continue(struct intel_overlay *overlay, drm_i915_private_t *dev_priv = dev->dev_private; u32 flip_addr = overlay->flip_addr; u32 tmp; - int ret; RING_LOCALS; BUG_ON(!overlay->active); @@ -264,11 +263,40 @@ static void intel_overlay_continue(struct intel_overlay *overlay, if (tmp & (1 << 17)) DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); - BEGIN_LP_RING(6); + BEGIN_LP_RING(4); OUT_RING(MI_FLUSH); OUT_RING(MI_NOOP); OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); OUT_RING(flip_addr); + ADVANCE_LP_RING(); + + overlay->last_flip_req = i915_add_request(dev, NULL, 0); +} + +static int intel_overlay_wait_flip(struct intel_overlay *overlay) +{ + struct drm_device *dev = overlay->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + int ret; + u32 tmp; + RING_LOCALS; + + if (overlay->last_flip_req != 0) { + ret = i915_do_wait_request(dev, overlay->last_flip_req, 0); + + if (ret != 0) + return ret; + + overlay->last_flip_req = 0; + + tmp = I915_READ(ISR); + + if (!(tmp & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT)) + return 0; + } + + /* synchronous slowpath */ + BEGIN_LP_RING(2); OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); OUT_RING(MI_NOOP); ADVANCE_LP_RING(); @@ -279,13 +307,8 @@ static void intel_overlay_continue(struct intel_overlay *overlay, DRM_ERROR("intel overlay: ring sync failed, hw likely wedged\n"); overlay->hw_wedged = 1; } -} -static int intel_overlay_wait_flip(struct intel_overlay *overlay) -{ - /* don't overcomplicate things for now with asynchronous operations - * see comment above */ - return 0; + return ret; } /* overlay needs to be disabled in OCMD reg */ @@ -344,7 +367,9 @@ static int intel_overlay_off(struct intel_overlay *overlay) return ret; } -/* wait for pending overlay flip and release old frame */ +/* Wait for pending overlay flip and release old frame. + * Needs to be called before the overlay register are changed + * via intel_overlay_(un)map_regs_atomic */ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) { int ret;