From patchwork Sat Apr 6 23:08:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Longerbeam X-Patchwork-Id: 10888271 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 68D351669 for ; Sat, 6 Apr 2019 23:09:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3BA3C28760 for ; Sat, 6 Apr 2019 23:09:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1E1F6287A7; Sat, 6 Apr 2019 23:09:21 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 0C2A828760 for ; Sat, 6 Apr 2019 23:09:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726436AbfDFXJN (ORCPT ); Sat, 6 Apr 2019 19:09:13 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:45657 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726027AbfDFXJN (ORCPT ); Sat, 6 Apr 2019 19:09:13 -0400 Received: by mail-pg1-f194.google.com with SMTP id y3so5054765pgk.12; Sat, 06 Apr 2019 16:09:13 -0700 (PDT) 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=L140M9NwbWyz6AhYHSMJDKQiieDEmJyG2w8gK/BOeZFmFKmbl2voNn0xThg47HhnGJ nKBTe5unSIlxzduxUqtUuWlXURSR51JWlPFVZhOa7ahGx+DwZQPH34kzIavY0Uaopwbh n7R0cFo6BlpEgmvNG45jriJW+E3hFk4ykjt/jUobgqUl1B8w3oYna52QNnSeSF+vEh0c 4MUDjVufjo9qHGY/oMtinl2cidvynzDfq0NzfWKz3Yqddm+9t5TyW0UPuJkXPUQTQmib UnuPDSUVV+cgD37yigzKNJtyfeRuAJZk2o+DEgfbLXlQHlwrW9135R0lrz47FLMhS5cn 7dkQ== 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=Lt722asD2QZafqNNaiMy8oEWD9bVemFVvPNoVntYd23g2+MiTFoDQvleHMXPfeUM18 B0gS3YlTllqcVs1yKVKShS+SZd5ODB+ZJ2xflsSqne8gBA1smtRGwAi8U7n9zDpLmtuB nBGh1hdcuLIsJsqaWDwxzBvEqYkLR1tmdfIBf2dj6ff8oPIIxhk+hsFG5lN9VP+S5DKC cUoH5XZ20/7ACW6t7wa3iBk95VbHqIcBsO3Eh4CBzSH2jGfAQJsz44rB3W0Afl/kludA 8O0d9z+UlyImy6lWRhL8h9gRobxHp1ZMrN98yv2jo8hRmqdyt7YMPCIN0gZcC6o58g8e wPBg== X-Gm-Message-State: APjAAAUw59HGpwI/KJ5Is+0LwiUQy7teeXf5xwCJ1hT34tHPQ+sRymgA eO8WgDWDPJ45GotItqzPvVcFbGaq X-Google-Smtp-Source: APXvYqzZQtLjLKEkOW25mrG0uokCAfSeQE3/W3jrtSjSbSkD5F6vf/Kl2IWaOQEnkXsQFYjWc1avaw== X-Received: by 2002:aa7:9095:: with SMTP id i21mr21031709pfa.134.1554592152216; Sat, 06 Apr 2019 16:09:12 -0700 (PDT) Received: from mappy.sklembedded.com (c-24-4-228-186.hsd1.ca.comcast.net. [24.4.228.186]) by smtp.gmail.com with ESMTPSA id i31sm44550127pgi.36.2019.04.06.16.09.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 06 Apr 2019 16:09:11 -0700 (PDT) From: Steve Longerbeam To: linux-media@vger.kernel.org Cc: Steve Longerbeam , stable@vger.kernel.org, Philipp Zabel , dri-devel@lists.freedesktop.org (open list:DRM DRIVERS FOR FREESCALE IMX), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v7 1/5] gpu: ipu-v3: ipu-ic: Fix saturation bit offset in TPMEM Date: Sat, 6 Apr 2019 16:08:59 -0700 Message-Id: <20190406230903.16488-2-slongerbeam@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190406230903.16488-1-slongerbeam@gmail.com> References: <20190406230903.16488-1-slongerbeam@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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 Sat Apr 6 23:09:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Longerbeam X-Patchwork-Id: 10888289 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 A60C71575 for ; Sat, 6 Apr 2019 23:09:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 89F3227FB0 for ; Sat, 6 Apr 2019 23:09:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7D7BC28508; Sat, 6 Apr 2019 23:09:44 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable 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 40A9827FB0 for ; Sat, 6 Apr 2019 23:09:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726600AbfDFXJT (ORCPT ); Sat, 6 Apr 2019 19:09:19 -0400 Received: from mail-pl1-f196.google.com ([209.85.214.196]:43583 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726027AbfDFXJS (ORCPT ); Sat, 6 Apr 2019 19:09:18 -0400 Received: by mail-pl1-f196.google.com with SMTP id n8so497495plp.10; Sat, 06 Apr 2019 16:09:17 -0700 (PDT) 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=5zkr2aP+Nw57OfoSsfAxYgO/iyntfVvGKbQ9CdbTku0=; b=YcipZRgUtoyEn0MjDOwCtFhUHBocV62fOppQYAZpf1sX/tjyIDPG460iIiUZF5E52I cBoIlLHLJ4sqs6smWuN8blO4xFoJFRAmB8nZjMBFbYTFI1iGwVx2k82WBQgm/WU9d0En 5SElIkiXB/wymshf9RlMfGEYfoGjgmRRUie3fy+vyUH7qVMXoimvsGCQPB4C8pN+jErK X4fGjjiubEN0GdV8iwObSzDWZSuOqrdOeeSK+fMaZhjnlqxkr4Q+C/MhcH+DRfiMWctx T4oH4NNHcBOwun8eUGDsDio3ZvWPkt/f4hcceacU9SyVnOGxlUOh9TYe3OZsQekDunyw q+ig== 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=5zkr2aP+Nw57OfoSsfAxYgO/iyntfVvGKbQ9CdbTku0=; b=dazM6CxoyCx3zCAFJLsT56VCq2NQG4VGUyLL3e4MJousDR6gtNTAlZmwy6KchpptTn dyhwZzyS4AHvEcZMeUd59UVtMxlt2XWT6OEnOIWWbRZcf457fkt05jcEPs1+qewYdyw1 vpqVXJ1cCnW44m23xyU9f3FcYhyDmGaw7boBXcUnWZZYMb+rJUSwKMNL1Nga5r6Gpfba yng4c0rD7eVyIQEhhI8YgAwHkcoqsw8OZIIGSnUY2a/bndkGUb+a5oyKT2RCQyEAu4ON MVMKpPPHAPKZUbwGtufTpyl87AFJoy6T/eXNw852ujKRTGFd+e3N3RzyhXIqurS5fvAo +/Ew== X-Gm-Message-State: APjAAAXxpd85VtqN72z4BQ/Gn2bz/sJO3rYRxFekkoHVkASWuStQgDGl k7sTBbh31TO73eUiEMQBrpgdJ+dE X-Google-Smtp-Source: APXvYqzcFHSque016md3wZogAnGyQr9V3H/uhX7fH9Y+G745W13GVH7UyyhsCtpnseiauTrO9gSTyA== X-Received: by 2002:a17:902:e20e:: with SMTP id ce14mr21716858plb.193.1554592155605; Sat, 06 Apr 2019 16:09:15 -0700 (PDT) Received: from mappy.sklembedded.com (c-24-4-228-186.hsd1.ca.comcast.net. [24.4.228.186]) by smtp.gmail.com with ESMTPSA id i31sm44550127pgi.36.2019.04.06.16.09.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 06 Apr 2019 16:09:14 -0700 (PDT) From: Steve Longerbeam To: linux-media@vger.kernel.org Cc: Steve Longerbeam , stable@vger.kernel.org, Philipp Zabel , Mauro Carvalho Chehab , Greg Kroah-Hartman , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Bartlomiej Zolnierkiewicz , linux-kernel@vger.kernel.org (open list), dri-devel@lists.freedesktop.org (open list:DRM DRIVERS FOR FREESCALE IMX), devel@driverdev.osuosl.org (open list:STAGING SUBSYSTEM), linux-arm-kernel@lists.infradead.org (moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE), linux-fbdev@vger.kernel.org (open list:FRAMEBUFFER LAYER) Subject: [PATCH v7 2/5] gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Date: Sat, 6 Apr 2019 16:09:00 -0700 Message-Id: <20190406230903.16488-3-slongerbeam@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190406230903.16488-1-slongerbeam@gmail.com> References: <20190406230903.16488-1-slongerbeam@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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. Fixes: 1aa8ea0d2bd5d ("gpu: ipu-v3: Add Image Converter unit") Signed-off-by: Steve Longerbeam Cc: stable@vger.kernel.org --- 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 5c8e6ad8c025..7e8405d3b75c 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c @@ -460,6 +460,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; @@ -468,6 +469,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) { @@ -481,10 +493,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; @@ -576,6 +587,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; @@ -584,10 +596,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 Sat Apr 6 23:09:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Longerbeam X-Patchwork-Id: 10888291 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 E9E7D1669 for ; Sat, 6 Apr 2019 23:09:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BCBF827FB0 for ; Sat, 6 Apr 2019 23:09:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B11EB2833E; Sat, 6 Apr 2019 23:09:45 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 7D26E28382 for ; Sat, 6 Apr 2019 23:09:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726582AbfDFXJT (ORCPT ); Sat, 6 Apr 2019 19:09:19 -0400 Received: from mail-pl1-f195.google.com ([209.85.214.195]:33799 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726548AbfDFXJS (ORCPT ); Sat, 6 Apr 2019 19:09:18 -0400 Received: by mail-pl1-f195.google.com with SMTP id y6so5069267plt.1; Sat, 06 Apr 2019 16:09:18 -0700 (PDT) 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=Y5F5TkFX0AnKxwmdZeCsztIQ2thjKHOFsP07ycnxDutXTty4MFyxoQuTznuq6QvUM4 biPSvSIR03t4r/qfv2qio2Nsoi/tBM2lZnZbxRJrUCWaGrI2h9LN26g6uo4CuY/qcFa1 d/HokLTzBGhBaqo8zDdF9/WlfKJXhuMXh6x8+32hVJ5JPlaykmMffjM74tJpsdParhzh C9iCwhGS1hKtQcnCo6yytJEDZdnwXLeshRAmYVfponTH2KpUQc5dWmDoNujKy+MCvO7E Pa1DZN/21kZDpQ3kiXLnoWdKoF8MbFuV5X5JmIazDzy2WUksWc8bxrzOzJbqqWTzhE9e vRfQ== 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=lah5B5X7yC9VwrJWjJDvWYyaBUy4dauX0soMeG6ZoTntZK6QIBCRSvDeYX2FbLuUgx oQzg4Eefx2WqHva0az9wbEbsmoTX912RjRcsJaPnN+lPwsjraeqEsvQzNI3+GhyjjKxb euAp+g60fQdyWmn1dOSNvgeT2xuaV1f0TZ7FewQbcAK/bcCiGYu5wmsiv0gPIBwSqqlT quoTNAG1HZiz7Pn8pC7s7XXqlqcD0Wnei6OOUkagN2bTSv43xSDIJArRcsSI/HT7b7TL uPx3wfvcx1z/WHmu5kwxmApSapuilYvHIg/K2SNyFJsxdUjIR37M+b0S1MTshTONOK29 UN4Q== X-Gm-Message-State: APjAAAV02KAv8VwuUPbhEv32fAFJulLyC62SCZl0JTPB9xhQiG+RKPL0 Iipt3F06igQrjTXML/l6n0eaCn9D X-Google-Smtp-Source: APXvYqxKxSL7YQ8p0JJbSeUFp9TvxUjtb9CN6lXk7shdPIcioJL8LuNTtMK9Dte4l6hkxMZir+bQiA== X-Received: by 2002:a17:902:2aa6:: with SMTP id j35mr21692612plb.56.1554592157281; Sat, 06 Apr 2019 16:09:17 -0700 (PDT) Received: from mappy.sklembedded.com (c-24-4-228-186.hsd1.ca.comcast.net. [24.4.228.186]) by smtp.gmail.com with ESMTPSA id i31sm44550127pgi.36.2019.04.06.16.09.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 06 Apr 2019 16:09:16 -0700 (PDT) From: Steve Longerbeam To: linux-media@vger.kernel.org Cc: Steve Longerbeam , Philipp Zabel , dri-devel@lists.freedesktop.org (open list:DRM DRIVERS FOR FREESCALE IMX), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v7 3/5] gpu: ipu-v3: ipu-ic-csc: Add support for limited range encoding Date: Sat, 6 Apr 2019 16:09:01 -0700 Message-Id: <20190406230903.16488-4-slongerbeam@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190406230903.16488-1-slongerbeam@gmail.com> References: <20190406230903.16488-1-slongerbeam@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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 Sat Apr 6 23:09:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Longerbeam X-Patchwork-Id: 10888285 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 3F79D1669 for ; Sat, 6 Apr 2019 23:09:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 117F227FB0 for ; Sat, 6 Apr 2019 23:09:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 05FCD28508; Sat, 6 Apr 2019 23:09:40 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 612D227FB0 for ; Sat, 6 Apr 2019 23:09:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726693AbfDFXJd (ORCPT ); Sat, 6 Apr 2019 19:09:33 -0400 Received: from mail-pl1-f193.google.com ([209.85.214.193]:41765 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726633AbfDFXJV (ORCPT ); Sat, 6 Apr 2019 19:09:21 -0400 Received: by mail-pl1-f193.google.com with SMTP id d1so5064466plj.8; Sat, 06 Apr 2019 16:09:20 -0700 (PDT) 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=u2CJHuP+mlcuAlWQcV+owWFbPFC6wVKcWwh80i3aZoFl6gw7mh5esYsKmDURBbknUz Sn41Ks+a/L9sB8YjmtAKfSAMLmUcQXxk2Tz8DKhwKfvp1VfVBhEGhx1E0NDtYeVVB4H3 7Yx5JnFro5faXv5HURzYnPsE2qdpAr5adYXFkQu0izPsARg5pDtEYAonqBbzxZSBTkUU kJAt3PZewG//fUrFwXweB8fimmt8QFh+qF/bm1LE2NkFJJmwoZDW+KA9D8G7vOeh+63F Kcbcsvu+3ntHxUSRF04o7HSte/O8ZjIdEuy0rVSnDXCwV/1vFu9J6p0r8CR4L/v+3EA5 bLmg== 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=TpI/Zv+Zg/AGWm4qRqjjGNQ8GsBns81cHCuqK7NoAQy6cx94kvZIJOi199RA3B7VcI oyncCEyEdLQ+DuQa0Fs+I52BXr7mnZENhKYbbeCzgCqX0fHJ85qG1hIfIEHSFEQwca7E xROD3R33rbU5XgwGZMU5+KqFWRMRR9Yoi6D8Kn8RaPWjH0sXkK1sqmWAmKbEaV8Q2Zxs ADqlrveW1Z096gkB4DVK1H8bHpAiXWXgx4wDq0qWDadh0b4e1z5FLY2fkkBuJJeKq+1F tAMwBkUvNWSpWtfe8m4jPNC42tp1s6av3sIVXIGpDNbJe4wGuGZQgOcmOWMqmyNzQktp 6j+A== X-Gm-Message-State: APjAAAWgH4rx3foaAJ185vbbyAkCs/yP+/TZ7NsYApKr6VzKOx1ekTxp E5U59jNhKfhYLLVo1EsE4toFDCfP X-Google-Smtp-Source: APXvYqyB2zkXHJyKOMcaXbH72PsVzQ752yWo+UhPbj8OCDS9YFc0h8937cv0rgq2n+jqie8Vt7IIsA== X-Received: by 2002:a17:902:7c94:: with SMTP id y20mr21626181pll.263.1554592158783; Sat, 06 Apr 2019 16:09:18 -0700 (PDT) Received: from mappy.sklembedded.com (c-24-4-228-186.hsd1.ca.comcast.net. [24.4.228.186]) by smtp.gmail.com with ESMTPSA id i31sm44550127pgi.36.2019.04.06.16.09.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 06 Apr 2019 16:09:18 -0700 (PDT) From: Steve Longerbeam To: linux-media@vger.kernel.org Cc: Steve Longerbeam , Philipp Zabel , dri-devel@lists.freedesktop.org (open list:DRM DRIVERS FOR FREESCALE IMX), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v7 4/5] gpu: ipu-v3: ipu-ic-csc: Add support for Rec.709 encoding Date: Sat, 6 Apr 2019 16:09:02 -0700 Message-Id: <20190406230903.16488-5-slongerbeam@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190406230903.16488-1-slongerbeam@gmail.com> References: <20190406230903.16488-1-slongerbeam@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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]; From patchwork Sat Apr 6 23:09:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Longerbeam X-Patchwork-Id: 10888279 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 05CA41669 for ; Sat, 6 Apr 2019 23:09:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C80CC2875A for ; Sat, 6 Apr 2019 23:09:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B575328761; Sat, 6 Apr 2019 23:09: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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 D45292875A for ; Sat, 6 Apr 2019 23:09:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726664AbfDFXJZ (ORCPT ); Sat, 6 Apr 2019 19:09:25 -0400 Received: from mail-pf1-f193.google.com ([209.85.210.193]:40503 "EHLO mail-pf1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726637AbfDFXJW (ORCPT ); Sat, 6 Apr 2019 19:09:22 -0400 Received: by mail-pf1-f193.google.com with SMTP id c207so5344552pfc.7; Sat, 06 Apr 2019 16:09:21 -0700 (PDT) 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=9vFEtR41P1AeMUFHOos3mmBMGwqw/eIJuTUHN6Bzt0E=; b=tWLV2kAtZ0zCBoYqByF2BIn61QI61S+DaiWeHI6ME0YzikrKg61D240PXVwQC2GI0c efRkfAx7PeQSLSuO/00SCfDxz6amkFZBPma+HsXZ/D9byjDGPcm/Iq4+E63PmVdmQ98f eRxUx7b9OFMcBoJ0fU+bcOfgv6mw8dhavlhKno/+jgnHOyjL4aYzfoxCuDc15XkqFcBn qUkHPPGIufmW8u8qlVUteB7hx95COHxbPwgUAD5HPWGTprjdSJiFpVtEAF89qaEhFhyS Kw961ZuXQt5Eybm8ggUI98XRBupLUEsacrUsL/JV0lVJpt3yhnAoxYrGnw2YOCOGpfd0 rVog== 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=9vFEtR41P1AeMUFHOos3mmBMGwqw/eIJuTUHN6Bzt0E=; b=uQKrXAt5EprSiGY1s2dr+iR1haNpu5O4Z69juVylr7WM40c+fc3IDVPiUjXOcGVUi7 ZqY6rE6Puc/Z78zY8RREgaN6fOsFgPqYs0melGdhWCHJYVI8vl3uO0ej1EhNpqHzynRC p6mCu0eaFhD5MYOiPePsGYPqQl+a13NTlneWAQtgBnbalHBjzXM1byIMIrFw+WVjoyD4 IBtdbhAEwfiekQ7b0+WSKMnxlYdWBsApeOjC/bFpUDsh3iSnkv8muaHCnc8YU3AplWJ1 H6sqUTYQhOyjlM+pLr0lNiH6yA064J7NNz/QG1x+3TZdGl3URbb6ix1VXEESy3d0NcC2 BaxA== X-Gm-Message-State: APjAAAXj1LgpXLTaZZxIdQxEJD6TCPlN/H1N6OmnTKGgB7L5CT/3xn5j FXJxkSBOMRzq+CEMpFRAfPIezvXz X-Google-Smtp-Source: APXvYqwqqHvfxjQg6esfqRcwFPixYio4QGyNrLwc9PXpiDO0HIUQJ3uAkxnOnDp0ZPcmjT3AoX097w== X-Received: by 2002:a65:5189:: with SMTP id h9mr19973347pgq.304.1554592160759; Sat, 06 Apr 2019 16:09:20 -0700 (PDT) Received: from mappy.sklembedded.com (c-24-4-228-186.hsd1.ca.comcast.net. [24.4.228.186]) by smtp.gmail.com with ESMTPSA id i31sm44550127pgi.36.2019.04.06.16.09.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 06 Apr 2019 16:09:20 -0700 (PDT) From: Steve Longerbeam To: linux-media@vger.kernel.org Cc: Steve Longerbeam , Philipp Zabel , Mauro Carvalho Chehab , Greg Kroah-Hartman , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Rui Miguel Silva , devel@driverdev.osuosl.org (open list:STAGING SUBSYSTEM), linux-arm-kernel@lists.infradead.org (moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v7 5/5] media: imx: Try colorimetry at both sink and source pads Date: Sat, 6 Apr 2019 16:09:03 -0700 Message-Id: <20190406230903.16488-6-slongerbeam@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190406230903.16488-1-slongerbeam@gmail.com> References: <20190406230903.16488-1-slongerbeam@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Retask imx_media_fill_default_mbus_fields() to try colorimetry parameters, renaming it to to imx_media_try_colorimetry(), and call it at both sink and source pad try_fmt's. The unrelated check for uninitialized field value is moved out to appropriate places in each subdev try_fmt. The IC now supports Rec.709 and BT.601 Y'CbCr encoding, and both limited and full range quantization for both YUV and RGB space, so allow those for pipelines that route through the IC. Signed-off-by: Steve Longerbeam --- Changes in v7: - squashed with "media: imx: Allow Rec.709 encoding for IC routes". - remove the RGB full-range quantization restriction for IC routes. --- drivers/staging/media/imx/imx-ic-prp.c | 6 +- drivers/staging/media/imx/imx-ic-prpencvf.c | 8 +-- drivers/staging/media/imx/imx-media-csi.c | 19 +++--- drivers/staging/media/imx/imx-media-utils.c | 73 ++++++++++----------- drivers/staging/media/imx/imx-media-vdic.c | 5 +- drivers/staging/media/imx/imx-media.h | 5 +- drivers/staging/media/imx/imx7-media-csi.c | 8 +-- 7 files changed, 62 insertions(+), 62 deletions(-) diff --git a/drivers/staging/media/imx/imx-ic-prp.c b/drivers/staging/media/imx/imx-ic-prp.c index 3d43cdcb4bb9..8010ee706164 100644 --- a/drivers/staging/media/imx/imx-ic-prp.c +++ b/drivers/staging/media/imx/imx-ic-prp.c @@ -197,8 +197,8 @@ static int prp_set_fmt(struct v4l2_subdev *sd, sdformat->format.code = cc->codes[0]; } - imx_media_fill_default_mbus_fields(&sdformat->format, infmt, - true); + if (sdformat->format.field == V4L2_FIELD_ANY) + sdformat->format.field = V4L2_FIELD_NONE; break; case PRP_SRC_PAD_PRPENC: case PRP_SRC_PAD_PRPVF: @@ -207,6 +207,8 @@ static int prp_set_fmt(struct v4l2_subdev *sd, break; } + imx_media_try_colorimetry(&sdformat->format, true); + fmt = __prp_get_fmt(priv, cfg, sdformat->pad, sdformat->which); *fmt = sdformat->format; out: diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index 7e8405d3b75c..5cc41cec59bf 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c @@ -911,8 +911,6 @@ static void prp_try_fmt(struct prp_priv *priv, /* propagate colorimetry from sink */ sdformat->format.colorspace = infmt->colorspace; sdformat->format.xfer_func = infmt->xfer_func; - sdformat->format.quantization = infmt->quantization; - sdformat->format.ycbcr_enc = infmt->ycbcr_enc; } else { v4l_bound_align_image(&sdformat->format.width, MIN_W_SINK, MAX_W_SINK, W_ALIGN_SINK, @@ -920,9 +918,11 @@ static void prp_try_fmt(struct prp_priv *priv, MIN_H_SINK, MAX_H_SINK, H_ALIGN_SINK, S_ALIGN); - imx_media_fill_default_mbus_fields(&sdformat->format, infmt, - true); + if (sdformat->format.field == V4L2_FIELD_ANY) + sdformat->format.field = V4L2_FIELD_NONE; } + + imx_media_try_colorimetry(&sdformat->format, true); } static int prp_set_fmt(struct v4l2_subdev *sd, diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 41965d8b56c4..19865218646e 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -1379,9 +1379,15 @@ static void csi_try_field(struct csi_priv *priv, struct v4l2_mbus_framefmt *infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sdformat->which); - /* no restrictions on sink pad field type */ - if (sdformat->pad == CSI_SINK_PAD) + /* + * no restrictions on sink pad field type except must + * be initialized. + */ + if (sdformat->pad == CSI_SINK_PAD) { + if (sdformat->format.field == V4L2_FIELD_ANY) + sdformat->format.field = V4L2_FIELD_NONE; return; + } switch (infmt->field) { case V4L2_FIELD_SEQ_TB: @@ -1459,8 +1465,6 @@ static void csi_try_fmt(struct csi_priv *priv, /* propagate colorimetry from sink */ sdformat->format.colorspace = infmt->colorspace; sdformat->format.xfer_func = infmt->xfer_func; - sdformat->format.quantization = infmt->quantization; - sdformat->format.ycbcr_enc = infmt->ycbcr_enc; break; case CSI_SINK_PAD: @@ -1480,10 +1484,6 @@ static void csi_try_fmt(struct csi_priv *priv, csi_try_field(priv, cfg, sdformat); - imx_media_fill_default_mbus_fields( - &sdformat->format, infmt, - priv->active_output_pad == CSI_SRC_PAD_DIRECT); - /* Reset crop and compose rectangles */ crop->left = 0; crop->top = 0; @@ -1499,6 +1499,9 @@ static void csi_try_fmt(struct csi_priv *priv, break; } + + imx_media_try_colorimetry(&sdformat->format, + priv->active_output_pad == CSI_SRC_PAD_DIRECT); } static int csi_set_fmt(struct v4l2_subdev *sd, diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c index 1c63a2765a81..a1fd8d610549 100644 --- a/drivers/staging/media/imx/imx-media-utils.c +++ b/drivers/staging/media/imx/imx-media-utils.c @@ -515,21 +515,18 @@ int imx_media_init_cfg(struct v4l2_subdev *sd, EXPORT_SYMBOL_GPL(imx_media_init_cfg); /* - * Check whether the field and colorimetry parameters in tryfmt are - * uninitialized, and if so fill them with the values from fmt, - * or if tryfmt->colorspace has been initialized, all the default - * colorimetry params can be derived from tryfmt->colorspace. + * Default the colorspace in tryfmt to SRGB if set to an unsupported + * colorspace or not initialized. Then set the remaining colorimetry + * parameters based on the colorspace if they are uninitialized. * * tryfmt->code must be set on entry. * * If this format is destined to be routed through the Image Converter, - * quantization and Y`CbCr encoding must be fixed. The IC expects and - * produces fixed quantization and Y`CbCr encoding at its input and output - * (full range for RGB, limited range for YUV, and V4L2_YCBCR_ENC_601). + * Y`CbCr encoding must be fixed. The IC supports only BT.601 Y`CbCr + * or Rec.709 Y`CbCr encoding. */ -void imx_media_fill_default_mbus_fields(struct v4l2_mbus_framefmt *tryfmt, - struct v4l2_mbus_framefmt *fmt, - bool ic_route) +void imx_media_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt, + bool ic_route) { const struct imx_media_pixfmt *cc; bool is_rgb = false; @@ -537,44 +534,46 @@ void imx_media_fill_default_mbus_fields(struct v4l2_mbus_framefmt *tryfmt, cc = imx_media_find_mbus_format(tryfmt->code, CS_SEL_ANY, true); if (!cc) cc = imx_media_find_ipu_format(tryfmt->code, CS_SEL_ANY); - if (cc && cc->cs != IPUV3_COLORSPACE_YUV) + if (cc && cc->cs == IPUV3_COLORSPACE_RGB) is_rgb = true; - /* fill field if necessary */ - if (tryfmt->field == V4L2_FIELD_ANY) - tryfmt->field = fmt->field; + switch (tryfmt->colorspace) { + case V4L2_COLORSPACE_SMPTE170M: + case V4L2_COLORSPACE_REC709: + case V4L2_COLORSPACE_JPEG: + case V4L2_COLORSPACE_SRGB: + case V4L2_COLORSPACE_BT2020: + case V4L2_COLORSPACE_OPRGB: + case V4L2_COLORSPACE_DCI_P3: + case V4L2_COLORSPACE_RAW: + break; + default: + tryfmt->colorspace = V4L2_COLORSPACE_SRGB; + break; + } + + if (tryfmt->xfer_func == V4L2_XFER_FUNC_DEFAULT) + tryfmt->xfer_func = + V4L2_MAP_XFER_FUNC_DEFAULT(tryfmt->colorspace); - /* fill colorimetry if necessary */ - if (tryfmt->colorspace == V4L2_COLORSPACE_DEFAULT) { - tryfmt->colorspace = fmt->colorspace; - tryfmt->xfer_func = fmt->xfer_func; - tryfmt->ycbcr_enc = fmt->ycbcr_enc; - tryfmt->quantization = fmt->quantization; + if (ic_route) { + if (tryfmt->ycbcr_enc != V4L2_YCBCR_ENC_601 && + tryfmt->ycbcr_enc != V4L2_YCBCR_ENC_709) + tryfmt->ycbcr_enc = V4L2_YCBCR_ENC_601; } else { - if (tryfmt->xfer_func == V4L2_XFER_FUNC_DEFAULT) { - tryfmt->xfer_func = - V4L2_MAP_XFER_FUNC_DEFAULT(tryfmt->colorspace); - } if (tryfmt->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT) { tryfmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(tryfmt->colorspace); } - if (tryfmt->quantization == V4L2_QUANTIZATION_DEFAULT) { - tryfmt->quantization = - V4L2_MAP_QUANTIZATION_DEFAULT( - is_rgb, tryfmt->colorspace, - tryfmt->ycbcr_enc); - } } - if (ic_route) { - tryfmt->quantization = is_rgb ? - V4L2_QUANTIZATION_FULL_RANGE : - V4L2_QUANTIZATION_LIM_RANGE; - tryfmt->ycbcr_enc = V4L2_YCBCR_ENC_601; - } + if (tryfmt->quantization == V4L2_QUANTIZATION_DEFAULT) + tryfmt->quantization = + V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb, + tryfmt->colorspace, + tryfmt->ycbcr_enc); } -EXPORT_SYMBOL_GPL(imx_media_fill_default_mbus_fields); +EXPORT_SYMBOL_GPL(imx_media_try_colorimetry); int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix, struct v4l2_rect *compose, diff --git a/drivers/staging/media/imx/imx-media-vdic.c b/drivers/staging/media/imx/imx-media-vdic.c index 5439b88dba20..33f2b90c6e31 100644 --- a/drivers/staging/media/imx/imx-media-vdic.c +++ b/drivers/staging/media/imx/imx-media-vdic.c @@ -621,14 +621,13 @@ static void vdic_try_fmt(struct vdic_priv *priv, &sdformat->format.height, MIN_H, MAX_H_VDIC, H_ALIGN, S_ALIGN); - imx_media_fill_default_mbus_fields(&sdformat->format, infmt, - true); - /* input must be interlaced! Choose SEQ_TB if not */ if (!V4L2_FIELD_HAS_BOTH(sdformat->format.field)) sdformat->format.field = V4L2_FIELD_SEQ_TB; break; } + + imx_media_try_colorimetry(&sdformat->format, true); } static int vdic_set_fmt(struct v4l2_subdev *sd, diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h index dd603a6b3a70..83ae1433fc57 100644 --- a/drivers/staging/media/imx/imx-media.h +++ b/drivers/staging/media/imx/imx-media.h @@ -176,9 +176,8 @@ int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus, const struct imx_media_pixfmt **cc); int imx_media_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg); -void imx_media_fill_default_mbus_fields(struct v4l2_mbus_framefmt *tryfmt, - struct v4l2_mbus_framefmt *fmt, - bool ic_route); +void imx_media_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt, + bool ic_route); int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix, struct v4l2_rect *compose, const struct v4l2_mbus_framefmt *mbus, diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c index 18eb5d3ecf10..99fb519da754 100644 --- a/drivers/staging/media/imx/imx7-media-csi.c +++ b/drivers/staging/media/imx/imx7-media-csi.c @@ -1003,8 +1003,6 @@ static int imx7_csi_try_fmt(struct imx7_csi *csi, sdformat->format.colorspace = in_fmt->colorspace; sdformat->format.xfer_func = in_fmt->xfer_func; - sdformat->format.quantization = in_fmt->quantization; - sdformat->format.ycbcr_enc = in_fmt->ycbcr_enc; break; case IMX7_CSI_PAD_SINK: *cc = imx_media_find_mbus_format(sdformat->format.code, @@ -1015,14 +1013,14 @@ static int imx7_csi_try_fmt(struct imx7_csi *csi, false); sdformat->format.code = (*cc)->codes[0]; } - - imx_media_fill_default_mbus_fields(&sdformat->format, in_fmt, - false); break; default: return -EINVAL; break; } + + imx_media_try_colorimetry(&sdformat->format, false); + return 0; }