VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   34 Branches   58 Tags
author: andy.hu <andy.hu@starfivetech.com> 2023-06-20 09:25:27 +0000 committer: andy.hu <andy.hu@starfivetech.com> 2023-06-20 09:25:27 +0000 commit: 11ecf33c599661c28e8a4bd8966e06ff5951b805 parent: b39db4c6d0b91b1a4e347912a5f6508207882109
Commit Summary:
Merge branch 'CR_5520_ov5645_changhuang.liang' into 'jh7110-5.15.y-devel'
Diffstat:
6 files changed, 107 insertions, 68 deletions
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_csi.c b/drivers/media/platform/starfive/v4l2_driver/stf_csi.c
index 4f5d615ad14b..9f905d0ed0d8 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_csi.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_csi.c
@@ -12,15 +12,23 @@
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-subdev.h>
 
-static const struct csi_format csi_formats_st7110[] = {
-	{ MEDIA_BUS_FMT_YUYV8_2X8, 16},
-	{ MEDIA_BUS_FMT_RGB565_2X8_LE, 16},
+static const struct csi_format csi_formats_sink[] = {
+	{ MEDIA_BUS_FMT_UYVY8_2X8, 16},
 	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10},
 	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10},
 	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10},
 	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10},
 };
 
+/* this bpp need see csi controllor */
+static const struct csi_format csi_formats_src[] = {
+	{ MEDIA_BUS_FMT_AYUV8_1X32, 32},
+	{ MEDIA_BUS_FMT_SRGGB10_1X10, 16},
+	{ MEDIA_BUS_FMT_SGRBG10_1X10, 16},
+	{ MEDIA_BUS_FMT_SGBRG10_1X10, 16},
+	{ MEDIA_BUS_FMT_SBGGR10_1X10, 16},
+};
+
 static int csi_find_format(u32 code,
 		const struct csi_format *formats,
 		unsigned int nformats)
@@ -40,8 +48,10 @@ int stf_csi_subdev_init(struct stfcamss *stfcamss)
 	csi_dev->s_type = SENSOR_VIN;
 	csi_dev->hw_ops = &csi_ops;
 	csi_dev->stfcamss = stfcamss;
-	csi_dev->formats = csi_formats_st7110;
-	csi_dev->nformats = ARRAY_SIZE(csi_formats_st7110);
+	csi_dev->formats_sink = csi_formats_sink;
+	csi_dev->nformats_sink = ARRAY_SIZE(csi_formats_sink);
+	csi_dev->formats_src = csi_formats_src;
+	csi_dev->nformats_src = ARRAY_SIZE(csi_formats_src);
 	mutex_init(&csi_dev->stream_lock);
 	return 0;
 }
@@ -74,10 +84,8 @@ static u32 code_to_data_type(int code)
 	case MEDIA_BUS_FMT_SGBRG10_1X10:
 	case MEDIA_BUS_FMT_SBGGR10_1X10:
 		return 0x2b;
-	case MEDIA_BUS_FMT_YUYV8_2X8:
+	case MEDIA_BUS_FMT_UYVY8_2X8:
 		return 0x1E;
-	case MEDIA_BUS_FMT_RGB565_2X8_LE:
-		return 0x22;
 	default:
 		return 0x2b;
 	}
@@ -89,8 +97,9 @@ static int csi_set_stream(struct v4l2_subdev *sd, int enable)
 	struct v4l2_mbus_framefmt *format;
 	int ret = 0;
 	u32 code, width, dt;
+	u8 bpp;
 
-	format = __csi_get_format(csi_dev, NULL, STF_CSI_PAD_SRC,
+	format = __csi_get_format(csi_dev, NULL, STF_CSI_PAD_SINK,
 				V4L2_SUBDEV_FORMAT_ACTIVE);
 	if (format == NULL)
 		return -EINVAL;
@@ -98,26 +107,27 @@ static int csi_set_stream(struct v4l2_subdev *sd, int enable)
 	width = format->width;
 
 	ret = csi_find_format(format->code,
-				csi_dev->formats,
-				csi_dev->nformats);
+				csi_dev->formats_sink,
+				csi_dev->nformats_sink);
 	if (ret < 0)
 		return ret;
 
-	code = csi_dev->formats[ret].code;
+	code = csi_dev->formats_sink[ret].code;
+	bpp = csi_dev->formats_src[ret].bpp;
 	dt = code_to_data_type(code);
 
 	mutex_lock(&csi_dev->stream_lock);
 	if (enable) {
 		if (csi_dev->stream_count == 0) {
 			csi_dev->hw_ops->csi_clk_enable(csi_dev);
-			csi_dev->hw_ops->csi_stream_set(csi_dev, enable, dt, width);
+			csi_dev->hw_ops->csi_stream_set(csi_dev, enable, dt, width, bpp);
 		}
 		csi_dev->stream_count++;
 	} else {
 		if (csi_dev->stream_count == 0)
 			goto exit;
 		if (csi_dev->stream_count == 1) {
-			csi_dev->hw_ops->csi_stream_set(csi_dev, enable, dt, width);
+			csi_dev->hw_ops->csi_stream_set(csi_dev, enable, dt, width, bpp);
 			csi_dev->hw_ops->csi_clk_disable(csi_dev);
 		}
 		csi_dev->stream_count--;
@@ -139,12 +149,12 @@ static void csi_try_format(struct stf_csi_dev *csi_dev,
 	case STF_CSI_PAD_SINK:
 		/* Set format on sink pad */
 
-		for (i = 0; i < csi_dev->nformats; i++)
-			if (fmt->code == csi_dev->formats[i].code)
+		for (i = 0; i < csi_dev->nformats_sink; i++)
+			if (fmt->code == csi_dev->formats_sink[i].code)
 				break;
 
-		if (i >= csi_dev->nformats)
-			fmt->code = csi_dev->formats[0].code;
+		if (i >= csi_dev->nformats_sink)
+			fmt->code = csi_dev->formats_sink[0].code;
 
 		fmt->width = clamp_t(u32,
 				fmt->width,
@@ -163,8 +173,27 @@ static void csi_try_format(struct stf_csi_dev *csi_dev,
 		break;
 
 	case STF_CSI_PAD_SRC:
+		/* Set format on src pad */
+
+		for (i = 0; i < csi_dev->nformats_src; i++)
+			if (fmt->code == csi_dev->formats_src[i].code)
+				break;
+
+		if (i >= csi_dev->nformats_src)
+			fmt->code = csi_dev->formats_src[0].code;
+
+		fmt->width = clamp_t(u32,
+				fmt->width,
+				STFCAMSS_FRAME_MIN_WIDTH,
+				STFCAMSS_FRAME_MAX_WIDTH);
+		fmt->height = clamp_t(u32,
+				fmt->height,
+				STFCAMSS_FRAME_MIN_HEIGHT,
+				STFCAMSS_FRAME_MAX_HEIGHT);
 
-		*fmt = *__csi_get_format(csi_dev, state, STF_CSI_PAD_SINK, which);
+		fmt->field = V4L2_FIELD_NONE;
+		fmt->colorspace = V4L2_COLORSPACE_SRGB;
+		fmt->flags = 0;
 
 		break;
 	}
@@ -176,10 +205,10 @@ static int csi_enum_mbus_code(struct v4l2_subdev *sd,
 {
 	struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
 
-	if (code->index >= csi_dev->nformats)
+	if (code->index >= csi_dev->nformats_sink)
 		return -EINVAL;
 	if (code->pad == STF_CSI_PAD_SINK) {
-		code->code = csi_dev->formats[code->index].code;
+		code->code = csi_dev->formats_sink[code->index].code;
 	} else {
 		struct v4l2_mbus_framefmt *sink_fmt;
 
@@ -247,6 +276,8 @@ static int csi_set_format(struct v4l2_subdev *sd,
 {
 	struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
 	struct v4l2_mbus_framefmt *format;
+	struct v4l2_mbus_framefmt *format_src;
+	int ret;
 
 	format = __csi_get_format(csi_dev, state, fmt->pad, fmt->which);
 	if (format == NULL)
@@ -263,13 +294,17 @@ static int csi_set_format(struct v4l2_subdev *sd,
 	}
 	mutex_unlock(&csi_dev->stream_lock);
 
-	/* Propagate the format from sink to source */
 	if (fmt->pad == STF_CSI_PAD_SINK) {
-		format = __csi_get_format(csi_dev, state, STF_CSI_PAD_SRC,
+		format_src = __csi_get_format(csi_dev, state, STF_DVP_PAD_SRC,
 					fmt->which);
 
-		*format = fmt->format;
-		csi_try_format(csi_dev, state, STF_CSI_PAD_SRC, format,
+		ret = csi_find_format(format->code, csi_dev->formats_sink,
+				csi_dev->nformats_sink);
+		if (ret < 0)
+			return ret;
+
+		format_src->code = csi_dev->formats_src[ret].code;
+		csi_try_format(csi_dev, state, STF_DVP_PAD_SRC, format_src,
 					fmt->which);
 	}
 out:
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_csi.h b/drivers/media/platform/starfive/v4l2_driver/stf_csi.h
index 6d5dc73f82a1..f55b67b7ddba 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_csi.h
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_csi.h
@@ -30,9 +30,8 @@ struct csi_hw_ops {
 	int (*csi_power_on)(struct stf_csi_dev *csi_dev, u8 on);
 	int (*csi_clk_enable)(struct stf_csi_dev *csi_dev);
 	int (*csi_clk_disable)(struct stf_csi_dev *csi_dev);
-	int (*csi_set_format)(struct stf_csi_dev *csi_dev,
-			u32 vsize, u8 bpp, int is_raw10);
-	int (*csi_stream_set)(struct stf_csi_dev *csi_dev, int on, u32 dt, u32 width);
+	int (*csi_stream_set)(struct stf_csi_dev *csi_dev, int on,
+			      u32 dt, u32 width, u8 bpp);
 };
 
 struct stf_csi_dev {
@@ -41,8 +40,10 @@ struct stf_csi_dev {
 	struct v4l2_subdev subdev;
 	struct media_pad pads[STF_CSI_PADS_NUM];
 	struct v4l2_mbus_framefmt fmt[STF_CSI_PADS_NUM];
-	const struct csi_format *formats;
-	unsigned int nformats;
+	const struct csi_format *formats_sink;
+	unsigned int nformats_sink;
+	const struct csi_format *formats_src;
+	unsigned int nformats_src;
 	struct csi_hw_ops *hw_ops;
 	struct mutex stream_lock;
 	int stream_count;
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_csi_hw_ops.c b/drivers/media/platform/starfive/v4l2_driver/stf_csi_hw_ops.c
index 4af0ca8119e0..ff8c2f33ad7a 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_csi_hw_ops.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_csi_hw_ops.c
@@ -226,8 +226,28 @@ static void csi2rx_stop(struct stf_csi_dev *csi_dev, void *reg_base)
 		writel(0, reg_base + CSI2RX_STREAM_CTRL_REG(i));
 }
 
+static void csi_set_vin_axiwr_pix(struct stf_csi_dev *csi_dev, u32 width, u8 bpp)
+{
+	struct stf_vin_dev *vin = csi_dev->stfcamss->vin;
+	u32 value = 0;
+	int cnfg_axiwr_pix_ct = 64 / bpp;
+
+	if (cnfg_axiwr_pix_ct == 2)
+		value = 0;
+	else if (cnfg_axiwr_pix_ct == 4)
+		value = 1;
+	else if (cnfg_axiwr_pix_ct == 8)
+		value = 2;
+
+	reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
+		BIT(14)|BIT(13), value << 13);	//u0_vin_cnfg_axiwr0_pix_ct
+	reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
+		BIT(12)|BIT(11)|BIT(10)|BIT(9)|BIT(8)|BIT(7)|BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2),
+		(width / cnfg_axiwr_pix_ct - 1)<<2);	//u0_vin_cnfg_axiwr0_pix_cnt_end
+}
+
 static int stf_csi_stream_set(struct stf_csi_dev *csi_dev,
-					int on, u32 dt, u32 width)
+			      int on, u32 dt, u32 width, u8 bpp)
 {
 	struct stf_vin_dev *vin = csi_dev->stfcamss->vin;
 	void __iomem *reg_base = vin->csi2rx_base;
@@ -237,15 +257,10 @@ static int stf_csi_stream_set(struct stf_csi_dev *csi_dev,
 		reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_20,
 			BIT(3)|BIT(2)|BIT(1)|BIT(0),
 			0<<0);		//u0_vin_cnfg_axiwr0_channel_sel
-		reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
-			BIT(14)|BIT(13),
-			1<<13);		//u0_vin_cnfg_axiwr0_pix_ct
 		reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
 			BIT(16)|BIT(15),
 			0<<15);		//u0_vin_cnfg_axiwr0_pixel_high_bit_sel
-		reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
-			BIT(12)|BIT(11)|BIT(10)|BIT(9)|BIT(8)|BIT(7)|BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2),
-			(width / 4 - 1)<<2);	//u0_vin_cnfg_axiwr0_pix_cnt_end
+		csi_set_vin_axiwr_pix(csi_dev, width, bpp);
 		break;
 	case SENSOR_ISP:
 		reg_set_bit(vin->sysctrl_base,	SYSCONSAIF_SYSCFG_36,
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_csiphy.c b/drivers/media/platform/starfive/v4l2_driver/stf_csiphy.c
index 2e57ee2df513..4ef8e021009e 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_csiphy.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_csiphy.c
@@ -13,8 +13,7 @@
 #include <media/v4l2-subdev.h>
 
 static const struct csiphy_format csiphy_formats_st7110[] = {
-	{ MEDIA_BUS_FMT_YUYV8_2X8, 16},
-	{ MEDIA_BUS_FMT_RGB565_2X8_LE, 16},
+	{ MEDIA_BUS_FMT_UYVY8_2X8, 16},
 	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10},
 	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10},
 	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10},
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_video.c b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
index ea38dafe8857..83ff347615f9 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_video.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
@@ -14,6 +14,8 @@
 #include <media/videobuf2-dma-contig.h>
 
 static const struct stfcamss_format_info formats_pix_st7110_wr[] = {
+	{ MEDIA_BUS_FMT_AYUV8_1X32, V4L2_PIX_FMT_AYUV32, 1,
+	  { { 1, 1 } }, { { 1, 1 } }, { 32 } },
 	{ MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
 	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
 	{ MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_PIX_FMT_RGB565, 1,
@@ -867,11 +869,12 @@ static int video_g_fmt_mp(struct file *file, void *fh, struct v4l2_format *f)
 static int video_entity_s_fmt(struct stfcamss_video *video,
 			struct media_entity *entity,
 			struct v4l2_subdev_state *state,
-			struct v4l2_subdev_format *fmt, u32 dst_code)
+			struct v4l2_subdev_format *fmt)
 {
 	struct v4l2_subdev *subdev;
 	struct media_pad *pad;
 	struct v4l2_mbus_framefmt *mf = &fmt->format;
+	struct v4l2_subdev_format fmt_src;
 	u32 width, height, code;
 	int ret, index = 0;
 
@@ -886,13 +889,7 @@ static int video_entity_s_fmt(struct stfcamss_video *video,
 		pad = media_entity_remote_pad(pad);
 		if (pad && is_media_entity_v4l2_subdev(pad->entity)) {
 			fmt->pad = index;
-			if (index)
-				mf->code = dst_code;
 			ret = v4l2_subdev_call(subdev, pad, set_fmt, state, fmt);
-			st_warn(ST_VIDEO,
-				"\"%s\":%d pad fmt set to 0x%x %ux%u, dst_code = 0x%x, ret=%d\n",
-				subdev->name, fmt->pad, mf->code,
-				mf->width, mf->height, dst_code, ret);
 			if (mf->code != code ||
 				mf->width != width || mf->height != height) {
 				st_warn(ST_VIDEO,
@@ -901,8 +898,16 @@ static int video_entity_s_fmt(struct stfcamss_video *video,
 					subdev->name, fmt->pad, mf->code,
 					mf->width, mf->height);
 			}
-			if (index)
-				ret = video_entity_s_fmt(video, pad->entity, state, fmt, dst_code);
+			if (index) {
+				fmt_src.pad = index;
+				fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+				ret = v4l2_subdev_call(subdev, pad, get_fmt, state, &fmt_src);
+				if (ret)
+					return ret;
+
+				fmt->format.code = fmt_src.format.code;
+				ret = video_entity_s_fmt(video, pad->entity, state, fmt);
+			}
 		}
 
 		if (ret < 0 && ret != -ENOIOCTLCMD)
@@ -921,6 +926,7 @@ static int video_pipeline_s_fmt(struct stfcamss_video *video,
 	struct v4l2_subdev *subdev;
 	int ret, index;
 	struct v4l2_subdev_format fmt = {
+		.pad = 0,
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
 		.reserved = {getcrop_pad_id(video->id)}
 	};
@@ -948,37 +954,27 @@ static int video_pipeline_s_fmt(struct stfcamss_video *video,
 			return index;
 		v4l2_fill_mbus_format(mf, pix, video->formats[index].code);
 	}
-	code = mf->code;
+
 	width = mf->width;
 	height = mf->height;
+
 	sensor = stfcamss_find_sensor(entity);
-	if (sensor) {
-		subdev = media_entity_to_v4l2_subdev(sensor);
-		ret = v4l2_subdev_call(subdev, pad, set_fmt, state, &fmt);
-		st_warn(ST_VIDEO,
-			"\"%s\":%d pad fmt set to 0x%x %ux%u\n",
-			subdev->name, fmt.pad, mf->code,
-			mf->width, mf->height);
-		if (mf->code != code ||
-			mf->width != width || mf->height != height) {
-			st_warn(ST_VIDEO,
-				"\"%s\":%d pad fmt has been"
-				" changed to 0x%x %ux%u\n",
-				subdev->name, fmt.pad, mf->code,
-				mf->width, mf->height);
-		}
-	} else {
+	if (!sensor) {
 		st_err(ST_VIDEO, "Can't find sensor\n");
 		return -ENOTTY;
 	}
+
+	subdev = media_entity_to_v4l2_subdev(sensor);
+	ret = v4l2_subdev_call(subdev, pad, get_fmt, state, &fmt);
+	if (ret)
+		return ret;
+
 	/*
 	 * Starting from sensor subdevice, walk within
 	 * pipeline and set format on each subdevice
 	 */
-	sensor = stfcamss_find_sensor(entity);
 	pad = media_entity_remote_pad(&sensor->pads[0]);
-	ret = video_entity_s_fmt(video, pad->entity, state, &fmt, code);
-
+	ret = video_entity_s_fmt(video, pad->entity, state, &fmt);
 	if (ret < 0 && ret != -ENOIOCTLCMD)
 		return ret;
 
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_vin.c b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
index a716be49a0eb..5758ab77d7ea 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
@@ -45,6 +45,7 @@ static const struct vin2_format vin2_formats_st7110[] = {
 	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12},
 	{ MEDIA_BUS_FMT_Y12_1X12, 8},
 	{ MEDIA_BUS_FMT_YUV8_1X24, 8},
+	{ MEDIA_BUS_FMT_AYUV8_1X32, 32},
 };
 
 static const struct vin2_format isp_formats_st7110_raw[] = {