Message ID | 20241202145831.127297-5-dan.scally@ideasonboard.com |
---|---|
State | New |
Headers | show |
Series | [v3,1/5] media: v4l2: Add Renesas Camera Receiver Unit pixel formats | expand |
Hi Dan, Thank you for the patch. On Mon, Dec 02, 2024 at 02:58:30PM +0000, Daniel Scally wrote: > As a preliminary step for supporting the CRU pixel formats, extend > the driver such that multiple media bus codes can support each of > the output pixel formats. > > Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> > --- > Changes in v3: > > - New patch due to changes to patch 1 > > .../platform/renesas/rzg2l-cru/rzg2l-cru.h | 8 ++- > .../platform/renesas/rzg2l-cru/rzg2l-ip.c | 67 +++++++++++++++---- > .../platform/renesas/rzg2l-cru/rzg2l-video.c | 2 +- > 3 files changed, 61 insertions(+), 16 deletions(-) > > diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h > index aaf85054f8842..ab923bfa3becf 100644 > --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h > +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h > @@ -71,7 +71,11 @@ struct rzg2l_cru_ip { > * @yuv: Flag to indicate whether the format is YUV-based. > */ > struct rzg2l_cru_ip_format { > - u32 code; > + /* > + * RAW output formats might be produced by RAW media codes with any one > + * of the 4 common bayer patterns. > + */ > + u32 codes[4]; > u32 datatype; > u32 format; > u32 icndmr; > @@ -169,5 +173,7 @@ struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru); > const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code); > const struct rzg2l_cru_ip_format *rzg2l_cru_ip_format_to_fmt(u32 format); > const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index); > +bool rzg2l_cru_ip_fmt_supports_mbus_code(const struct rzg2l_cru_ip_format *fmt, > + unsigned int code); > > #endif > diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c > index 399a337dbafbf..54a79d5c13e10 100644 > --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c > +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c > @@ -13,35 +13,45 @@ > > static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = { > { > - .code = MEDIA_BUS_FMT_UYVY8_1X16, > + .codes = { > + MEDIA_BUS_FMT_UYVY8_1X16, > + }, > .datatype = MIPI_CSI2_DT_YUV422_8B, > .format = V4L2_PIX_FMT_UYVY, > .icndmr = ICnDMR_YCMODE_UYVY, > .yuv = true, > }, > { > - .code = MEDIA_BUS_FMT_SBGGR8_1X8, > + .codes = { > + MEDIA_BUS_FMT_SBGGR8_1X8, > + }, > .format = V4L2_PIX_FMT_SBGGR8, > .datatype = MIPI_CSI2_DT_RAW8, > .icndmr = 0, > .yuv = false, > }, > { > - .code = MEDIA_BUS_FMT_SGBRG8_1X8, > + .codes = { > + MEDIA_BUS_FMT_SGBRG8_1X8, > + }, > .format = V4L2_PIX_FMT_SGBRG8, > .datatype = MIPI_CSI2_DT_RAW8, > .icndmr = 0, > .yuv = false, > }, > { > - .code = MEDIA_BUS_FMT_SGRBG8_1X8, > + .codes = { > + MEDIA_BUS_FMT_SGRBG8_1X8, > + }, > .format = V4L2_PIX_FMT_SGRBG8, > .datatype = MIPI_CSI2_DT_RAW8, > .icndmr = 0, > .yuv = false, > }, > { > - .code = MEDIA_BUS_FMT_SRGGB8_1X8, > + .codes = { > + MEDIA_BUS_FMT_SRGGB8_1X8, > + }, > .format = V4L2_PIX_FMT_SRGGB8, > .datatype = MIPI_CSI2_DT_RAW8, > .icndmr = 0, > @@ -51,11 +61,14 @@ static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = { > > const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code) > { > - unsigned int i; > + unsigned int i, j; > > - for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) > - if (rzg2l_cru_ip_formats[i].code == code) > - return &rzg2l_cru_ip_formats[i]; > + for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) { > + for (j = 0; j < ARRAY_SIZE(rzg2l_cru_ip_formats[i].codes); j++) { > + if (rzg2l_cru_ip_formats[i].codes[j] == code) > + return &rzg2l_cru_ip_formats[i]; > + } > + } > > return NULL; > } > @@ -80,6 +93,17 @@ const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index) > return &rzg2l_cru_ip_formats[index]; > } > > +bool rzg2l_cru_ip_fmt_supports_mbus_code(const struct rzg2l_cru_ip_format *fmt, > + unsigned int code) > +{ > + unsigned int i; > + > + for (i = 0; i < ARRAY_SIZE(fmt->codes); i++) > + if (fmt->codes[i] == code) > + return true; > + > + return false; > +} > struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru) > { > struct v4l2_subdev_state *state; > @@ -155,7 +179,7 @@ static int rzg2l_cru_ip_set_format(struct v4l2_subdev *sd, > sink_format = v4l2_subdev_state_get_format(state, fmt->pad); > > if (!rzg2l_cru_ip_code_to_fmt(fmt->format.code)) > - sink_format->code = rzg2l_cru_ip_formats[0].code; > + sink_format->code = rzg2l_cru_ip_formats[0].codes[0]; > else > sink_format->code = fmt->format.code; > > @@ -181,11 +205,26 @@ static int rzg2l_cru_ip_enum_mbus_code(struct v4l2_subdev *sd, > struct v4l2_subdev_state *state, > struct v4l2_subdev_mbus_code_enum *code) > { > - if (code->index >= ARRAY_SIZE(rzg2l_cru_ip_formats)) > - return -EINVAL; > + unsigned int index = code->index; > + unsigned int i, j; > > - code->code = rzg2l_cru_ip_formats[code->index].code; > - return 0; > + for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) { > + const struct rzg2l_cru_ip_format *fmt = &rzg2l_cru_ip_formats[i]; > + > + for (j = 0; j < ARRAY_SIZE(fmt->codes); j++) { > + if (!fmt->codes[j]) > + continue; > + > + if (!index) { > + code->code = fmt->codes[j]; > + return 0; > + } > + > + index--; > + } > + } > + > + return -EINVAL; > } > > static int rzg2l_cru_ip_enum_frame_size(struct v4l2_subdev *sd, > diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c > index 028b390488c84..57d1ff45ce1e9 100644 > --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c > +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c > @@ -891,7 +891,7 @@ static int rzg2l_cru_video_link_validate(struct media_link *link) > if (fmt.format.width != cru->format.width || > fmt.format.height != cru->format.height || > fmt.format.field != cru->format.field || > - video_fmt->code != fmt.format.code) > + !rzg2l_cru_ip_fmt_supports_mbus_code(video_fmt, fmt.format.code)) > return -EPIPE; > > return 0;
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h index aaf85054f8842..ab923bfa3becf 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h @@ -71,7 +71,11 @@ struct rzg2l_cru_ip { * @yuv: Flag to indicate whether the format is YUV-based. */ struct rzg2l_cru_ip_format { - u32 code; + /* + * RAW output formats might be produced by RAW media codes with any one + * of the 4 common bayer patterns. + */ + u32 codes[4]; u32 datatype; u32 format; u32 icndmr; @@ -169,5 +173,7 @@ struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru); const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code); const struct rzg2l_cru_ip_format *rzg2l_cru_ip_format_to_fmt(u32 format); const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index); +bool rzg2l_cru_ip_fmt_supports_mbus_code(const struct rzg2l_cru_ip_format *fmt, + unsigned int code); #endif diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c index 399a337dbafbf..54a79d5c13e10 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c @@ -13,35 +13,45 @@ static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = { { - .code = MEDIA_BUS_FMT_UYVY8_1X16, + .codes = { + MEDIA_BUS_FMT_UYVY8_1X16, + }, .datatype = MIPI_CSI2_DT_YUV422_8B, .format = V4L2_PIX_FMT_UYVY, .icndmr = ICnDMR_YCMODE_UYVY, .yuv = true, }, { - .code = MEDIA_BUS_FMT_SBGGR8_1X8, + .codes = { + MEDIA_BUS_FMT_SBGGR8_1X8, + }, .format = V4L2_PIX_FMT_SBGGR8, .datatype = MIPI_CSI2_DT_RAW8, .icndmr = 0, .yuv = false, }, { - .code = MEDIA_BUS_FMT_SGBRG8_1X8, + .codes = { + MEDIA_BUS_FMT_SGBRG8_1X8, + }, .format = V4L2_PIX_FMT_SGBRG8, .datatype = MIPI_CSI2_DT_RAW8, .icndmr = 0, .yuv = false, }, { - .code = MEDIA_BUS_FMT_SGRBG8_1X8, + .codes = { + MEDIA_BUS_FMT_SGRBG8_1X8, + }, .format = V4L2_PIX_FMT_SGRBG8, .datatype = MIPI_CSI2_DT_RAW8, .icndmr = 0, .yuv = false, }, { - .code = MEDIA_BUS_FMT_SRGGB8_1X8, + .codes = { + MEDIA_BUS_FMT_SRGGB8_1X8, + }, .format = V4L2_PIX_FMT_SRGGB8, .datatype = MIPI_CSI2_DT_RAW8, .icndmr = 0, @@ -51,11 +61,14 @@ static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = { const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code) { - unsigned int i; + unsigned int i, j; - for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) - if (rzg2l_cru_ip_formats[i].code == code) - return &rzg2l_cru_ip_formats[i]; + for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) { + for (j = 0; j < ARRAY_SIZE(rzg2l_cru_ip_formats[i].codes); j++) { + if (rzg2l_cru_ip_formats[i].codes[j] == code) + return &rzg2l_cru_ip_formats[i]; + } + } return NULL; } @@ -80,6 +93,17 @@ const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index) return &rzg2l_cru_ip_formats[index]; } +bool rzg2l_cru_ip_fmt_supports_mbus_code(const struct rzg2l_cru_ip_format *fmt, + unsigned int code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(fmt->codes); i++) + if (fmt->codes[i] == code) + return true; + + return false; +} struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru) { struct v4l2_subdev_state *state; @@ -155,7 +179,7 @@ static int rzg2l_cru_ip_set_format(struct v4l2_subdev *sd, sink_format = v4l2_subdev_state_get_format(state, fmt->pad); if (!rzg2l_cru_ip_code_to_fmt(fmt->format.code)) - sink_format->code = rzg2l_cru_ip_formats[0].code; + sink_format->code = rzg2l_cru_ip_formats[0].codes[0]; else sink_format->code = fmt->format.code; @@ -181,11 +205,26 @@ static int rzg2l_cru_ip_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_mbus_code_enum *code) { - if (code->index >= ARRAY_SIZE(rzg2l_cru_ip_formats)) - return -EINVAL; + unsigned int index = code->index; + unsigned int i, j; - code->code = rzg2l_cru_ip_formats[code->index].code; - return 0; + for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) { + const struct rzg2l_cru_ip_format *fmt = &rzg2l_cru_ip_formats[i]; + + for (j = 0; j < ARRAY_SIZE(fmt->codes); j++) { + if (!fmt->codes[j]) + continue; + + if (!index) { + code->code = fmt->codes[j]; + return 0; + } + + index--; + } + } + + return -EINVAL; } static int rzg2l_cru_ip_enum_frame_size(struct v4l2_subdev *sd, diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c index 028b390488c84..57d1ff45ce1e9 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c @@ -891,7 +891,7 @@ static int rzg2l_cru_video_link_validate(struct media_link *link) if (fmt.format.width != cru->format.width || fmt.format.height != cru->format.height || fmt.format.field != cru->format.field || - video_fmt->code != fmt.format.code) + !rzg2l_cru_ip_fmt_supports_mbus_code(video_fmt, fmt.format.code)) return -EPIPE; return 0;
As a preliminary step for supporting the CRU pixel formats, extend the driver such that multiple media bus codes can support each of the output pixel formats. Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> --- Changes in v3: - New patch due to changes to patch 1 .../platform/renesas/rzg2l-cru/rzg2l-cru.h | 8 ++- .../platform/renesas/rzg2l-cru/rzg2l-ip.c | 67 +++++++++++++++---- .../platform/renesas/rzg2l-cru/rzg2l-video.c | 2 +- 3 files changed, 61 insertions(+), 16 deletions(-)