[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", ®);
>+ 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