diff mbox series

[v3,4/5] media: rzg2l-cru: Support multiple mbus codes per pixel format

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

Commit Message

Daniel Scally Dec. 2, 2024, 2:58 p.m. UTC
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(-)

Comments

Laurent Pinchart Dec. 3, 2024, 11:19 a.m. UTC | #1
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 mbox series

Patch

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;