From patchwork Wed Feb 24 16:48:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jyri Sarha X-Patchwork-Id: 8409701 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 5A8ECC0553 for ; Wed, 24 Feb 2016 16:49:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7099320361 for ; Wed, 24 Feb 2016 16:49:42 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 740A72028D for ; Wed, 24 Feb 2016 16:49:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 832186E80A; Wed, 24 Feb 2016 16:49:40 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from comal.ext.ti.com (comal.ext.ti.com [198.47.26.152]) by gabe.freedesktop.org (Postfix) with ESMTPS id 24FE06E807 for ; Wed, 24 Feb 2016 16:49:37 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id u1OGnXgY013263; Wed, 24 Feb 2016 10:49:33 -0600 Received: from DLEE71.ent.ti.com (dlee71.ent.ti.com [157.170.170.114]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id u1OGnXsj006045; Wed, 24 Feb 2016 10:49:33 -0600 Received: from dflp32.itg.ti.com (10.64.6.15) by DLEE71.ent.ti.com (157.170.170.114) with Microsoft SMTP Server id 14.3.224.2; Wed, 24 Feb 2016 10:49:33 -0600 Received: from imryr.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id u1OGmwin009536; Wed, 24 Feb 2016 10:49:31 -0600 From: Jyri Sarha To: Subject: [PATCH v4 16/22] drm/tilcdc: Do not update the next frame buffer close to vertical blank Date: Wed, 24 Feb 2016 18:48:50 +0200 Message-ID: <722ee4172bdd130d19ea3f727a4fa29a90329441.1456331965.git.jsarha@ti.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: References: MIME-Version: 1.0 Cc: Jyri Sarha , tomi.valkeinen@ti.com, laurent.pinchart@ideasonboard.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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 From: Tomi Valkeinen Do not update the next frame buffer close to vertical blank. This is to avoid situation when the frame changes between writing of LCDC_DMA_FB_BASE_ADDR_0_REG and LCDC_DMA_FB_CEILING_ADDR_0_REG. Signed-off-by: Tomi Valkeinen [Added description to the patch] Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 61 +++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 32572285..b1df046 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -21,6 +21,8 @@ #include "tilcdc_drv.h" #include "tilcdc_regs.h" +#define TILCDC_VBLANK_SAFETY_THRESHOLD_US 1000 + struct tilcdc_crtc { struct drm_crtc base; @@ -29,8 +31,12 @@ struct tilcdc_crtc { int dpms; wait_queue_head_t frame_done_wq; bool frame_done; + spinlock_t irq_lock; + + ktime_t last_vblank; struct drm_framebuffer *curr_fb; + struct drm_framebuffer *next_fb; /* for deferred fb unref's: */ struct drm_flip_work unref_work; @@ -146,6 +152,8 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; int r; unsigned long flags; + s64 tdiff; + ktime_t next_vblank; r = tilcdc_verify_fb(crtc, fb); if (r) @@ -162,12 +170,21 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, pm_runtime_get_sync(dev->dev); + spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags); + + next_vblank = ktime_add_us(tilcdc_crtc->last_vblank, + 1000000 / crtc->hwmode.vrefresh); - set_scanout(crtc, fb); + tdiff = ktime_to_us(ktime_sub(next_vblank, ktime_get())); + + if (tdiff >= TILCDC_VBLANK_SAFETY_THRESHOLD_US) + set_scanout(crtc, fb); + else + tilcdc_crtc->next_fb = fb; - spin_lock_irqsave(&dev->event_lock, flags); tilcdc_crtc->event = event; - spin_unlock_irqrestore(&dev->event_lock, flags); + + spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags); pm_runtime_put_sync(dev->dev); @@ -211,6 +228,12 @@ void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) pm_runtime_put_sync(dev->dev); + if (tilcdc_crtc->next_fb) { + drm_flip_work_queue(&tilcdc_crtc->unref_work, + tilcdc_crtc->next_fb); + tilcdc_crtc->next_fb = NULL; + } + if (tilcdc_crtc->curr_fb) { drm_flip_work_queue(&tilcdc_crtc->unref_work, tilcdc_crtc->curr_fb); @@ -651,19 +674,39 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) if (stat & LCDC_END_OF_FRAME0) { unsigned long flags; + bool skip_event = false; + ktime_t now; + + now = ktime_get(); drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq); + spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags); + + tilcdc_crtc->last_vblank = now; + + if (tilcdc_crtc->next_fb) { + set_scanout(crtc, tilcdc_crtc->next_fb); + tilcdc_crtc->next_fb = NULL; + skip_event = true; + } + + spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags); + drm_handle_vblank(dev, 0); - spin_lock_irqsave(&dev->event_lock, flags); + if (!skip_event) { + struct drm_pending_vblank_event *event; - if (tilcdc_crtc->event) { - drm_send_vblank_event(dev, 0, tilcdc_crtc->event); + spin_lock_irqsave(&dev->event_lock, flags); + + event = tilcdc_crtc->event; tilcdc_crtc->event = NULL; - } + if (event) + drm_send_vblank_event(dev, 0, event); - spin_unlock_irqrestore(&dev->event_lock, flags); + spin_unlock_irqrestore(&dev->event_lock, flags); + } } if (priv->rev == 2) { @@ -697,6 +740,8 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) drm_flip_work_init(&tilcdc_crtc->unref_work, "unref", unref_worker); + spin_lock_init(&tilcdc_crtc->irq_lock); + ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs); if (ret < 0) goto fail;