From patchwork Wed May 22 01:03:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Longerbeam X-Patchwork-Id: 10954657 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 408D814B6 for ; Wed, 22 May 2019 01:03:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3395128A71 for ; Wed, 22 May 2019 01:03:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 27F5A28B25; Wed, 22 May 2019 01:03:32 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8EA3C28A71 for ; Wed, 22 May 2019 01:03:31 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 21872896BF; Wed, 22 May 2019 01:03:29 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) by gabe.freedesktop.org (Postfix) with ESMTPS id D0237896BF for ; Wed, 22 May 2019 01:03:27 +0000 (UTC) Received: by mail-pl1-x643.google.com with SMTP id a5so177139pls.12 for ; Tue, 21 May 2019 18:03:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hZxOPx40sM31sXATrJWIrdV0RTZA1DlPQH1xR20a6EI=; b=YNQJJfd7vl1qiBM8V3vSANOKijAKYEXmWs1eoYoXQOvqzVnWqXeDZFuYNntgA9JyMp ZWb7/XPGrJqjH9NlQCt7nfvPrCPtO838UEP9sG/kctyVW8aaRf64FUr1B7S+XD5HLN+7 oVDCOtkrQnTa4spNxZezIjSXJC65/ydosPtjn+1c+9TO87zA1YS1CEENa5OG3vL38RmB WAmsKNyUIt4/avLtr7S8rbHRVj4BEqJSVBuQCpkPNVC71p4LcDdZ5cfIuS0LjfrcUUWv EC7IYXjkFp7bN4XnB4y5eyLTEXK0ivj7TvdZO2CMDrZfiOXEUPMZoisAIfwPNsyJ7jiF j0lg== X-Gm-Message-State: APjAAAXxWjAEeqr5PNlpYa9R5lhZYnTP8RnmuiIv8G8H025/JJ0ls3Rc XSIF46j5Th0712uxTmAOUBs= X-Google-Smtp-Source: APXvYqxX3046Ypk/1iJeTlE7JccOi5IUU7WTFVOh31S6dnrg9pgR8igRa5NROi7akpn4K9HbrvEROQ== X-Received: by 2002:a17:902:424:: with SMTP id 33mr87086594ple.102.1558487007261; Tue, 21 May 2019 18:03:27 -0700 (PDT) Received: from majic.sklembedded.com (c-73-202-231-77.hsd1.ca.comcast.net. [73.202.231.77]) by smtp.googlemail.com with ESMTPSA id q193sm34291242pfc.52.2019.05.21.18.03.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 May 2019 18:03:26 -0700 (PDT) From: Steve Longerbeam To: linux-media@vger.kernel.org Subject: [PATCH v8 1/5] gpu: ipu-v3: ipu-ic: Fix saturation bit offset in TPMEM Date: Tue, 21 May 2019 18:03:13 -0700 Message-Id: <20190522010317.23710-2-slongerbeam@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190522010317.23710-1-slongerbeam@gmail.com> References: <20190522010317.23710-1-slongerbeam@gmail.com> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hZxOPx40sM31sXATrJWIrdV0RTZA1DlPQH1xR20a6EI=; b=jgen3ia4nDSmuFARPMsvjj7DWaO1iW//OuXl403j+o/G/TeeSqMiVvZ0ntMuQMMXz6 dtYV3xJmd6l827CYLhYs0ByM6njiVjg79s2sLCEs10WDDns51gcmIiqVYfDp/6R1nW+G D7wCvEhSSQapr8PxP9ML32wzLwnQZxIdUggSCXCB7IypYUWUyr8i5evxZj6HPi+WRFmO yXzbdeJePZ2tMsOKiODoiM6UEvZefm+7ELDy419DUzcbnyj1I3a46oV0Ah5yp0TC7bIQ KccvvkiC4s8eBlLscwu0inRFcPY4XG+2RKJmEymnUlEEow92i0+LBjTtou2cCMaAb2x1 Njgg== X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: open list , "open list:DRM DRIVERS FOR FREESCALE IMX" , stable@vger.kernel.org, Steve Longerbeam MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP The saturation bit was being set at bit 9 in the second 32-bit word of the TPMEM CSC. This isn't correct, the saturation bit is bit 42, which is bit 10 of the second word. Fixes: 1aa8ea0d2bd5d ("gpu: ipu-v3: Add Image Converter unit") Signed-off-by: Steve Longerbeam Reviewed-by: Philipp Zabel Cc: stable@vger.kernel.org --- drivers/gpu/ipu-v3/ipu-ic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/ipu-v3/ipu-ic.c b/drivers/gpu/ipu-v3/ipu-ic.c index 594c3cbc8291..18816ccf600e 100644 --- a/drivers/gpu/ipu-v3/ipu-ic.c +++ b/drivers/gpu/ipu-v3/ipu-ic.c @@ -257,7 +257,7 @@ static int init_csc(struct ipu_ic *ic, writel(param, base++); param = ((a[0] & 0x1fe0) >> 5) | (params->scale << 8) | - (params->sat << 9); + (params->sat << 10); writel(param, base++); param = ((a[1] & 0x1f) << 27) | ((c[0][1] & 0x1ff) << 18) | From patchwork Wed May 22 01:03:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Longerbeam X-Patchwork-Id: 10954659 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BB0EF933 for ; Wed, 22 May 2019 01:03:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ABA3028A71 for ; Wed, 22 May 2019 01:03:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9F7F128AAA; Wed, 22 May 2019 01:03:35 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 74EA428A71 for ; Wed, 22 May 2019 01:03:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F3B94896C7; Wed, 22 May 2019 01:03:32 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) by gabe.freedesktop.org (Postfix) with ESMTPS id DF6E6896C4 for ; Wed, 22 May 2019 01:03:30 +0000 (UTC) Received: by mail-pl1-x643.google.com with SMTP id f97so191319plb.5 for ; Tue, 21 May 2019 18:03:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7hje4FsfBPJPMKbxtLZB2p363LKCH0+OWM/5l2pYlCQ=; b=mcnAO0b23tefhiyRq2Y8WzuHl0Xc0mzIbYGjDoCgMons7XnGT0t0c0nXf9d8VChNpg 8WY+ivEWky3Ys768WrcHPWGceQV0TaFYSHsN7kFmxc8La1eV85wwZXhKXkk2vIR+Obmx 6knZZ1W2c/M+XHy6MkoU3urD5yEkXZiQ1RiM5bkzmc/yDjcIGgtb2xToEV35NEYlIiBq qV8laY3XRTogDikAWedhFfNlZINA43nDrn91yWHHCorTLHdwYtqvbGL5UOXDZ6K0U/Fr vK/OWtx7eqa31w3XEGpc6ewqatPub3Cey/KAYldVjxdAaaiNso+TVehGEh0GuaaPuXnT 4q9g== X-Gm-Message-State: APjAAAWS6oUdVhATXE9v+gHSXAO1V8S03oOm9SRfIKRw6R5lCQ/6evMe F0hAM8Gu7HpBaK7/5dtdkhE= X-Google-Smtp-Source: APXvYqy6HXFpMBopQ5N+7EA4FCDrWyrwi9faPF2z60FqUVwkDffdxvrpUvcQprh7YxSXJuWYuE5FPA== X-Received: by 2002:a17:902:4623:: with SMTP id o32mr66617798pld.276.1558487010155; Tue, 21 May 2019 18:03:30 -0700 (PDT) Received: from majic.sklembedded.com (c-73-202-231-77.hsd1.ca.comcast.net. [73.202.231.77]) by smtp.googlemail.com with ESMTPSA id q193sm34291242pfc.52.2019.05.21.18.03.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 May 2019 18:03:29 -0700 (PDT) From: Steve Longerbeam To: linux-media@vger.kernel.org Subject: [PATCH v8 2/5] gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Date: Tue, 21 May 2019 18:03:14 -0700 Message-Id: <20190522010317.23710-3-slongerbeam@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190522010317.23710-1-slongerbeam@gmail.com> References: <20190522010317.23710-1-slongerbeam@gmail.com> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7hje4FsfBPJPMKbxtLZB2p363LKCH0+OWM/5l2pYlCQ=; b=cJfIE37IhFI1J+tbPbzYI52k0rd7G7+wj/XfuUKd0kUZxwBlOtbqM1OapByKS84pVk 4vaOECZBoVljnGEB2PAXht1SZZhqmznzCiWenPP7zyp8/z7Cxwn3PjK8UMrTE3m6P5mZ kLnIgAqbrJipIroW0bshtF3iuYEHxZpPaidesEcEGsDEj0tzLgPoLMeGc2X2y0aLZui1 tJGkVdV9W+ygxnJn/2wYN2cztVfecVNo4FhryhHxKR/aorAg0OJP4cJb541orj3L+FKf WEmZsqXyJCvi2zBR+r6iBMFvm6La2jWKVEEbkgCzRW+/Lcw91wWK/41zp5nSjeUQLclY qOWw== X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "open list:STAGING SUBSYSTEM" , "open list:FRAMEBUFFER LAYER" , Pengutronix Kernel Team , Bartlomiej Zolnierkiewicz , Greg Kroah-Hartman , open list , "open list:DRM DRIVERS FOR FREESCALE IMX" , NXP Linux Team , Steve Longerbeam , Mauro Carvalho Chehab , Shawn Guo , "moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE" MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam --- Changes in v8: - remove Fixes: and cc: stable. This patch is too difficult to backport to stable trees. Changes in v7: - squashed with "gpu: ipu-v3: ipu-ic: Fix BT.601 coefficients". - moved the coefficient tables and calc_csc_coeffs() to a new module ipu-ic-csc.c, and added exported ipu_ic_calc_csc() to it. - drop v4l2_colorspace (chromaticities) from 'struct ipu_ic_colorspace'. It's implied that xfer_func (gamma function) must be the same for input and output, so make that implicit for chromaticities too. - drop passing priv to calc_csc_coeffs(), was only used to print error messages. - removed the inverse_encode boolean in calc_csc_coeffs(). - express negative coefficients as true signed int's, for better readability. - tweak inverse coeff in comments, no change to rounded table values. --- drivers/gpu/ipu-v3/Makefile | 4 +- drivers/gpu/ipu-v3/ipu-ic-csc.c | 129 ++++++++++++++++++ drivers/gpu/ipu-v3/ipu-ic.c | 138 +++++++------------- drivers/gpu/ipu-v3/ipu-image-convert.c | 28 ++-- drivers/staging/media/imx/imx-ic-prpencvf.c | 34 ++++- include/video/imx-ipu-v3.h | 56 +++++++- 6 files changed, 271 insertions(+), 118 deletions(-) create mode 100644 drivers/gpu/ipu-v3/ipu-ic-csc.c diff --git a/drivers/gpu/ipu-v3/Makefile b/drivers/gpu/ipu-v3/Makefile index 7cc8b47e488b..5fe5ef20701a 100644 --- a/drivers/gpu/ipu-v3/Makefile +++ b/drivers/gpu/ipu-v3/Makefile @@ -2,8 +2,8 @@ obj-$(CONFIG_IMX_IPUV3_CORE) += imx-ipu-v3.o imx-ipu-v3-objs := ipu-common.o ipu-cpmem.o ipu-csi.o ipu-dc.o ipu-di.o \ - ipu-dp.o ipu-dmfc.o ipu-ic.o ipu-image-convert.o \ - ipu-smfc.o ipu-vdi.o + ipu-dp.o ipu-dmfc.o ipu-ic.o ipu-ic-csc.o \ + ipu-image-convert.o ipu-smfc.o ipu-vdi.o ifdef CONFIG_DRM imx-ipu-v3-objs += ipu-pre.o ipu-prg.o diff --git a/drivers/gpu/ipu-v3/ipu-ic-csc.c b/drivers/gpu/ipu-v3/ipu-ic-csc.c new file mode 100644 index 000000000000..5fb469cd64fe --- /dev/null +++ b/drivers/gpu/ipu-v3/ipu-ic-csc.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Mentor Graphics Inc. + */ + +#include +#include +#include +#include +#include +#include "ipu-prv.h" + +/* identity matrix */ +static const struct ipu_ic_csc_params identity = { + .coeff = { + { 128, 0, 0, }, + { 0, 128, 0, }, + { 0, 0, 128, }, + }, + .offset = { 0, 0, 0, }, + .scale = 2, +}; + +static const struct ipu_ic_csc_params *rgb2rgb[] = { + &identity, +}; + +static const struct ipu_ic_csc_params *yuv2yuv[] = { + &identity, +}; + +/* + * BT.601 RGB full-range to YUV full-range + * + * Y = .2990 * R + .5870 * G + .1140 * B + * U = -.1687 * R - .3313 * G + .5000 * B + 128 + * V = .5000 * R - .4187 * G - .0813 * B + 128 + */ +static const struct ipu_ic_csc_params rgbf2yuvf_601 = { + .coeff = { + { 77, 150, 29, }, + { -43, -85, 128, }, + { 128, -107, -21, }, + }, + .offset = { 0, 512, 512, }, + .scale = 1, +}; + +/* + * BT.601 YUV full-range to RGB full-range + * + * R = 1. * Y + 0 * (Cb - 128) + 1.4020 * (Cr - 128) + * G = 1. * Y - .3441 * (Cb - 128) - .7141 * (Cr - 128) + * B = 1. * Y + 1.7720 * (Cb - 128) + 0 * (Cr - 128) + * + * equivalently (factoring out the offsets): + * + * R = 1. * Y + 0 * Cb + 1.4020 * Cr - 179.456 + * G = 1. * Y - .3441 * Cb - .7141 * Cr + 135.450 + * B = 1. * Y + 1.7720 * Cb + 0 * Cr - 226.816 + */ +static const struct ipu_ic_csc_params yuvf2rgbf_601 = { + .coeff = { + { 128, 0, 179, }, + { 128, -44, -91, }, + { 128, 227, 0, }, + }, + .offset = { -359, 271, -454, }, + .scale = 2, +}; + +static const struct ipu_ic_csc_params *rgb2yuv_601[] = { + &rgbf2yuvf_601, +}; + +static const struct ipu_ic_csc_params *yuv2rgb_601[] = { + &yuvf2rgbf_601, +}; + +static int calc_csc_coeffs(struct ipu_ic_csc *csc) +{ + if (csc->out_cs.enc != V4L2_YCBCR_ENC_601) + return -ENOTSUPP; + + if ((csc->in_cs.cs == IPUV3_COLORSPACE_YUV && + csc->in_cs.quant != V4L2_QUANTIZATION_FULL_RANGE) || + (csc->out_cs.cs == IPUV3_COLORSPACE_YUV && + csc->out_cs.quant != V4L2_QUANTIZATION_FULL_RANGE)) + return -ENOTSUPP; + + if ((csc->in_cs.cs == IPUV3_COLORSPACE_RGB && + csc->in_cs.quant != V4L2_QUANTIZATION_FULL_RANGE) || + (csc->out_cs.cs == IPUV3_COLORSPACE_RGB && + csc->out_cs.quant != V4L2_QUANTIZATION_FULL_RANGE)) + return -ENOTSUPP; + + if (csc->in_cs.cs == csc->out_cs.cs) { + csc->params = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ? + *yuv2yuv[0] : *rgb2rgb[0]; + return 0; + } + + csc->params = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ? + *yuv2rgb_601[0] : *rgb2yuv_601[0]; + + return 0; +} + +int __ipu_ic_calc_csc(struct ipu_ic_csc *csc) +{ + return calc_csc_coeffs(csc); +} +EXPORT_SYMBOL_GPL(__ipu_ic_calc_csc); + +int ipu_ic_calc_csc(struct ipu_ic_csc *csc, + enum v4l2_ycbcr_encoding in_enc, + enum v4l2_quantization in_quant, + enum ipu_color_space in_cs, + enum v4l2_ycbcr_encoding out_enc, + enum v4l2_quantization out_quant, + enum ipu_color_space out_cs) +{ + ipu_ic_fill_colorspace(&csc->in_cs, in_enc, in_quant, in_cs); + ipu_ic_fill_colorspace(&csc->out_cs, out_enc, out_quant, out_cs); + + return __ipu_ic_calc_csc(csc); + +} +EXPORT_SYMBOL_GPL(ipu_ic_calc_csc); diff --git a/drivers/gpu/ipu-v3/ipu-ic.c b/drivers/gpu/ipu-v3/ipu-ic.c index 18816ccf600e..d64083c24940 100644 --- a/drivers/gpu/ipu-v3/ipu-ic.c +++ b/drivers/gpu/ipu-v3/ipu-ic.c @@ -146,8 +146,10 @@ struct ipu_ic { const struct ic_task_regoffs *reg; const struct ic_task_bitfields *bit; - enum ipu_color_space in_cs, g_in_cs; - enum ipu_color_space out_cs; + struct ipu_ic_colorspace in_cs; + struct ipu_ic_colorspace g_in_cs; + struct ipu_ic_colorspace out_cs; + bool graphics; bool rotation; bool in_use; @@ -175,60 +177,11 @@ static inline void ipu_ic_write(struct ipu_ic *ic, u32 value, unsigned offset) writel(value, ic->priv->base + offset); } -struct ic_csc_params { - s16 coeff[3][3]; /* signed 9-bit integer coefficients */ - s16 offset[3]; /* signed 11+2-bit fixed point offset */ - u8 scale:2; /* scale coefficients * 2^(scale-1) */ - bool sat:1; /* saturate to (16, 235(Y) / 240(U, V)) */ -}; - -/* - * Y = R * .299 + G * .587 + B * .114; - * U = R * -.169 + G * -.332 + B * .500 + 128.; - * V = R * .500 + G * -.419 + B * -.0813 + 128.; - */ -static const struct ic_csc_params ic_csc_rgb2ycbcr = { - .coeff = { - { 77, 150, 29 }, - { 469, 427, 128 }, - { 128, 405, 491 }, - }, - .offset = { 0, 512, 512 }, - .scale = 1, -}; - -/* transparent RGB->RGB matrix for graphics combining */ -static const struct ic_csc_params ic_csc_rgb2rgb = { - .coeff = { - { 128, 0, 0 }, - { 0, 128, 0 }, - { 0, 0, 128 }, - }, - .scale = 2, -}; - -/* - * R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128)); - * G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128)); - * B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); - */ -static const struct ic_csc_params ic_csc_ycbcr2rgb = { - .coeff = { - { 149, 0, 204 }, - { 149, 462, 408 }, - { 149, 255, 0 }, - }, - .offset = { -446, 266, -554 }, - .scale = 2, -}; - static int init_csc(struct ipu_ic *ic, - enum ipu_color_space inf, - enum ipu_color_space outf, + const struct ipu_ic_csc *csc, int csc_index) { struct ipu_ic_priv *priv = ic->priv; - const struct ic_csc_params *params; u32 __iomem *base; const u16 (*c)[3]; const u16 *a; @@ -237,27 +190,16 @@ static int init_csc(struct ipu_ic *ic, base = (u32 __iomem *) (priv->tpmem_base + ic->reg->tpmem_csc[csc_index]); - if (inf == IPUV3_COLORSPACE_YUV && outf == IPUV3_COLORSPACE_RGB) - params = &ic_csc_ycbcr2rgb; - else if (inf == IPUV3_COLORSPACE_RGB && outf == IPUV3_COLORSPACE_YUV) - params = &ic_csc_rgb2ycbcr; - else if (inf == IPUV3_COLORSPACE_RGB && outf == IPUV3_COLORSPACE_RGB) - params = &ic_csc_rgb2rgb; - else { - dev_err(priv->ipu->dev, "Unsupported color space conversion\n"); - return -EINVAL; - } - /* Cast to unsigned */ - c = (const u16 (*)[3])params->coeff; - a = (const u16 *)params->offset; + c = (const u16 (*)[3])csc->params.coeff; + a = (const u16 *)csc->params.offset; param = ((a[0] & 0x1f) << 27) | ((c[0][0] & 0x1ff) << 18) | ((c[1][1] & 0x1ff) << 9) | (c[2][2] & 0x1ff); writel(param, base++); - param = ((a[0] & 0x1fe0) >> 5) | (params->scale << 8) | - (params->sat << 10); + param = ((a[0] & 0x1fe0) >> 5) | (csc->params.scale << 8) | + (csc->params.sat << 10); writel(param, base++); param = ((a[1] & 0x1f) << 27) | ((c[0][1] & 0x1ff) << 18) | @@ -344,14 +286,14 @@ void ipu_ic_task_enable(struct ipu_ic *ic) if (ic->rotation) ic_conf |= ic->bit->ic_conf_rot_en; - if (ic->in_cs != ic->out_cs) + if (ic->in_cs.cs != ic->out_cs.cs) ic_conf |= ic->bit->ic_conf_csc1_en; if (ic->graphics) { ic_conf |= ic->bit->ic_conf_cmb_en; ic_conf |= ic->bit->ic_conf_csc1_en; - if (ic->g_in_cs != ic->out_cs) + if (ic->g_in_cs.cs != ic->out_cs.cs) ic_conf |= ic->bit->ic_conf_csc2_en; } @@ -386,11 +328,12 @@ void ipu_ic_task_disable(struct ipu_ic *ic) EXPORT_SYMBOL_GPL(ipu_ic_task_disable); int ipu_ic_task_graphics_init(struct ipu_ic *ic, - enum ipu_color_space in_g_cs, + const struct ipu_ic_colorspace *g_in_cs, bool galpha_en, u32 galpha, bool colorkey_en, u32 colorkey) { struct ipu_ic_priv *priv = ic->priv; + struct ipu_ic_csc csc2; unsigned long flags; u32 reg, ic_conf; int ret = 0; @@ -403,21 +346,36 @@ int ipu_ic_task_graphics_init(struct ipu_ic *ic, ic_conf = ipu_ic_read(ic, IC_CONF); if (!(ic_conf & ic->bit->ic_conf_csc1_en)) { - /* need transparent CSC1 conversion */ - ret = init_csc(ic, IPUV3_COLORSPACE_RGB, - IPUV3_COLORSPACE_RGB, 0); + struct ipu_ic_csc csc1; + + ret = ipu_ic_calc_csc(&csc1, + V4L2_YCBCR_ENC_601, + V4L2_QUANTIZATION_FULL_RANGE, + IPUV3_COLORSPACE_RGB, + V4L2_YCBCR_ENC_601, + V4L2_QUANTIZATION_FULL_RANGE, + IPUV3_COLORSPACE_RGB); if (ret) goto unlock; - } - - ic->g_in_cs = in_g_cs; - if (ic->g_in_cs != ic->out_cs) { - ret = init_csc(ic, ic->g_in_cs, ic->out_cs, 1); + /* need transparent CSC1 conversion */ + ret = init_csc(ic, &csc1, 0); if (ret) goto unlock; } + ic->g_in_cs = *g_in_cs; + csc2.in_cs = ic->g_in_cs; + csc2.out_cs = ic->out_cs; + + ret = __ipu_ic_calc_csc(&csc2); + if (ret) + goto unlock; + + ret = init_csc(ic, &csc2, 1); + if (ret) + goto unlock; + if (galpha_en) { ic_conf |= IC_CONF_IC_GLB_LOC_A; reg = ipu_ic_read(ic, IC_CMBP_1); @@ -443,10 +401,9 @@ int ipu_ic_task_graphics_init(struct ipu_ic *ic, EXPORT_SYMBOL_GPL(ipu_ic_task_graphics_init); int ipu_ic_task_init_rsc(struct ipu_ic *ic, + const struct ipu_ic_csc *csc, int in_width, int in_height, int out_width, int out_height, - enum ipu_color_space in_cs, - enum ipu_color_space out_cs, u32 rsc) { struct ipu_ic_priv *priv = ic->priv; @@ -478,28 +435,23 @@ int ipu_ic_task_init_rsc(struct ipu_ic *ic, ipu_ic_write(ic, rsc, ic->reg->rsc); /* Setup color space conversion */ - ic->in_cs = in_cs; - ic->out_cs = out_cs; + ic->in_cs = csc->in_cs; + ic->out_cs = csc->out_cs; - if (ic->in_cs != ic->out_cs) { - ret = init_csc(ic, ic->in_cs, ic->out_cs, 0); - if (ret) - goto unlock; - } + ret = init_csc(ic, csc, 0); -unlock: spin_unlock_irqrestore(&priv->lock, flags); return ret; } int ipu_ic_task_init(struct ipu_ic *ic, + const struct ipu_ic_csc *csc, int in_width, int in_height, - int out_width, int out_height, - enum ipu_color_space in_cs, - enum ipu_color_space out_cs) + int out_width, int out_height) { - return ipu_ic_task_init_rsc(ic, in_width, in_height, out_width, - out_height, in_cs, out_cs, 0); + return ipu_ic_task_init_rsc(ic, csc, + in_width, in_height, + out_width, out_height, 0); } EXPORT_SYMBOL_GPL(ipu_ic_task_init); diff --git a/drivers/gpu/ipu-v3/ipu-image-convert.c b/drivers/gpu/ipu-v3/ipu-image-convert.c index 13103ab86050..3520eac0eacc 100644 --- a/drivers/gpu/ipu-v3/ipu-image-convert.c +++ b/drivers/gpu/ipu-v3/ipu-image-convert.c @@ -155,6 +155,7 @@ struct ipu_image_convert_ctx { /* Source/destination image data and rotation mode */ struct ipu_image_convert_image in; struct ipu_image_convert_image out; + struct ipu_ic_csc csc; enum ipu_rotate_mode rot_mode; u32 downsize_coeff_h; u32 downsize_coeff_v; @@ -1317,7 +1318,6 @@ static int convert_start(struct ipu_image_convert_run *run, unsigned int tile) struct ipu_image_convert_priv *priv = chan->priv; struct ipu_image_convert_image *s_image = &ctx->in; struct ipu_image_convert_image *d_image = &ctx->out; - enum ipu_color_space src_cs, dest_cs; unsigned int dst_tile = ctx->out_tile_map[tile]; unsigned int dest_width, dest_height; unsigned int col, row; @@ -1327,9 +1327,6 @@ static int convert_start(struct ipu_image_convert_run *run, unsigned int tile) dev_dbg(priv->ipu->dev, "%s: task %u: starting ctx %p run %p tile %u -> %u\n", __func__, chan->ic_task, ctx, run, tile, dst_tile); - src_cs = ipu_pixelformat_to_colorspace(s_image->fmt->fourcc); - dest_cs = ipu_pixelformat_to_colorspace(d_image->fmt->fourcc); - if (ipu_rot_mode_is_irt(ctx->rot_mode)) { /* swap width/height for resizer */ dest_width = d_image->tile[dst_tile].height; @@ -1352,13 +1349,12 @@ static int convert_start(struct ipu_image_convert_run *run, unsigned int tile) s_image->tile[tile].height, dest_width, dest_height, rsc); /* setup the IC resizer and CSC */ - ret = ipu_ic_task_init_rsc(chan->ic, - s_image->tile[tile].width, - s_image->tile[tile].height, - dest_width, - dest_height, - src_cs, dest_cs, - rsc); + ret = ipu_ic_task_init_rsc(chan->ic, &ctx->csc, + s_image->tile[tile].width, + s_image->tile[tile].height, + dest_width, + dest_height, + rsc); if (ret) { dev_err(priv->ipu->dev, "ipu_ic_task_init failed, %d\n", ret); return ret; @@ -2058,6 +2054,16 @@ ipu_image_convert_prepare(struct ipu_soc *ipu, enum ipu_ic_task ic_task, calc_tile_resize_coefficients(ctx); + ret = ipu_ic_calc_csc(&ctx->csc, + s_image->base.pix.ycbcr_enc, + s_image->base.pix.quantization, + ipu_pixelformat_to_colorspace(s_image->fmt->fourcc), + d_image->base.pix.ycbcr_enc, + d_image->base.pix.quantization, + ipu_pixelformat_to_colorspace(d_image->fmt->fourcc)); + if (ret) + goto out_free; + dump_format(ctx, s_image); dump_format(ctx, d_image); diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index 64037b0a8387..e8b36a181ccc 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c @@ -456,6 +456,7 @@ static int prp_setup_rotation(struct prp_priv *priv) const struct imx_media_pixfmt *outcc, *incc; struct v4l2_mbus_framefmt *infmt; struct v4l2_pix_format *outfmt; + struct ipu_ic_csc csc; dma_addr_t phys[2]; int ret; @@ -464,6 +465,17 @@ static int prp_setup_rotation(struct prp_priv *priv) incc = priv->cc[PRPENCVF_SINK_PAD]; outcc = vdev->cc; + ret = ipu_ic_calc_csc(&csc, + infmt->ycbcr_enc, infmt->quantization, + incc->cs, + outfmt->ycbcr_enc, outfmt->quantization, + outcc->cs); + if (ret) { + v4l2_err(&ic_priv->sd, "ipu_ic_calc_csc failed, %d\n", + ret); + return ret; + } + ret = imx_media_alloc_dma_buf(priv->md, &priv->rot_buf[0], outfmt->sizeimage); if (ret) { @@ -477,10 +489,9 @@ static int prp_setup_rotation(struct prp_priv *priv) goto free_rot0; } - ret = ipu_ic_task_init(priv->ic, + ret = ipu_ic_task_init(priv->ic, &csc, infmt->width, infmt->height, - outfmt->height, outfmt->width, - incc->cs, outcc->cs); + outfmt->height, outfmt->width); if (ret) { v4l2_err(&ic_priv->sd, "ipu_ic_task_init failed, %d\n", ret); goto free_rot1; @@ -572,6 +583,7 @@ static int prp_setup_norotation(struct prp_priv *priv) const struct imx_media_pixfmt *outcc, *incc; struct v4l2_mbus_framefmt *infmt; struct v4l2_pix_format *outfmt; + struct ipu_ic_csc csc; dma_addr_t phys[2]; int ret; @@ -580,10 +592,20 @@ static int prp_setup_norotation(struct prp_priv *priv) incc = priv->cc[PRPENCVF_SINK_PAD]; outcc = vdev->cc; - ret = ipu_ic_task_init(priv->ic, + ret = ipu_ic_calc_csc(&csc, + infmt->ycbcr_enc, infmt->quantization, + incc->cs, + outfmt->ycbcr_enc, outfmt->quantization, + outcc->cs); + if (ret) { + v4l2_err(&ic_priv->sd, "ipu_ic_calc_csc failed, %d\n", + ret); + return ret; + } + + ret = ipu_ic_task_init(priv->ic, &csc, infmt->width, infmt->height, - outfmt->width, outfmt->height, - incc->cs, outcc->cs); + outfmt->width, outfmt->height); if (ret) { v4l2_err(&ic_priv->sd, "ipu_ic_task_init failed, %d\n", ret); return ret; diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h index b03fafa1ff58..06b0b57e996c 100644 --- a/include/video/imx-ipu-v3.h +++ b/include/video/imx-ipu-v3.h @@ -387,20 +387,64 @@ enum ipu_ic_task { IC_NUM_TASKS, }; +/* + * The parameters that describe a colorspace according to the + * Image Converter: + * - Y'CbCr encoding + * - quantization + * - "colorspace" (RGB or YUV). + */ +struct ipu_ic_colorspace { + enum v4l2_ycbcr_encoding enc; + enum v4l2_quantization quant; + enum ipu_color_space cs; +}; + +static inline void +ipu_ic_fill_colorspace(struct ipu_ic_colorspace *ic_cs, + enum v4l2_ycbcr_encoding enc, + enum v4l2_quantization quant, + enum ipu_color_space cs) +{ + ic_cs->enc = enc; + ic_cs->quant = quant; + ic_cs->cs = cs; +} + +struct ipu_ic_csc_params { + s16 coeff[3][3]; /* signed 9-bit integer coefficients */ + s16 offset[3]; /* signed 11+2-bit fixed point offset */ + u8 scale:2; /* scale coefficients * 2^(scale-1) */ + bool sat:1; /* saturate to (16, 235(Y) / 240(U, V)) */ +}; + +struct ipu_ic_csc { + struct ipu_ic_colorspace in_cs; + struct ipu_ic_colorspace out_cs; + struct ipu_ic_csc_params params; +}; + struct ipu_ic; + +int __ipu_ic_calc_csc(struct ipu_ic_csc *csc); +int ipu_ic_calc_csc(struct ipu_ic_csc *csc, + enum v4l2_ycbcr_encoding in_enc, + enum v4l2_quantization in_quant, + enum ipu_color_space in_cs, + enum v4l2_ycbcr_encoding out_enc, + enum v4l2_quantization out_quant, + enum ipu_color_space out_cs); int ipu_ic_task_init(struct ipu_ic *ic, + const struct ipu_ic_csc *csc, int in_width, int in_height, - int out_width, int out_height, - enum ipu_color_space in_cs, - enum ipu_color_space out_cs); + int out_width, int out_height); int ipu_ic_task_init_rsc(struct ipu_ic *ic, + const struct ipu_ic_csc *csc, int in_width, int in_height, int out_width, int out_height, - enum ipu_color_space in_cs, - enum ipu_color_space out_cs, u32 rsc); int ipu_ic_task_graphics_init(struct ipu_ic *ic, - enum ipu_color_space in_g_cs, + const struct ipu_ic_colorspace *g_in_cs, bool galpha_en, u32 galpha, bool colorkey_en, u32 colorkey); void ipu_ic_task_enable(struct ipu_ic *ic); From patchwork Wed May 22 01:03:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Longerbeam X-Patchwork-Id: 10954663 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BA2E214B6 for ; Wed, 22 May 2019 01:03:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC63928AAA for ; Wed, 22 May 2019 01:03:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A096A28B25; Wed, 22 May 2019 01:03:39 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2D02228A71 for ; Wed, 22 May 2019 01:03:39 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8A20A896E5; Wed, 22 May 2019 01:03:35 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pl1-x642.google.com (mail-pl1-x642.google.com [IPv6:2607:f8b0:4864:20::642]) by gabe.freedesktop.org (Postfix) with ESMTPS id 209CB896C7 for ; Wed, 22 May 2019 01:03:32 +0000 (UTC) Received: by mail-pl1-x642.google.com with SMTP id p1so197626plo.2 for ; Tue, 21 May 2019 18:03:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=KR2SKJZVR7dpL/K3IRH5SfiJbtnvBNtS7TM5fTzvwUU=; b=JL1t4P4oG7pfzjrIX6VAjLV22tK1cmPG8eb+t7S1smXDNoHEi75MbxucmVKJ7vC6OJ Mcc/RAw/iWpQ55iDS6UKDSury5Vp0FiUXcKnhec0wamXff3+Tj3rjLeSn3VWdrpf9SpL 1mYq+h1kwQvFWMU5GhqcRFIsmWNtZ9SlP2yq9Von4cAbN/fo3Ezy8i4o3WWkzeABODHP jSvEv+JdG2Fr5xJr+OH04HdFPSXDJ1o+u0aOMv72O1nozvqBt573oDt90UTM2wuvK3c4 Yxthhr2DPrGOkhq0NdqtsHzHkPbWOb5KRYKNA4UuCdp0Cmv2lxp9mZAoqTGMjvwXyJU1 PpAw== X-Gm-Message-State: APjAAAUaNTJdFPqsL/3mIszkTwNa9r6gZgcEAn2yyXs52R7igqzXXj1p JYKQkxfau+xjyiOzhJDBwwZ8aRDf X-Google-Smtp-Source: APXvYqykPyD2qJbS9WVld6QmroysQrD9PBf86L0y3vxq20JEw07sose/NZ9zVGHthyLMv4cZwb9Qug== X-Received: by 2002:a17:902:12f:: with SMTP id 44mr40653762plb.137.1558487011546; Tue, 21 May 2019 18:03:31 -0700 (PDT) Received: from majic.sklembedded.com (c-73-202-231-77.hsd1.ca.comcast.net. [73.202.231.77]) by smtp.googlemail.com with ESMTPSA id q193sm34291242pfc.52.2019.05.21.18.03.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 May 2019 18:03:30 -0700 (PDT) From: Steve Longerbeam To: linux-media@vger.kernel.org Subject: [PATCH v8 3/5] gpu: ipu-v3: ipu-ic-csc: Add support for limited range encoding Date: Tue, 21 May 2019 18:03:15 -0700 Message-Id: <20190522010317.23710-4-slongerbeam@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190522010317.23710-1-slongerbeam@gmail.com> References: <20190522010317.23710-1-slongerbeam@gmail.com> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=KR2SKJZVR7dpL/K3IRH5SfiJbtnvBNtS7TM5fTzvwUU=; b=HHgQUWC34be18WJ5hpThjXaJU/6mavEM8ZzuyekAbNVxY/4FX8Cs/A5WF6CsgOwtKE NxUmOwiHscHOZ6sxipTWhKlKUD5q3a3HTRuWmduWUtGNyeWty1CBbEAR48zNpf8gxjxV T3ss6wWbGfo35ppJ6pmZdjOwfLO7EEJODY5/VgkTlNVvKDVKLeR4B9o3ry0EBX9F6kzx zfmP+JnvBG9mV5DZKXKcHjtqAgXCSMI2mmxCjL99jcC1cnirFzqCO8GKMYDaKXRJwEMV J/J6k/95z9HZR5yKOo95sEBfgoljDZt45iN33bTeJRM36aW2/3wSHXTg80Je6dQGWvQM pLqg== X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: open list , "open list:DRM DRIVERS FOR FREESCALE IMX" , Steve Longerbeam MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add support for encodings to or from limited range quantization. Signed-off-by: Steve Longerbeam --- Changes in v7: - hard-code the coefficients instead of deriving the limited range coefficients from the full2full coefficients on the fly with fixed-point math. - add support for RGB limited-range. --- drivers/gpu/ipu-v3/ipu-ic-csc.c | 180 +++++++++++++++++++++++++++++--- 1 file changed, 166 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/ipu-v3/ipu-ic-csc.c b/drivers/gpu/ipu-v3/ipu-ic-csc.c index 5fb469cd64fe..8e9150b1d668 100644 --- a/drivers/gpu/ipu-v3/ipu-ic-csc.c +++ b/drivers/gpu/ipu-v3/ipu-ic-csc.c @@ -10,6 +10,10 @@ #include #include "ipu-prv.h" +#define QUANT_MAP(q) \ + ((q) == V4L2_QUANTIZATION_FULL_RANGE || \ + (q) == V4L2_QUANTIZATION_DEFAULT ? 0 : 1) + /* identity matrix */ static const struct ipu_ic_csc_params identity = { .coeff = { @@ -21,12 +25,87 @@ static const struct ipu_ic_csc_params identity = { .scale = 2, }; +/* + * RGB full-range to RGB limited-range + * + * R_lim = 0.8588 * R_full + 16 + * G_lim = 0.8588 * G_full + 16 + * B_lim = 0.8588 * B_full + 16 + */ +static const struct ipu_ic_csc_params rgbf2rgbl = { + .coeff = { + { 220, 0, 0, }, + { 0, 220, 0, }, + { 0, 0, 220, }, + }, + .offset = { 64, 64, 64, }, + .scale = 1, +}; + +/* + * RGB limited-range to RGB full-range + * + * R_full = 1.1644 * (R_lim - 16) + * G_full = 1.1644 * (G_lim - 16) + * B_full = 1.1644 * (B_lim - 16) + */ +static const struct ipu_ic_csc_params rgbl2rgbf = { + .coeff = { + { 149, 0, 0, }, + { 0, 149, 0, }, + { 0, 0, 149, }, + }, + .offset = { -37, -37, -37, }, + .scale = 2, +}; + +/* + * YUV full-range to YUV limited-range + * + * Y_lim = 0.8588 * Y_full + 16 + * Cb_lim = 0.8784 * (Cb_full - 128) + 128 + * Cr_lim = 0.8784 * (Cr_full - 128) + 128 + */ +static const struct ipu_ic_csc_params yuvf2yuvl = { + .coeff = { + { 220, 0, 0, }, + { 0, 225, 0, }, + { 0, 0, 225, }, + }, + .offset = { 64, 62, 62, }, + .scale = 1, + .sat = true, +}; + +/* + * YUV limited-range to YUV full-range + * + * Y_full = 1.1644 * (Y_lim - 16) + * Cb_full = 1.1384 * (Cb_lim - 128) + 128 + * Cr_full = 1.1384 * (Cr_lim - 128) + 128 + */ +static const struct ipu_ic_csc_params yuvl2yuvf = { + .coeff = { + { 149, 0, 0, }, + { 0, 146, 0, }, + { 0, 0, 146, }, + }, + .offset = { -37, -35, -35, }, + .scale = 2, +}; + static const struct ipu_ic_csc_params *rgb2rgb[] = { &identity, + &rgbf2rgbl, + &rgbl2rgbf, + &identity, }; static const struct ipu_ic_csc_params *yuv2yuv[] = { &identity, + &yuvf2yuvl, + &yuvl2yuvf, + &identity, }; /* @@ -46,6 +125,41 @@ static const struct ipu_ic_csc_params rgbf2yuvf_601 = { .scale = 1, }; +/* BT.601 RGB full-range to YUV limited-range */ +static const struct ipu_ic_csc_params rgbf2yuvl_601 = { + .coeff = { + { 66, 129, 25, }, + { -38, -74, 112, }, + { 112, -94, -18, }, + }, + .offset = { 64, 512, 512, }, + .scale = 1, + .sat = true, +}; + +/* BT.601 RGB limited-range to YUV full-range */ +static const struct ipu_ic_csc_params rgbl2yuvf_601 = { + .coeff = { + { 89, 175, 34, }, + { -50, -99, 149, }, + { 149, -125, -24, }, + }, + .offset = { -75, 512, 512, }, + .scale = 1, +}; + +/* BT.601 RGB limited-range to YUV limited-range */ +static const struct ipu_ic_csc_params rgbl2yuvl_601 = { + .coeff = { + { 77, 150, 29, }, + { -44, -87, 131, }, + { 131, -110, -21, }, + }, + .offset = { 0, 512, 512, }, + .scale = 1, + .sat = true, +}; + /* * BT.601 YUV full-range to RGB full-range * @@ -69,39 +183,77 @@ static const struct ipu_ic_csc_params yuvf2rgbf_601 = { .scale = 2, }; +/* BT.601 YUV full-range to RGB limited-range */ +static const struct ipu_ic_csc_params yuvf2rgbl_601 = { + .coeff = { + { 110, 0, 154, }, + { 110, -38, -78, }, + { 110, 195, 0, }, + }, + .offset = { -276, 265, -358, }, + .scale = 2, +}; + +/* BT.601 YUV limited-range to RGB full-range */ +static const struct ipu_ic_csc_params yuvl2rgbf_601 = { + .coeff = { + { 75, 0, 102, }, + { 75, -25, -52, }, + { 75, 129, 0, }, + }, + .offset = { -223, 136, -277, }, + .scale = 3, +}; + +/* BT.601 YUV limited-range to RGB limited-range */ +static const struct ipu_ic_csc_params yuvl2rgbl_601 = { + .coeff = { + { 128, 0, 175, }, + { 128, -43, -89, }, + { 128, 222, 0, }, + }, + .offset = { -351, 265, -443, }, + .scale = 2, +}; + static const struct ipu_ic_csc_params *rgb2yuv_601[] = { &rgbf2yuvf_601, + &rgbf2yuvl_601, + &rgbl2yuvf_601, + &rgbl2yuvl_601, }; static const struct ipu_ic_csc_params *yuv2rgb_601[] = { &yuvf2rgbf_601, + &yuvf2rgbl_601, + &yuvl2rgbf_601, + &yuvl2rgbl_601, }; static int calc_csc_coeffs(struct ipu_ic_csc *csc) { + const struct ipu_ic_csc_params **params_tbl; + int tbl_idx; + if (csc->out_cs.enc != V4L2_YCBCR_ENC_601) return -ENOTSUPP; - if ((csc->in_cs.cs == IPUV3_COLORSPACE_YUV && - csc->in_cs.quant != V4L2_QUANTIZATION_FULL_RANGE) || - (csc->out_cs.cs == IPUV3_COLORSPACE_YUV && - csc->out_cs.quant != V4L2_QUANTIZATION_FULL_RANGE)) - return -ENOTSUPP; - - if ((csc->in_cs.cs == IPUV3_COLORSPACE_RGB && - csc->in_cs.quant != V4L2_QUANTIZATION_FULL_RANGE) || - (csc->out_cs.cs == IPUV3_COLORSPACE_RGB && - csc->out_cs.quant != V4L2_QUANTIZATION_FULL_RANGE)) - return -ENOTSUPP; + tbl_idx = (QUANT_MAP(csc->in_cs.quant) << 1) | + QUANT_MAP(csc->out_cs.quant); if (csc->in_cs.cs == csc->out_cs.cs) { csc->params = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ? - *yuv2yuv[0] : *rgb2rgb[0]; + *yuv2yuv[tbl_idx] : *rgb2rgb[tbl_idx]; + return 0; } - csc->params = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ? - *yuv2rgb_601[0] : *rgb2yuv_601[0]; + /* YUV <-> RGB encoding is required */ + + params_tbl = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ? + yuv2rgb_601 : rgb2yuv_601; + + csc->params = *params_tbl[tbl_idx]; return 0; } From patchwork Wed May 22 01:03:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Longerbeam X-Patchwork-Id: 10954661 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A357914B6 for ; Wed, 22 May 2019 01:03:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 94A6F28A71 for ; Wed, 22 May 2019 01:03:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 889F128AAA; Wed, 22 May 2019 01:03:37 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1181728A71 for ; Wed, 22 May 2019 01:03:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DC62A896E7; Wed, 22 May 2019 01:03:34 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pf1-x443.google.com (mail-pf1-x443.google.com [IPv6:2607:f8b0:4864:20::443]) by gabe.freedesktop.org (Postfix) with ESMTPS id B1B12896E7 for ; Wed, 22 May 2019 01:03:33 +0000 (UTC) Received: by mail-pf1-x443.google.com with SMTP id t87so373109pfa.2 for ; Tue, 21 May 2019 18:03:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4LWWo6vClK616q2qAdH10ez3h7JYhnb9DJf05zCL0Rc=; b=H6zVUPvHYPWuGh+kj7eEAnAdowFUQAVvO2Mv01OTQIc4mbJ1eOAmHT8r2hcz8S2frg PMJQCf5mvJbKAXOGjXnVbO2kDa3bMy0didlfxWnrJgsphhsJX3en3O6Oe+LUsKrpwGPE OJCnykkHhYJ7jEDUcrcNgoObSWIpordwBfeHJw1rBX0wtibmGs0j42LcVcRj7SWw7Zy8 hrpUCfsMtQK5OLIwOrJa6UsvhdJkIUWRPXHqrYVRIMZ4Df3n/hR9Pcqre8pu62YcQ4FP ISNlf2dChjiDLQZWTL0tEehVwN6kEdnMDgDK0SKkR9sOfgVjW53C20WhPmTmbiw8NIsh cL9w== X-Gm-Message-State: APjAAAVU5OT3B6bMtqW1+8OqufH8LN5E1ib0olAjj22a2ofb+EVBs7ag fdXg8GXo7rlhOF3KLI3eLS0= X-Google-Smtp-Source: APXvYqx46cgSSnZBSN8MWy4w7UZ6LJ5vZdvCQjHSWoe3hmviwnIYYozuLF6vRtAMmZFD3wJxA9CP7A== X-Received: by 2002:a62:575b:: with SMTP id l88mr91654511pfb.143.1558487013025; Tue, 21 May 2019 18:03:33 -0700 (PDT) Received: from majic.sklembedded.com (c-73-202-231-77.hsd1.ca.comcast.net. [73.202.231.77]) by smtp.googlemail.com with ESMTPSA id q193sm34291242pfc.52.2019.05.21.18.03.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 May 2019 18:03:32 -0700 (PDT) From: Steve Longerbeam To: linux-media@vger.kernel.org Subject: [PATCH v8 4/5] gpu: ipu-v3: ipu-ic-csc: Add support for Rec.709 encoding Date: Tue, 21 May 2019 18:03:16 -0700 Message-Id: <20190522010317.23710-5-slongerbeam@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190522010317.23710-1-slongerbeam@gmail.com> References: <20190522010317.23710-1-slongerbeam@gmail.com> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4LWWo6vClK616q2qAdH10ez3h7JYhnb9DJf05zCL0Rc=; b=HbANLn+g0LwhyL73Znthe1lIqjmXuS5dqUXxR+6LYakUxm9jvTiZqWvFAXWT6Mg0Cu VxWu2fAdjE+2eb5xGK+NY38ms+xhOutmalOoq/bJWbCnk73gDzvGFRQimK5EVDONrWZm Ho93lEevjG5LyoArdC6YBvHYJzIPtn3GhFJIFGqhQm/FpkxIMJl22y6Dx6vclvMMAr9C wdKsrcvKRrOKH5OgtQZherSQQ5CdFYgrze/sRst4uhjq+9249vdQ6TtiZCyqN7qAAp4X aXafPWhJQaFdqPWtnw/SYFfKwRN75UkKzBF+gmethj1+YRDrsNgKFiZR3RLBLQivMAbZ oDsw== X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: open list , "open list:DRM DRIVERS FOR FREESCALE IMX" , Steve Longerbeam MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add support for Rec.709 encoding and inverse encoding. Reported-by: Tim Harvey Signed-off-by: Steve Longerbeam --- Changes in v7: - moved CSC tables to new module ipu-ic-csc.c. - express negative coefficients as true signed int's, for better readability. Changes in v5: - moved API changes to a previous patch. - moved CSC coeff calc to new function calc_csc_coeffs(). Changes in v4: - fix compile error. Chnges in v3: - none. Changes in v2: - only return "Unsupported YCbCr encoding" error if inf != outf, since if inf == outf, the identity matrix can be used. Reported by Tim Harvey. --- drivers/gpu/ipu-v3/ipu-ic-csc.c | 139 ++++++++++++++++++++++++++++++-- 1 file changed, 134 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/ipu-v3/ipu-ic-csc.c b/drivers/gpu/ipu-v3/ipu-ic-csc.c index 8e9150b1d668..09e94aa12c40 100644 --- a/drivers/gpu/ipu-v3/ipu-ic-csc.c +++ b/drivers/gpu/ipu-v3/ipu-ic-csc.c @@ -230,14 +230,133 @@ static const struct ipu_ic_csc_params *yuv2rgb_601[] = { &yuvl2rgbl_601, }; +/* + * REC.709 encoding from RGB full range to YUV full range: + * + * Y = .2126 * R + .7152 * G + .0722 * B + * U = -.1146 * R - .3854 * G + .5000 * B + 128 + * V = .5000 * R - .4542 * G - .0458 * B + 128 + */ +static const struct ipu_ic_csc_params rgbf2yuvf_709 = { + .coeff = { + { 54, 183, 19 }, + { -29, -99, 128 }, + { 128, -116, -12 }, + }, + .offset = { 0, 512, 512 }, + .scale = 1, +}; + +/* Rec.709 RGB full-range to YUV limited-range */ +static const struct ipu_ic_csc_params rgbf2yuvl_709 = { + .coeff = { + { 47, 157, 16, }, + { -26, -87, 112, }, + { 112, -102, -10, }, + }, + .offset = { 64, 512, 512, }, + .scale = 1, + .sat = true, +}; + +/* Rec.709 RGB limited-range to YUV full-range */ +static const struct ipu_ic_csc_params rgbl2yuvf_709 = { + .coeff = { + { 63, 213, 22, }, + { -34, -115, 149, }, + { 149, -135, -14, }, + }, + .offset = { -75, 512, 512, }, + .scale = 1, +}; + +/* Rec.709 RGB limited-range to YUV limited-range */ +static const struct ipu_ic_csc_params rgbl2yuvl_709 = { + .coeff = { + { 54, 183, 18, }, + { -30, -101, 131, }, + { 131, -119, -12, }, + }, + .offset = { 0, 512, 512, }, + .scale = 1, + .sat = true, +}; + +/* + * Inverse REC.709 encoding from YUV full range to RGB full range: + * + * R = 1. * Y + 0 * (Cb - 128) + 1.5748 * (Cr - 128) + * G = 1. * Y - .1873 * (Cb - 128) - .4681 * (Cr - 128) + * B = 1. * Y + 1.8556 * (Cb - 128) + 0 * (Cr - 128) + * + * equivalently (factoring out the offsets): + * + * R = 1. * Y + 0 * Cb + 1.5748 * Cr - 201.574 + * G = 1. * Y - .1873 * Cb - .4681 * Cr + 83.891 + * B = 1. * Y + 1.8556 * Cb + 0 * Cr - 237.517 + */ +static const struct ipu_ic_csc_params yuvf2rgbf_709 = { + .coeff = { + { 128, 0, 202 }, + { 128, -24, -60 }, + { 128, 238, 0 }, + }, + .offset = { -403, 168, -475 }, + .scale = 2, +}; + +/* Rec.709 YUV full-range to RGB limited-range */ +static const struct ipu_ic_csc_params yuvf2rgbl_709 = { + .coeff = { + { 110, 0, 173, }, + { 110, -21, -51, }, + { 110, 204, 0, }, + }, + .offset = { -314, 176, -376, }, + .scale = 2, +}; + +/* Rec.709 YUV limited-range to RGB full-range */ +static const struct ipu_ic_csc_params yuvl2rgbf_709 = { + .coeff = { + { 75, 0, 115, }, + { 75, -14, -34, }, + { 75, 135, 0, }, + }, + .offset = { -248, 77, -289, }, + .scale = 3, +}; + +/* Rec.709 YUV limited-range to RGB limited-range */ +static const struct ipu_ic_csc_params yuvl2rgbl_709 = { + .coeff = { + { 128, 0, 197, }, + { 128, -23, -59, }, + { 128, 232, 0, }, + }, + .offset = { -394, 164, -464, }, + .scale = 2, +}; + +static const struct ipu_ic_csc_params *rgb2yuv_709[] = { + &rgbf2yuvf_709, + &rgbf2yuvl_709, + &rgbl2yuvf_709, + &rgbl2yuvl_709, +}; + +static const struct ipu_ic_csc_params *yuv2rgb_709[] = { + &yuvf2rgbf_709, + &yuvf2rgbl_709, + &yuvl2rgbf_709, + &yuvl2rgbl_709, +}; + static int calc_csc_coeffs(struct ipu_ic_csc *csc) { const struct ipu_ic_csc_params **params_tbl; int tbl_idx; - if (csc->out_cs.enc != V4L2_YCBCR_ENC_601) - return -ENOTSUPP; - tbl_idx = (QUANT_MAP(csc->in_cs.quant) << 1) | QUANT_MAP(csc->out_cs.quant); @@ -250,8 +369,18 @@ static int calc_csc_coeffs(struct ipu_ic_csc *csc) /* YUV <-> RGB encoding is required */ - params_tbl = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ? - yuv2rgb_601 : rgb2yuv_601; + switch (csc->out_cs.enc) { + case V4L2_YCBCR_ENC_601: + params_tbl = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ? + yuv2rgb_601 : rgb2yuv_601; + break; + case V4L2_YCBCR_ENC_709: + params_tbl = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ? + yuv2rgb_709 : rgb2yuv_709; + break; + default: + return -ENOTSUPP; + } csc->params = *params_tbl[tbl_idx];