From patchwork Thu May 17 02:44:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Inki Dae X-Patchwork-Id: 10405183 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 95F56601C8 for ; Thu, 17 May 2018 02:44:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 868832885C for ; Thu, 17 May 2018 02:44:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7B41728861; Thu, 17 May 2018 02:44:17 +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=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID 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 17CFC2885C for ; Thu, 17 May 2018 02:44:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751395AbeEQCoP (ORCPT ); Wed, 16 May 2018 22:44:15 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:20963 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751259AbeEQCoO (ORCPT ); Wed, 16 May 2018 22:44:14 -0400 Received: from epcas1p4.samsung.com (unknown [182.195.41.48]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20180517024412epoutp0323887d83dc4ad4f0631c4edd61ca43ca~vTnJ1pMJ62248022480epoutp03M; Thu, 17 May 2018 02:44:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20180517024412epoutp0323887d83dc4ad4f0631c4edd61ca43ca~vTnJ1pMJ62248022480epoutp03M DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1526525052; bh=8HRShQuKoAlrXBAisnJr9V3pfMKl7/2PGSY4KzP4Fuc=; h=From:To:Cc:Subject:Date:References:From; b=T8sxBzbM1Aeen9Nyy8wg2uzXgFFqQW/aogbhKHX82TEWM0tXcpzZX4+naaXDJOtxH fcKbz1WjG2Ci2rWNBGSAWf4Ub6q8oWl2KjSs1jHZIj+JAmyqut4tOIdmDZlc/M9Dpm RVFS59KqyxEK3Xc69OWvNHE4vehDnWNqweYJyMyk= Received: from epsmges2p1.samsung.com (unknown [182.195.40.153]) by epcas1p4.samsung.com (KnoxPortal) with ESMTP id 20180517024409epcas1p447edb57e721744b9a889a2fb4248a700~vTnHqSCFE0129201292epcas1p4n; Thu, 17 May 2018 02:44:09 +0000 (GMT) Received: from epcas2p2.samsung.com ( [182.195.41.54]) by epsmges2p1.samsung.com (Symantec Messaging Gateway) with SMTP id 1C.6E.04128.97CECFA5; Thu, 17 May 2018 11:44:09 +0900 (KST) Received: from epsmgms2p2new.samsung.com (unknown [182.195.42.143]) by epcas2p4.samsung.com (KnoxPortal) with ESMTP id 20180517024409epcas2p44999752365d9ec5590562ae81122af6c~vTnHMGO0g0349503495epcas2p4W; Thu, 17 May 2018 02:44:09 +0000 (GMT) X-AuditID: b6c32a45-8f3ff70000001020-57-5afcec797bf8 Received: from epmmp2 ( [203.254.227.17]) by epsmgms2p2new.samsung.com (Symantec Messaging Gateway) with SMTP id 42.A0.03817.97CECFA5; Thu, 17 May 2018 11:44:09 +0900 (KST) Received: from daeinki-desktop.tn.corp.samsungelectronics.net ([10.113.62.206]) by mmp2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0P8U00G0ZQ9LM820@mmp2.samsung.com>; Thu, 17 May 2018 11:44:09 +0900 (KST) From: Inki Dae To: dri-devel@lists.freedesktop.org Cc: linux-samsung-soc@vger.kernel.org, m.szyprowski@samsung.com, Inki Dae Subject: [PATCH] drm/exynos: ipp: fix image broken issue Date: Thu, 17 May 2018 11:44:07 +0900 Message-id: <1526525047-16924-1-git-send-email-inki.dae@samsung.com> X-Mailer: git-send-email 1.9.1 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpileLIzCtJLcpLzFFi42LZdljTTLfyzZ8og333jCyufH3PZjHp/gQW ixnn9zFZrD1yl92BxeN+93Emj74tqxg9Pm+SC2COSrXJSE1MSS1SSM1Lzk/JzEu3VfIOjneO NzUzMNQ1tLQwV1LIS8xNtVVy8QnQdcvMAdqmpFCWmFMKFApILC5W0rezKcovLUlVyMgvLrFV ijY0NNIzNDDXMzIC0saxVkamQCUJqRlX/51jKzhsVXHgRzdjA+M9/S5GTg4JAROJZ//+MXYx cnEICexglDg+qZUJwvnOKDF721UWmKoZsyaygdhCAhuAEltqIYomMklc/3qWHSTBJqAqMXHF fbAiEQFlib8TVzGC2MwCSRJvDqwHqxEWsJC41j+NFcRmAarftfAn2AJeAReJ1eu/MUIsk5M4 eWwyK8gCCYGzrBIPj64AKuIAclwknrQbQtQIS7w6voUdwpaWeLZqIyNEfTujxK6z19kgnB5G ieWLF0FVGUs8W9jFBHERn0TH4b/sEEN5JTrahCBKPCTmrJoG9bGjxMez55hASoQEYiVed9tO YJRcwMiwilEstaA4Nz212KjAUK84Mbe4NC9dLzk/dxMjOP61XHcwzjjnc4hRgINRiYdXwO5P lBBrYllxZe4hRgkOZiURXqFuoBBvSmJlVWpRfnxRaU5q8SFGU2BwTGSWEk3OB6amvJJ4Q1Mj Y2NjC1NzS2MDSyVx3jVKX6OEBNITS1KzU1MLUotg+pg4OKUaGD3a5lp8dHj+85rqPP98ma1G yoHHtSTfxWvd/u71aqGTV08Qy85NH1L0JskJsyxw4Pb49eSUSIeGqfRXb4cX9t/YF7gEbDwt FbEhdtGfOtuiLawf7dt3SO32sHNzZZBr5TEXampbuWpbgfYZ6SXZYv8Sc2Mk/HbtaXl4KmZy 168t203NylUNlViKMxINtZiLihMBKlCDfxUDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrNJMWRmVeSWpSXmKPExsVy+t9jQd3KN3+iDJ4uFbG48vU9m8Wk+xNY LGac38dksfbIXXYHFo/73ceZPPq2rGL0+LxJLoA5issmJTUnsyy1SN8ugSvj6r9zbAWHrSoO /OhmbGC8p9/FyMkhIWAiMWPWRLYuRi4OIYF1jBJ/Dn5ignAmM0nsOvGeFaSKTUBVYuKK+2wg toiAssTfiasYQWxmgSSJtsl/wGqEBSwkrvVPA7NZgOp3LfzJAmLzCrhIrF7/jRFim5zEyWOT WScwci1gZFjFKJlaUJybnltsVGCUl1quV5yYW1yal66XnJ+7iRHo5W2Htfp3MD5eEn+IUYCD UYmHV8DuT5QQa2JZcWXuIUYJDmYlEV6hbqAQb0piZVVqUX58UWlOavEhRmkOFiVxXv78Y5FC AumJJanZqakFqUUwWSYOTqkGRnfrX9tD/lhWv55y1vdw/pNF8ufXGsw5x/Gq61v44g+hCuE7 g98VRk+oMmpe0HenYJ5a4oIf6k+z1svUmpxYEbBg7lbl/1rLg8zqLn7cMDmhR2leoyX7+S+O 9s5zhSfO8VtueX+Wi5NUyW/pn5cnSytnvbm11/dBMOvhi+c+vPd8Z/WM4/jH07FKLMUZiYZa zEXFiQBwm62w7gEAAA== X-CMS-MailID: 20180517024409epcas2p44999752365d9ec5590562ae81122af6c X-Msg-Generator: CA CMS-TYPE: 102P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20180517024409epcas2p44999752365d9ec5590562ae81122af6c X-RootMTR: 20180517024409epcas2p44999752365d9ec5590562ae81122af6c References: 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 Fixed image broken issue while video play back with 854x480. GScaler device of Exynos5433 has IN_ID_MAX field in GSC_IN_CON register, which determines how much GScaler DMA has to drain data from system memory at once. Therefore, image size should be fixed up before IPP driver verifies whether gem buffer is enough for it or not. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 87 +++++++++++++++++++++++++++------ drivers/gpu/drm/exynos/exynos_drm_ipp.c | 15 ++++++ drivers/gpu/drm/exynos/exynos_drm_ipp.h | 12 +++++ 3 files changed, 100 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index e99dd1e..41cb82d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -86,6 +86,28 @@ struct gsc_scaler { unsigned long main_vratio; }; +/** + * struct gsc_driverdata - per device type driver data for init time. + * + * @limits: picture size limits array + * @clk_names: names of clocks needed by this variant + * @num_clocks: the number of clocks needed by this variant + * @has_in_ic_max: indicate whether GSCALER_IN_CON register has + * IN_IC_MAX field which means maxinum AXI + * read capability. + * @in_ic_max_shift: indicate which position IN_IC_MAX field is located. + * @in_ic_max_mask: A mask value to IN_IC_MAX field. + */ +struct gsc_driverdata { + const struct drm_exynos_ipp_limit *limits; + int num_limits; + const char *clk_names[GSC_MAX_CLOCKS]; + int num_clocks; + unsigned int has_in_ic_max:1; + unsigned int in_ic_max_shift; + unsigned int in_ic_max_mask; +}; + /* * A structure of gsc context. * @@ -96,6 +118,9 @@ struct gsc_scaler { * @id: gsc id. * @irq: irq number. * @rotation: supports rotation of src. + * @align_size: A size that GSC_SRCIMG_WIDTH value of GSC_SRCIMG_SIZE + * register should be aligned with(in byte). + * @driver_data: a pointer to gsc_driverdata. */ struct gsc_context { struct exynos_drm_ipp ipp; @@ -114,20 +139,8 @@ struct gsc_context { int id; int irq; bool rotation; -}; - -/** - * struct gsc_driverdata - per device type driver data for init time. - * - * @limits: picture size limits array - * @clk_names: names of clocks needed by this variant - * @num_clocks: the number of clocks needed by this variant - */ -struct gsc_driverdata { - const struct drm_exynos_ipp_limit *limits; - int num_limits; - const char *clk_names[GSC_MAX_CLOCKS]; - int num_clocks; + unsigned int align_size; + struct gsc_driverdata *driver_data; }; /* 8-tap Filter Coefficient */ @@ -1095,6 +1108,18 @@ static void gsc_start(struct gsc_context *ctx) gsc_write(cfg, GSC_ENABLE); } +static void gsc_fixup(struct exynos_drm_ipp *ipp, + struct exynos_drm_ipp_task *task) +{ + struct gsc_context *ctx = container_of(ipp, struct gsc_context, ipp); + struct exynos_drm_ipp_buffer *src = &task->src; + + if (!ctx->driver_data->has_in_ic_max) + return; + + src->buf.width = ALIGN(src->buf.width, ctx->align_size); +} + static int gsc_commit(struct exynos_drm_ipp *ipp, struct exynos_drm_ipp_task *task) { @@ -1124,6 +1149,32 @@ static int gsc_commit(struct exynos_drm_ipp *ipp, return 0; } +static void gsc_get_align_size(struct gsc_context *ctx) +{ + u32 cfg, mask, shift; + + mask = ctx->driver_data->in_ic_max_mask; + shift = ctx->driver_data->in_ic_max_shift; + + pm_runtime_get_sync(ctx->dev); + + cfg = gsc_read(GSC_IN_CON); + + cfg = (cfg & mask << shift) >> shift; + + if (cfg == 0) + ctx->align_size = 4; + else if (cfg == 1) + ctx->align_size = 8; + else + ctx->align_size = 16; + + DRM_DEBUG_KMS("align_size = %d\n", ctx->align_size); + + pm_runtime_mark_last_busy(ctx->dev); + pm_runtime_put_autosuspend(ctx->dev); +} + static void gsc_abort(struct exynos_drm_ipp *ipp, struct exynos_drm_ipp_task *task) { @@ -1142,6 +1193,7 @@ static void gsc_abort(struct exynos_drm_ipp *ipp, } static struct exynos_drm_ipp_funcs ipp_funcs = { + .fixup = gsc_fixup, .commit = gsc_commit, .abort = gsc_abort, }; @@ -1155,6 +1207,9 @@ static int gsc_bind(struct device *dev, struct device *master, void *data) ctx->drm_dev = drm_dev; drm_iommu_attach_device(drm_dev, dev); + if (ctx->driver_data->has_in_ic_max) + gsc_get_align_size(ctx); + exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs, DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT, @@ -1221,6 +1276,7 @@ static int gsc_probe(struct platform_device *pdev) } ctx->formats = formats; ctx->num_formats = ARRAY_SIZE(gsc_formats); + ctx->driver_data = driver_data; /* clock control */ for (i = 0; i < ctx->num_clocks; i++) { @@ -1366,6 +1422,9 @@ static int __maybe_unused gsc_runtime_resume(struct device *dev) .num_clocks = 4, .limits = gsc_5433_limits, .num_limits = ARRAY_SIZE(gsc_5433_limits), + .has_in_ic_max = 1, + .in_ic_max_shift = 24, + .in_ic_max_mask = 0x3, }; static const struct of_device_id exynos_drm_gsc_of_match[] = { diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 26374e5..3f90b05 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -560,6 +560,14 @@ static int exynos_drm_ipp_check_scale_limits( return 0; } +static void exynos_drm_ipp_fixup_buffer(struct exynos_drm_ipp_task *task) +{ + struct exynos_drm_ipp *ipp = task->ipp; + + if (ipp->funcs->fixup) + ipp->funcs->fixup(ipp, task); +} + static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task) { struct exynos_drm_ipp *ipp = task->ipp; @@ -618,6 +626,7 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task) rotate, false); if (ret) return ret; + ret = exynos_drm_ipp_check_scale_limits(&src->rect, &dst->rect, src_fmt->limits, src_fmt->num_limits, swap); @@ -654,6 +663,12 @@ static int exynos_drm_ipp_task_setup_buffers(struct exynos_drm_ipp_task *task, DRM_DEBUG_DRIVER("Setting buffer for task %pK\n", task); + /* + * image size should be fixed up before setup buffer call + * which verifies whether image size exceeds gem buffer size or not. + */ + exynos_drm_ipp_fixup_buffer(task); + ret = exynos_drm_ipp_task_setup_buffer(src, filp); if (ret) { DRM_DEBUG_DRIVER("Task %pK: src buffer setup failed\n", task); diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h index 0b27d4a..5c2059f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h @@ -20,6 +20,18 @@ */ struct exynos_drm_ipp_funcs { /** + * @fixup: + * + * Correct buffer size according to hardware limit of each DMA device. + * Some DMA device has maximum memory read capability through AXI bus, + * which reads data from memory as a given bytes. + * Therefore, IPP driver needs to check if the buffer size meets + * the HW limlit of each DMA device such as GScaler, Scaler, + * Rotator and FIMC. + */ + void (*fixup)(struct exynos_drm_ipp *ipp, + struct exynos_drm_ipp_task *task); + /** * @commit: * * This is the main entry point to start framebuffer processing