diff options
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/media/imx/imx-ic-prp.c | 6 | ||||
-rw-r--r-- | drivers/staging/media/imx/imx-ic-prpencvf.c | 42 | ||||
-rw-r--r-- | drivers/staging/media/imx/imx-media-csi.c | 19 | ||||
-rw-r--r-- | drivers/staging/media/imx/imx-media-utils.c | 73 | ||||
-rw-r--r-- | drivers/staging/media/imx/imx-media-vdic.c | 5 | ||||
-rw-r--r-- | drivers/staging/media/imx/imx-media.h | 5 | ||||
-rw-r--r-- | drivers/staging/media/imx/imx7-media-csi.c | 8 |
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; } |