On Mon Jun 30 16:06:51 2025 +0100, 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. > > Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad...@bp.renesas.com> > Reviewed-by: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com> > Signed-off-by: Daniel Scally <dan.scally+rene...@ideasonboard.com> > Link: > https://lore.kernel.org/r/20250630150651.2698237-1-dan.sca...@ideasonboard.com > Signed-off-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com> > Signed-off-by: Hans Verkuil <hverk...@xs4all.nl>
Patch committed. Thanks, Hans Verkuil .../media/platform/renesas/rzg2l-cru/rzg2l-cru.h | 10 +++- .../media/platform/renesas/rzg2l-cru/rzg2l-ip.c | 67 +++++++++++++++++----- .../media/platform/renesas/rzg2l-cru/rzg2l-video.c | 2 +- 3 files changed, 62 insertions(+), 17 deletions(-) --- diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h index bba174973ac3..be95b41c37df 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h @@ -64,14 +64,18 @@ struct rzg2l_cru_ip { /** * struct rzg2l_cru_ip_format - CRU IP format - * @code: Media bus code + * @codes: Array of up to four media bus codes * @datatype: MIPI CSI2 data type * @format: 4CC format identifier (V4L2_PIX_FMT_*) * @icndmr: ICnDMR register value * @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; @@ -190,6 +194,8 @@ 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); void rzg2l_cru_enable_interrupts(struct rzg2l_cru_dev *cru); void rzg2l_cru_disable_interrupts(struct rzg2l_cru_dev *cru); diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c index 15fc1028082a..fbbcdb96c457 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; @@ -157,7 +181,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; @@ -183,11 +207,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 e151e6597609..a8817a7066b2 100644 --- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c +++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c @@ -1145,7 +1145,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;