From patchwork Wed Feb 22 16:05:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrzej Hajda X-Patchwork-Id: 9587079 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9F681600CA for ; Wed, 22 Feb 2017 16:05:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8D3BE28678 for ; Wed, 22 Feb 2017 16:05:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 81C2928683; Wed, 22 Feb 2017 16:05:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F3EFC28678 for ; Wed, 22 Feb 2017 16:05:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754685AbdBVQFX (ORCPT ); Wed, 22 Feb 2017 11:05:23 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:63980 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754749AbdBVQFV (ORCPT ); Wed, 22 Feb 2017 11:05:21 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OLS00BVTA0URD80@mailout1.w1.samsung.com> for linux-samsung-soc@vger.kernel.org; Wed, 22 Feb 2017 16:05:18 +0000 (GMT) Received: from eusmges4.samsung.com (unknown [203.254.199.244]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20170222160517eucas1p28624779d54fbc11c4de21cffeb34dcef~lp5a6MDG82599125991eucas1p2N; Wed, 22 Feb 2017 16:05:17 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges4.samsung.com (EUCPMTA) with SMTP id E8.12.28517.DB6BDA85; Wed, 22 Feb 2017 16:05:17 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20170222160516eucas1p102bcb93b7f0356cfafbb707987b9e85f~lp5aKYhtK0644906449eucas1p1R; Wed, 22 Feb 2017 16:05:16 +0000 (GMT) X-AuditID: cbfec7f4-f79716d000006f65-5a-58adb6bd788f Received: from eusync3.samsung.com ( [203.254.199.213]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 76.9A.10233.3C6BDA85; Wed, 22 Feb 2017 16:05:23 +0000 (GMT) Received: from AMDC2768.DIGITAL.local ([106.120.43.17]) by eusync3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OLS00IUKA0QUK20@eusync3.samsung.com>; Wed, 22 Feb 2017 16:05:16 +0000 (GMT) From: Andrzej Hajda To: Inki Dae Cc: Andrzej Hajda , Bartlomiej Zolnierkiewicz , Marek Szyprowski , dri-devel@lists.freedesktop.org, linux-samsung-soc@vger.kernel.org, Krzysztof Kozlowski , Javier Martinez Canillas Subject: [PATCH 3/4] drm/exynos/decon5433: fix vblank event handling Date: Wed, 22 Feb 2017 17:05:04 +0100 Message-id: <1487779505-4062-4-git-send-email-a.hajda@samsung.com> X-Mailer: git-send-email 2.7.4 In-reply-to: <1487779505-4062-1-git-send-email-a.hajda@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrPIsWRmVeSWpSXmKPExsWy7djP87p7t62NMFj3Ttri1rpzrBYbZ6xn tbjy9T2bxaT7E1gs3rxdw2Rx/vwGdosZ5/cxWaw9cpfdgcNj06pONo/73ceZPLb032X36Nuy itHj8ya5ANYoLpuU1JzMstQifbsErowJr/+yFTzVqJh17RB7A+MaxS5GTg4JAROJ/qVfWCBs MYkL99azdTFycQgJLGWUWPn+HyuE85lR4tWjTmaYjktnGqESyxglmn4cgmr5zyjxceFLRpAq NgFNib+bb7KB2CICyhKr9rWzgxQxC2xgkrg5+zlQEQeHsICLxKOJtiA1LAKqEtPWnwPbwCvg JPHqyVMmiG1yEjfPgWzm4OAUcJZYdNESZIyEwH82iduHH4DFJQRkJTYdgDrORWLDtp2MELaw xKvjW9ghbBmJy5O7WSB6uxklPvWfYIdwpjBK/PswA6rbWuLw8YusIDazAJ/EpG3ToRbwSnS0 CUGUeEgc/DIdGl6OEk8nvWCCeH4ao8SpptmMExhlFjAyrGIUSS0tzk1PLTbRK07MLS7NS9dL zs/dxAiM5tP/jn/Zwbj4mNUhRgEORiUe3gOL1kYIsSaWFVfmHmKU4GBWEuH9vxgoxJuSWFmV WpQfX1Sak1p8iFGag0VJnHfPgivhQgLpiSWp2ampBalFMFkmDk6pBsbOy3t2GP+XCKzmWRKe YuMVee5U7X3ePSYW3Y5xVS2KSw942NQ+yTji/nJtzIK1LTzVMgYCqdlfw7nqhdWvrpiYbF6X tC7X6s40pZr1fOzxy+b/adT627PjgdX6A5ovFqfKSZ7VjHxn1Sh7eWqmrvZvDQfdhHfvzn6Y p3NvrzSPV4GZ/kPhxUosxRmJhlrMRcWJACFJqz3iAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrLLMWRmVeSWpSXmKPExsVy+t/xq7qHt62NMLj1l8ni1rpzrBYbZ6xn tbjy9T2bxaT7E1gs3rxdw2Rx/vwGdosZ5/cxWaw9cpfdgcNj06pONo/73ceZPLb032X36Nuy itHj8ya5ANYoN5uM1MSU1CKF1Lzk/JTMvHRbpdAQN10LJYW8xNxUW6UIXd+QICWFssScUiDP yAANODgHuAcr6dsluGVMeP2XreCpRsWsa4fYGxjXKHYxcnJICJhIXDrTyAphi0lcuLeerYuR i0NIYAmjxNw385kgnEYmia47J5hAqtgENCX+br7JBmKLCChLrNrXzg5SxCywgUnibt9JoFEc HMICLhKPJtqC1LAIqEpMW3+OGcTmFXCSePXkKRPENjmJm+c6mUHKOQWcJRZdtAQJCwGVvJ61 lH0CI+8CRoZVjCKppcW56bnFRnrFibnFpXnpesn5uZsYgUG97djPLTsYu94FH2IU4GBU4uE9 sGhthBBrYllxZe4hRgkOZiUR3v+LgUK8KYmVValF+fFFpTmpxYcYTYFumsgsJZqcD4y4vJJ4 QxNDc0tDI2MLC3MjIyVx3qkfroQLCaQnlqRmp6YWpBbB9DFxcEo1MAqwHDvfxib8Nypu53Qt HnFG3+UlvZv9G15+XVfEGTSjZ30dbxZ/ZuBpzvOtS5a/XXZIsmP6556Ll3n2sS1/mGH07Lbb y8O7Q+7/Nzup/XORTMsX+eUKF5Nn/1mwhkGS4ZnQgqQDPW+vRvp3JG43nb7nScq6erlFrP8e f9d/PetdzP2T39R38TIosRRnJBpqMRcVJwIAzOWQ2YACAAA= X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170222160516eucas1p102bcb93b7f0356cfafbb707987b9e85f X-Msg-Generator: CA X-Sender-IP: 182.198.249.180 X-Local-Sender: =?UTF-8?B?QW5kcnplaiBIYWpkYRtTUlBPTC1LZXJuZWwgKFRQKRvsgrw=?= =?UTF-8?B?7ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?UTF-8?B?QW5kcnplaiBIYWpkYRtTUlBPTC1LZXJuZWwgKFRQKRtTYW1z?= =?UTF-8?B?dW5nIEVsZWN0cm9uaWNzG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Sender-Code: =?UTF-8?B?QzEwG0VIURtDMTBDRDAyQ0QwMjczOTI=?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20170222160516eucas1p102bcb93b7f0356cfafbb707987b9e85f X-RootMTR: 20170222160516eucas1p102bcb93b7f0356cfafbb707987b9e85f References: <1487779505-4062-1-git-send-email-a.hajda@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Current implementation of event handling assumes that vblank interrupt is always called at the right time. It is not true, it can be delayed due to various reasons. As a result different races can happen. The patch fixes the issue by using hardware frame counter present in DECON to serialize vblank and commit completion events. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 62 +++++++++++++++++++++++++-- include/video/exynos5433_decon.h | 9 ++++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 147911e..bfa9396 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -68,6 +68,8 @@ struct decon_context { unsigned long flags; unsigned long out_type; int first_win; + spinlock_t vblank_lock; + u32 frame_id; }; static const uint32_t decon_formats[] = { @@ -365,25 +367,32 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, static void decon_atomic_flush(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = crtc->ctx; + unsigned long flags; int i; if (test_bit(BIT_SUSPENDED, &ctx->flags)) return; + spin_lock_irqsave(&ctx->vblank_lock, flags); + for (i = ctx->first_win; i < WINDOWS_NR; i++) decon_shadow_protect_win(ctx, i, false); + if (ctx->out_type & IFTYPE_I80) + set_bit(BIT_WIN_UPDATED, &ctx->flags); + if (test_and_clear_bit(BIT_REQUEST_UPDATE, &ctx->flags)) decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); - if (ctx->out_type & IFTYPE_I80) - set_bit(BIT_WIN_UPDATED, &ctx->flags); - exynos_crtc_handle_event(crtc); + exynos_crtc_handle_event(ctx->crtc); + + spin_unlock_irqrestore(&ctx->vblank_lock, flags); } static void decon_swreset(struct decon_context *ctx) { unsigned int tries; + unsigned long flags; writel(0, ctx->addr + DECON_VIDCON0); for (tries = 2000; tries; --tries) { @@ -401,6 +410,10 @@ static void decon_swreset(struct decon_context *ctx) WARN(tries == 0, "failed to software reset DECON\n"); + spin_lock_irqsave(&ctx->vblank_lock, flags); + ctx->frame_id = 0; + spin_unlock_irqrestore(&ctx->vblank_lock, flags); + if (!(ctx->out_type & IFTYPE_HDMI)) return; @@ -579,6 +592,46 @@ static const struct component_ops decon_component_ops = { .unbind = decon_unbind, }; +static void decon_handle_vblank(struct decon_context *ctx) +{ + u32 frm, pfrm, status, cnt; + + spin_lock(&ctx->vblank_lock); + + /* To get consistent result repeat read until frame id is stable. */ + frm = readl(ctx->addr + DECON_CRFMID); + cnt = 3; + do { + status = readl(ctx->addr + DECON_VIDCON1); + pfrm = frm; + frm = readl(ctx->addr + DECON_CRFMID); + } while (frm != pfrm && --cnt); + + status &= VIDCON1_VSTATUS_MASK | VIDCON1_I80_ACTIVE; + + /* In case of delayed vblank CRFMID could be already incremented, + * it should be taken into account. + */ + if (frm > 0) + switch (status) { + case VIDCON1_VSTATUS_VS: + if (ctx->out_type & IFTYPE_I80) + break; + case VIDCON1_I80_ACTIVE: + case VIDCON1_VSTATUS_BP: + case VIDCON1_VSTATUS_AC: + --frm; + } + + if (frm != ctx->frame_id) { + if (frm > ctx->frame_id) + drm_crtc_handle_vblank(&ctx->crtc->base); + ctx->frame_id = frm; + } + + spin_unlock(&ctx->vblank_lock); +} + static irqreturn_t decon_irq_handler(int irq, void *dev_id) { struct decon_context *ctx = dev_id; @@ -599,7 +652,7 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id) (VIDOUT_INTERLACE_EN_F | VIDOUT_INTERLACE_FIELD_F)) return IRQ_HANDLED; } - drm_crtc_handle_vblank(&ctx->crtc->base); + decon_handle_vblank(ctx); } out: @@ -672,6 +725,7 @@ static int exynos5433_decon_probe(struct platform_device *pdev) __set_bit(BIT_SUSPENDED, &ctx->flags); ctx->dev = dev; ctx->out_type = (unsigned long)of_device_get_match_data(dev); + spin_lock_init(&ctx->vblank_lock); if (ctx->out_type & IFTYPE_HDMI) { ctx->first_win = 1; diff --git a/include/video/exynos5433_decon.h b/include/video/exynos5433_decon.h index ef8e2a8..beefc62 100644 --- a/include/video/exynos5433_decon.h +++ b/include/video/exynos5433_decon.h @@ -46,6 +46,8 @@ #define DECON_FRAMEFIFO_STATUS 0x0524 #define DECON_CMU 0x1404 #define DECON_UPDATE 0x1410 +#define DECON_CRFMID 0x1414 +#define DECON_RRFRMID 0x1418 #define DECON_UPDATE_SCHEME 0x1438 #define DECON_VIDCON1 0x2000 #define DECON_VIDCON2 0x2004 @@ -142,6 +144,13 @@ #define STANDALONE_UPDATE_F (1 << 0) /* DECON_VIDCON1 */ +#define VIDCON1_LINECNT_MASK (0x0fff << 16) +#define VIDCON1_I80_ACTIVE (1 << 15) +#define VIDCON1_VSTATUS_MASK (0x3 << 13) +#define VIDCON1_VSTATUS_VS (0 << 13) +#define VIDCON1_VSTATUS_BP (1 << 13) +#define VIDCON1_VSTATUS_AC (2 << 13) +#define VIDCON1_VSTATUS_FP (3 << 13) #define VIDCON1_VCLK_MASK (0x3 << 9) #define VIDCON1_VCLK_RUN_VDEN_DISABLE (0x3 << 9) #define VIDCON1_VCLK_HOLD (0x0 << 9)