summaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorSteve Longerbeam <slongerbeam@gmail.com>2019-05-21 18:03:14 -0700
committerPhilipp Zabel <p.zabel@pengutronix.de>2019-06-14 15:31:45 +0200
commitf208b26e61df411cf0bee413bee57ff434e8b38a (patch)
tree8615d253cb6ab908aa0a09438caf6af499a9290b /drivers/staging
parent3d1f62c686acdedf5ed9642b763f3808d6a47d1e (diff)
downloadlinux-stable-f208b26e61df411cf0bee413bee57ff434e8b38a.tar.gz
linux-stable-f208b26e61df411cf0bee413bee57ff434e8b38a.tar.bz2
linux-stable-f208b26e61df411cf0bee413bee57ff434e8b38a.zip
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions
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 <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/media/imx/imx-ic-prpencvf.c34
1 files changed, 28 insertions, 6 deletions
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;