From patchwork Tue Dec 15 19:03:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jyri Sarha X-Patchwork-Id: 58455 Delivered-To: patch@linaro.org Received: by 10.112.89.199 with SMTP id bq7csp233660lbb; Tue, 15 Dec 2015 11:04:09 -0800 (PST) X-Received: by 10.66.158.193 with SMTP id ww1mr27612084pab.21.1450206242542; Tue, 15 Dec 2015 11:04:02 -0800 (PST) Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTP id b3si3471295pas.71.2015.12.15.11.04.02; Tue, 15 Dec 2015 11:04:02 -0800 (PST) Received-SPF: pass (google.com: domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; spf=pass (google.com: domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7910672030; Tue, 15 Dec 2015 11:04:01 -0800 (PST) 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 7910D72030 for ; Tue, 15 Dec 2015 11:04:00 -0800 (PST) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id tBFJ3vPh024987; Tue, 15 Dec 2015 13:03:57 -0600 Received: from DLEE70.ent.ti.com (dlemailx.itg.ti.com [157.170.170.113]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id tBFJ3voB028035; Tue, 15 Dec 2015 13:03:57 -0600 Received: from dlep32.itg.ti.com (157.170.170.100) by DLEE70.ent.ti.com (157.170.170.113) with Microsoft SMTP Server id 14.3.224.2; Tue, 15 Dec 2015 13:03:56 -0600 Received: from imryr.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id tBFJ3bb0015462; Tue, 15 Dec 2015 13:03:55 -0600 From: Jyri Sarha To: Subject: [PATCH 08/12] drm/tilcdc: fix the ping-pong dma tearing issue seen on buffer flipping Date: Tue, 15 Dec 2015 21:03:19 +0200 Message-ID: X-Mailer: git-send-email 1.9.1 In-Reply-To: References: MIME-Version: 1.0 Cc: Jyri Sarha , Darren Etheridge , 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" From: Darren Etheridge Update the DMA pointers during the pan display ioctl. Borrowed from da8xx_fb.c update the scanout buffers immediately so the DMA ping/pong doesn't end up out of sync with what we really want it to DMA, otherwise part of the screen ends up tearing during rapid flip operations. Ported from commit deb95c6c958f ("video: da8xx-fb: fix flicker due to 1 frame delay in updated frame") Signed-off-by: Darren Etheridge [Rewrapped description and fixed commit reference] Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index cc45818..50384fa 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -31,6 +31,8 @@ struct tilcdc_crtc { int dpms; wait_queue_head_t frame_done_wq; bool frame_done; + spinlock_t irq_lock; + int dma_completed_channel; /* fb currently set to scanout 0/1: */ struct drm_framebuffer *scanout[2]; @@ -102,10 +104,23 @@ static void update_scanout(struct drm_crtc *crtc) (crtc->mode.vdisplay * fb->pitches[0]); if (tilcdc_crtc->dpms == DRM_MODE_DPMS_ON) { - /* already enabled, so just mark the frames that need - * updating and they will be updated on vblank: + /* + * already enabled, so just mark the frames that need + * updating and they will be updated on vblank + * and update the inactive DMA channel immediately + * to avoid any tearing due to the DMA already starting + * on the pending dma buffer when we hit the vblank IRQ */ - tilcdc_crtc->dirty |= LCDC_END_OF_FRAME0 | LCDC_END_OF_FRAME1; + if (tilcdc_crtc->dma_completed_channel == 0) { + tilcdc_crtc->dirty |= LCDC_END_OF_FRAME1; + set_scanout(crtc, 0); + } + + if (tilcdc_crtc->dma_completed_channel == 1) { + tilcdc_crtc->dirty |= LCDC_END_OF_FRAME0; + set_scanout(crtc, 1); + } + drm_vblank_get(dev, 0); } else { /* not enabled yet, so update registers immediately: */ @@ -647,6 +662,7 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; struct tilcdc_drm_private *priv = dev->dev_private; uint32_t stat = tilcdc_read_irqstatus(dev); + unsigned long irq_flags; if ((stat & LCDC_SYNC_LOST) && (stat & LCDC_FIFO_UNDERFLOW)) { stop(crtc); @@ -662,11 +678,19 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) tilcdc_clear_irqstatus(dev, stat); - if (dirty & LCDC_END_OF_FRAME0) + spin_lock_irqsave(&tilcdc_crtc->irq_lock, irq_flags); + + if (dirty & LCDC_END_OF_FRAME0) { set_scanout(crtc, 0); + tilcdc_crtc->dma_completed_channel = 0; + } - if (dirty & LCDC_END_OF_FRAME1) + if (dirty & LCDC_END_OF_FRAME1) { set_scanout(crtc, 1); + tilcdc_crtc->dma_completed_channel = 1; + } + + spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, irq_flags); drm_handle_vblank(dev, 0); @@ -732,6 +756,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;