@@ -62,6 +62,20 @@ struct rzg2l_cru_ip {
struct v4l2_subdev *remote;
};
+/**
+ * struct rzg2l_cru_ip_format - CRU IP format
+ * @code: Media bus code
+ * @format: 4CC format identifier (V4L2_PIX_FMT_*)
+ * @datatype: MIPI CSI2 data type
+ * @bpp: bytes per pixel
+ */
+struct rzg2l_cru_ip_format {
+ u32 code;
+ u32 format;
+ u32 datatype;
+ u8 bpp;
+};
+
/**
* struct rzg2l_cru_dev - Renesas CRU device structure
* @dev: (OF) device
@@ -144,10 +158,12 @@ int rzg2l_cru_video_register(struct rzg2l_cru_dev *cru);
void rzg2l_cru_video_unregister(struct rzg2l_cru_dev *cru);
irqreturn_t rzg2l_cru_irq(int irq, void *data);
-const struct v4l2_format_info *rzg2l_cru_format_from_pixel(u32 format);
-
int rzg2l_cru_ip_subdev_register(struct rzg2l_cru_dev *cru);
void rzg2l_cru_ip_subdev_unregister(struct rzg2l_cru_dev *cru);
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);
+
#endif
@@ -6,17 +6,21 @@
*/
#include <linux/delay.h>
-#include "rzg2l-cru.h"
-struct rzg2l_cru_ip_format {
- u32 code;
-};
+#include <media/mipi-csi2.h>
+
+#include "rzg2l-cru.h"
static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = {
- { .code = MEDIA_BUS_FMT_UYVY8_1X16, },
+ {
+ .code = MEDIA_BUS_FMT_UYVY8_1X16,
+ .format = V4L2_PIX_FMT_UYVY,
+ .datatype = MIPI_CSI2_DT_YUV422_8B,
+ .bpp = 2,
+ },
};
-static const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code)
+const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code)
{
unsigned int i;
@@ -27,6 +31,26 @@ static const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int c
return NULL;
}
+const struct rzg2l_cru_ip_format *rzg2l_cru_ip_format_to_fmt(u32 format)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) {
+ if (rzg2l_cru_ip_formats[i].format == format)
+ return &rzg2l_cru_ip_formats[i];
+ }
+
+ return NULL;
+}
+
+const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index)
+{
+ if (index >= ARRAY_SIZE(rzg2l_cru_ip_formats))
+ return NULL;
+
+ return &rzg2l_cru_ip_formats[index];
+}
+
struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru)
{
struct v4l2_subdev_state *state;
@@ -300,21 +300,10 @@ static void rzg2l_cru_initialize_axi(struct rzg2l_cru_dev *cru)
rzg2l_cru_write(cru, AMnAXIATTR, amnaxiattr);
}
-static void rzg2l_cru_csi2_setup(struct rzg2l_cru_dev *cru, bool *input_is_yuv,
- struct v4l2_mbus_framefmt *ip_sd_fmt, u8 csi_vc)
+static void rzg2l_cru_csi2_setup(struct rzg2l_cru_dev *cru, u8 csi_vc,
+ u32 csi2_datatype)
{
- u32 icnmc;
-
- switch (ip_sd_fmt->code) {
- case MEDIA_BUS_FMT_UYVY8_1X16:
- icnmc = ICnMC_INF(MIPI_CSI2_DT_YUV422_8B);
- *input_is_yuv = true;
- break;
- default:
- *input_is_yuv = false;
- icnmc = ICnMC_INF(MIPI_CSI2_DT_USER_DEFINED(0));
- break;
- }
+ u32 icnmc = ICnMC_INF(csi2_datatype);
icnmc |= (rzg2l_cru_read(cru, ICnMC) & ~ICnMC_INF_MASK);
@@ -328,17 +317,20 @@ static int rzg2l_cru_initialize_image_conv(struct rzg2l_cru_dev *cru,
struct v4l2_mbus_framefmt *ip_sd_fmt,
u8 csi_vc)
{
- bool output_is_yuv = false;
- bool input_is_yuv = false;
+ const struct v4l2_format_info *src_finfo, *dst_finfo;
+ const struct rzg2l_cru_ip_format *cru_ip_fmt;
u32 icndmr;
- rzg2l_cru_csi2_setup(cru, &input_is_yuv, ip_sd_fmt, csi_vc);
+ cru_ip_fmt = rzg2l_cru_ip_code_to_fmt(ip_sd_fmt->code);
+ rzg2l_cru_csi2_setup(cru, csi_vc, cru_ip_fmt->datatype);
+
+ src_finfo = v4l2_format_info(cru_ip_fmt->format);
+ dst_finfo = v4l2_format_info(cru->format.pixelformat);
/* Output format */
switch (cru->format.pixelformat) {
case V4L2_PIX_FMT_UYVY:
icndmr = ICnDMR_YCMODE_UYVY;
- output_is_yuv = true;
break;
default:
dev_err(cru->dev, "Invalid pixelformat (0x%x)\n",
@@ -347,7 +339,7 @@ static int rzg2l_cru_initialize_image_conv(struct rzg2l_cru_dev *cru,
}
/* If input and output use same colorspace, do bypass mode */
- if (output_is_yuv == input_is_yuv)
+ if (v4l2_is_format_yuv(src_finfo) && v4l2_is_format_yuv(dst_finfo))
rzg2l_cru_write(cru, ICnMC,
rzg2l_cru_read(cru, ICnMC) | ICnMC_CSCTHR);
else
@@ -810,35 +802,15 @@ int rzg2l_cru_dma_register(struct rzg2l_cru_dev *cru)
/* -----------------------------------------------------------------------------
* V4L2 stuff
*/
-
-static const struct v4l2_format_info rzg2l_cru_formats[] = {
- {
- .format = V4L2_PIX_FMT_UYVY,
- .bpp[0] = 2,
- },
-};
-
-const struct v4l2_format_info *rzg2l_cru_format_from_pixel(u32 format)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(rzg2l_cru_formats); i++)
- if (rzg2l_cru_formats[i].format == format)
- return rzg2l_cru_formats + i;
-
- return NULL;
-}
-
static u32 rzg2l_cru_format_bytesperline(struct v4l2_pix_format *pix)
{
- const struct v4l2_format_info *fmt;
-
- fmt = rzg2l_cru_format_from_pixel(pix->pixelformat);
+ const struct rzg2l_cru_ip_format *fmt;
+ fmt = rzg2l_cru_ip_format_to_fmt(pix->pixelformat);
if (WARN_ON(!fmt))
- return -EINVAL;
+ return 0;
- return pix->width * fmt->bpp[0];
+ return pix->width * fmt->bpp;
}
static u32 rzg2l_cru_format_sizeimage(struct v4l2_pix_format *pix)
@@ -849,7 +821,7 @@ static u32 rzg2l_cru_format_sizeimage(struct v4l2_pix_format *pix)
static void rzg2l_cru_format_align(struct rzg2l_cru_dev *cru,
struct v4l2_pix_format *pix)
{
- if (!rzg2l_cru_format_from_pixel(pix->pixelformat))
+ if (!rzg2l_cru_ip_format_to_fmt(pix->pixelformat))
pix->pixelformat = RZG2L_CRU_DEFAULT_FORMAT;
switch (pix->field) {
@@ -941,10 +913,13 @@ static int rzg2l_cru_g_fmt_vid_cap(struct file *file, void *priv,
static int rzg2l_cru_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- if (f->index >= ARRAY_SIZE(rzg2l_cru_formats))
+ const struct rzg2l_cru_ip_format *fmt;
+
+ fmt = rzg2l_cru_ip_index_to_fmt(f->index);
+ if (!fmt)
return -EINVAL;
- f->pixelformat = rzg2l_cru_formats[f->index].format;
+ f->pixelformat = fmt->format;
return 0;
}