From patchwork Thu May 24 01:04:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Inki Dae X-Patchwork-Id: 10422573 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 D40176019D for ; Thu, 24 May 2018 01:04:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C08A1292EA for ; Thu, 24 May 2018 01:04:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B4E83292F1; Thu, 24 May 2018 01:04:33 +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 6CA9F292EA for ; Thu, 24 May 2018 01:04:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935260AbeEXBEc (ORCPT ); Wed, 23 May 2018 21:04:32 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:45868 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935247AbeEXBEa (ORCPT ); Wed, 23 May 2018 21:04:30 -0400 Received: from epcas1p3.samsung.com (unknown [182.195.41.47]) by mailout3.samsung.com (KnoxPortal) with ESMTP id 20180524010428epoutp031e866cd3348753fd8ca5b1826b6ec6c6~xbxEtPh0g1444114441epoutp03Q; Thu, 24 May 2018 01:04:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout3.samsung.com 20180524010428epoutp031e866cd3348753fd8ca5b1826b6ec6c6~xbxEtPh0g1444114441epoutp03Q DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1527123868; bh=y1J21Mm+US1xK7BjfhjxIC2nSCU+Jbceb/l6Ky7MiFM=; h=From:To:Cc:Subject:Date:References:From; b=XfE3G988d3JtpDaxlvp4JbbocvZRFGD4khm20Og3ms+ltRlH/ZMTnSL+/O6SxC1N+ 74pnoQBsx49wfqNsqw3jyyfIugDMhIJu2m2RQjVaceiFnpjPy6Zum3UIkM98/pQeWw 9znQkoOOGwbWwriJmwvoD0HLeTh4nlcT6QStHv98= Received: from epsmges2p2.samsung.com (unknown [182.195.40.156]) by epcas1p3.samsung.com (KnoxPortal) with ESMTP id 20180524010425epcas1p30e68e1110e4c18385e6dbb28a20da60b~xbxCJ9XZe0232102321epcas1p3o; Thu, 24 May 2018 01:04:25 +0000 (GMT) Received: from epcas2p1.samsung.com ( [182.195.41.53]) by epsmges2p2.samsung.com (Symantec Messaging Gateway) with SMTP id 70.B3.04132.99F060B5; Thu, 24 May 2018 10:04:25 +0900 (KST) Received: from epsmgms2p2new.samsung.com (unknown [182.195.42.143]) by epcas2p2.samsung.com (KnoxPortal) with ESMTP id 20180524010425epcas2p21d2167ade0c70c8db08f8aa34b39ea65~xbxB3N2qX1405314053epcas2p2A; Thu, 24 May 2018 01:04:25 +0000 (GMT) X-AuditID: b6c32a46-145ff70000001024-fe-5b060f99f0f2 Received: from epmmp1.local.host ( [203.254.227.16]) by epsmgms2p2new.samsung.com (Symantec Messaging Gateway) with SMTP id 55.2F.03817.89F060B5; Thu, 24 May 2018 10:04:25 +0900 (KST) Received: from daeinki-desktop.tn.corp.samsungelectronics.net ([10.113.62.206]) by mmp1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0P970067OKBC8840@mmp1.samsung.com>; Thu, 24 May 2018 10:04:24 +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 v2] drm/exynos: ipp: fix image broken issue Date: Thu, 24 May 2018 10:04:23 +0900 Message-id: <1527123863-9633-1-git-send-email-inki.dae@samsung.com> X-Mailer: git-send-email 1.9.1 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpgleLIzCtJLcpLzFFi42LZdljTVHcmP1u0wao/0hZXvr5ns5h0fwKL xYzz+5gs1h65y+7A4nG/+ziTR9+WVYwenzfJBTBHpdpkpCampBYppOYl56dk5qXbKnkHxzvH m5oZGOoaWlqYKynkJeam2iq5+AToumXmAG1TUihLzCkFCgUkFhcr6dvZFOWXlqQqZOQXl9gq RRsaGukZGpjrGRkBaeNYKyNToJKE1IzV1zgLVrtUHHy0nq2Bcbt5FyMnh4SAicSON92sXYxc HEICOxglFv2cyQqSEBL4ziixup8ZpmjR/zfMEEW7GSUuTT3IAuFMZJKYsGcnO0gVm4CqxMQV 99lAbBEBZYm/E1cxgtjMAkkSbw6sB6rh4BAWsJbY+l4WJMwCVD57x0SwEl4BZ4n3VxYzQSyT kzh5bDLYRRICZ1kl3vbdZALplRBwkTh02RmiRlji1fEt7BC2tMSzVRsZIerbGSV2nb3OBuH0 MEosX7wIqspY4tnCLiaIg/gkOg7/ZYcYyivR0SYEUeIhsajjOCNE2FHi/e9aSEDESjx5/IZ9 AqPkAkaGVYxiqQXFuempxUYFRnrFibnFpXnpesn5uZsYwbGv5baDcck5n0OMAhyMSjy8F1JZ o4VYE8uKK3MPMUpwMCuJ8M7lYosW4k1JrKxKLcqPLyrNSS0+xGgKDI6JzFKiyfnAtJRXEm9o amRsbGxham5pbGCpJM570+xflJBAemJJanZqakFqEUwfEwenVANj1HtBLUEx5iVPSsunOyZO jSk4uLri4kVTfpOIxdbMU85cvvkodvn1tZcfaykoWudEPT2xLGKfzf+P77JMYw9ceFCdYypb tSBCzrksil1hkkPvLmOtD/PsbvfJSS1eL+5x9im7pU+SZPV8+d0uv9Pe5CxhnuD+3ujV2vlH m/7phzeu2GGV53haiaU4I9FQi7moOBEA0CExzxMDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrJJMWRmVeSWpSXmKPExsVy+t9jAd2Z/GzRBgcusFlc+fqezWLS/Qks FjPO72OyWHvkLrsDi8f97uNMHn1bVjF6fN4kF8AcxWWTkpqTWZZapG+XwJWx+hpnwWqXioOP 1rM1MG4372Lk5JAQMJFY9P8NcxcjF4eQwE5GiePn1rFCOJOZJA5P28IMUsUmoCoxccV9NhBb REBZ4u/EVYwgNrNAkkTb5D9ADRwcwgLWElvfy4KEWYDKZ++YCFbCK+As8f7KYiaIZXISJ49N Zp3AyLWAkWEVo2RqQXFuem6xUYFRXmq5XnFibnFpXrpecn7uJkagh7cd1urfwfh4SfwhRgEO RiUe3guprNFCrIllxZW5hxglOJiVRHjncrFFC/GmJFZWpRblxxeV5qQWH2KU5mBREuflzz8W KSSQnliSmp2aWpBaBJNl4uCUamCMlr3kyhas1lCuceT5w7Ct8m/e6xX+8NvWcaLc44jt3k8N O+MYdocKxETWppivvf7p+oney3UZTy1E1769toczV6nkQfg8q2kZXe7LTXLydUv3fD9baqL8 X4HP1aggLE2zQHTW07PW8s+f5+u7/grrvXu56XqEJK9v34mzK4//nF3C8S58n54SS3FGoqEW c1FxIgCU492f7AEAAA== X-CMS-MailID: 20180524010425epcas2p21d2167ade0c70c8db08f8aa34b39ea65 X-Msg-Generator: CA CMS-TYPE: 102P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20180524010425epcas2p21d2167ade0c70c8db08f8aa34b39ea65 X-RootMTR: 20180524010425epcas2p21d2167ade0c70c8db08f8aa34b39ea65 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. Changelog v2: - Fix align limit of image width size to 16bytes because with other values , 4 and 8bytes, it doesn't work. - Change the function name from gst_get_align_size to gst_set_align_limit. gst_set_align_limit function name is more reasonable. - Call fixup buffer function before calling size limit check. - Remove checking align of image offset, x and y. The offest values have no any limit but only size. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 94 +++++++++++++++++++++++++++------ drivers/gpu/drm/exynos/exynos_drm_ipp.c | 18 +++++-- drivers/gpu/drm/exynos/exynos_drm_ipp.h | 12 +++++ 3 files changed, 106 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index e99dd1e..8bc31b5 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,15 @@ 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; + + 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 +1146,41 @@ static int gsc_commit(struct exynos_drm_ipp *ipp, return 0; } +static void gsc_set_align_limit(struct gsc_context *ctx) +{ + const struct drm_exynos_ipp_limit *limits = ctx->driver_data->limits; + + if (ctx->driver_data->has_in_ic_max) { + 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); + + /* + * fix align limit to 16bytes. With other limit values, 4 + * and 8, it doesn't work. + */ + cfg = (cfg & ~(mask << shift)); + cfg |= 2 << shift; + + gsc_write(cfg, GSC_IN_CON); + + pm_runtime_mark_last_busy(ctx->dev); + pm_runtime_put_autosuspend(ctx->dev); + + ctx->align_size = 16; + } else { + /* No HW register to get the align limit so use fixed value. */ + ctx->align_size = limits->h.align; + } + + DRM_DEBUG_KMS("align_size = %d\n", ctx->align_size); +} + static void gsc_abort(struct exynos_drm_ipp *ipp, struct exynos_drm_ipp_task *task) { @@ -1142,6 +1199,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 +1213,8 @@ static int gsc_bind(struct device *dev, struct device *master, void *data) ctx->drm_dev = drm_dev; drm_iommu_attach_device(drm_dev, dev); + gsc_set_align_limit(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 +1281,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++) { @@ -1340,7 +1401,7 @@ static int __maybe_unused gsc_runtime_resume(struct device *dev) }; static const struct drm_exynos_ipp_limit gsc_5433_limits[] = { - { IPP_SIZE_LIMIT(BUFFER, .h = { 32, 8191, 2 }, .v = { 16, 8191, 2 }) }, + { IPP_SIZE_LIMIT(BUFFER, .h = { 32, 8191, 16 }, .v = { 16, 8191, 2 }) }, { IPP_SIZE_LIMIT(AREA, .h = { 16, 4800, 1 }, .v = { 8, 3344, 1 }) }, { IPP_SIZE_LIMIT(ROTATED, .h = { 32, 2047 }, .v = { 8, 8191 }) }, { IPP_SCALE_LIMIT(.h = { (1 << 16) / 16, (1 << 16) * 8 }, @@ -1366,6 +1427,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..2319c12 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -510,9 +510,7 @@ static int exynos_drm_ipp_check_size_limits(struct exynos_drm_ipp_buffer *buf, } __get_size_limit(limits, num_limits, id, &l); if (!__size_limit_check(buf->rect.w, lh) || - !__align_check(buf->rect.x, lh->align) || - !__size_limit_check(buf->rect.h, lv) || - !__align_check(buf->rect.y, lv->align)) + !__size_limit_check(buf->rect.h, lv)) return -EINVAL; return 0; @@ -560,6 +558,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; @@ -607,6 +613,12 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task) return -EINVAL; } + /* + * 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); + src_fmt = __ipp_format_get(ipp, src->buf.fourcc, src->buf.modifier, DRM_EXYNOS_IPP_FORMAT_SOURCE); if (!src_fmt) { 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