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: 7856851 Return-Path: X-Original-To: patchwork-dri-devel@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 ED9149F349 for ; Tue, 15 Dec 2015 19:04:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0D128203E5 for ; Tue, 15 Dec 2015 19:04:04 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 4642A203C2 for ; Tue, 15 Dec 2015 19:04:02 +0000 (UTC) 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" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_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: 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;