struct v4l2_subdev_format *sdformat)
 {
        struct prp_priv *priv = sd_to_priv(sd);
+       struct v4l2_mbus_framefmt *fmt, *infmt;
        const struct imx_media_pixfmt *cc;
-       struct v4l2_mbus_framefmt *fmt;
        int ret = 0;
        u32 code;
 
                goto out;
        }
 
+       infmt = __prp_get_fmt(priv, cfg, PRP_SINK_PAD, sdformat->which);
+
        switch (sdformat->pad) {
        case PRP_SINK_PAD:
                v4l_bound_align_image(&sdformat->format.width, MIN_W, MAX_W,
                        cc = imx_media_find_ipu_format(code, CS_SEL_ANY);
                        sdformat->format.code = cc->codes[0];
                }
+
+               imx_media_fill_default_mbus_fields(&sdformat->format, infmt,
+                                                  true);
                break;
        case PRP_SRC_PAD_PRPENC:
        case PRP_SRC_PAD_PRPVF:
                /* Output pads mirror input pad */
-               fmt = __prp_get_fmt(priv, cfg, PRP_SINK_PAD, sdformat->which);
-               sdformat->format = *fmt;
+               sdformat->format = *infmt;
                break;
        }
 
 
                        struct v4l2_subdev_format *sdformat,
                        const struct imx_media_pixfmt **cc)
 {
+       struct v4l2_mbus_framefmt *infmt;
+
        *cc = imx_media_find_ipu_format(sdformat->format.code, CS_SEL_ANY);
        if (!*cc) {
                u32 code;
                sdformat->format.code = (*cc)->codes[0];
        }
 
-       if (sdformat->pad == PRPENCVF_SRC_PAD) {
-               struct v4l2_mbus_framefmt *infmt =
-                       __prp_get_fmt(priv, cfg, PRPENCVF_SINK_PAD,
-                                     sdformat->which);
+       infmt = __prp_get_fmt(priv, cfg, PRPENCVF_SINK_PAD, sdformat->which);
 
+       if (sdformat->pad == PRPENCVF_SRC_PAD) {
                if (sdformat->format.field != V4L2_FIELD_NONE)
                        sdformat->format.field = infmt->field;
 
                prp_bound_align_output(&sdformat->format, infmt,
                                       priv->rot_mode);
+
+               /* 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,
                                      &sdformat->format.height,
                                      MIN_H_SINK, MAX_H_SINK, H_ALIGN_SINK,
                                      S_ALIGN);
+
+               imx_media_fill_default_mbus_fields(&sdformat->format, infmt,
+                                                  true);
        }
 }
 
 
        struct v4l2_mbus_framefmt *infmt;
        u32 code;
 
+       infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sdformat->which);
+
        switch (sdformat->pad) {
        case CSI_SRC_PAD_DIRECT:
        case CSI_SRC_PAD_IDMAC:
-               infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD,
-                                     sdformat->which);
                incc = imx_media_find_mbus_format(infmt->code,
                                                  CS_SEL_ANY, true);
 
                        sdformat->format.field =  (infmt->height == 480) ?
                                V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT;
                }
+
+               /* 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:
                v4l_bound_align_image(&sdformat->format.width, MIN_W, MAX_W,
                                                        CS_SEL_ANY, false);
                        sdformat->format.code = (*cc)->codes[0];
                }
+
+               imx_media_fill_default_mbus_fields(
+                       &sdformat->format, infmt,
+                       priv->active_output_pad == CSI_SRC_PAD_DIRECT);
                break;
        }
 }
 
 }
 EXPORT_SYMBOL_GPL(imx_media_init_mbus_fmt);
 
+/*
+ * 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.
+ *
+ * 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).
+ */
+void imx_media_fill_default_mbus_fields(struct v4l2_mbus_framefmt *tryfmt,
+                                       struct v4l2_mbus_framefmt *fmt,
+                                       bool ic_route)
+{
+       const struct imx_media_pixfmt *cc;
+       bool is_rgb = false;
+
+       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)
+               is_rgb = true;
+
+       /* fill field if necessary */
+       if (tryfmt->field == V4L2_FIELD_ANY)
+               tryfmt->field = fmt->field;
+
+       /* 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;
+       } 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;
+       }
+}
+EXPORT_SYMBOL_GPL(imx_media_fill_default_mbus_fields);
+
 int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
                                  struct v4l2_mbus_framefmt *mbus,
                                  const struct imx_media_pixfmt *cc)
 
                sdformat->format.code = (*cc)->codes[0];
        }
 
+       infmt = __vdic_get_fmt(priv, cfg, priv->active_input_pad,
+                              sdformat->which);
+
        switch (sdformat->pad) {
        case VDIC_SRC_PAD_DIRECT:
-               infmt = __vdic_get_fmt(priv, cfg, priv->active_input_pad,
-                                      sdformat->which);
                sdformat->format = *infmt;
                /* output is always progressive! */
                sdformat->format.field = V4L2_FIELD_NONE;
                                      &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;
 
 int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
                            u32 width, u32 height, u32 code, u32 field,
                            const struct imx_media_pixfmt **cc);
-
+void imx_media_fill_default_mbus_fields(struct v4l2_mbus_framefmt *tryfmt,
+                                       struct v4l2_mbus_framefmt *fmt,
+                                       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);