summaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/media/imx/imx-ic-prp.c6
-rw-r--r--drivers/staging/media/imx/imx-ic-prpencvf.c42
-rw-r--r--drivers/staging/media/imx/imx-media-csi.c19
-rw-r--r--drivers/staging/media/imx/imx-media-utils.c73
-rw-r--r--drivers/staging/media/imx/imx-media-vdic.c5
-rw-r--r--drivers/staging/media/imx/imx-media.h5
-rw-r--r--drivers/staging/media/imx/imx7-media-csi.c8
7 files changed, 90 insertions, 68 deletions
diff --git a/drivers/staging/media/imx/imx-ic-prp.c b/drivers/staging/media/imx/imx-ic-prp.c
index 5b4af3cfe670..35e60a120dc1 100644
--- a/drivers/staging/media/imx/imx-ic-prp.c
+++ b/drivers/staging/media/imx/imx-ic-prp.c
@@ -187,8 +187,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:
@@ -197,6 +197,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 82bba68c554e..67ffa46a8e96 100644
--- a/drivers/staging/media/imx/imx-ic-prpencvf.c
+++ b/drivers/staging/media/imx/imx-ic-prpencvf.c
@@ -452,6 +452,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;
@@ -460,6 +461,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(ic_priv->ipu_dev, &priv->rot_buf[0],
outfmt->sizeimage);
if (ret) {
@@ -473,10 +485,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;
@@ -570,6 +581,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;
@@ -578,10 +590,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;
@@ -883,8 +905,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,
@@ -892,9 +912,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 0eeb0db6d83f..367e39f5b382 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -1373,9 +1373,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:
@@ -1453,8 +1459,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:
@@ -1474,10 +1478,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;
@@ -1493,6 +1493,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 b5b8a3b7730a..9088c4b720a3 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -511,21 +511,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;
@@ -533,44 +530,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_mbus_framefmt *mbus,
diff --git a/drivers/staging/media/imx/imx-media-vdic.c b/drivers/staging/media/imx/imx-media-vdic.c
index 4d90eecb04a2..cfad65a16917 100644
--- a/drivers/staging/media/imx/imx-media-vdic.c
+++ b/drivers/staging/media/imx/imx-media-vdic.c
@@ -608,14 +608,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 8a60bdafe2da..4d124a86b358 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -166,9 +166,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_mbus_framefmt *mbus,
const struct imx_media_pixfmt *cc);
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index f775870df7e0..500b4c08d967 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -1002,8 +1002,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,
@@ -1014,13 +1012,13 @@ 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;
}
+
+ imx_media_try_colorimetry(&sdformat->format, false);
+
return 0;
}