diff mbox series

[2/6] media: rcar-vin: Simplify remote source type detection

Message ID 20240129202254.1126012-3-niklas.soderlund+renesas@ragnatech.se
State New
Headers show
Series media: rcar-vin: Make use of multiple connections in v4l-async | expand

Commit Message

Niklas Söderlund Jan. 29, 2024, 8:22 p.m. UTC
The video source connected to a VIN instance can be either be a CSI-2
receiver, a CS-ISP or a parallel device. Each one requiring slightly
different configuration, sometimes reusing the same registers with
different meaning depending on what video source is used. The video
source type can change at run-time using the media device API.

This was introduced with R-Car Gen3 with two possible video sources and
have since been extended with one more. Instead of adding more flags
that needs to be set/cleared when changing links in the media graph add
functionality to use the media device to determine the video source
type.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 .../platform/renesas/rcar-vin/rcar-core.c     |  3 --
 .../platform/renesas/rcar-vin/rcar-dma.c      | 48 ++++++++++++++-----
 .../platform/renesas/rcar-vin/rcar-vin.h      |  2 -
 3 files changed, 35 insertions(+), 18 deletions(-)
diff mbox series

Patch

diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-core.c b/drivers/media/platform/renesas/rcar-vin/rcar-core.c
index 47aeeeb4354e..8555fa446811 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-core.c
@@ -807,7 +807,6 @@  static int rvin_csi2_link_notify(struct media_link *link, u32 flags,
 		for (i = 0; i < RCAR_VIN_NUM; i++) {
 			if (group->vin[i] &&
 			    group->vin[i]->parallel.subdev == sd) {
-				group->vin[i]->is_csi = false;
 				ret = 0;
 				goto out;
 			}
@@ -865,8 +864,6 @@  static int rvin_csi2_link_notify(struct media_link *link, u32 flags,
 		ret = rvin_set_channel_routing(group->vin[master_id], chsel);
 		if (ret)
 			goto out;
-
-		vin->is_csi = true;
 	}
 out:
 	mutex_unlock(&group->lock);
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-dma.c b/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
index e2c40abc6d3d..f392e177c59b 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
@@ -178,6 +178,28 @@  static bool rvin_scaler_needed(const struct rvin_dev *vin)
 		 vin->compose.height == vin->format.height);
 }
 
+static struct v4l2_subdev *rvin_remote_subdev(const struct rvin_dev *vin)
+{
+	struct media_pad *pad;
+
+	if (!vin->info->use_mc)
+		return vin->parallel.subdev;
+
+	pad = media_pad_remote_pad_first(&vin->pad);
+	if (!pad)
+		return NULL;
+
+	return media_entity_to_v4l2_subdev(pad->entity);
+}
+
+static bool rvin_remote_is_parallel(const struct rvin_dev *vin)
+{
+	if (!vin->parallel.subdev)
+		return false;
+
+	return rvin_remote_subdev(vin) == vin->parallel.subdev;
+}
+
 struct vin_coeff {
 	unsigned short xs_value;
 	u32 coeff_set[24];
@@ -752,7 +774,7 @@  static int rvin_setup(struct rvin_dev *vin)
 		break;
 	case MEDIA_BUS_FMT_UYVY8_2X8:
 		/* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
-		if (!vin->is_csi &&
+		if (rvin_remote_is_parallel(vin) &&
 		    vin->parallel.mbus_type == V4L2_MBUS_BT656)
 			vnmc |= VNMC_INF_YUV8_BT656;
 		else
@@ -765,7 +787,7 @@  static int rvin_setup(struct rvin_dev *vin)
 		break;
 	case MEDIA_BUS_FMT_UYVY10_2X10:
 		/* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
-		if (!vin->is_csi &&
+		if (rvin_remote_is_parallel(vin) &&
 		    vin->parallel.mbus_type == V4L2_MBUS_BT656)
 			vnmc |= VNMC_INF_YUV10_BT656;
 		else
@@ -791,13 +813,13 @@  static int rvin_setup(struct rvin_dev *vin)
 		case VNMC_INF_YUV10_BT656:
 		case VNMC_INF_YUV16:
 		case VNMC_INF_RGB666:
-			if (vin->is_csi) {
+			if (!rvin_remote_is_parallel(vin)) {
 				vin_err(vin, "Invalid setting in MIPI CSI2\n");
 				return -EINVAL;
 			}
 			break;
 		case VNMC_INF_RAW8:
-			if (!vin->is_csi) {
+			if (rvin_remote_is_parallel(vin)) {
 				vin_err(vin, "Invalid setting in Digital Pins\n");
 				return -EINVAL;
 			}
@@ -813,7 +835,7 @@  static int rvin_setup(struct rvin_dev *vin)
 	else
 		dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);
 
-	if (!vin->is_csi) {
+	if (rvin_remote_is_parallel(vin)) {
 		/* Hsync Signal Polarity Select */
 		if (!(vin->parallel.bus.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
 			dmr2 |= VNDMR2_HPS;
@@ -904,10 +926,10 @@  static int rvin_setup(struct rvin_dev *vin)
 
 		if (vin->info->model == RCAR_GEN3) {
 			/* Select between CSI-2 and parallel input */
-			if (vin->is_csi)
-				vnmc &= ~VNMC_DPINE;
-			else
+			if (rvin_remote_is_parallel(vin))
 				vnmc |= VNMC_DPINE;
+			else
+				vnmc &= ~VNMC_DPINE;
 		}
 	}
 
@@ -1337,14 +1359,16 @@  static int rvin_mc_validate_format(struct rvin_dev *vin, struct v4l2_subdev *sd,
 
 static int rvin_set_stream(struct rvin_dev *vin, int on)
 {
-	struct v4l2_subdev *sd;
+	struct v4l2_subdev *sd = rvin_remote_subdev(vin);
 	struct media_pad *pad;
 	int ret;
 
+	if (!sd)
+		return -EPIPE;
+
 	/* No media controller used, simply pass operation to subdevice. */
 	if (!vin->info->use_mc) {
-		ret = v4l2_subdev_call(vin->parallel.subdev, video, s_stream,
-				       on);
+		ret = v4l2_subdev_call(sd, video, s_stream, on);
 
 		return ret == -ENOIOCTLCMD ? 0 : ret;
 	}
@@ -1353,8 +1377,6 @@  static int rvin_set_stream(struct rvin_dev *vin, int on)
 	if (!pad)
 		return -EPIPE;
 
-	sd = media_entity_to_v4l2_subdev(pad->entity);
-
 	if (!on) {
 		video_device_pipeline_stop(&vin->vdev);
 		return v4l2_subdev_call(sd, video, s_stream, 0);
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-vin.h b/drivers/media/platform/renesas/rcar-vin/rcar-vin.h
index ce5419818b36..4bfe8ea031c5 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-vin.h
@@ -202,7 +202,6 @@  struct rvin_info {
  * @sequence:		V4L2 buffers sequence number
  * @state:		keeps track of operation state
  *
- * @is_csi:		flag to mark the VIN as using a CSI-2 subdevice
  * @chsel:		Cached value of the current CSI-2 channel selection
  *
  * @mbus_code:		media bus format code
@@ -246,7 +245,6 @@  struct rvin_dev {
 	unsigned int sequence;
 	enum rvin_dma_state state;
 
-	bool is_csi;
 	unsigned int chsel;
 
 	u32 mbus_code;