[PATCH v2 43/55] media: rkisp1: Support the ISP parallel input

Dafna Hirschfeld dafna at fastmail.com
Sun Jul 10 19:12:21 PDT 2022


On 01.07.2022 02:07, Laurent Pinchart wrote:
>From: Paul Elder <paul.elder at ideasonboard.com>
>
>The ISP has a parallel input, exposed through port 1 in the device tree
>node. While the driver supports configuring the ISP for the parallel and
>BT.656 input modes, the DT parsing code, the subdev bound handler and
>the ISP stream start handler only support the CSI input. Extend them to
>support the parallel input.
>
>Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
>Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

Reviewed-by: Dafna Hirschfeld <dafna at fastmail.com>

>---
> .../platform/rockchip/rkisp1/rkisp1-common.h  |  2 +
> .../platform/rockchip/rkisp1/rkisp1-dev.c     | 68 ++++++++++++++++---
> .../platform/rockchip/rkisp1/rkisp1-isp.c     | 18 ++++-
> 3 files changed, 77 insertions(+), 11 deletions(-)
>
>diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
>index 84832e1367ff..e436f1572566 100644
>--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
>+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
>@@ -130,6 +130,7 @@ struct rkisp1_info {
>  * @mbus_flags:		media bus (V4L2_MBUS_*) flags
>  * @sd:			a pointer to v4l2_subdev struct of the sensor
>  * @pixel_rate_ctrl:	pixel rate of the sensor, used to initialize the phy
>+ * @port:		port number (0: MIPI, 1: Parallel)
>  */
> struct rkisp1_sensor_async {
> 	struct v4l2_async_subdev asd;
>@@ -140,6 +141,7 @@ struct rkisp1_sensor_async {
> 	unsigned int mbus_flags;
> 	struct v4l2_subdev *sd;
> 	struct v4l2_ctrl *pixel_rate_ctrl;
>+	unsigned int port;
> };
>
> /*
>diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
>index 0eb37ba557ce..1dcade2fd2a7 100644
>--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
>+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
>@@ -129,6 +129,7 @@ static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier,
> 	struct rkisp1_sensor_async *s_asd =
> 		container_of(asd, struct rkisp1_sensor_async, asd);
> 	int source_pad;
>+	int ret;
>
> 	s_asd->sd = sd;
>
>@@ -140,7 +141,20 @@ static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier,
> 		return source_pad;
> 	}
>
>-	return rkisp1_csi_link_sensor(rkisp1, sd, s_asd, source_pad);
>+	if (s_asd->port == 0)
>+		return rkisp1_csi_link_sensor(rkisp1, sd, s_asd, source_pad);
>+
>+	ret = media_create_pad_link(&sd->entity, source_pad,
>+				    &rkisp1->isp.sd.entity,
>+				    RKISP1_ISP_PAD_SINK_VIDEO,
>+				    !s_asd->index ? MEDIA_LNK_FL_ENABLED : 0);
>+	if (ret) {
>+		dev_err(rkisp1->dev, "failed to link source pad of %s\n",
>+			sd->name);
>+		return ret;
>+	}
>+
>+	return 0;
> }
>
> static int rkisp1_subdev_notifier_complete(struct v4l2_async_notifier *notifier)
>@@ -178,12 +192,33 @@ static int rkisp1_subdev_notifier_register(struct rkisp1_device *rkisp1)
> 	ntf->ops = &rkisp1_subdev_notifier_ops;
>
> 	fwnode_graph_for_each_endpoint(fwnode, ep) {
>-		struct v4l2_fwnode_endpoint vep = {
>-			.bus_type = V4L2_MBUS_CSI2_DPHY
>-		};
>+		struct fwnode_handle *port;
>+		struct v4l2_fwnode_endpoint vep = { };
> 		struct rkisp1_sensor_async *rk_asd;
> 		struct fwnode_handle *source;
>+		u32 reg = 0;
>
>+		/* Select the bus type based on the port. */
>+		port = fwnode_get_parent(ep);
>+		fwnode_property_read_u32(port, "reg", &reg);
>+		fwnode_handle_put(port);
>+
>+		switch (reg) {
>+		case 0:
>+			vep.bus_type = V4L2_MBUS_CSI2_DPHY;
>+			break;
>+
>+		case 1:
>+			/*
>+			 * Parallel port. The bus-type property in DT is
>+			 * mandatory for port 1, it will be used to determine if
>+			 * it's PARALLEL or BT656.
>+			 */
>+			vep.bus_type = V4L2_MBUS_UNKNOWN;
>+			break;
>+		}
>+
>+		/* Parse the endpoint and validate the bus type. */
> 		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
> 		if (ret) {
> 			dev_err(rkisp1->dev, "failed to parse endpoint %pfw\n",
>@@ -191,6 +226,17 @@ static int rkisp1_subdev_notifier_register(struct rkisp1_device *rkisp1)
> 			break;
> 		}
>
>+		if (vep.base.port == 1) {
>+			if (vep.bus_type != V4L2_MBUS_PARALLEL &&
>+			    vep.bus_type != V4L2_MBUS_BT656) {
>+				dev_err(rkisp1->dev,
>+					"port 1 must be parallel or BT656\n");
>+				ret = -EINVAL;
>+				break;
>+			}
>+		}
>+
>+		/* Add the async subdev to the notifier. */
> 		source = fwnode_graph_get_remote_endpoint(ep);
> 		if (!source) {
> 			dev_err(rkisp1->dev,
>@@ -211,11 +257,17 @@ static int rkisp1_subdev_notifier_register(struct rkisp1_device *rkisp1)
> 		rk_asd->index = index++;
> 		rk_asd->source_ep = source;
> 		rk_asd->mbus_type = vep.bus_type;
>-		rk_asd->mbus_flags = vep.bus.mipi_csi2.flags;
>-		rk_asd->lanes = vep.bus.mipi_csi2.num_data_lanes;
>+		rk_asd->port = vep.base.port;
>
>-		dev_dbg(rkisp1->dev, "registered ep id %d with %d lanes\n",
>-			vep.base.id, rk_asd->lanes);
>+		if (vep.bus_type == V4L2_MBUS_CSI2_DPHY) {
>+			rk_asd->mbus_flags = vep.bus.mipi_csi2.flags;
>+			rk_asd->lanes = vep.bus.mipi_csi2.num_data_lanes;
>+		} else {
>+			rk_asd->mbus_flags = vep.bus.parallel.flags;
>+		}
>+
>+		dev_dbg(rkisp1->dev, "registered ep id %d, bus type %u, %u lanes\n",
>+			vep.base.id, rk_asd->mbus_type, rk_asd->lanes);
> 	}
>
> 	if (ret) {
>diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
>index ea0bbccb5aee..383a3ec83ca9 100644
>--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
>+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
>@@ -729,6 +729,8 @@ static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
> 	struct rkisp1_device *rkisp1 = isp->rkisp1;
> 	struct media_pad *source_pad;
> 	struct media_pad *sink_pad;
>+	enum v4l2_mbus_type mbus_type;
>+	u32 mbus_flags;
> 	int ret;
>
> 	if (!enable) {
>@@ -751,12 +753,22 @@ static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
> 		return -EPIPE;
> 	}
>
>-	if (rkisp1->source != &rkisp1->csi.sd)
>-		return -EPIPE;
>+	if (rkisp1->source == &rkisp1->csi.sd) {
>+		mbus_type = V4L2_MBUS_CSI2_DPHY;
>+		mbus_flags = 0;
>+	} else {
>+		const struct rkisp1_sensor_async *asd;
>+
>+		asd = container_of(rkisp1->source->asd,
>+				   struct rkisp1_sensor_async, asd);
>+
>+		mbus_type = asd->mbus_type;
>+		mbus_flags = asd->mbus_flags;
>+	}
>
> 	isp->frame_sequence = -1;
> 	mutex_lock(&isp->ops_lock);
>-	ret = rkisp1_config_cif(isp, V4L2_MBUS_CSI2_DPHY, 0);
>+	ret = rkisp1_config_cif(isp, mbus_type, mbus_flags);
> 	if (ret)
> 		goto mutex_unlock;
>
>-- 
>Regards,
>
>Laurent Pinchart
>
>
>_______________________________________________
>Linux-rockchip mailing list
>Linux-rockchip at lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/linux-rockchip



More information about the Linux-rockchip mailing list