From patchwork Mon Nov 30 13:53:34 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 7725661 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 72A80BEEE5 for ; Mon, 30 Nov 2015 13:54:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 77FB020524 for ; Mon, 30 Nov 2015 13:54:08 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 4885D205DD for ; Mon, 30 Nov 2015 13:54:07 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A11E96E5C4; Mon, 30 Nov 2015 05:54:02 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout3.w1.samsung.com (mailout3.w1.samsung.com [210.118.77.13]) by gabe.freedesktop.org (Postfix) with ESMTPS id D54536E5BC for ; Mon, 30 Nov 2015 05:53:56 -0800 (PST) Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0NYM00AV1RXV8QB0@mailout3.w1.samsung.com> for dri-devel@lists.freedesktop.org; Mon, 30 Nov 2015 13:53:55 +0000 (GMT) X-AuditID: cbfec7f5-f79b16d000005389-fd-565c54f251e4 Received: from eusync2.samsung.com ( [203.254.199.212]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id 86.78.21385.2F45C565; Mon, 30 Nov 2015 13:53:54 +0000 (GMT) Received: from amdc1339.digital.local ([106.116.147.30]) by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0NYM007NRRXFE700@eusync2.samsung.com>; Mon, 30 Nov 2015 13:53:54 +0000 (GMT) From: Marek Szyprowski To: dri-devel@lists.freedesktop.org, linux-samsung-soc@vger.kernel.org Subject: [PATCH v2 19/22] drm/exynos: fix to calculate offset of each plane for ipp gsc Date: Mon, 30 Nov 2015 14:53:34 +0100 Message-id: <1448891617-18830-20-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.2 In-reply-to: <1448891617-18830-1-git-send-email-m.szyprowski@samsung.com> References: <1448891617-18830-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrJLMWRmVeSWpSXmKPExsVy+t/xK7qfQmLCDF5OsbK4te4cq8XGGetZ La58fc9msfPBLnaLSfcnsFi8ebuGyeLFvYssFq9fGFrMOL+PyWLtkbvsFjMmv2SzaFv9gdVi 1a4/jA68Hjtn3WX3uN99nMnj3zF2jy39QN7OSXuZPPq2rGL0+LxJLoA9issmJTUnsyy1SN8u gStjRhdPwTnNig17vzA1MH5S7GLk5JAQMJFYu+EdK4QtJnHh3nq2LkYuDiGBpYwSp9qeMEM4 TUwS7y6sZAOpYhMwlOh62wVmiwi4STQdngnWzSxwmFni8NQ6EFtYIFLi05GNLCA2i4CqxJ3F V8HqeQU8JZ5v/sMIsU1O4v/LFUwgNidQ/MnZ0+wgtpCAh8SGGceYJjDyLmBkWMUomlqaXFCc lJ5rpFecmFtcmpeul5yfu4kREqBfdzAuPWZ1iFGAg1GJh1fCLDpMiDWxrLgy9xCjBAezkghv oGlMmBBvSmJlVWpRfnxRaU5q8SFGaQ4WJXHembvehwgJpCeWpGanphakFsFkmTg4pRoYneZt r9k01VFov7OLk9AWWQeDKWo9V3viXXJvm6t38MecvbXmR3ZbRIvY3BX71m6ZMMm7veNS4rWa xvuFp9+GqQfcTHgrPDdoUssM+x8FT7am7F+aoPdJ9sOdYL/i2Uyqc5Wc2q5Lt5jPn1jZ6Hq3 eVJVSZ+dxsyM2282ti94/chUYqXSWZ4fSizFGYmGWsxFxYkAheuc9kwCAAA= Cc: Javier Martinez Canillas , Krzysztof Kozlowski , Bartlomiej Zolnierkiewicz , Seung-Woo Kim , Andrzej Hajda , Tobias Jakobi , Marek Szyprowski 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.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: Seung-Woo Kim NV12 and YUV420 formats are needed to calculate offset of each plane in a gem buffer for ipp gsc. Without proper offset, only Y plane can be processed, so result shows green frame. This patch fixes to calculate offset for cbcr planes for NV12 and YUV420 formats. Signed-off-by: Seung-Woo Kim Signed-off-by: Marek Szyprowski --- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 116 ++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 7aecd23cfa11..2882b9347cc8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -486,6 +486,98 @@ static void gsc_handle_irq(struct gsc_context *ctx, bool enable, gsc_write(cfg, GSC_IRQ); } +static int gsc_set_planar_addr(struct drm_exynos_ipp_buf_info *buf_info, + u32 fmt, struct drm_exynos_sz *sz) +{ + dma_addr_t *base[EXYNOS_DRM_PLANAR_MAX]; + uint64_t size[EXYNOS_DRM_PLANAR_MAX]; + uint64_t ofs[EXYNOS_DRM_PLANAR_MAX]; + bool bypass = false; + uint64_t tsize = 0; + int i; + + for_each_ipp_planar(i) { + base[i] = &buf_info->base[i]; + size[i] = buf_info->size[i]; + ofs[i] = 0; + tsize += size[i]; + DRM_DEBUG_KMS("base[%d][0x%lx]s[%d][%llu]\n", + i, (unsigned long)*base[i], i, size[i]); + } + + if (!tsize) { + DRM_INFO("failed to get buffer size.\n"); + return 0; + } + + switch (fmt) { + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV61: + ofs[0] = sz->hsize * sz->vsize; + ofs[1] = ofs[0] >> 1; + if (*base[0] && *base[1]) { + if (size[0] + size[1] < ofs[0] + ofs[1]) + goto err_info; + bypass = true; + } + break; + case DRM_FORMAT_YUV410: + case DRM_FORMAT_YVU410: + case DRM_FORMAT_YUV411: + case DRM_FORMAT_YVU411: + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YUV444: + case DRM_FORMAT_YVU444: + ofs[0] = sz->hsize * sz->vsize; + ofs[1] = ofs[2] = ofs[0] >> 2; + if (*base[0] && *base[1] && *base[2]) { + if (size[0]+size[1]+size[2] < ofs[0]+ofs[1]+ofs[2]) + goto err_info; + bypass = true; + } + break; + case DRM_FORMAT_XRGB8888: + ofs[0] = sz->hsize * sz->vsize << 2; + if (*base[0]) { + if (size[0] < ofs[0]) + goto err_info; + } + bypass = true; + break; + default: + bypass = true; + break; + } + + if (!bypass) { + *base[1] = *base[0] + ofs[0]; + if (ofs[1] && ofs[2]) + *base[2] = *base[1] + ofs[1]; + } + + DRM_DEBUG_KMS("y[0x%lx],cb[0x%lx],cr[0x%lx]\n", (unsigned long)*base[0], + (unsigned long)*base[1], (unsigned long)*base[2]); + + return 0; + +err_info: + DRM_ERROR("invalid size for fmt[0x%x]\n", fmt); + + for_each_ipp_planar(i) { + base[i] = &buf_info->base[i]; + size[i] = buf_info->size[i]; + + DRM_ERROR("base[%d][0x%lx]s[%d][%llu]ofs[%d][%llu]\n", + i, (unsigned long)*base[i], i, size[i], i, ofs[i]); + } + + return -EINVAL; +} static int gsc_src_set_fmt(struct device *dev, u32 fmt) { @@ -715,6 +807,8 @@ static int gsc_src_set_addr(struct device *dev, struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; struct drm_exynos_ipp_property *property; + struct drm_exynos_ipp_config *config; + int ret; if (!c_node) { DRM_ERROR("failed to get c_node.\n"); @@ -734,6 +828,13 @@ static int gsc_src_set_addr(struct device *dev, /* address register set */ switch (buf_type) { case IPP_BUF_ENQUEUE: + config = &property->config[EXYNOS_DRM_OPS_SRC]; + ret = gsc_set_planar_addr(buf_info, config->fmt, &config->sz); + if (ret) { + dev_err(dev, "failed to set plane src addr.\n"); + return ret; + } + gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y], GSC_IN_BASE_ADDR_Y(buf_id)); gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB], @@ -1170,6 +1271,8 @@ static int gsc_dst_set_addr(struct device *dev, struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; struct drm_exynos_ipp_property *property; + struct drm_exynos_ipp_config *config; + int ret; if (!c_node) { DRM_ERROR("failed to get c_node.\n"); @@ -1189,6 +1292,13 @@ static int gsc_dst_set_addr(struct device *dev, /* address register set */ switch (buf_type) { case IPP_BUF_ENQUEUE: + config = &property->config[EXYNOS_DRM_OPS_DST]; + ret = gsc_set_planar_addr(buf_info, config->fmt, &config->sz); + if (ret) { + dev_err(dev, "failed to set plane dst addr.\n"); + return ret; + } + gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y], GSC_OUT_BASE_ADDR_Y(buf_id)); gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB], @@ -1320,6 +1430,12 @@ static irqreturn_t gsc_irq_handler(int irq, void *dev_id) return IRQ_NONE; } + if (c_node->state == IPP_STATE_STOP) { + DRM_ERROR("invalid state: prop_id[%d]\n", + c_node->property.prop_id); + return IRQ_HANDLED; + } + if (status & GSC_IRQ_STATUS_OR_FRM_DONE) { dev_dbg(ippdrv->dev, "occurred frame done at %d, status 0x%x.\n", ctx->id, status);