From patchwork Thu Aug 20 02:33:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hyungwon Hwang X-Patchwork-Id: 7040391 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 A936AC05AC for ; Thu, 20 Aug 2015 02:33:48 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7040220780 for ; Thu, 20 Aug 2015 02:33:47 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 1EB86207C4 for ; Thu, 20 Aug 2015 02:33:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 712816EC67; Wed, 19 Aug 2015 19:33:44 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout3.samsung.com (mailout3.samsung.com [203.254.224.33]) by gabe.freedesktop.org (Postfix) with ESMTPS id 754396E28D for ; Wed, 19 Aug 2015 19:33:42 -0700 (PDT) Received: from epcpsbgr3.samsung.com (u143.gpu120.samsung.co.kr [203.254.230.143]) by mailout3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0NTD005QW0G3AI70@mailout3.samsung.com> for dri-devel@lists.freedesktop.org; Thu, 20 Aug 2015 11:33:39 +0900 (KST) Received: from epcpsbgm1new.samsung.com ( [172.20.52.114]) by epcpsbgr3.samsung.com (EPCPMTA) with SMTP id 49.40.24422.38C35D55; Thu, 20 Aug 2015 11:33:39 +0900 (KST) X-AuditID: cbfee68f-f793b6d000005f66-bd-55d53c83cce9 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1new.samsung.com (EPCPMTA) with SMTP id 38.4F.23663.38C35D55; Thu, 20 Aug 2015 11:33:39 +0900 (KST) Received: from localhost.localdomain.localdomain ([10.252.82.145]) by mmp1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0NTD006CE0FTMVC0@mmp1.samsung.com>; Thu, 20 Aug 2015 11:33:39 +0900 (KST) From: Hyungwon Hwang To: dri-devel@lists.freedesktop.org Subject: [PATCH 2/2] drm/exynos: implement atomic_{begin/flush} of FIMD and DECON Date: Thu, 20 Aug 2015 11:33:27 +0900 Message-id: <1440038007-32192-2-git-send-email-human.hwang@samsung.com> X-Mailer: git-send-email 2.4.3 In-reply-to: <1440038007-32192-1-git-send-email-human.hwang@samsung.com> References: <1440038007-32192-1-git-send-email-human.hwang@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrELMWRmVeSWpSXmKPExsWyRsSkSLfZ5mqowdwOdYsrX9+zWSyd0cdq Men+BBaLF/cusljMmPySzYHV4373cSaPvi2rGAOYorhsUlJzMstSi/TtErgynt3cxl7QGVFx a/Z59gbG2R5djJwcEgImEn09HYwQtpjEhXvr2boYuTiEBFYwSjSf62KHKVpy9hIzRGIpo8Tv xvVMEE4bk8Snq+fA2tkE9CQWXPsB1iEioCzxd+IqsDizQKnEnfmLgbo5OIQFgiX6f6qAmCwC qhKTLuWCVPAKuEtMfLYBapecxLn1X1hAbE4BD4l/U9vA4kJANdNft7OCrJUQ+M0msfrwFDaQ BIuAgMS3yYdYQGZKCMhKbDrADDFHUuLgihssExiFFzAyrGIUTS1ILihOSi8y1itOzC0uzUvX S87P3cQIDNrT/57172C8e8D6EKMAB6MSD+8F4auhQqyJZcWVuYcYTYE2TGSWEk3OB8ZGXkm8 obGZkYWpiamxkbmlmZI470Kpn8FCAumJJanZqakFqUXxRaU5qcWHGJk4OKUaGKujBRxvLFX8 xbe+9+D1yeFsP+53VNaWrxLxPHli2oHGFdY1vidW3f1y7m6iAPuGYJ7JOyNk73V8/pChyK16 0a5o4+HpyY+01ELTBdb07xQTVBMu0vm3w9FGkEH22jK1o8rT1otxLRCR0r98Y49s/dqmnz1z toRkrf35ljvFUbMmJTsqRzNrrxJLcUaioRZzUXEiAA1+8gBVAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupnkeLIzCtJLcpLzFFi42I5/e+xgG6zzdVQg/1nFCyufH3PZrF0Rh+r xaT7E1gsXty7yGIxY/JLNgdWj/vdx5k8+rasYgxgimpgtMlITUxJLVJIzUvOT8nMS7dV8g6O d443NTMw1DW0tDBXUshLzE21VXLxCdB1y8wB2qekUJaYUwoUCkgsLlbSt8M0ITTETdcCpjFC 1zckCK7HyAANJKxhzHh2cxt7QWdExa3Z59kbGGd7dDFyckgImEgsOXuJGcIWk7hwbz1bFyMX h5DAUkaJ343rmSCcNiaJT1fPMYJUsQnoSSy49oMdxBYRUJb4O3EVWJxZoFTizvzFQJM4OIQF giX6f6qAmCwCqhKTLuWCVPAKuEtMfLaBHWKXnMS59V9YQGxOAQ+Jf1PbwOJCQDXTX7ezTmDk XcDIsIpRIrUguaA4KT3XMC+1XK84Mbe4NC9dLzk/dxMjODKeSe1gPLjL/RCjAAejEg/vBeGr oUKsiWXFlbmHGCU4mJVEeP10gEK8KYmVValF+fFFpTmpxYcYTYHumsgsJZqcD4zavJJ4Q2MT MyNLI3NDCyNjcyVxXtkNm0OFBNITS1KzU1MLUotg+pg4OKUaGDnVbudMe/6RzfPBD9eVZakq VzKZ9iuf1px2WfHodS7540uZmvd+mrtSUMLG0ybjyNuVGyVdouokL9YkRCoW9h6s7jj+Vmnu 0r/T1Zkyzy+7+2yqYdjk1ladfI78w85MaQ9uJQQL+lvLJB8PnjPxwelvkfOnnfjKUbd1704r 9xflb9r3Ob0KmqTEUpyRaKjFXFScCACTJhL2ogIAAA== DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Cc: sw0312.kim@samsung.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: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.8 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 Each CRTC's atomic_{begin/flush} must stop/start the update of shadow registers to active register in the functions. This patch achieves these purpose by moving the setting of protection bits to those functions from {fimd/decon}_update_plane. Signed-off-by: Hyungwon Hwang --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 47 +++++++++++++++++------- drivers/gpu/drm/exynos/exynos7_drm_decon.c | 47 ++++++++++++++++-------- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 51 ++++++++++++++++++--------- 3 files changed, 103 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 484e312..fef0333 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -31,6 +31,7 @@ struct decon_context { struct drm_device *drm_dev; struct exynos_drm_crtc *crtc; struct exynos_drm_plane planes[WINDOWS_NR]; + unsigned int updated_plane; void __iomem *addr; struct clk *clks[6]; unsigned int default_win; @@ -204,17 +205,17 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, writel(val, ctx->addr + DECON_WINCONx(win)); } -static void decon_shadow_protect_win(struct decon_context *ctx, int win, - bool protect) +static void decon_shadow_protect_win(struct decon_context *ctx, + unsigned int win_bits, bool protect) { u32 val; val = readl(ctx->addr + DECON_SHADOWCON); if (protect) - val |= SHADOWCON_Wx_PROTECT(win); + val |= win_bits; else - val &= ~SHADOWCON_Wx_PROTECT(win); + val &= ~win_bits; writel(val, ctx->addr + DECON_SHADOWCON); } @@ -232,8 +233,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, if (ctx->suspended) return; - decon_shadow_protect_win(ctx, win, true); - val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y); writel(val, ctx->addr + DECON_VIDOSDxA(win)); @@ -265,15 +264,12 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, val |= WINCONx_ENWIN_F; writel(val, ctx->addr + DECON_WINCONx(win)); - decon_shadow_protect_win(ctx, win, false); - /* standalone update */ val = readl(ctx->addr + DECON_UPDATE); val |= STANDALONE_UPDATE_F; writel(val, ctx->addr + DECON_UPDATE); - if (ctx->i80_if) - atomic_set(&ctx->win_updated, 1); + ctx->updated_plane |= SHADOWCON_Wx_PROTECT(win); } static void decon_disable_plane(struct exynos_drm_crtc *crtc, @@ -286,14 +282,14 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, if (ctx->suspended) return; - decon_shadow_protect_win(ctx, win, true); + decon_shadow_protect_win(ctx, SHADOWCON_Wx_PROTECT(win), true); /* window disable */ val = readl(ctx->addr + DECON_WINCONx(win)); val &= ~WINCONx_ENWIN_F; writel(val, ctx->addr + DECON_WINCONx(win)); - decon_shadow_protect_win(ctx, win, false); + decon_shadow_protect_win(ctx, SHADOWCON_Wx_PROTECT(win), false); /* standalone update */ val = readl(ctx->addr + DECON_UPDATE); @@ -405,6 +401,31 @@ void decon_te_irq_handler(struct exynos_drm_crtc *crtc) drm_crtc_handle_vblank(&ctx->crtc->base); } +static void decon_begin(struct exynos_drm_crtc *crtc) +{ + struct decon_context *ctx = crtc->ctx; + int i; + unsigned int val = 0; + + for (i = 0; i < WINDOWS_NR; i++) + val |= SHADOWCON_Wx_PROTECT(i); + + /* protect windows */ + decon_shadow_protect_win(ctx, val, true); +} + +static void decon_flush(struct exynos_drm_crtc *crtc) +{ + struct decon_context *ctx = crtc->ctx; + + if (ctx->updated_plane) { + decon_shadow_protect_win(ctx, ctx->updated_plane, false); + + if (ctx->i80_if) + atomic_set(&ctx->win_updated, 1); + } +} + static void decon_clear_channels(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = crtc->ctx; @@ -458,6 +479,8 @@ static struct exynos_drm_crtc_ops decon_crtc_ops = { .update_plane = decon_update_plane, .disable_plane = decon_disable_plane, .te_handler = decon_te_irq_handler, + .atomic_begin = decon_begin, + .atomic_flush = decon_flush, }; static int decon_bind(struct device *dev, struct device *master, void *data) diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 0792654..c81de86 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -47,6 +47,7 @@ struct decon_context { struct drm_device *drm_dev; struct exynos_drm_crtc *crtc; struct exynos_drm_plane planes[WINDOWS_NR]; + unsigned int updated_plane; struct clk *pclk; struct clk *aclk; struct clk *eclk; @@ -369,17 +370,15 @@ static void decon_win_set_colkey(struct decon_context *ctx, unsigned int win) * @protect: 1 to protect (disable updates) */ static void decon_shadow_protect_win(struct decon_context *ctx, - unsigned int win, bool protect) + unsigned int win_bits, bool protect) { - u32 bits, val; - - bits = SHADOWCON_WINx_PROTECT(win); + u32 val; val = readl(ctx->regs + SHADOWCON); if (protect) - val |= bits; + val |= win_bits; else - val &= ~bits; + val &= ~win_bits; writel(val, ctx->regs + SHADOWCON); } @@ -410,9 +409,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, * is set. */ - /* protect windows */ - decon_shadow_protect_win(ctx, win, true); - /* buffer start address */ val = (unsigned long)plane->dma_addr[0]; writel(val, ctx->regs + VIDW_BUF_START(win)); @@ -484,12 +480,11 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, val |= WINCONx_ENWIN; writel(val, ctx->regs + WINCON(win)); - /* Enable DMA channel and unprotect windows */ - decon_shadow_protect_win(ctx, win, false); - val = readl(ctx->regs + DECON_UPDATE); val |= DECON_UPDATE_STANDALONE_F; writel(val, ctx->regs + DECON_UPDATE); + + ctx->updated_plane |= SHADOWCON_WINx_PROTECT(win); } static void decon_disable_plane(struct exynos_drm_crtc *crtc, @@ -503,7 +498,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, return; /* protect windows */ - decon_shadow_protect_win(ctx, win, true); + decon_shadow_protect_win(ctx, SHADOWCON_WINx_PROTECT(win), true); /* wincon */ val = readl(ctx->regs + WINCON(win)); @@ -511,7 +506,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, writel(val, ctx->regs + WINCON(win)); /* unprotect windows */ - decon_shadow_protect_win(ctx, win, false); + decon_shadow_protect_win(ctx, SHADOWCON_WINx_PROTECT(win), false); val = readl(ctx->regs + DECON_UPDATE); val |= DECON_UPDATE_STANDALONE_F; @@ -606,6 +601,28 @@ static void decon_disable(struct exynos_drm_crtc *crtc) ctx->suspended = true; } +static void decon_begin(struct exynos_drm_crtc *crtc) +{ + struct decon_context *ctx = crtc->ctx; + int i; + unsigned int val = 0; + + for (i = 0; i < WINDOWS_NR; i++) + val |= SHADOWCON_WINx_PROTECT(i); + + /* protect windows */ + decon_shadow_protect_win(ctx, val, true); +} + +static void decon_flush(struct exynos_drm_crtc *crtc) +{ + struct decon_context *ctx = crtc->ctx; + + if (ctx->updated_plane) + decon_shadow_protect_win(ctx, ctx->updated_plane, false); +} + + static const struct exynos_drm_crtc_ops decon_crtc_ops = { .enable = decon_enable, .disable = decon_disable, @@ -616,6 +633,8 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = { .wait_for_vblank = decon_wait_for_vblank, .update_plane = decon_update_plane, .disable_plane = decon_disable_plane, + .atomic_begin = decon_begin, + .atomic_flush = decon_flush, }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 5def6bc..0b41bb2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -149,6 +149,7 @@ struct fimd_context { struct drm_device *drm_dev; struct exynos_drm_crtc *crtc; struct exynos_drm_plane planes[WINDOWS_NR]; + unsigned int updated_plane; struct clk *bus_clk; struct clk *lcd_clk; void __iomem *regs; @@ -587,23 +588,22 @@ static void fimd_win_set_colkey(struct fimd_context *ctx, unsigned int win) * @protect: 1 to protect (disable updates) */ static void fimd_shadow_protect_win(struct fimd_context *ctx, - unsigned int win, bool protect) + unsigned int win_bits, bool protect) { - u32 reg, bits, val; + u32 reg, val; if (ctx->driver_data->has_shadowcon) { reg = SHADOWCON; - bits = SHADOWCON_WINx_PROTECT(win); } else { reg = PRTCON; - bits = PRTCON_PROTECT; + win_bits = PRTCON_PROTECT; } val = readl(ctx->regs + reg); if (protect) - val |= bits; + val |= win_bits; else - val &= ~bits; + val &= ~win_bits; writel(val, ctx->regs + reg); } @@ -632,10 +632,6 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, * is set. */ - /* protect windows */ - fimd_shadow_protect_win(ctx, win, true); - - offset = plane->src_x * bpp; offset += plane->src_y * pitch; @@ -707,11 +703,32 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, if (ctx->driver_data->has_shadowcon) fimd_enable_shadow_channel_path(ctx, win, true); - /* Enable DMA channel and unprotect windows */ - fimd_shadow_protect_win(ctx, win, false); + ctx->updated_plane |= SHADOWCON_WINx_PROTECT(win); +} + +static void fimd_begin(struct exynos_drm_crtc *crtc) +{ + struct fimd_context *ctx = crtc->ctx; + int i; + unsigned int val = 0; + + for (i = 0; i < WINDOWS_NR; i++) + val |= SHADOWCON_WINx_PROTECT(i); - if (ctx->i80_if) - atomic_set(&ctx->win_updated, 1); + /* protect windows */ + fimd_shadow_protect_win(ctx, val, true); +} + +static void fimd_flush(struct exynos_drm_crtc *crtc) +{ + struct fimd_context *ctx = crtc->ctx; + + if (ctx->updated_plane) { + fimd_shadow_protect_win(ctx, ctx->updated_plane, false); + + if (ctx->i80_if) + atomic_set(&ctx->win_updated, 1); + } } static void fimd_disable_plane(struct exynos_drm_crtc *crtc, @@ -724,7 +741,7 @@ static void fimd_disable_plane(struct exynos_drm_crtc *crtc, return; /* protect windows */ - fimd_shadow_protect_win(ctx, win, true); + fimd_shadow_protect_win(ctx, SHADOWCON_WINx_PROTECT(win), true); fimd_enable_video_output(ctx, win, false); @@ -732,7 +749,7 @@ static void fimd_disable_plane(struct exynos_drm_crtc *crtc, fimd_enable_shadow_channel_path(ctx, win, false); /* unprotect windows */ - fimd_shadow_protect_win(ctx, win, false); + fimd_shadow_protect_win(ctx, SHADOWCON_WINx_PROTECT(win), false); } static void fimd_enable(struct exynos_drm_crtc *crtc) @@ -879,6 +896,8 @@ static const struct exynos_drm_crtc_ops fimd_crtc_ops = { .disable_plane = fimd_disable_plane, .te_handler = fimd_te_handler, .clock_enable = fimd_dp_clock_enable, + .atomic_begin = fimd_begin, + .atomic_flush = fimd_flush, }; static irqreturn_t fimd_irq_handler(int irq, void *dev_id)