linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/32] rcar-vin: Add Gen3 with media controller support
@ 2016-11-02 13:22 Niklas Söderlund
  2016-11-02 13:22 ` [PATCH 01/32] media: entity: Add has_route entity operation Niklas Söderlund
                   ` (31 more replies)
  0 siblings, 32 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:22 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Hi All,

This series enable Gen3 VIN support in rcar-vin driver for Renesas 
r8a7795 and r8a7796. It is based on top of v4.9-rc3.

Parts of this series was previously part of an different series from me 
which enabled Gen3 support in a different way (using s_input instead of 
a media controller) but after feedback during ELCE the Gen3 enablement 
is now almost completely rewritten.

 Patch 1-2: pick-up media entity features from Laurent which the driver 
 depends on.

 Patch 3-5: fix small issues in the driver.

 Patch 6-13: changes the driver from attaching to a video source 
 subdevice at probe time to when the video device node (/dev/videoX) are 
 opened. It also allows for the subdevice which is attached is not the 
 same as last time it was opened, but only at the time the first user 
 opens, i.e. when v4l2_fh_is_singular_file() is true.

 Patch 14-15: prepare the internal data structures for Gen3.

 Patch 16-17: small refactoring preparing for Gen3 additions.

 Patch 18-19: add logic to work with the Gen3 hardware registers

 Patch 20-24: add media control support, link setup and link notify 
 handlers.

 Patch 25-29: add logic to the driver to work together with the media 
 controller.

 Patch 30-32: document the new Gen3 DT bindings, add r8a7795 and r8a7796 
 definitions and device info structures.

The driver is tested on both Renesas H3 (r8a7795) and M3-W (r8a7796) 
together with the new rcar-csi2 driver (posted separately) and a 
prototype driver of the ADV7482 (not ready for upstream but publicly 
available). It is possible to capture both CVBS and HDMI video streams, 
v4l2-compliance passes with no errors (there is one warning due the 
ADV7482 driver) and media-ctl can be used to change the routing from the 
different CSI-2 sources to the different VIN consumers.

Gen2 compatibility is verified on Koelsch and no problems where found, 
video can be captured just like before and v4l2-compliance passes 
without errors or warnings.

Laurent Pinchart (2):
  media: entity: Add has_route entity operation
  media: entity: Add media_entity_has_route() function

Niklas Söderlund (30):
  media: rcar-vin: reset bytesperline and sizeimage when resetting
    format
  media: rcar-vin: use rvin_reset_format() in S_DV_TIMINGS
  media: rcar-vin: fix how pads are handled for v4l2 subdeivce
    operations
  media: rcar-vin: fix standard in input enumeration
  media: rcar-vin: add wrapper to get rvin_graph_entity
  media: rcar-vin: move subdev source and sink pad index to
    rvin_graph_entity
  media: rcar-vin: move pad number discovery to async complete handler
  media: rcar-vin: use pad information when verifying media bus format
  media: rcar-vin: refactor pad lookup code
  media: rcar-vin: split rvin_s_fmt_vid_cap()
  media: rcar-vin: register the video device early
  media: rcar-vin: move chip information to own struct
  media: rcar-vin: move max width and height information to chip
    information
  media: rcar-vin: change name of video device
  media: rcar-vin: clarify error message from the digital notifier
  media: rcar-vin: enable Gen3 hardware configuration
  media: rcar-vin: add functions to manipulate Gen3 CHSEL value
  media: rcar-vin: expose a sink pad if we are on Gen3
  media: rcar-vin: add group allocator functions
  media: rcar-vin: add chsel information to rvin_info
  media: rcar-vin: parse Gen3 OF and setup media graph
  media: rcar-vin: add link notify for Gen3
  media: rcar-vin: enable CSI2 group subdevices in lookup helpers
  media: rcar-vin: add helpers for bridge
  media: rcar-vin: start/stop the CSI2 bridge stream
  media: rcar-vin: propagate format to bridge
  media: rcar-vin: attach to CSI2 group when the video device is opened
  media: rcar-vin: add Gen3 devicetree bindings documentation
  media: rcar-vin: enable support for r8a7795
  media: rcar-vin: enable support for r8a7796

 .../devicetree/bindings/media/rcar_vin.txt         |  117 +-
 drivers/media/media-entity.c                       |   29 +
 drivers/media/platform/rcar-vin/Kconfig            |    2 +-
 drivers/media/platform/rcar-vin/rcar-core.c        | 1134 +++++++++++++++++++-
 drivers/media/platform/rcar-vin/rcar-dma.c         |  240 ++++-
 drivers/media/platform/rcar-vin/rcar-v4l2.c        |  394 ++++---
 drivers/media/platform/rcar-vin/rcar-vin.h         |  112 +-
 include/media/media-entity.h                       |    8 +
 8 files changed, 1790 insertions(+), 246 deletions(-)

-- 
2.10.2


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 01/32] media: entity: Add has_route entity operation
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
@ 2016-11-02 13:22 ` Niklas Söderlund
  2016-11-08 12:43   ` Sakari Ailus
  2016-11-02 13:22 ` [PATCH 02/32] media: entity: Add media_entity_has_route() function Niklas Söderlund
                   ` (30 subsequent siblings)
  31 siblings, 1 reply; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:22 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Michal Simek, Niklas Söderlund

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

The optional operation can be used by entities to report whether two
pads are internally connected.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 include/media/media-entity.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index b2203ee..8f9fc85 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -181,6 +181,9 @@ struct media_pad {
  * @link_validate:	Return whether a link is valid from the entity point of
  *			view. The media_entity_pipeline_start() function
  *			validates all links by calling this operation. Optional.
+ * @has_route:		Return whether a route exists inside the entity between
+ *			two given pads. Optional. If the operation isn't
+ *			implemented all pads will be considered as connected.
  *
  * .. note::
  *
@@ -192,6 +195,8 @@ struct media_entity_operations {
 			  const struct media_pad *local,
 			  const struct media_pad *remote, u32 flags);
 	int (*link_validate)(struct media_link *link);
+	bool (*has_route)(struct media_entity *entity, unsigned int pad0,
+			  unsigned int pad1);
 };
 
 /**
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 02/32] media: entity: Add media_entity_has_route() function
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
  2016-11-02 13:22 ` [PATCH 01/32] media: entity: Add has_route entity operation Niklas Söderlund
@ 2016-11-02 13:22 ` Niklas Söderlund
  2016-11-08 12:42   ` Sakari Ailus
  2016-11-02 13:23 ` [PATCH 03/32] media: rcar-vin: reset bytesperline and sizeimage when resetting format Niklas Söderlund
                   ` (29 subsequent siblings)
  31 siblings, 1 reply; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:22 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Michal Simek, Niklas Söderlund

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

This is a wrapper around the media entity has_route operation.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/media-entity.c | 29 +++++++++++++++++++++++++++++
 include/media/media-entity.h |  3 +++
 2 files changed, 32 insertions(+)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index c68239e..4d03ea7 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -242,6 +242,35 @@ EXPORT_SYMBOL_GPL(media_entity_pads_init);
  * Graph traversal
  */
 
+/**
+ * media_entity_has_route - Check if two entity pads are connected internally
+ * @entity: The entity
+ * @pad0: The first pad index
+ * @pad1: The second pad index
+ *
+ * This function can be used to check whether two pads of an entity are
+ * connected internally in the entity.
+ *
+ * The caller must hold entity->source->parent->mutex.
+ *
+ * Return: true if the pads are connected internally and false otherwise.
+ */
+bool media_entity_has_route(struct media_entity *entity, unsigned int pad0,
+			    unsigned int pad1)
+{
+	if (pad0 >= entity->num_pads || pad1 >= entity->num_pads)
+		return false;
+
+	if (pad0 == pad1)
+		return true;
+
+	if (!entity->ops || !entity->ops->has_route)
+		return true;
+
+	return entity->ops->has_route(entity, pad0, pad1);
+}
+EXPORT_SYMBOL_GPL(media_entity_has_route);
+
 static struct media_entity *
 media_entity_other(struct media_entity *entity, struct media_link *link)
 {
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 8f9fc85..5fb3f06 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -851,6 +851,9 @@ void media_entity_graph_walk_cleanup(struct media_entity_graph *graph);
  */
 void media_entity_put(struct media_entity *entity);
 
+bool media_entity_has_route(struct media_entity *entity, unsigned int sink,
+			    unsigned int source);
+
 /**
  * media_entity_graph_walk_start - Start walking the media graph at a
  *	given entity
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 03/32] media: rcar-vin: reset bytesperline and sizeimage when resetting format
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
  2016-11-02 13:22 ` [PATCH 01/32] media: entity: Add has_route entity operation Niklas Söderlund
  2016-11-02 13:22 ` [PATCH 02/32] media: entity: Add media_entity_has_route() function Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 16:43   ` Sergei Shtylyov
  2016-11-02 13:23 ` [PATCH 04/32] media: rcar-vin: use rvin_reset_format() in S_DV_TIMINGS Niklas Söderlund
                   ` (28 subsequent siblings)
  31 siblings, 1 reply; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

These two fields where forgotten when refactoring the format reset code
path. If they are not also reset at the same time as width and hight the
format read using G_FMT will not match realty.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 2bbe6d4..69bc4cf 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -151,6 +151,9 @@ static int rvin_reset_format(struct rvin_dev *vin)
 
 	rvin_reset_crop_compose(vin);
 
+	vin->format.bytesperline = rvin_format_bytesperline(&vin->format);
+	vin->format.sizeimage = rvin_format_sizeimage(&vin->format);
+
 	return 0;
 }
 
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 04/32] media: rcar-vin: use rvin_reset_format() in S_DV_TIMINGS
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (2 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 03/32] media: rcar-vin: reset bytesperline and sizeimage when resetting format Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 05/32] media: rcar-vin: fix how pads are handled for v4l2 subdeivce operations Niklas Söderlund
                   ` (27 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Use rvin_reset_format() in rvin_s_dv_timings() instead if just resetting
a few fields. This fixes an issue where the field format was not
properly set after S_DV_TIMINGS.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 69bc4cf..7ca2759 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -573,12 +573,8 @@ static int rvin_s_dv_timings(struct file *file, void *priv_fh,
 	if (ret)
 		return ret;
 
-	vin->source.width = timings->bt.width;
-	vin->source.height = timings->bt.height;
-	vin->format.width = timings->bt.width;
-	vin->format.height = timings->bt.height;
-
-	return 0;
+	/* Changing the timings will change the width/height */
+	return rvin_reset_format(vin);
 }
 
 static int rvin_g_dv_timings(struct file *file, void *priv_fh,
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 05/32] media: rcar-vin: fix how pads are handled for v4l2 subdeivce operations
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (3 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 04/32] media: rcar-vin: use rvin_reset_format() in S_DV_TIMINGS Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 06/32] media: rcar-vin: fix standard in input enumeration Niklas Söderlund
                   ` (26 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

The rcar-vin driver only uses one pad, pad number 0.

 All v4l2 operations which did not check that the requested operation
 was for pad 0 have been updated with a check to enforce this.

 All v4l2 operations that stored (and later restore) the requested pad
 before substituting it for the subdeivce pad number have been update
 not store the incoming pad and simply restore it to 0 after the
 subdevice operation is complete.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 7ca2759..610f59e 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -550,14 +550,16 @@ static int rvin_enum_dv_timings(struct file *file, void *priv_fh,
 {
 	struct rvin_dev *vin = video_drvdata(file);
 	struct v4l2_subdev *sd = vin_to_source(vin);
-	int pad, ret;
+	int ret;
+
+	if (timings->pad)
+		return -EINVAL;
 
-	pad = timings->pad;
 	timings->pad = vin->sink_pad_idx;
 
 	ret = v4l2_subdev_call(sd, pad, enum_dv_timings, timings);
 
-	timings->pad = pad;
+	timings->pad = 0;
 
 	return ret;
 }
@@ -600,14 +602,16 @@ static int rvin_dv_timings_cap(struct file *file, void *priv_fh,
 {
 	struct rvin_dev *vin = video_drvdata(file);
 	struct v4l2_subdev *sd = vin_to_source(vin);
-	int pad, ret;
+	int ret;
+
+	if (cap->pad)
+		return -EINVAL;
 
-	pad = cap->pad;
 	cap->pad = vin->sink_pad_idx;
 
 	ret = v4l2_subdev_call(sd, pad, dv_timings_cap, cap);
 
-	cap->pad = pad;
+	cap->pad = 0;
 
 	return ret;
 }
@@ -616,17 +620,16 @@ static int rvin_g_edid(struct file *file, void *fh, struct v4l2_edid *edid)
 {
 	struct rvin_dev *vin = video_drvdata(file);
 	struct v4l2_subdev *sd = vin_to_source(vin);
-	int input, ret;
+	int ret;
 
 	if (edid->pad)
 		return -EINVAL;
 
-	input = edid->pad;
 	edid->pad = vin->sink_pad_idx;
 
 	ret = v4l2_subdev_call(sd, pad, get_edid, edid);
 
-	edid->pad = input;
+	edid->pad = 0;
 
 	return ret;
 }
@@ -635,17 +638,16 @@ static int rvin_s_edid(struct file *file, void *fh, struct v4l2_edid *edid)
 {
 	struct rvin_dev *vin = video_drvdata(file);
 	struct v4l2_subdev *sd = vin_to_source(vin);
-	int input, ret;
+	int ret;
 
 	if (edid->pad)
 		return -EINVAL;
 
-	input = edid->pad;
 	edid->pad = vin->sink_pad_idx;
 
 	ret = v4l2_subdev_call(sd, pad, set_edid, edid);
 
-	edid->pad = input;
+	edid->pad = 0;
 
 	return ret;
 }
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 06/32] media: rcar-vin: fix standard in input enumeration
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (4 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 05/32] media: rcar-vin: fix how pads are handled for v4l2 subdeivce operations Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 07/32] media: rcar-vin: add wrapper to get rvin_graph_entity Niklas Söderlund
                   ` (25 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

If the subdevice supports dv_timings_cap the driver should not fill in
the standard. Also don't use the standard from probe time ask the
subdevice each time, this is done in preparation for Gen3 support where
the source subdevice might change during runtime.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 610f59e..f9218f2 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -483,10 +483,16 @@ static int rvin_enum_input(struct file *file, void *priv,
 		return ret;
 
 	i->type = V4L2_INPUT_TYPE_CAMERA;
-	i->std = vin->vdev.tvnorms;
 
-	if (v4l2_subdev_has_op(sd, pad, dv_timings_cap))
+	if (v4l2_subdev_has_op(sd, pad, dv_timings_cap)) {
 		i->capabilities = V4L2_IN_CAP_DV_TIMINGS;
+		i->std = 0;
+	} else {
+		i->capabilities = V4L2_IN_CAP_STD;
+		ret = v4l2_subdev_call(sd, video, g_tvnorms, &i->std);
+		if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+			return ret;
+	}
 
 	strlcpy(i->name, "Camera", sizeof(i->name));
 
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 07/32] media: rcar-vin: add wrapper to get rvin_graph_entity
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (5 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 06/32] media: rcar-vin: fix standard in input enumeration Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 08/32] media: rcar-vin: move subdev source and sink pad index to rvin_graph_entity Niklas Söderlund
                   ` (24 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Update the driver to retrieve the code and mbus_cfg values from a
rvin_graph_entity retrieved from a wrapper function instead of directly
accessing the entity for the digital port. This is done to prepare for
Gen3 support where the subdeivce might change during runtime, so to
directly accesses a specific rvin_graph_entity is bad.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c |  9 +++++++++
 drivers/media/platform/rcar-vin/rcar-dma.c  | 15 ++++++++++-----
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  6 +++++-
 drivers/media/platform/rcar-vin/rcar-vin.h  |  1 +
 4 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 098a0b1..89a9280 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -26,6 +26,15 @@
 #include "rcar-vin.h"
 
 /* -----------------------------------------------------------------------------
+ * Subdevice helpers
+ */
+
+struct rvin_graph_entity *vin_to_entity(struct rvin_dev *vin)
+{
+	return &vin->digital;
+}
+
+/* -----------------------------------------------------------------------------
  * Async notifier
  */
 
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
index 9ccd5ff..eac5c19 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -131,10 +131,15 @@ static u32 rvin_read(struct rvin_dev *vin, u32 offset)
 
 static int rvin_setup(struct rvin_dev *vin)
 {
+	struct rvin_graph_entity *rent;
 	u32 vnmc, dmr, dmr2, interrupts;
 	v4l2_std_id std;
 	bool progressive = false, output_is_yuv = false, input_is_yuv = false;
 
+	rent = vin_to_entity(vin);
+	if (!rent)
+		return -ENODEV;
+
 	switch (vin->format.field) {
 	case V4L2_FIELD_TOP:
 		vnmc = VNMC_IM_ODD;
@@ -174,7 +179,7 @@ static int rvin_setup(struct rvin_dev *vin)
 	/*
 	 * Input interface
 	 */
-	switch (vin->digital.code) {
+	switch (rent->code) {
 	case MEDIA_BUS_FMT_YUYV8_1X16:
 		/* BT.601/BT.1358 16bit YCbCr422 */
 		vnmc |= VNMC_INF_YUV16;
@@ -182,7 +187,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 */
-		vnmc |= vin->digital.mbus_cfg.type == V4L2_MBUS_BT656 ?
+		vnmc |= rent->mbus_cfg.type == V4L2_MBUS_BT656 ?
 			VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
 		input_is_yuv = true;
 		break;
@@ -191,7 +196,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 */
-		vnmc |= vin->digital.mbus_cfg.type == V4L2_MBUS_BT656 ?
+		vnmc |= rent->mbus_cfg.type == V4L2_MBUS_BT656 ?
 			VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
 		input_is_yuv = true;
 		break;
@@ -203,11 +208,11 @@ static int rvin_setup(struct rvin_dev *vin)
 	dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);
 
 	/* Hsync Signal Polarity Select */
-	if (!(vin->digital.mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
+	if (!(rent->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
 		dmr2 |= VNDMR2_HPS;
 
 	/* Vsync Signal Polarity Select */
-	if (!(vin->digital.mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
+	if (!(rent->mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
 		dmr2 |= VNDMR2_VPS;
 
 	/*
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index f9218f2..370bb18 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -164,6 +164,7 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
 {
 	struct v4l2_subdev *sd;
 	struct v4l2_subdev_pad_config *pad_cfg;
+	struct rvin_graph_entity *rent;
 	struct v4l2_subdev_format format = {
 		.which = which,
 	};
@@ -171,8 +172,11 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
 	int ret;
 
 	sd = vin_to_source(vin);
+	rent = vin_to_entity(vin);
+	if (!rent)
+		return -ENODEV;
 
-	v4l2_fill_mbus_format(&format.format, pix, vin->digital.code);
+	v4l2_fill_mbus_format(&format.format, pix, rent->code);
 
 	pad_cfg = v4l2_subdev_alloc_pad_config(sd);
 	if (pad_cfg == NULL)
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index 727e215..daec26a 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -144,6 +144,7 @@ struct rvin_dev {
 	struct v4l2_rect compose;
 };
 
+struct rvin_graph_entity *vin_to_entity(struct rvin_dev *vin);
 #define vin_to_source(vin)		vin->digital.subdev
 
 /* Debug */
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 08/32] media: rcar-vin: move subdev source and sink pad index to rvin_graph_entity
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (6 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 07/32] media: rcar-vin: add wrapper to get rvin_graph_entity Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 09/32] media: rcar-vin: move pad number discovery to async complete handler Niklas Söderlund
                   ` (23 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Move the sink and source pad index from struct rvin_dev to struct
rvin_graph_entity. This is done in preparation of Gen3 support where the
active subdeivce can be changed during runtime. And if the subdevice is
changed the pad numbers are different so it's better to read them a
rvin_graph_entity then from directly from the rvin_dev.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 45 ++++++++++++++++++++++-------
 drivers/media/platform/rcar-vin/rcar-vin.h  | 17 ++++++-----
 2 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 370bb18..f8ff7c4 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -109,9 +109,14 @@ static int rvin_reset_format(struct rvin_dev *vin)
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
 	};
 	struct v4l2_mbus_framefmt *mf = &fmt.format;
+	struct rvin_graph_entity *rent;
 	int ret;
 
-	fmt.pad = vin->src_pad_idx;
+	rent = vin_to_entity(vin);
+	if (!rent)
+		return -ENODEV;
+
+	fmt.pad = rent->source_pad_idx;
 
 	ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt);
 	if (ret)
@@ -182,7 +187,7 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
 	if (pad_cfg == NULL)
 		return -ENOMEM;
 
-	format.pad = vin->src_pad_idx;
+	format.pad = rent->source_pad_idx;
 
 	field = pix->field;
 
@@ -560,12 +565,17 @@ static int rvin_enum_dv_timings(struct file *file, void *priv_fh,
 {
 	struct rvin_dev *vin = video_drvdata(file);
 	struct v4l2_subdev *sd = vin_to_source(vin);
+	struct rvin_graph_entity *rent;
 	int ret;
 
+	rent = vin_to_entity(vin);
+	if (!rent)
+		return -ENODEV;
+
 	if (timings->pad)
 		return -EINVAL;
 
-	timings->pad = vin->sink_pad_idx;
+	timings->pad = rent->sink_pad_idx;
 
 	ret = v4l2_subdev_call(sd, pad, enum_dv_timings, timings);
 
@@ -612,12 +622,17 @@ static int rvin_dv_timings_cap(struct file *file, void *priv_fh,
 {
 	struct rvin_dev *vin = video_drvdata(file);
 	struct v4l2_subdev *sd = vin_to_source(vin);
+	struct rvin_graph_entity *rent;
 	int ret;
 
+	rent = vin_to_entity(vin);
+	if (!rent)
+		return -ENODEV;
+
 	if (cap->pad)
 		return -EINVAL;
 
-	cap->pad = vin->sink_pad_idx;
+	cap->pad = rent->sink_pad_idx;
 
 	ret = v4l2_subdev_call(sd, pad, dv_timings_cap, cap);
 
@@ -630,12 +645,17 @@ static int rvin_g_edid(struct file *file, void *fh, struct v4l2_edid *edid)
 {
 	struct rvin_dev *vin = video_drvdata(file);
 	struct v4l2_subdev *sd = vin_to_source(vin);
+	struct rvin_graph_entity *rent;
 	int ret;
 
+	rent = vin_to_entity(vin);
+	if (!rent)
+		return -ENODEV;
+
 	if (edid->pad)
 		return -EINVAL;
 
-	edid->pad = vin->sink_pad_idx;
+	edid->pad = rent->sink_pad_idx;
 
 	ret = v4l2_subdev_call(sd, pad, get_edid, edid);
 
@@ -648,12 +668,17 @@ static int rvin_s_edid(struct file *file, void *fh, struct v4l2_edid *edid)
 {
 	struct rvin_dev *vin = video_drvdata(file);
 	struct v4l2_subdev *sd = vin_to_source(vin);
+	struct rvin_graph_entity *rent;
 	int ret;
 
+	rent = vin_to_entity(vin);
+	if (!rent)
+		return -ENODEV;
+
 	if (edid->pad)
 		return -EINVAL;
 
-	edid->pad = vin->sink_pad_idx;
+	edid->pad = rent->sink_pad_idx;
 
 	ret = v4l2_subdev_call(sd, pad, set_edid, edid);
 
@@ -926,19 +951,19 @@ int rvin_v4l2_probe(struct rvin_dev *vin)
 	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
 		V4L2_CAP_READWRITE;
 
-	vin->src_pad_idx = 0;
+	vin->digital.source_pad_idx = 0;
 	for (pad_idx = 0; pad_idx < sd->entity.num_pads; pad_idx++)
 		if (sd->entity.pads[pad_idx].flags == MEDIA_PAD_FL_SOURCE)
 			break;
 	if (pad_idx >= sd->entity.num_pads)
 		return -EINVAL;
 
-	vin->src_pad_idx = pad_idx;
+	vin->digital.source_pad_idx = pad_idx;
 
-	vin->sink_pad_idx = 0;
+	vin->digital.sink_pad_idx = 0;
 	for (pad_idx = 0; pad_idx < sd->entity.num_pads; pad_idx++)
 		if (sd->entity.pads[pad_idx].flags == MEDIA_PAD_FL_SINK) {
-			vin->sink_pad_idx = pad_idx;
+			vin->digital.sink_pad_idx = pad_idx;
 			break;
 		}
 
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index daec26a..d31212a 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -70,10 +70,12 @@ struct rvin_video_format {
 
 /**
  * struct rvin_graph_entity - Video endpoint from async framework
- * @asd:	sub-device descriptor for async framework
- * @subdev:	subdevice matched using async framework
- * @code:	Media bus format from source
- * @mbus_cfg:	Media bus format from DT
+ * @asd:		sub-device descriptor for async framework
+ * @subdev:		subdevice matched using async framework
+ * @code:		Media bus format from source
+ * @mbus_cfg:		Media bus format from DT
+ * @source_pad_idx:	source pad index on remote device
+ * @sink_pad_idx:	sink pad index on remote device
  */
 struct rvin_graph_entity {
 	struct v4l2_async_subdev asd;
@@ -81,6 +83,9 @@ struct rvin_graph_entity {
 
 	u32 code;
 	struct v4l2_mbus_config mbus_cfg;
+
+	int source_pad_idx;
+	int sink_pad_idx;
 };
 
 /**
@@ -91,8 +96,6 @@ struct rvin_graph_entity {
  *
  * @vdev:		V4L2 video device associated with VIN
  * @v4l2_dev:		V4L2 device
- * @src_pad_idx:	source pad index for media controller drivers
- * @sink_pad_idx:	sink pad index for media controller drivers
  * @ctrl_handler:	V4L2 control handler
  * @notifier:		V4L2 asynchronous subdevs notifier
  * @digital:		entity in the DT for local digital subdevice
@@ -121,8 +124,6 @@ struct rvin_dev {
 
 	struct video_device vdev;
 	struct v4l2_device v4l2_dev;
-	int src_pad_idx;
-	int sink_pad_idx;
 	struct v4l2_ctrl_handler ctrl_handler;
 	struct v4l2_async_notifier notifier;
 	struct rvin_graph_entity digital;
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 09/32] media: rcar-vin: move pad number discovery to async complete handler
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (7 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 08/32] media: rcar-vin: move subdev source and sink pad index to rvin_graph_entity Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 10/32] media: rcar-vin: use pad information when verifying media bus format Niklas Söderlund
                   ` (22 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

The rvin_v4l2_probe() handler will with Gen3 support need to handle more
then one subdevice. To prepare for this move the digital subdev pad
number discover to the digital specific async notification complete
function.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 23 +++++++++++++++++++++++
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 18 +-----------------
 2 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 89a9280..2c40b6a 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -68,6 +68,8 @@ static bool rvin_mbus_supported(struct rvin_graph_entity *entity)
 static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
 {
 	struct rvin_dev *vin = notifier_to_vin(notifier);
+	struct v4l2_subdev *sd = vin->digital.subdev;
+	unsigned int pad_idx;
 	int ret;
 
 	/* Verify subdevices mbus format */
@@ -80,6 +82,27 @@ static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
 	vin_dbg(vin, "Found media bus format for %s: %d\n",
 		vin->digital.subdev->name, vin->digital.code);
 
+	/* Figure out source and sink pad ids */
+	vin->digital.source_pad_idx = 0;
+	for (pad_idx = 0; pad_idx < sd->entity.num_pads; pad_idx++)
+		if (sd->entity.pads[pad_idx].flags == MEDIA_PAD_FL_SOURCE)
+			break;
+	if (pad_idx >= sd->entity.num_pads)
+		return -EINVAL;
+
+	vin->digital.source_pad_idx = pad_idx;
+
+	vin->digital.sink_pad_idx = 0;
+	for (pad_idx = 0; pad_idx < sd->entity.num_pads; pad_idx++)
+		if (sd->entity.pads[pad_idx].flags == MEDIA_PAD_FL_SINK) {
+			vin->digital.sink_pad_idx = pad_idx;
+			break;
+		}
+
+	vin_dbg(vin, "Found media pads for %s source: %d sink %d\n",
+		vin->digital.subdev->name, vin->digital.source_pad_idx,
+		vin->digital.sink_pad_idx);
+
 	ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
 	if (ret < 0) {
 		vin_err(vin, "Failed to register subdev nodes\n");
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index f8ff7c4..51324c6 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -905,7 +905,7 @@ int rvin_v4l2_probe(struct rvin_dev *vin)
 {
 	struct video_device *vdev = &vin->vdev;
 	struct v4l2_subdev *sd = vin_to_source(vin);
-	int pad_idx, ret;
+	int ret;
 
 	v4l2_set_subdev_hostdata(sd, vin);
 
@@ -951,22 +951,6 @@ int rvin_v4l2_probe(struct rvin_dev *vin)
 	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
 		V4L2_CAP_READWRITE;
 
-	vin->digital.source_pad_idx = 0;
-	for (pad_idx = 0; pad_idx < sd->entity.num_pads; pad_idx++)
-		if (sd->entity.pads[pad_idx].flags == MEDIA_PAD_FL_SOURCE)
-			break;
-	if (pad_idx >= sd->entity.num_pads)
-		return -EINVAL;
-
-	vin->digital.source_pad_idx = pad_idx;
-
-	vin->digital.sink_pad_idx = 0;
-	for (pad_idx = 0; pad_idx < sd->entity.num_pads; pad_idx++)
-		if (sd->entity.pads[pad_idx].flags == MEDIA_PAD_FL_SINK) {
-			vin->digital.sink_pad_idx = pad_idx;
-			break;
-		}
-
 	vin->format.pixelformat	= RVIN_DEFAULT_FORMAT;
 	rvin_reset_format(vin);
 
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 10/32] media: rcar-vin: use pad information when verifying media bus format
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (8 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 09/32] media: rcar-vin: move pad number discovery to async complete handler Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 11/32] media: rcar-vin: refactor pad lookup code Niklas Söderlund
                   ` (21 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Now that the pad information is present in struct rvin_graph_entity use
it when verifying the media bus format.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 2c40b6a..fb6368c 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -48,6 +48,7 @@ static bool rvin_mbus_supported(struct rvin_graph_entity *entity)
 	};
 
 	code.index = 0;
+	code.pad = entity->source_pad_idx;
 	while (!v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code)) {
 		code.index++;
 		switch (code.code) {
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 11/32] media: rcar-vin: refactor pad lookup code
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (9 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 10/32] media: rcar-vin: use pad information when verifying media bus format Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 12/32] media: rcar-vin: split rvin_s_fmt_vid_cap() Niklas Söderlund
                   ` (20 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

The code to lookup which pad is source and sink can be broken out to a
helper function.

A bad check is also dropped in this refactoring. If the subdeivce don't
supply pad information the driver would not be able to use it if the
check is kept.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 29 +++++++++++++----------------
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index fb6368c..50058fe 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -66,11 +66,21 @@ static bool rvin_mbus_supported(struct rvin_graph_entity *entity)
 	return false;
 }
 
+static unsigned int rvin_pad_idx(struct v4l2_subdev *sd, int direction)
+{
+	unsigned int pad_idx;
+
+	for (pad_idx = 0; pad_idx < sd->entity.num_pads; pad_idx++)
+		if (sd->entity.pads[pad_idx].flags == direction)
+			return pad_idx;
+
+	return 0;
+}
+
 static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
 {
 	struct rvin_dev *vin = notifier_to_vin(notifier);
 	struct v4l2_subdev *sd = vin->digital.subdev;
-	unsigned int pad_idx;
 	int ret;
 
 	/* Verify subdevices mbus format */
@@ -84,21 +94,8 @@ static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
 		vin->digital.subdev->name, vin->digital.code);
 
 	/* Figure out source and sink pad ids */
-	vin->digital.source_pad_idx = 0;
-	for (pad_idx = 0; pad_idx < sd->entity.num_pads; pad_idx++)
-		if (sd->entity.pads[pad_idx].flags == MEDIA_PAD_FL_SOURCE)
-			break;
-	if (pad_idx >= sd->entity.num_pads)
-		return -EINVAL;
-
-	vin->digital.source_pad_idx = pad_idx;
-
-	vin->digital.sink_pad_idx = 0;
-	for (pad_idx = 0; pad_idx < sd->entity.num_pads; pad_idx++)
-		if (sd->entity.pads[pad_idx].flags == MEDIA_PAD_FL_SINK) {
-			vin->digital.sink_pad_idx = pad_idx;
-			break;
-		}
+	vin->digital.source_pad_idx = rvin_pad_idx(sd, MEDIA_PAD_FL_SOURCE);
+	vin->digital.sink_pad_idx = rvin_pad_idx(sd, MEDIA_PAD_FL_SINK);
 
 	vin_dbg(vin, "Found media pads for %s source: %d sink %d\n",
 		vin->digital.subdev->name, vin->digital.source_pad_idx,
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 12/32] media: rcar-vin: split rvin_s_fmt_vid_cap()
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (10 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 11/32] media: rcar-vin: refactor pad lookup code Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 13/32] media: rcar-vin: register the video device early Niklas Söderlund
                   ` (19 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

The functionality provided by rvin_s_fmt_vid_cap() will be needed in
other places to add Gen3 support. Split it up in a function which do the
work and one which interface with the v4l2 API.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 51324c6..929f58b 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -313,10 +313,8 @@ static int rvin_try_fmt_vid_cap(struct file *file, void *priv,
 				 &source);
 }
 
-static int rvin_s_fmt_vid_cap(struct file *file, void *priv,
-			      struct v4l2_format *f)
+static int __rvin_s_fmt_vid_cap(struct rvin_dev *vin, struct v4l2_format *f)
 {
-	struct rvin_dev *vin = video_drvdata(file);
 	struct rvin_source_fmt source;
 	int ret;
 
@@ -338,6 +336,14 @@ static int rvin_s_fmt_vid_cap(struct file *file, void *priv,
 	return 0;
 }
 
+static int rvin_s_fmt_vid_cap(struct file *file, void *priv,
+			      struct v4l2_format *f)
+{
+	struct rvin_dev *vin = video_drvdata(file);
+
+	return __rvin_s_fmt_vid_cap(vin, f);
+}
+
 static int rvin_g_fmt_vid_cap(struct file *file, void *priv,
 			      struct v4l2_format *f)
 {
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 13/32] media: rcar-vin: register the video device early
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (11 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 12/32] media: rcar-vin: split rvin_s_fmt_vid_cap() Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 14/32] media: rcar-vin: move chip information to own struct Niklas Söderlund
                   ` (18 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

This is done to prepare for Gen3 support where there can be more then
one video pipeline which can terminate in a particular VIN instance.
Each pipeline have its own set of subdevices so to attach to a specific
subdevice at probe time is not possible. The pipelines will be
configured using the media controller API.

This patch changes the rcar-vin behavior so that the video device is
registered at probe time but attaching to a subdeivce is only once the
video device node is opened. If at that time there is no video source
subdevice for the VIN to use the open will fail with -EBUSY.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c |  10 +-
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 226 ++++++++++++++--------------
 drivers/media/platform/rcar-vin/rcar-vin.h  |   2 +
 3 files changed, 121 insertions(+), 117 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 50058fe..5807d8d 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -107,7 +107,7 @@ static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
 		return ret;
 	}
 
-	return rvin_v4l2_probe(vin);
+	return 0;
 }
 
 static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier,
@@ -118,7 +118,6 @@ static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier,
 
 	if (vin->digital.subdev == subdev) {
 		vin_dbg(vin, "unbind digital subdev %s\n", subdev->name);
-		rvin_v4l2_remove(vin);
 		vin->digital.subdev = NULL;
 		return;
 	}
@@ -283,6 +282,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
 
 	vin->dev = &pdev->dev;
 	vin->chip = (enum chip_id)match->data;
+	vin->last_input = NULL;
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (mem == NULL)
@@ -304,6 +304,10 @@ static int rcar_vin_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto error;
 
+	ret = rvin_v4l2_probe(vin);
+	if (ret)
+		goto error;
+
 	pm_suspend_ignore_children(&pdev->dev, true);
 	pm_runtime_enable(&pdev->dev);
 
@@ -322,6 +326,8 @@ static int rcar_vin_remove(struct platform_device *pdev)
 
 	pm_runtime_disable(&pdev->dev);
 
+	rvin_v4l2_remove(vin);
+
 	v4l2_async_notifier_unregister(&vin->notifier);
 
 	rvin_dma_remove(vin);
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 929f58b..47137d7 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -483,6 +483,94 @@ static int rvin_cropcap(struct file *file, void *priv,
 	return v4l2_subdev_call(sd, video, g_pixelaspect, &crop->pixelaspect);
 }
 
+static int rvin_attach_subdevices(struct rvin_dev *vin)
+{
+	struct v4l2_subdev_format fmt = {
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+	};
+	struct v4l2_mbus_framefmt *mf = &fmt.format;
+	struct v4l2_subdev *sd = vin_to_source(vin);
+	struct rvin_graph_entity *rent;
+	struct v4l2_format f;
+	int ret;
+
+	rent = vin_to_entity(vin);
+	if (!rent)
+		return -ENODEV;
+
+	ret = v4l2_subdev_call(sd, core, s_power, 1);
+	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+		return ret;
+
+	if (rent != vin->last_input) {
+		/* Input source have changed, reset our format */
+
+		vin->vdev.tvnorms = 0;
+		ret = v4l2_subdev_call(sd, video, g_tvnorms,
+				       &vin->vdev.tvnorms);
+		if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+			goto error;
+
+		/* Free old controls (safe even if there where none) */
+		v4l2_ctrl_handler_free(&vin->ctrl_handler);
+
+		ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);
+		if (ret < 0)
+			goto error;
+
+		/* Add new controls */
+		ret = v4l2_ctrl_add_handler(&vin->ctrl_handler,
+					    sd->ctrl_handler, NULL);
+		if (ret < 0)
+			goto error;
+
+		v4l2_ctrl_handler_setup(&vin->ctrl_handler);
+
+		fmt.pad = rent->source_pad_idx;
+
+		/* Try to improve our guess of a reasonable window format */
+		ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
+		if (ret)
+			goto error;
+
+		/* Set default format */
+		vin->format.width	= mf->width;
+		vin->format.height	= mf->height;
+		vin->format.colorspace	= mf->colorspace;
+		vin->format.field	= mf->field;
+		vin->format.pixelformat	= RVIN_DEFAULT_FORMAT;
+
+		/* Set initial crop and compose */
+		vin->crop.top = vin->crop.left = 0;
+		vin->crop.width = mf->width;
+		vin->crop.height = mf->height;
+
+		vin->compose.top = vin->compose.left = 0;
+		vin->compose.width = mf->width;
+		vin->compose.height = mf->height;
+
+		f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		f.fmt.pix = vin->format;
+		ret = __rvin_s_fmt_vid_cap(vin, &f);
+		if (ret)
+			goto error;
+	}
+
+	vin->last_input = rent;
+
+	return 0;
+error:
+	v4l2_subdev_call(sd, core, s_power, 0);
+	return ret;
+}
+
+static void rvin_detach_subdevices(struct rvin_dev *vin)
+{
+	struct v4l2_subdev *sd = vin_to_source(vin);
+
+	v4l2_subdev_call(sd, core, s_power, 0);
+}
+
 static int rvin_enum_input(struct file *file, void *priv,
 			   struct v4l2_input *i)
 {
@@ -741,80 +829,6 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = {
  * File Operations
  */
 
-static int rvin_power_on(struct rvin_dev *vin)
-{
-	int ret;
-	struct v4l2_subdev *sd = vin_to_source(vin);
-
-	pm_runtime_get_sync(vin->v4l2_dev.dev);
-
-	ret = v4l2_subdev_call(sd, core, s_power, 1);
-	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
-		return ret;
-	return 0;
-}
-
-static int rvin_power_off(struct rvin_dev *vin)
-{
-	int ret;
-	struct v4l2_subdev *sd = vin_to_source(vin);
-
-	ret = v4l2_subdev_call(sd, core, s_power, 0);
-
-	pm_runtime_put(vin->v4l2_dev.dev);
-
-	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
-		return ret;
-
-	return 0;
-}
-
-static int rvin_initialize_device(struct file *file)
-{
-	struct rvin_dev *vin = video_drvdata(file);
-	int ret;
-
-	struct v4l2_format f = {
-		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
-		.fmt.pix = {
-			.width		= vin->format.width,
-			.height		= vin->format.height,
-			.field		= vin->format.field,
-			.colorspace	= vin->format.colorspace,
-			.pixelformat	= vin->format.pixelformat,
-		},
-	};
-
-	ret = rvin_power_on(vin);
-	if (ret < 0)
-		return ret;
-
-	pm_runtime_enable(&vin->vdev.dev);
-	ret = pm_runtime_resume(&vin->vdev.dev);
-	if (ret < 0 && ret != -ENOSYS)
-		goto eresume;
-
-	/*
-	 * Try to configure with default parameters. Notice: this is the
-	 * very first open, so, we cannot race against other calls,
-	 * apart from someone else calling open() simultaneously, but
-	 * .host_lock is protecting us against it.
-	 */
-	ret = rvin_s_fmt_vid_cap(file, NULL, &f);
-	if (ret < 0)
-		goto esfmt;
-
-	v4l2_ctrl_handler_setup(&vin->ctrl_handler);
-
-	return 0;
-esfmt:
-	pm_runtime_disable(&vin->vdev.dev);
-eresume:
-	rvin_power_off(vin);
-
-	return ret;
-}
-
 static int rvin_open(struct file *file)
 {
 	struct rvin_dev *vin = video_drvdata(file);
@@ -826,17 +840,31 @@ static int rvin_open(struct file *file)
 
 	ret = v4l2_fh_open(file);
 	if (ret)
-		goto unlock;
+		goto err_out;
 
-	if (!v4l2_fh_is_singular_file(file))
-		goto unlock;
+	/* If there is no subdevice there is not much we can do */
+	if (!vin_to_source(vin)) {
+		ret = -EBUSY;
+		goto err_open;
+	}
 
-	if (rvin_initialize_device(file)) {
-		v4l2_fh_release(file);
-		ret = -ENODEV;
+	if (v4l2_fh_is_singular_file(file)) {
+		pm_runtime_get_sync(vin->dev);
+		ret = rvin_attach_subdevices(vin);
+		if (ret) {
+			vin_err(vin, "Error attaching subdevice\n");
+			goto err_power;
+		}
 	}
 
-unlock:
+	mutex_unlock(&vin->lock);
+
+	return 0;
+err_power:
+	pm_runtime_put(vin->dev);
+err_open:
+	v4l2_fh_release(file);
+err_out:
 	mutex_unlock(&vin->lock);
 	return ret;
 }
@@ -860,9 +888,8 @@ static int rvin_release(struct file *file)
 	 * Then de-initialize hw module.
 	 */
 	if (fh_singular) {
-		pm_runtime_suspend(&vin->vdev.dev);
-		pm_runtime_disable(&vin->vdev.dev);
-		rvin_power_off(vin);
+		rvin_detach_subdevices(vin);
+		pm_runtime_put(vin->dev);
 	}
 
 	mutex_unlock(&vin->lock);
@@ -910,41 +937,10 @@ static void rvin_notify(struct v4l2_subdev *sd,
 int rvin_v4l2_probe(struct rvin_dev *vin)
 {
 	struct video_device *vdev = &vin->vdev;
-	struct v4l2_subdev *sd = vin_to_source(vin);
 	int ret;
 
-	v4l2_set_subdev_hostdata(sd, vin);
-
 	vin->v4l2_dev.notify = rvin_notify;
 
-	ret = v4l2_subdev_call(sd, video, g_tvnorms, &vin->vdev.tvnorms);
-	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
-		return ret;
-
-	if (vin->vdev.tvnorms == 0) {
-		/* Disable the STD API if there are no tvnorms defined */
-		v4l2_disable_ioctl(&vin->vdev, VIDIOC_G_STD);
-		v4l2_disable_ioctl(&vin->vdev, VIDIOC_S_STD);
-		v4l2_disable_ioctl(&vin->vdev, VIDIOC_QUERYSTD);
-		v4l2_disable_ioctl(&vin->vdev, VIDIOC_ENUMSTD);
-	}
-
-	/* Add the controls */
-	/*
-	 * Currently the subdev with the largest number of controls (13) is
-	 * ov6550. So let's pick 16 as a hint for the control handler. Note
-	 * that this is a hint only: too large and you waste some memory, too
-	 * small and there is a (very) small performance hit when looking up
-	 * controls in the internal hash.
-	 */
-	ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);
-	if (ret < 0)
-		return ret;
-
-	ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, sd->ctrl_handler, NULL);
-	if (ret < 0)
-		return ret;
-
 	/* video node */
 	vdev->fops = &rvin_fops;
 	vdev->v4l2_dev = &vin->v4l2_dev;
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index d31212a..2a1b190 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -111,6 +111,7 @@ struct rvin_graph_entity {
  * @sequence:		V4L2 buffers sequence number
  * @state:		keeps track of operation state
  *
+ * @last_input:		points to the last active input source
  * @source:		active format from the video source
  * @format:		active V4L2 pixel format
  *
@@ -138,6 +139,7 @@ struct rvin_dev {
 	unsigned int sequence;
 	enum rvin_dma_state state;
 
+	struct rvin_graph_entity *last_input;
 	struct rvin_source_fmt source;
 	struct v4l2_pix_format format;
 
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 14/32] media: rcar-vin: move chip information to own struct
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (12 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 13/32] media: rcar-vin: register the video device early Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-07 12:40   ` Geert Uytterhoeven
  2016-11-02 13:23 ` [PATCH 15/32] media: rcar-vin: move max width and height information to chip information Niklas Söderlund
                   ` (17 subsequent siblings)
  31 siblings, 1 reply; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

When Gen3 support is added to the driver more then chip id will be
different for the different Soc. To avoid a lot of if statements in the
code create a struct chip_info to contain this information.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 49 ++++++++++++++++++++++++-----
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  3 +-
 drivers/media/platform/rcar-vin/rcar-vin.h  | 12 +++++--
 3 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 5807d8d..372443e 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -253,14 +253,47 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
  * Platform Device Driver
  */
 
+static const struct rvin_info rcar_info_h1 = {
+	.chip = RCAR_H1,
+};
+
+static const struct rvin_info rcar_info_m1 = {
+	.chip = RCAR_M1,
+};
+
+static const struct rvin_info rcar_info_gen2 = {
+	.chip = RCAR_GEN2,
+};
+
 static const struct of_device_id rvin_of_id_table[] = {
-	{ .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
-	{ .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
-	{ .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
-	{ .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
-	{ .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
-	{ .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
-	{ .compatible = "renesas,rcar-gen2-vin", .data = (void *)RCAR_GEN2 },
+	{
+		.compatible = "renesas,vin-r8a7794",
+		.data = (void *)&rcar_info_gen2,
+	},
+	{
+		.compatible = "renesas,vin-r8a7793",
+		.data = (void *)&rcar_info_gen2,
+	},
+	{
+		.compatible = "renesas,vin-r8a7791",
+		.data = (void *)&rcar_info_gen2,
+	},
+	{
+		.compatible = "renesas,vin-r8a7790",
+		.data = (void *)&rcar_info_gen2,
+	},
+	{
+		.compatible = "renesas,vin-r8a7779",
+		.data = (void *)&rcar_info_h1,
+	},
+	{
+		.compatible = "renesas,vin-r8a7778",
+		.data = (void *)&rcar_info_m1,
+	},
+	{
+		.compatible = "renesas,rcar-gen2-vin",
+		.data = (void *)&rcar_info_gen2,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
@@ -281,7 +314,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
 		return -ENODEV;
 
 	vin->dev = &pdev->dev;
-	vin->chip = (enum chip_id)match->data;
+	vin->info = (const struct rvin_info *)match->data;
 	vin->last_input = NULL;
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 47137d7..05b0181 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -279,7 +279,8 @@ static int __rvin_try_format(struct rvin_dev *vin,
 	pix->sizeimage = max_t(u32, pix->sizeimage,
 			       rvin_format_sizeimage(pix));
 
-	if (vin->chip == RCAR_M1 && pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
+	if (vin->info->chip == RCAR_M1 &&
+	    pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
 		vin_err(vin, "pixel format XBGR32 not supported on M1\n");
 		return -EINVAL;
 	}
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index 2a1b190..17a5fce 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -89,10 +89,18 @@ struct rvin_graph_entity {
 };
 
 /**
+ * struct rvin_info- Information about the particular VIN implementation
+ * @chip:		type of VIN chip
+ */
+struct rvin_info {
+	enum chip_id chip;
+};
+
+/**
  * struct rvin_dev - Renesas VIN device structure
  * @dev:		(OF) device
  * @base:		device I/O register space remapped to virtual memory
- * @chip:		type of VIN chip
+ * @info		info about VIN instance
  *
  * @vdev:		V4L2 video device associated with VIN
  * @v4l2_dev:		V4L2 device
@@ -121,7 +129,7 @@ struct rvin_graph_entity {
 struct rvin_dev {
 	struct device *dev;
 	void __iomem *base;
-	enum chip_id chip;
+	const struct rvin_info *info;
 
 	struct video_device vdev;
 	struct v4l2_device v4l2_dev;
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 15/32] media: rcar-vin: move max width and height information to chip information
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (13 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 14/32] media: rcar-vin: move chip information to own struct Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 16/32] media: rcar-vin: change name of video device Niklas Söderlund
                   ` (16 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

On Gen3 the max supported width and height will be different from Gen2.
Move the limits to the struct chip_info to prepare for Gen3 support.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 6 ++++++
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 6 ++----
 drivers/media/platform/rcar-vin/rcar-vin.h  | 6 ++++++
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 372443e..e3dea60 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -255,14 +255,20 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 
 static const struct rvin_info rcar_info_h1 = {
 	.chip = RCAR_H1,
+	.max_width = 2048,
+	.max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_m1 = {
 	.chip = RCAR_M1,
+	.max_width = 2048,
+	.max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_gen2 = {
 	.chip = RCAR_GEN2,
+	.max_width = 2048,
+	.max_height = 2048,
 };
 
 static const struct of_device_id rvin_of_id_table[] = {
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 05b0181..f5fbe9f 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -23,8 +23,6 @@
 #include "rcar-vin.h"
 
 #define RVIN_DEFAULT_FORMAT	V4L2_PIX_FMT_YUYV
-#define RVIN_MAX_WIDTH		2048
-#define RVIN_MAX_HEIGHT		2048
 
 /* -----------------------------------------------------------------------------
  * Format Conversions
@@ -271,8 +269,8 @@ static int __rvin_try_format(struct rvin_dev *vin,
 	walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1;
 
 	/* Limit to VIN capabilities */
-	v4l_bound_align_image(&pix->width, 2, RVIN_MAX_WIDTH, walign,
-			      &pix->height, 4, RVIN_MAX_HEIGHT, 2, 0);
+	v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign,
+			      &pix->height, 4, vin->info->max_height, 2, 0);
 
 	pix->bytesperline = max_t(u32, pix->bytesperline,
 				  rvin_format_bytesperline(pix));
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index 17a5fce..ddeca9f 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -91,9 +91,15 @@ struct rvin_graph_entity {
 /**
  * struct rvin_info- Information about the particular VIN implementation
  * @chip:		type of VIN chip
+ *
+ * max_width:		max input with the VIN supports
+ * max_height:		max input height the VIN supports
  */
 struct rvin_info {
 	enum chip_id chip;
+
+	unsigned int max_width;
+	unsigned int max_height;
 };
 
 /**
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 16/32] media: rcar-vin: change name of video device
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (14 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 15/32] media: rcar-vin: move max width and height information to chip information Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 17/32] media: rcar-vin: clarify error message from the digital notifier Niklas Söderlund
                   ` (15 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

The rcar-vin driver needs to be part of a media controller to support
Gen3. Give each VIN instance a unique name so it can be referenced from
userspace.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index f5fbe9f..e99815f 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -944,7 +944,8 @@ int rvin_v4l2_probe(struct rvin_dev *vin)
 	vdev->fops = &rvin_fops;
 	vdev->v4l2_dev = &vin->v4l2_dev;
 	vdev->queue = &vin->queue;
-	strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name));
+	snprintf(vdev->name, sizeof(vdev->name), "%s.%s", KBUILD_MODNAME,
+		 dev_name(vin->dev));
 	vdev->release = video_device_release_empty;
 	vdev->ioctl_ops = &rvin_ioctl_ops;
 	vdev->lock = &vin->lock;
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 17/32] media: rcar-vin: clarify error message from the digital notifier
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (15 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 16/32] media: rcar-vin: change name of video device Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 18/32] media: rcar-vin: enable Gen3 hardware configuration Niklas Söderlund
                   ` (14 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Some of the parser functions previously only used by the digital
subdevice OF/V4L2 async code will be shared with the CSI2 group
notifiers. Clarify which notifier register error message and mark which
functions are generic helpers.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index e3dea60..f961957 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -35,7 +35,7 @@ struct rvin_graph_entity *vin_to_entity(struct rvin_dev *vin)
 }
 
 /* -----------------------------------------------------------------------------
- * Async notifier
+ * Async notifier helpers
  */
 
 #define notifier_to_vin(n) container_of(n, struct rvin_dev, notifier)
@@ -77,6 +77,10 @@ static unsigned int rvin_pad_idx(struct v4l2_subdev *sd, int direction)
 	return 0;
 }
 
+/* -----------------------------------------------------------------------------
+ * Digital async notifier
+ */
+
 static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
 {
 	struct rvin_dev *vin = notifier_to_vin(notifier);
@@ -242,7 +246,7 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 
 	ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);
 	if (ret < 0) {
-		vin_err(vin, "Notifier registration failed\n");
+		vin_err(vin, "Digital notifier registration failed\n");
 		return ret;
 	}
 
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 18/32] media: rcar-vin: enable Gen3 hardware configuration
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (16 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 17/32] media: rcar-vin: clarify error message from the digital notifier Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 19/32] media: rcar-vin: add functions to manipulate Gen3 CHSEL value Niklas Söderlund
                   ` (13 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Add the register needed to work with Gen3 hardware. This patch adds
the logic for how to work with the Gen3 hardware. More work is required
to enable the subdevice structure needed to configure capturing.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 98 ++++++++++++++++++++----------
 drivers/media/platform/rcar-vin/rcar-vin.h |  1 +
 2 files changed, 68 insertions(+), 31 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
index eac5c19..80958e6 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -33,21 +33,23 @@
 #define VNELPRC_REG	0x10	/* Video n End Line Pre-Clip Register */
 #define VNSPPRC_REG	0x14	/* Video n Start Pixel Pre-Clip Register */
 #define VNEPPRC_REG	0x18	/* Video n End Pixel Pre-Clip Register */
-#define VNSLPOC_REG	0x1C	/* Video n Start Line Post-Clip Register */
-#define VNELPOC_REG	0x20	/* Video n End Line Post-Clip Register */
-#define VNSPPOC_REG	0x24	/* Video n Start Pixel Post-Clip Register */
-#define VNEPPOC_REG	0x28	/* Video n End Pixel Post-Clip Register */
 #define VNIS_REG	0x2C	/* Video n Image Stride Register */
 #define VNMB_REG(m)	(0x30 + ((m) << 2)) /* Video n Memory Base m Register */
 #define VNIE_REG	0x40	/* Video n Interrupt Enable Register */
 #define VNINTS_REG	0x44	/* Video n Interrupt Status Register */
 #define VNSI_REG	0x48	/* Video n Scanline Interrupt Register */
 #define VNMTC_REG	0x4C	/* Video n Memory Transfer Control Register */
-#define VNYS_REG	0x50	/* Video n Y Scale Register */
-#define VNXS_REG	0x54	/* Video n X Scale Register */
 #define VNDMR_REG	0x58	/* Video n Data Mode Register */
 #define VNDMR2_REG	0x5C	/* Video n Data Mode Register 2 */
 #define VNUVAOF_REG	0x60	/* Video n UV Address Offset Register */
+
+/* Register offsets specific for Gen2 */
+#define VNSLPOC_REG	0x1C	/* Video n Start Line Post-Clip Register */
+#define VNELPOC_REG	0x20	/* Video n End Line Post-Clip Register */
+#define VNSPPOC_REG	0x24	/* Video n Start Pixel Post-Clip Register */
+#define VNEPPOC_REG	0x28	/* Video n End Pixel Post-Clip Register */
+#define VNYS_REG	0x50	/* Video n Y Scale Register */
+#define VNXS_REG	0x54	/* Video n X Scale Register */
 #define VNC1A_REG	0x80	/* Video n Coefficient Set C1A Register */
 #define VNC1B_REG	0x84	/* Video n Coefficient Set C1B Register */
 #define VNC1C_REG	0x88	/* Video n Coefficient Set C1C Register */
@@ -73,9 +75,13 @@
 #define VNC8B_REG	0xF4	/* Video n Coefficient Set C8B Register */
 #define VNC8C_REG	0xF8	/* Video n Coefficient Set C8C Register */
 
+/* Register offsets specific for Gen3 */
+#define VNCSI_IFMD_REG		0x20 /* Video n CSI2 Interface Mode Register */
 
 /* Register bit fields for R-Car VIN */
 /* Video n Main Control Register bits */
+#define VNMC_DPINE		(1 << 27) /* Gen3 specific */
+#define VNMC_SCLE		(1 << 26) /* Gen3 specific */
 #define VNMC_FOC		(1 << 21)
 #define VNMC_YCAL		(1 << 19)
 #define VNMC_INF_YUV8_BT656	(0 << 16)
@@ -119,6 +125,13 @@
 #define VNDMR2_FTEV		(1 << 17)
 #define VNDMR2_VLV(n)		((n & 0xf) << 12)
 
+/* Video n CSI2 Interface Mode Register (Gen3) */
+#define VNCSI_IFMD_DES2		(1 << 27)
+#define VNCSI_IFMD_DES1		(1 << 26)
+#define VNCSI_IFMD_DES0		(1 << 25)
+#define VNCSI_IFMD_CSI_CHSEL(n) ((n & 0xf) << 0)
+#define VNCSI_IFMD_CSI_CHSEL_MASK 0xf
+
 static void rvin_write(struct rvin_dev *vin, u32 value, u32 offset)
 {
 	iowrite32(value, vin->base + offset);
@@ -205,7 +218,10 @@ static int rvin_setup(struct rvin_dev *vin)
 	}
 
 	/* Enable VSYNC Field Toogle mode after one VSYNC input */
-	dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);
+	if (vin->info->chip == RCAR_GEN3)
+		dmr2 = VNDMR2_FTEV;
+	else
+		dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);
 
 	/* Hsync Signal Polarity Select */
 	if (!(rent->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
@@ -257,6 +273,14 @@ static int rvin_setup(struct rvin_dev *vin)
 	if (input_is_yuv == output_is_yuv)
 		vnmc |= VNMC_BPS;
 
+	if (vin->info->chip == RCAR_GEN3) {
+		/* Select between CSI-2 and Digital input */
+		if (rent->mbus_cfg.type == V4L2_MBUS_CSI2)
+			vnmc &= ~VNMC_DPINE;
+		else
+			vnmc |= VNMC_DPINE;
+	}
+
 	/* Progressive or interlaced mode */
 	interrupts = progressive ? VNIE_FIE : VNIE_EFE;
 
@@ -758,28 +782,10 @@ static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs)
 	rvin_write(vin, p_set->coeff_set[23], VNC8C_REG);
 }
 
-void rvin_crop_scale_comp(struct rvin_dev *vin)
+static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin)
 {
 	u32 xs, ys;
 
-	/* Set Start/End Pixel/Line Pre-Clip */
-	rvin_write(vin, vin->crop.left, VNSPPRC_REG);
-	rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
-	switch (vin->format.field) {
-	case V4L2_FIELD_INTERLACED:
-	case V4L2_FIELD_INTERLACED_TB:
-	case V4L2_FIELD_INTERLACED_BT:
-		rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG);
-		rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1,
-			   VNELPRC_REG);
-		break;
-	default:
-		rvin_write(vin, vin->crop.top, VNSLPRC_REG);
-		rvin_write(vin, vin->crop.top + vin->crop.height - 1,
-			   VNELPRC_REG);
-		break;
-	}
-
 	/* Set scaling coefficient */
 	ys = 0;
 	if (vin->crop.height != vin->compose.height)
@@ -817,11 +823,6 @@ void rvin_crop_scale_comp(struct rvin_dev *vin)
 		break;
 	}
 
-	if (vin->format.pixelformat == V4L2_PIX_FMT_NV16)
-		rvin_write(vin, ALIGN(vin->format.width, 0x20), VNIS_REG);
-	else
-		rvin_write(vin, ALIGN(vin->format.width, 0x10), VNIS_REG);
-
 	vin_dbg(vin,
 		"Pre-Clip: %ux%u@%u:%u YS: %d XS: %d Post-Clip: %ux%u@%u:%u\n",
 		vin->crop.width, vin->crop.height, vin->crop.left,
@@ -829,9 +830,44 @@ void rvin_crop_scale_comp(struct rvin_dev *vin)
 		0, 0);
 }
 
+void rvin_crop_scale_comp(struct rvin_dev *vin)
+{
+	/* Set Start/End Pixel/Line Pre-Clip */
+	rvin_write(vin, vin->crop.left, VNSPPRC_REG);
+	rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
+
+	switch (vin->format.field) {
+	case V4L2_FIELD_INTERLACED:
+	case V4L2_FIELD_INTERLACED_TB:
+	case V4L2_FIELD_INTERLACED_BT:
+		rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG);
+		rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1,
+			   VNELPRC_REG);
+		break;
+	default:
+		rvin_write(vin, vin->crop.top, VNSLPRC_REG);
+		rvin_write(vin, vin->crop.top + vin->crop.height - 1,
+			   VNELPRC_REG);
+		break;
+	}
+
+	/* TODO: Add support for the UDS scaler. */
+	if (vin->info->chip != RCAR_GEN3)
+		rvin_crop_scale_comp_gen2(vin);
+
+	if (vin->format.pixelformat == V4L2_PIX_FMT_NV16)
+		rvin_write(vin, ALIGN(vin->format.width, 0x20), VNIS_REG);
+	else
+		rvin_write(vin, ALIGN(vin->format.width, 0x10), VNIS_REG);
+}
+
 void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix,
 		    u32 width, u32 height)
 {
+	/* TODO: Add support for the UDS scaler. */
+	if (vin->info->chip == RCAR_GEN3)
+		return;
+
 	/* All VIN channels on Gen2 have scalers */
 	pix->width = width;
 	pix->height = height;
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index ddeca9f..b8f5634 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -33,6 +33,7 @@ enum chip_id {
 	RCAR_H1,
 	RCAR_M1,
 	RCAR_GEN2,
+	RCAR_GEN3,
 };
 
 /**
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 19/32] media: rcar-vin: add functions to manipulate Gen3 CHSEL value
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (17 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 18/32] media: rcar-vin: enable Gen3 hardware configuration Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 20/32] media: rcar-vin: expose a sink pad if we are on Gen3 Niklas Söderlund
                   ` (12 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

On Gen3 the CSI routing is controlled by the VnCSI_IFMD register. One
feature of this register is that it's only present in the VIN0 and VIN4
instances. The register in VIN0 controls the routing for VIN0-3 and the
register in VIN4 controls routing for VIN4-7.

To be able to control routing from a media device these functions need
to control runtime PM for the subgroup master (VIN0 and VIN4). The
subgroup master must be switched on before the register is manipulated,
once the operation is complete it's safe to switch the master off and
the new routing will still be in effect.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 43 ++++++++++++++++++++++++++++++
 drivers/media/platform/rcar-vin/rcar-vin.h |  3 +++
 2 files changed, 46 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
index 80958e6..322e4c1 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -16,6 +16,7 @@
 
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
 
 #include <media/videobuf2-dma-contig.h>
 
@@ -1247,3 +1248,45 @@ int rvin_dma_probe(struct rvin_dev *vin, int irq)
 
 	return ret;
 }
+
+/* -----------------------------------------------------------------------------
+ * Gen3 CHSEL manipulation
+ */
+
+int rvin_set_chsel(struct rvin_dev *vin, u8 chsel)
+{
+	u32 ifmd;
+
+	pm_runtime_get_sync(vin->dev);
+
+	/*
+	 * Undocumented feature: Writing to VNCSI_IFMD_REG will go
+	 * through and on read back look correct but won't have
+	 * any effect if VNMC_REG is not first set to 0.
+	 */
+	rvin_write(vin, 0, VNMC_REG);
+
+	ifmd = VNCSI_IFMD_DES2 | VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0 |
+		VNCSI_IFMD_CSI_CHSEL(chsel);
+
+	rvin_write(vin, ifmd, VNCSI_IFMD_REG);
+
+	vin_dbg(vin, "Set IFMD 0x%x\n", ifmd);
+
+	pm_runtime_put(vin->dev);
+
+	return 0;
+}
+
+int rvin_get_chsel(struct rvin_dev *vin)
+{
+	int chsel;
+
+	pm_runtime_get_sync(vin->dev);
+
+	chsel = rvin_read(vin, VNCSI_IFMD_REG) & VNCSI_IFMD_CSI_CHSEL_MASK;
+
+	pm_runtime_put(vin->dev);
+
+	return chsel;
+}
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index b8f5634..a6a49a96 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -184,4 +184,7 @@ void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix,
 		    u32 width, u32 height);
 void rvin_crop_scale_comp(struct rvin_dev *vin);
 
+int rvin_set_chsel(struct rvin_dev *vin, u8 chsel);
+int rvin_get_chsel(struct rvin_dev *vin);
+
 #endif
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 20/32] media: rcar-vin: expose a sink pad if we are on Gen3
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (18 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 19/32] media: rcar-vin: add functions to manipulate Gen3 CHSEL value Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 17:15   ` Sergei Shtylyov
  2016-11-02 13:23 ` [PATCH 21/32] media: rcar-vin: add group allocator functions Niklas Söderlund
                   ` (11 subsequent siblings)
  31 siblings, 1 reply; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Refactor the probe code path to look for the digital subdevice, if one
is found use it just like the driver did before (Gen2 mode) but if it's
not found prepare for a Gen3 mode by registering a pad for the media
controller API to use.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 21 ++++++++++++++++++++-
 drivers/media/platform/rcar-vin/rcar-vin.h  |  9 +++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index f961957..ce8b59a 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -308,6 +308,25 @@ static const struct of_device_id rvin_of_id_table[] = {
 };
 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
 
+static int rvin_graph_init(struct rvin_dev *vin)
+{
+	int ret;
+
+	/* Try to get digital video pipe */
+	ret = rvin_digital_graph_init(vin);
+
+	/* No digital pipe and we are on Gen3 try to joint CSI2 group */
+	if (ret == -ENODEV && vin->info->chip == RCAR_GEN3) {
+
+		vin->pads[RVIN_SINK].flags = MEDIA_PAD_FL_SINK;
+		ret = media_entity_pads_init(&vin->vdev.entity, 1, vin->pads);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
 static int rcar_vin_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match;
@@ -343,7 +362,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ret = rvin_digital_graph_init(vin);
+	ret = rvin_graph_init(vin);
 	if (ret < 0)
 		goto error;
 
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index a6a49a96..8ed43be 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -36,6 +36,11 @@ enum chip_id {
 	RCAR_GEN3,
 };
 
+enum rvin_pads {
+	RVIN_SINK,
+	RVIN_PAD_MAX,
+};
+
 /**
  * STOPPED  - No operation in progress
  * RUNNING  - Operation in progress have buffers
@@ -115,6 +120,8 @@ struct rvin_info {
  * @notifier:		V4L2 asynchronous subdevs notifier
  * @digital:		entity in the DT for local digital subdevice
  *
+ * @pads:		pads for media controller
+ *
  * @lock:		protects @queue
  * @queue:		vb2 buffers queue
  *
@@ -144,6 +151,8 @@ struct rvin_dev {
 	struct v4l2_async_notifier notifier;
 	struct rvin_graph_entity digital;
 
+	struct media_pad pads[RVIN_PAD_MAX];
+
 	struct mutex lock;
 	struct vb2_queue queue;
 
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 21/32] media: rcar-vin: add group allocator functions
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (19 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 20/32] media: rcar-vin: expose a sink pad if we are on Gen3 Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 22/32] media: rcar-vin: add chsel information to rvin_info Niklas Söderlund
                   ` (10 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

On Gen3 all VIN instances which wish to interact with with the shared
CSI2 resource needs to be part of the same media device and share other
information, such as subdevices and be able to call routing operations
on other VIN instances.

This patch adds a group allocator which joins all VIN instances in one
group. Inspiration for this patch is taken from Shuah Khans patch series
'Media Device Allocator API' which do a similar thing but allows a media
device to be shared across different drivers. The use case here is to
share group information between multiple instances of the same driver.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 103 ++++++++++++++++++++++++++++
 drivers/media/platform/rcar-vin/rcar-vin.h  |  41 +++++++++++
 2 files changed, 144 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index ce8b59a..68a16c8 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -26,6 +26,102 @@
 #include "rcar-vin.h"
 
 /* -----------------------------------------------------------------------------
+ * Gen3 CSI2 Group Allocator
+ */
+
+static DEFINE_MUTEX(rvin_group_lock);
+static struct rvin_group *rvin_group_data;
+
+static void rvin_group_release(struct kref *kref)
+{
+	struct rvin_group *group =
+		container_of(kref, struct rvin_group, refcount);
+
+	mutex_lock(&rvin_group_lock);
+
+	media_device_unregister(&group->mdev);
+	media_device_cleanup(&group->mdev);
+
+	rvin_group_data = NULL;
+
+	mutex_unlock(&rvin_group_lock);
+
+	kfree(group);
+}
+
+static struct rvin_group *__rvin_group_allocate(struct rvin_dev *vin)
+{
+	struct rvin_group *group;
+
+	if (rvin_group_data) {
+		group = rvin_group_data;
+		kref_get(&group->refcount);
+		vin_dbg(vin, "%s: get group=%p\n", __func__, group);
+		return group;
+	}
+
+	group = kzalloc(sizeof(*group), GFP_KERNEL);
+	if (!group)
+		return NULL;
+
+	kref_init(&group->refcount);
+	rvin_group_data = group;
+
+	vin_dbg(vin, "%s: alloc group=%p\n", __func__, group);
+	return group;
+}
+
+static struct rvin_group *rvin_group_allocate(struct rvin_dev *vin)
+{
+	struct rvin_group *group;
+	struct media_device *mdev;
+	int ret;
+
+	mutex_lock(&rvin_group_lock);
+
+	group = __rvin_group_allocate(vin);
+	if (!group) {
+		mutex_unlock(&rvin_group_lock);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/* Init group data if its not already initialized */
+	mdev = &group->mdev;
+	if (!mdev->dev) {
+		mutex_init(&group->lock);
+		mdev->dev = vin->dev;
+
+		strlcpy(mdev->driver_name, "Renesas VIN",
+			sizeof(mdev->driver_name));
+		strlcpy(mdev->model, vin->dev->of_node->name,
+			sizeof(mdev->model));
+		strlcpy(mdev->bus_info, of_node_full_name(vin->dev->of_node),
+			sizeof(mdev->bus_info));
+		mdev->driver_version = LINUX_VERSION_CODE;
+		media_device_init(mdev);
+
+		ret = media_device_register(mdev);
+		if (ret) {
+			vin_err(vin, "Failed to register media device\n");
+			mutex_unlock(&rvin_group_lock);
+			return ERR_PTR(ret);
+		}
+	}
+
+	vin->v4l2_dev.mdev = mdev;
+
+	mutex_unlock(&rvin_group_lock);
+
+	return group;
+}
+
+static void rvin_group_delete(struct rvin_dev *vin)
+{
+	vin_dbg(vin, "%s: group=%p\n", __func__, &vin->group);
+	kref_put(&vin->group->refcount, rvin_group_release);
+}
+
+/* -----------------------------------------------------------------------------
  * Subdevice helpers
  */
 
@@ -322,6 +418,10 @@ static int rvin_graph_init(struct rvin_dev *vin)
 		ret = media_entity_pads_init(&vin->vdev.entity, 1, vin->pads);
 		if (ret)
 			return ret;
+
+		vin->group = rvin_group_allocate(vin);
+		if (IS_ERR(vin->group))
+			return PTR_ERR(vin->group);
 	}
 
 	return ret;
@@ -390,6 +490,9 @@ static int rcar_vin_remove(struct platform_device *pdev)
 
 	rvin_v4l2_remove(vin);
 
+	if (vin->group)
+		rvin_group_delete(vin);
+
 	v4l2_async_notifier_unregister(&vin->notifier);
 
 	rvin_dma_remove(vin);
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index 8ed43be..90c28a7 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -17,10 +17,13 @@
 #ifndef __RCAR_VIN__
 #define __RCAR_VIN__
 
+#include <linux/kref.h>
+
 #include <media/v4l2-async.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-dev.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-mc.h>
 #include <media/videobuf2-v4l2.h>
 
 /* Number of HW buffers */
@@ -29,6 +32,9 @@
 /* Address alignment mask for HW buffers */
 #define HW_BUFFER_MASK 0x7f
 
+/* Max number on VIN instances that can be in a system */
+#define RCAR_VIN_NUM 8
+
 enum chip_id {
 	RCAR_H1,
 	RCAR_M1,
@@ -36,6 +42,15 @@ enum chip_id {
 	RCAR_GEN3,
 };
 
+enum rvin_csi_id {
+	RVIN_CSI20,
+	RVIN_CSI21,
+	RVIN_CSI40,
+	RVIN_CSI41,
+	RVIN_CSI_MAX,
+	RVIN_NOOPE,
+};
+
 enum rvin_pads {
 	RVIN_SINK,
 	RVIN_PAD_MAX,
@@ -94,6 +109,8 @@ struct rvin_graph_entity {
 	int sink_pad_idx;
 };
 
+struct rvin_group;
+
 /**
  * struct rvin_info- Information about the particular VIN implementation
  * @chip:		type of VIN chip
@@ -120,6 +137,7 @@ struct rvin_info {
  * @notifier:		V4L2 asynchronous subdevs notifier
  * @digital:		entity in the DT for local digital subdevice
  *
+ * @group:		Gen3 CSI group
  * @pads:		pads for media controller
  *
  * @lock:		protects @queue
@@ -151,6 +169,7 @@ struct rvin_dev {
 	struct v4l2_async_notifier notifier;
 	struct rvin_graph_entity digital;
 
+	struct rvin_group *group;
 	struct media_pad pads[RVIN_PAD_MAX];
 
 	struct mutex lock;
@@ -180,6 +199,28 @@ struct rvin_graph_entity *vin_to_entity(struct rvin_dev *vin);
 #define vin_warn(d, fmt, arg...)	dev_warn(d->dev, fmt, ##arg)
 #define vin_err(d, fmt, arg...)		dev_err(d->dev, fmt, ##arg)
 
+/**
+ * struct rvin_group - VIN CSI2 group information
+ * @refcount:		number of VIN instances using the group
+ *
+ * @mdev:		media device which represents the group
+ *
+ * @lock:		protects the vin, bridge and source members
+ * @vin:		VIN instances which are part of the group
+ * @bridge:		CSI2 bridge between video source and VIN
+ * @source:		video source connected to each bridge
+ */
+struct rvin_group {
+	struct kref refcount;
+
+	struct media_device mdev;
+
+	struct mutex lock;
+	struct rvin_dev *vin[RCAR_VIN_NUM];
+	struct rvin_graph_entity bridge[RVIN_CSI_MAX];
+	struct rvin_graph_entity source[RVIN_CSI_MAX];
+};
+
 int rvin_dma_probe(struct rvin_dev *vin, int irq);
 void rvin_dma_remove(struct rvin_dev *vin);
 
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 22/32] media: rcar-vin: add chsel information to rvin_info
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (20 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 21/32] media: rcar-vin: add group allocator functions Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 23/32] media: rcar-vin: parse Gen3 OF and setup media graph Niklas Söderlund
                   ` (9 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Each Gen3 SoC have a limited set of predefined routing possibilities for
which CSI2 device and virtual channel can be routed to which VIN
instance.  Prepare to store this information in the struct rvin_info.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-vin.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index 90c28a7..cd7d959 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -35,6 +35,9 @@
 /* Max number on VIN instances that can be in a system */
 #define RCAR_VIN_NUM 8
 
+/* Max number of CHSEL values for any Gen3 SoC */
+#define RCAR_CHSEL_MAX 6
+
 enum chip_id {
 	RCAR_H1,
 	RCAR_M1,
@@ -111,6 +114,16 @@ struct rvin_graph_entity {
 
 struct rvin_group;
 
+
+/** struct rvin_group_chsel - Map a CSI2 device and channel for a CHSEL value
+ * @csi:		VIN internal number for CSI2 device
+ * @chan:		CSI2 VC number on remote
+ */
+struct rvin_group_chsel {
+	enum rvin_csi_id csi;
+	int chan;
+};
+
 /**
  * struct rvin_info- Information about the particular VIN implementation
  * @chip:		type of VIN chip
@@ -123,6 +136,9 @@ struct rvin_info {
 
 	unsigned int max_width;
 	unsigned int max_height;
+
+	unsigned int num_chsels;
+	struct rvin_group_chsel chsels[RCAR_VIN_NUM][RCAR_CHSEL_MAX];
 };
 
 /**
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 23/32] media: rcar-vin: parse Gen3 OF and setup media graph
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (21 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 22/32] media: rcar-vin: add chsel information to rvin_info Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 24/32] media: rcar-vin: add link notify for Gen3 Niklas Söderlund
                   ` (8 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Parse the VIN Gen3 OF graph and register all devices in the CSI2 group
common media device. Once a subdevice is added to the common media
device list as many links as possible are added and if possible enabled.

The links between the video source device and the CSI2 bridge are
enabled as immutable since they can't change during runtime. While the
link between the CSI2 bridge and the VIN video device are enabled
according the CHSEL routing table suitable for the SoC.

The parsing and registering subdevices is a collaborative effort shared
between all rcar-vin instances which are part of the CSI2 group. Which
ever rcar-vin instance which fist sees a new subdevice in the graph adds
it to its private v4l2 async notifier and once it's bound it will be
available for the whole CSI2 group.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 485 ++++++++++++++++++++++++++++
 1 file changed, 485 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 68a16c8..20fe377 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -350,6 +350,483 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 }
 
 /* -----------------------------------------------------------------------------
+ * CSI async notifier
+ */
+
+/* group lock should be held when calling this function */
+static void rvin_group_update_pads(struct rvin_graph_entity *entity)
+{
+	struct media_entity *ent = &entity->subdev->entity;
+	unsigned int i;
+
+	/* Make sure source pad idx are sane */
+	if (entity->source_pad_idx >= ent->num_pads ||
+	    ent->pads[entity->source_pad_idx].flags != MEDIA_PAD_FL_SOURCE) {
+		entity->source_pad_idx =
+			rvin_pad_idx(entity->subdev, MEDIA_PAD_FL_SOURCE);
+	}
+
+	/* Try to find sink for source, fall back 0 which always is sink */
+	entity->sink_pad_idx = 0;
+	for (i = 0; i < ent->num_pads; ++i) {
+		struct media_pad *sink = &ent->pads[i];
+
+		if (!(sink->flags & MEDIA_PAD_FL_SINK))
+			continue;
+
+		if (sink->index == entity->source_pad_idx)
+			continue;
+
+		if (media_entity_has_route(ent, sink->index,
+					   entity->source_pad_idx))
+			entity->sink_pad_idx = sink->index;
+	}
+}
+
+/* group lock should be held when calling this function */
+static int rvin_group_add_link(struct rvin_dev *vin,
+			       struct media_entity *source,
+			       unsigned int source_pad_idx,
+			       struct media_entity *sink,
+			       unsigned int sink_idx,
+			       u32 flags)
+{
+	struct media_pad *source_pad, *sink_pad;
+	int ret = 0;
+
+	source_pad = &source->pads[source_pad_idx];
+	sink_pad = &sink->pads[sink_idx];
+
+	if (!media_entity_find_link(source_pad, sink_pad))
+		ret = media_create_pad_link(source, source_pad_idx,
+					    sink, sink_idx, flags);
+
+	if (ret)
+		vin_err(vin, "Error adding link from %s to %s\n",
+			source->name, sink->name);
+
+	return ret;
+}
+
+static int rvin_group_update_links(struct rvin_dev *vin)
+{
+	struct media_entity *source, *sink;
+	struct rvin_dev *master;
+	unsigned int i, n, idx, chsel, csi;
+	u32 flags;
+	int ret;
+
+	mutex_lock(&vin->group->lock);
+
+	/* Update Source -> Bridge */
+	for (i = 0; i < RVIN_CSI_MAX; i++) {
+		if (!vin->group->source[i].subdev)
+			continue;
+
+		if (!vin->group->bridge[i].subdev)
+			continue;
+
+		source = &vin->group->source[i].subdev->entity;
+		sink = &vin->group->bridge[i].subdev->entity;
+		idx = vin->group->source[i].source_pad_idx;
+		flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
+
+		ret = rvin_group_add_link(vin, source, idx, sink, 0, flags);
+		if (ret)
+			goto out;
+	}
+
+	/* Update Bridge -> VIN */
+	for (n = 0; n < RCAR_VIN_NUM; n++) {
+
+		/* Check that VIN is part of the group */
+		if (!vin->group->vin[n])
+			continue;
+
+		/* Check that subgroup master is part of the group */
+		master = vin->group->vin[n < 4 ? 0 : 4];
+		if (!master)
+			continue;
+
+		chsel = rvin_get_chsel(master);
+
+		for (i = 0; i < vin->info->num_chsels; i++) {
+			csi = vin->info->chsels[n][i].csi;
+
+			/* If the CSI is out of bounds it's a no operate skip */
+			if (csi >= RVIN_CSI_MAX)
+				continue;
+
+			/* Check that bridge are part of the group */
+			if (!vin->group->bridge[csi].subdev)
+				continue;
+
+			source = &vin->group->bridge[csi].subdev->entity;
+			sink = &vin->group->vin[n]->vdev.entity;
+			idx = vin->info->chsels[n][i].chan + 1;
+			flags = i == chsel ? MEDIA_LNK_FL_ENABLED : 0;
+
+			ret = rvin_group_add_link(vin, source, idx, sink, 0,
+						  flags);
+			if (ret)
+				goto out;
+		}
+	}
+out:
+	mutex_unlock(&vin->group->lock);
+
+	return ret;
+}
+
+static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
+{
+	struct rvin_dev *vin = notifier_to_vin(notifier);
+	unsigned int i;
+	int ret;
+
+	mutex_lock(&vin->group->lock);
+	for (i = 0; i < RVIN_CSI_MAX; i++) {
+		if (!vin->group->source[i].subdev)
+			continue;
+
+		rvin_group_update_pads(&vin->group->source[i]);
+
+		if (!rvin_mbus_supported(&vin->group->source[i])) {
+			vin_err(vin, "Unsupported media bus format for %s\n",
+				vin->group->source[i].subdev->name);
+			mutex_unlock(&vin->group->lock);
+			return -EINVAL;
+		}
+	}
+	mutex_unlock(&vin->group->lock);
+
+	ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
+	if (ret) {
+		vin_err(vin, "Failed to register subdev nodes\n");
+		return ret;
+	}
+
+	return rvin_group_update_links(vin);
+}
+
+static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
+				     struct v4l2_subdev *subdev,
+				     struct v4l2_async_subdev *asd)
+{
+	struct rvin_dev *vin = notifier_to_vin(notifier);
+	unsigned int i;
+
+	mutex_lock(&vin->group->lock);
+	for (i = 0; i < RVIN_CSI_MAX; i++) {
+		struct device_node *del = subdev->dev->of_node;
+
+		if (vin->group->bridge[i].asd.match.of.node == del) {
+			vin_dbg(vin, "Unbind bridge %s\n", subdev->name);
+			vin->group->bridge[i].subdev = NULL;
+			mutex_unlock(&vin->group->lock);
+			return;
+		}
+
+		if (vin->group->source[i].asd.match.of.node == del) {
+			vin_dbg(vin, "Unbind source %s\n", subdev->name);
+			vin->group->source[i].subdev = NULL;
+			mutex_unlock(&vin->group->lock);
+			return;
+		}
+	}
+	mutex_unlock(&vin->group->lock);
+
+	vin_err(vin, "No entity for subdev %s to unbind\n", subdev->name);
+}
+
+static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier,
+				   struct v4l2_subdev *subdev,
+				   struct v4l2_async_subdev *asd)
+{
+	struct rvin_dev *vin = notifier_to_vin(notifier);
+	unsigned int i;
+
+	v4l2_set_subdev_hostdata(subdev, vin);
+
+	mutex_lock(&vin->group->lock);
+	for (i = 0; i < RVIN_CSI_MAX; i++) {
+		struct device_node *new = subdev->dev->of_node;
+
+		if (vin->group->bridge[i].asd.match.of.node == new) {
+			vin_dbg(vin, "Bound bridge %s\n", subdev->name);
+			vin->group->bridge[i].subdev = subdev;
+			mutex_unlock(&vin->group->lock);
+			return 0;
+		}
+
+		if (vin->group->source[i].asd.match.of.node == new) {
+			vin_dbg(vin, "Bound source %s\n", subdev->name);
+			vin->group->source[i].subdev = subdev;
+			mutex_unlock(&vin->group->lock);
+			return 0;
+		}
+	}
+	mutex_unlock(&vin->group->lock);
+
+	vin_err(vin, "No entity for subdev %s to bind\n", subdev->name);
+	return -EINVAL;
+}
+
+static int rvin_group_parse_v4l2(struct rvin_dev *vin,
+				 struct device_node *ep,
+				 struct v4l2_mbus_config *mbus_cfg)
+{
+	struct v4l2_of_endpoint v4l2_ep;
+	int ret;
+
+	ret = v4l2_of_parse_endpoint(ep, &v4l2_ep);
+	if (ret) {
+		vin_err(vin, "Could not parse v4l2 endpoint\n");
+		return -EINVAL;
+	}
+
+	if (v4l2_ep.bus_type != V4L2_MBUS_CSI2) {
+		vin_err(vin, "Unsupported media bus type for %s\n",
+			of_node_full_name(ep));
+		return -EINVAL;
+	}
+
+	mbus_cfg->type = v4l2_ep.bus_type;
+	mbus_cfg->flags = v4l2_ep.bus.mipi_csi2.flags;
+
+	return 0;
+}
+
+static int rvin_group_vin_num_from_bridge(struct rvin_dev *vin,
+					  struct device_node *node,
+					  int test)
+{
+	struct device_node *remote;
+	struct of_endpoint endpoint;
+	int num;
+
+	remote = of_parse_phandle(node, "remote-endpoint", 0);
+	if (!remote)
+		return -EINVAL;
+
+	of_graph_parse_endpoint(remote, &endpoint);
+	of_node_put(remote);
+
+	num = endpoint.id;
+
+	if (test != -1 && num != test) {
+		vin_err(vin, "VIN numbering error at %s, was %d now %d\n",
+			of_node_full_name(node), test, num);
+		return -EINVAL;
+	}
+
+	return num;
+}
+
+static struct device_node *rvin_group_get_bridge(struct rvin_dev *vin,
+						 struct device_node *node)
+{
+	struct device_node *bridge;
+
+	bridge = of_graph_get_remote_port_parent(node);
+	if (!bridge) {
+		vin_err(vin, "No bridge found %s\n", of_node_full_name(node));
+		return ERR_PTR(-EINVAL);
+	}
+
+	/* Not all bridges are available, this is OK */
+	if (!of_device_is_available(bridge)) {
+		vin_dbg(vin, "Bridge %s not available\n",
+			of_node_full_name(bridge));
+		of_node_put(bridge);
+		return NULL;
+	}
+
+	return bridge;
+}
+
+static struct device_node *
+rvin_group_get_source(struct rvin_dev *vin,
+		      struct device_node *bridge,
+		      struct v4l2_mbus_config *mbus_cfg,
+		      unsigned int *remote_pad)
+{
+	struct device_node *source, *ep, *rp;
+	struct of_endpoint endpoint;
+	int ret;
+
+	ep = of_graph_get_endpoint_by_regs(bridge, 0, 0);
+	if (!ep) {
+		vin_dbg(vin, "Endpoint %s not connected to source\n",
+			of_node_full_name(ep));
+		return ERR_PTR(-EINVAL);
+	}
+
+	/* Check that source uses a supported media bus */
+	ret = rvin_group_parse_v4l2(vin, ep, mbus_cfg);
+	if (ret) {
+		of_node_put(ep);
+		return ERR_PTR(ret);
+	}
+
+	rp = of_graph_get_remote_port(ep);
+	of_graph_parse_endpoint(rp, &endpoint);
+	of_node_put(rp);
+	*remote_pad = endpoint.id;
+
+	source = of_graph_get_remote_port_parent(ep);
+	of_node_put(ep);
+	if (!source) {
+		vin_err(vin, "No source found for endpoint '%s'\n",
+			of_node_full_name(ep));
+		return ERR_PTR(-EINVAL);
+	}
+
+	return source;
+}
+
+/* group lock should be held when calling this function */
+static int rvin_group_graph_parse(struct rvin_dev *vin, unsigned long *bitmap)
+{
+	struct device_node *ep, *bridge, *source;
+	unsigned int i, remote_pad;
+	int vin_num = -1;
+
+	*bitmap = 0;
+
+	for (i = 0; i < RVIN_CSI_MAX; i++) {
+
+		/* Check if instance is connected to the bridge */
+		ep = of_graph_get_endpoint_by_regs(vin->dev->of_node, 1, i);
+		if (!ep) {
+			vin_dbg(vin, "Bridge: %d not connected\n", i);
+			continue;
+		}
+
+		vin_num = rvin_group_vin_num_from_bridge(vin, ep, vin_num);
+		if (vin_num < 0) {
+			of_node_put(ep);
+			return vin_num;
+		}
+
+		if (vin->group->bridge[i].asd.match.of.node) {
+			of_node_put(ep);
+			vin_dbg(vin, "Bridge: %d handled by other device\n", i);
+			continue;
+		}
+
+		bridge = rvin_group_get_bridge(vin, ep);
+		of_node_put(ep);
+		if (IS_ERR(bridge))
+			return PTR_ERR(bridge);
+		if (bridge == NULL)
+			continue;
+
+		source = rvin_group_get_source(vin, bridge,
+					       &vin->group->source[i].mbus_cfg,
+					       &remote_pad);
+		of_node_put(bridge);
+		if (IS_ERR(source))
+			return PTR_ERR(source);
+		if (source == NULL)
+			continue;
+
+		of_node_put(source);
+
+		vin->group->bridge[i].asd.match.of.node = bridge;
+		vin->group->bridge[i].asd.match_type = V4L2_ASYNC_MATCH_OF;
+		vin->group->source[i].asd.match.of.node = source;
+		vin->group->source[i].asd.match_type = V4L2_ASYNC_MATCH_OF;
+		vin->group->source[i].source_pad_idx = remote_pad;
+
+		*bitmap |= BIT(i);
+
+		vin_dbg(vin, "Handle bridge %s and source %s pad %d\n",
+			of_node_full_name(bridge), of_node_full_name(source),
+			remote_pad);
+	}
+
+	/* Insert ourself in the group */
+	vin_dbg(vin, "I'm VIN number %d", vin_num);
+	if (vin->group->vin[vin_num] != NULL) {
+		vin_err(vin, "VIN number %d already occupied\n", vin_num);
+		return -EINVAL;
+	}
+	vin->group->vin[vin_num] = vin;
+
+	return 0;
+}
+
+/* group lock should be held when calling this function */
+static void rvin_group_graph_revert(struct rvin_dev *vin, unsigned long bitmap)
+{
+	int bit;
+
+	for_each_set_bit(bit, &bitmap, RVIN_CSI_MAX) {
+		vin_dbg(vin, "Reverting graph for %s\n",
+			of_node_full_name(vin->dev->of_node));
+		vin->group->bridge[bit].asd.match.of.node = NULL;
+		vin->group->bridge[bit].asd.match_type = 0;
+		vin->group->source[bit].asd.match.of.node = NULL;
+		vin->group->source[bit].asd.match_type = 0;
+	}
+}
+
+static int rvin_group_graph_init(struct rvin_dev *vin)
+{
+	struct v4l2_async_subdev **subdevs = NULL;
+	unsigned long bitmap;
+	int i, bit, count, ret;
+
+	mutex_lock(&vin->group->lock);
+
+	ret = rvin_group_graph_parse(vin, &bitmap);
+	if (ret) {
+		rvin_group_graph_revert(vin, bitmap);
+		mutex_unlock(&vin->group->lock);
+		return ret;
+	}
+
+	/* Check if instance need to handle subdevices on behalf of the group */
+	count = hweight_long(bitmap) * 2;
+	if (!count) {
+		mutex_unlock(&vin->group->lock);
+		return 0;
+	}
+
+	subdevs = devm_kzalloc(vin->dev, sizeof(*subdevs) * count, GFP_KERNEL);
+	if (subdevs == NULL) {
+		rvin_group_graph_revert(vin, bitmap);
+		mutex_unlock(&vin->group->lock);
+		return -ENOMEM;
+	}
+
+	i = 0;
+	for_each_set_bit(bit, &bitmap, RVIN_CSI_MAX) {
+		subdevs[i++] = &vin->group->bridge[bit].asd;
+		subdevs[i++] = &vin->group->source[bit].asd;
+	}
+
+	vin_dbg(vin, "Claimed %d subdevices for group\n", count);
+
+	vin->notifier.num_subdevs = count;
+	vin->notifier.subdevs = subdevs;
+	vin->notifier.bound = rvin_group_notify_bound;
+	vin->notifier.unbind = rvin_group_notify_unbind;
+	vin->notifier.complete = rvin_group_notify_complete;
+
+	mutex_unlock(&vin->group->lock);
+
+	ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);
+	if (ret < 0) {
+		vin_err(vin, "Group notifier registration failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
  * Platform Device Driver
  */
 
@@ -422,6 +899,14 @@ static int rvin_graph_init(struct rvin_dev *vin)
 		vin->group = rvin_group_allocate(vin);
 		if (IS_ERR(vin->group))
 			return PTR_ERR(vin->group);
+
+		ret = rvin_group_graph_init(vin);
+		if (ret)
+			return ret;
+
+		ret = rvin_group_update_links(vin);
+		if (ret)
+			return ret;
 	}
 
 	return ret;
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 24/32] media: rcar-vin: add link notify for Gen3
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (22 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 23/32] media: rcar-vin: parse Gen3 OF and setup media graph Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 25/32] media: rcar-vin: enable CSI2 group subdevices in lookup helpers Niklas Söderlund
                   ` (7 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Add the ability to process media device link change request. Link
enablement are a bit complicated on Gen3, if it's possible to enable a
link depends on what other links already are enabled. On Gen3 the 8 VIN
are split into two subgroups (VIN0-3 and VIN4-7) and from a routing
perspective these two groups are independent of each other. Each
subgroups routing is controlled by the subgroup VIN master instance
(VIN0 and VIN4).

There are a limited number of possible route setups available for each
subgroup and the configuration of each setup is dictated by the
hardware. On H3 for example there are 6 possible route setups for each
subgroup to choose from.

This leads to the media device link notification code being rather large
since it will find the best routing configuration to try and accommodate
as many links as possible. When it's not possible to enable a new link
due to hardware constrains the link_notifier callback will return
-EBUSY.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 205 ++++++++++++++++++++++++++++
 1 file changed, 205 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 20fe377..06876a8 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -26,6 +26,209 @@
 #include "rcar-vin.h"
 
 /* -----------------------------------------------------------------------------
+ * Media Controller link notification
+ */
+
+static unsigned int rvin_group_csi_pad_to_chan(unsigned int pad)
+{
+	/*
+	 * The CSI2 driver is rcar-csi2 and we know it's pad layout are
+	 * 0: Source 1-4: Sinks so if we remove one from the pad we
+	 * get the rcar-vin internal CSI2 channel number
+	 */
+	return pad - 1;
+}
+
+/* group lock should be held when calling this function */
+static int rvin_group_entity_to_vin_num(struct rvin_group *group,
+					struct media_entity *entity)
+{
+	struct video_device *vdev;
+	int i;
+
+	if (!is_media_entity_v4l2_video_device(entity))
+		return -ENODEV;
+
+	vdev = media_entity_to_video_device(entity);
+
+	for (i = 0; i < RCAR_VIN_NUM; i++) {
+		if (!group->vin[i])
+			continue;
+
+		if (&group->vin[i]->vdev == vdev)
+			return i;
+	}
+
+	return -ENODEV;
+}
+
+/* group lock should be held when calling this function */
+static int rvin_group_entity_to_csi_num(struct rvin_group *group,
+					struct media_entity *entity)
+{
+	struct v4l2_subdev *sd;
+	int i;
+
+	if (!is_media_entity_v4l2_subdev(entity))
+		return -ENODEV;
+
+	sd = media_entity_to_v4l2_subdev(entity);
+
+	for (i = 0; i < RVIN_CSI_MAX; i++)
+		if (group->bridge[i].subdev == sd)
+			return i;
+
+	return -ENODEV;
+}
+
+/* group lock should be held when calling this function */
+static void __rvin_group_build_link_list(struct rvin_group *group,
+					 struct rvin_group_chsel *map,
+					 int start, int len)
+{
+	struct media_pad *vin_pad, *remote_pad;
+	unsigned int n;
+
+	for (n = 0; n < len; n++) {
+		map[n].csi = -1;
+		map[n].chan = -1;
+
+		if (!group->vin[start + n])
+			continue;
+
+		vin_pad = &group->vin[start + n]->vdev.entity.pads[RVIN_SINK];
+
+		remote_pad = media_entity_remote_pad(vin_pad);
+		if (!remote_pad)
+			continue;
+
+		map[n].csi =
+			rvin_group_entity_to_csi_num(group, remote_pad->entity);
+		map[n].chan = rvin_group_csi_pad_to_chan(remote_pad->index);
+	}
+}
+
+/* group lock should be held when calling this function */
+static int __rvin_group_try_get_chsel(struct rvin_group *group,
+				      struct rvin_group_chsel *map,
+				      int start, int len)
+{
+	const struct rvin_group_chsel *sel;
+	unsigned int i, n;
+	int chsel;
+
+	for (i = 0; i < group->vin[start]->info->num_chsels; i++) {
+		chsel = i;
+		for (n = 0; n < len; n++) {
+
+			/* If the link is not active it's OK */
+			if (map[n].csi == -1)
+				continue;
+
+			/* Check if chsel match requested link */
+			sel = &group->vin[start]->info->chsels[start + n][i];
+			if (map[n].csi != sel->csi ||
+			    map[n].chan != sel->chan) {
+				chsel = -1;
+				break;
+			}
+		}
+
+		/* A chsel which satisfy the links have been found */
+		if (chsel != -1)
+			return chsel;
+	}
+
+	/* No chsel can satisfy the requested links */
+	return -1;
+}
+
+/* group lock should be held when calling this function */
+static bool rvin_group_in_use(struct rvin_group *group)
+{
+	struct media_entity *entity;
+
+	media_device_for_each_entity(entity, &group->mdev)
+		if (entity->use_count)
+			return true;
+
+	return false;
+}
+
+static int rvin_group_link_notify(struct media_link *link, u32 flags,
+				  unsigned int notification)
+{
+	struct rvin_group *group = container_of(link->graph_obj.mdev,
+						struct rvin_group, mdev);
+	struct rvin_group_chsel chsel_map[4];
+	int vin_num, vin_master, csi_num, csi_chan;
+	unsigned int chsel;
+
+	mutex_lock(&group->lock);
+
+	vin_num = rvin_group_entity_to_vin_num(group, link->sink->entity);
+	csi_num = rvin_group_entity_to_csi_num(group, link->source->entity);
+	csi_chan = rvin_group_csi_pad_to_chan(link->source->index);
+
+	/*
+	 * Figure out which VIN node is the subgroup master.
+	 *
+	 * VIN0-3 are controlled by VIN0
+	 * VIN4-7 are controlled by VIN4
+	 */
+	vin_master = vin_num < 4 ? 0 : 4;
+
+	/* If not all devices exists something is horribly wrong */
+	if (vin_num < 0 || csi_num < 0 || !group->vin[vin_master])
+		goto error;
+
+	/* Special checking only needed for links which are to be enabled */
+	if (notification != MEDIA_DEV_NOTIFY_PRE_LINK_CH ||
+	    !(flags & MEDIA_LNK_FL_ENABLED))
+		goto out;
+
+	/* If any link in the group are in use, no new link can be enabled */
+	if (rvin_group_in_use(group))
+		goto error;
+
+	/* If the VIN already have a active link it's busy */
+	if (media_entity_remote_pad(&link->sink->entity->pads[RVIN_SINK]))
+		goto error;
+
+	/* Build list of active links */
+	__rvin_group_build_link_list(group, chsel_map, vin_master, 4);
+
+	/* Add the new proposed link */
+	chsel_map[vin_num - vin_master].csi = csi_num;
+	chsel_map[vin_num - vin_master].chan = csi_chan;
+
+	/* See if there is a chsel value which match our link selection */
+	chsel = __rvin_group_try_get_chsel(group, chsel_map, vin_master, 4);
+
+	/* No chsel can provide the request links */
+	if (chsel == -1)
+		goto error;
+
+	/* Update chsel value at group master */
+	if (rvin_set_chsel(group->vin[vin_master], chsel))
+		goto error;
+
+out:
+	mutex_unlock(&group->lock);
+
+	return v4l2_pipeline_link_notify(link, flags, notification);
+error:
+	mutex_unlock(&group->lock);
+
+	return -EBUSY;
+}
+
+
+static const struct media_device_ops rvin_media_ops = {
+	.link_notify = rvin_group_link_notify,
+};
+
+/* -----------------------------------------------------------------------------
  * Gen3 CSI2 Group Allocator
  */
 
@@ -100,6 +303,8 @@ static struct rvin_group *rvin_group_allocate(struct rvin_dev *vin)
 		mdev->driver_version = LINUX_VERSION_CODE;
 		media_device_init(mdev);
 
+		mdev->ops = &rvin_media_ops;
+
 		ret = media_device_register(mdev);
 		if (ret) {
 			vin_err(vin, "Failed to register media device\n");
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 25/32] media: rcar-vin: enable CSI2 group subdevices in lookup helpers
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (23 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 24/32] media: rcar-vin: add link notify for Gen3 Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 26/32] media: rcar-vin: add helpers for bridge Niklas Söderlund
                   ` (6 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Make the subdevice helpers look not only at the local digital subdevice
but also for the CSI2 group subdevices which can be present on Gen3.

Which CSI2 group subdevices are found depends on the CSI2 subgroup
routing which is stored in the CHSEL register of the subgroup master
(VIN0 for VIN0-3 and VIN4 for VIN4-7). The lookup functions look at this
value and returns the correct information or NULL if there is no
attached subdevices for the current routing for this device.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 66 ++++++++++++++++++++++++++++-
 drivers/media/platform/rcar-vin/rcar-vin.h  |  2 +-
 2 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 06876a8..f382f91 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -330,9 +330,73 @@ static void rvin_group_delete(struct rvin_dev *vin)
  * Subdevice helpers
  */
 
+static int rvin_group_vin_to_csi(struct rvin_dev *vin)
+{
+	int i, vin_num, vin_master, chsel, csi;
+
+	/*
+	 * Only try to translate to a CSI2 number if there is a enabled
+	 * link from the VIN sink pad. However if there are no links at
+	 * all we are at probe time so ignore the need for enabled links
+	 * to be able to make a better guess of initial format
+	 */
+	if (vin->pads[RVIN_SINK].entity->num_links &&
+	    !media_entity_remote_pad(&vin->pads[RVIN_SINK]))
+		return -1;
+
+	/* Find which VIN we are */
+	vin_num = -1;
+	for (i = 0; i < RCAR_VIN_NUM; i++)
+		if (vin == vin->group->vin[i])
+			vin_num = i;
+
+	if (vin_num == -1)
+		return -1;
+
+	vin_master = vin_num < 4 ? 0 : 4;
+	if (!vin->group->vin[vin_master])
+		return -1;
+
+	chsel = rvin_get_chsel(vin->group->vin[vin_master]);
+
+	csi = vin->info->chsels[vin_num][chsel].csi;
+	if (csi >= RVIN_CSI_MAX)
+		return -1;
+
+	if (!vin->group->source[csi].subdev || !vin->group->bridge[csi].subdev)
+		return -1;
+
+	return csi;
+}
+
 struct rvin_graph_entity *vin_to_entity(struct rvin_dev *vin)
 {
-	return &vin->digital;
+	int csi;
+
+	/* If there is a digital subdev use it */
+	if (vin->digital.subdev)
+		return &vin->digital;
+
+	csi = rvin_group_vin_to_csi(vin);
+	if (csi < 0)
+		return NULL;
+
+	return &vin->group->source[csi];
+}
+
+struct v4l2_subdev *vin_to_source(struct rvin_dev *vin)
+{
+	int csi;
+
+	/* If there is a digital subdev use it */
+	if (vin->digital.subdev)
+		return vin->digital.subdev;
+
+	csi = rvin_group_vin_to_csi(vin);
+	if (csi < 0)
+		return NULL;
+
+	return vin->group->source[csi].subdev;
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index cd7d959..2f1e087 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -207,7 +207,7 @@ struct rvin_dev {
 };
 
 struct rvin_graph_entity *vin_to_entity(struct rvin_dev *vin);
-#define vin_to_source(vin)		vin->digital.subdev
+struct v4l2_subdev *vin_to_source(struct rvin_dev *vin);
 
 /* Debug */
 #define vin_dbg(d, fmt, arg...)		dev_dbg(d->dev, fmt, ##arg)
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 26/32] media: rcar-vin: add helpers for bridge
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (24 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 25/32] media: rcar-vin: enable CSI2 group subdevices in lookup helpers Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 27/32] media: rcar-vin: start/stop the CSI2 bridge stream Niklas Söderlund
                   ` (5 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

On Gen3 there might be a CSI2 bridge between the video source and the
VIN. Add helpers to check for this and to fetch the bridge subdevice.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-core.c | 19 +++++++++++++++++++
 drivers/media/platform/rcar-vin/rcar-vin.h  |  2 ++
 2 files changed, 21 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index f382f91..a409157 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -369,6 +369,11 @@ static int rvin_group_vin_to_csi(struct rvin_dev *vin)
 	return csi;
 }
 
+bool vin_have_bridge(struct rvin_dev *vin)
+{
+	return vin->digital.subdev == NULL;
+}
+
 struct rvin_graph_entity *vin_to_entity(struct rvin_dev *vin)
 {
 	int csi;
@@ -399,6 +404,20 @@ struct v4l2_subdev *vin_to_source(struct rvin_dev *vin)
 	return vin->group->source[csi].subdev;
 }
 
+struct v4l2_subdev *vin_to_bridge(struct rvin_dev *vin)
+{
+	int csi;
+
+	if (vin->digital.subdev)
+		return NULL;
+
+	csi = rvin_group_vin_to_csi(vin);
+	if (csi < 0)
+		return NULL;
+
+	return vin->group->bridge[csi].subdev;
+}
+
 /* -----------------------------------------------------------------------------
  * Async notifier helpers
  */
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index 2f1e087..acaed2b 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -206,8 +206,10 @@ struct rvin_dev {
 	struct v4l2_rect compose;
 };
 
+bool vin_have_bridge(struct rvin_dev *vin);
 struct rvin_graph_entity *vin_to_entity(struct rvin_dev *vin);
 struct v4l2_subdev *vin_to_source(struct rvin_dev *vin);
+struct v4l2_subdev *vin_to_bridge(struct rvin_dev *vin);
 
 /* Debug */
 #define vin_dbg(d, fmt, arg...)		dev_dbg(d->dev, fmt, ##arg)
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 27/32] media: rcar-vin: start/stop the CSI2 bridge stream
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (25 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 26/32] media: rcar-vin: add helpers for bridge Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 28/32] media: rcar-vin: propagate format to bridge Niklas Söderlund
                   ` (4 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

On Gen3 the CSI2 bridge stream needs to be start/stop in conjunction
with the video source. Create helpers to deal with both the Gen2 single
subdevice case and the Gen3 CSI2 group case.

In the Gen3 case there might be other simultaneous users of the bridge
and source devices so examine each entity stream_count before acting on
any particular device.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 84 +++++++++++++++++++++++++++---
 1 file changed, 77 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
index 322e4c1..872f138 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -1089,15 +1089,87 @@ static void rvin_buffer_queue(struct vb2_buffer *vb)
 	spin_unlock_irqrestore(&vin->qlock, flags);
 }
 
+static int __rvin_start_streaming(struct rvin_dev *vin)
+{
+	struct v4l2_subdev *source, *bridge = NULL;
+	struct media_pipeline *pipe;
+	int ret;
+
+	source = vin_to_source(vin);
+	if (!source)
+		return -EINVAL;
+
+	if (vin_have_bridge(vin)) {
+		bridge = vin_to_bridge(vin);
+
+		if (!bridge)
+			return -EINVAL;
+
+		mutex_lock(&vin->group->lock);
+
+		pipe = bridge->entity.pipe ? bridge->entity.pipe :
+			&vin->vdev.pipe;
+		ret = media_entity_pipeline_start(&vin->vdev.entity, pipe);
+		if (ret) {
+			mutex_unlock(&vin->group->lock);
+			return ret;
+		}
+
+		/* Only need to start stream if it's not running */
+		if (bridge->entity.stream_count <= 1)
+			v4l2_subdev_call(bridge, video, s_stream, 1);
+		if (source->entity.stream_count <= 1)
+			v4l2_subdev_call(source, video, s_stream, 1);
+
+		mutex_unlock(&vin->group->lock);
+	} else {
+		v4l2_subdev_call(source, video, s_stream, 1);
+	}
+
+	return 0;
+}
+
+static int __rvin_stop_streaming(struct rvin_dev *vin)
+{
+	struct v4l2_subdev *source, *bridge = NULL;
+
+	source = vin_to_source(vin);
+	if (!source)
+		return -EINVAL;
+
+	if (vin_have_bridge(vin)) {
+		bridge = vin_to_bridge(vin);
+
+		if (!bridge)
+			return -EINVAL;
+
+		mutex_lock(&vin->group->lock);
+
+		media_entity_pipeline_stop(&vin->vdev.entity);
+
+		/* Only need to stop stream if there are no other users */
+		if (bridge->entity.stream_count <= 0)
+			v4l2_subdev_call(bridge, video, s_stream, 0);
+		if (source->entity.stream_count <= 0)
+			v4l2_subdev_call(source, video, s_stream, 0);
+
+		mutex_unlock(&vin->group->lock);
+	} else {
+		v4l2_subdev_call(source, video, s_stream, 0);
+	}
+
+	return 0;
+}
+
 static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
 	struct rvin_dev *vin = vb2_get_drv_priv(vq);
-	struct v4l2_subdev *sd;
 	unsigned long flags;
 	int ret;
 
-	sd = vin_to_source(vin);
-	v4l2_subdev_call(sd, video, s_stream, 1);
+	ret = __rvin_start_streaming(vin);
+	if (ret)
+		return ret;
 
 	spin_lock_irqsave(&vin->qlock, flags);
 
@@ -1122,7 +1194,7 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count)
 	/* Return all buffers if something went wrong */
 	if (ret) {
 		return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
-		v4l2_subdev_call(sd, video, s_stream, 0);
+		__rvin_stop_streaming(vin);
 	}
 
 	spin_unlock_irqrestore(&vin->qlock, flags);
@@ -1133,7 +1205,6 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count)
 static void rvin_stop_streaming(struct vb2_queue *vq)
 {
 	struct rvin_dev *vin = vb2_get_drv_priv(vq);
-	struct v4l2_subdev *sd;
 	unsigned long flags;
 	int retries = 0;
 
@@ -1172,8 +1243,7 @@ static void rvin_stop_streaming(struct vb2_queue *vq)
 
 	spin_unlock_irqrestore(&vin->qlock, flags);
 
-	sd = vin_to_source(vin);
-	v4l2_subdev_call(sd, video, s_stream, 0);
+	__rvin_stop_streaming(vin);
 
 	/* disable interrupts */
 	rvin_disable_interrupts(vin);
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 28/32] media: rcar-vin: propagate format to bridge
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (26 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 27/32] media: rcar-vin: start/stop the CSI2 bridge stream Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 29/32] media: rcar-vin: attach to CSI2 group when the video device is opened Niklas Söderlund
                   ` (3 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

The CSI2 bridge needs to know the video format, propagate it after the
video source have had its say on the format.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index e99815f..d363531 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -193,6 +193,21 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
 	if (ret < 0 && ret != -ENOIOCTLCMD)
 		goto done;
 
+	/* If we are part of a CSI2 group update bridge */
+	if (vin_have_bridge(vin)) {
+		struct v4l2_subdev *bridge = vin_to_bridge(vin);
+
+		if (!bridge) {
+			ret = -EINVAL;
+			goto done;
+		}
+
+		format.pad = 0;
+		ret = v4l2_subdev_call(bridge, pad, set_fmt, pad_cfg, &format);
+		if (ret < 0 && ret != -ENOIOCTLCMD)
+			goto done;
+	}
+
 	v4l2_fill_pix_format(pix, &format.format);
 
 	pix->field = field;
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 29/32] media: rcar-vin: attach to CSI2 group when the video device is opened
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (27 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 28/32] media: rcar-vin: propagate format to bridge Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 30/32] media: rcar-vin: add Gen3 devicetree bindings documentation Niklas Söderlund
                   ` (2 subsequent siblings)
  31 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Attempt to attach to the subdevices pointed out by the routing from the
CSI2 group when the video device is opened. This is the last piece
missing to enable CSI2 groups on Gen3.

If the current CSI2 routing for the group points ta a set of subdevices
which are not present (not all routings are available on all boards) the
open fall will fail with a -EBUSY error. The VIN instance will be
unavailable with this error until the group routing is changed to one
which provides it with a available set of subdevices.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index d363531..1801c6e 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -846,6 +846,7 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = {
 static int rvin_open(struct file *file)
 {
 	struct rvin_dev *vin = video_drvdata(file);
+	struct v4l2_subdev *source, *bridge;
 	int ret;
 
 	mutex_lock(&vin->lock);
@@ -857,12 +858,28 @@ static int rvin_open(struct file *file)
 		goto err_out;
 
 	/* If there is no subdevice there is not much we can do */
-	if (!vin_to_source(vin)) {
+	source = vin_to_source(vin);
+	if (!source) {
 		ret = -EBUSY;
 		goto err_open;
 	}
 
 	if (v4l2_fh_is_singular_file(file)) {
+		if (vin_have_bridge(vin)) {
+
+			/* If there are no bridge not much we can do */
+			bridge = vin_to_bridge(vin);
+			if (!bridge) {
+				ret = -EBUSY;
+				goto err_open;
+			}
+
+			v4l2_pipeline_pm_use(&vin->vdev.entity, 1);
+
+			vin_dbg(vin, "Group source: %s bridge: %s\n",
+				source->name,
+				bridge->name);
+		}
 		pm_runtime_get_sync(vin->dev);
 		ret = rvin_attach_subdevices(vin);
 		if (ret) {
@@ -876,6 +893,8 @@ static int rvin_open(struct file *file)
 	return 0;
 err_power:
 	pm_runtime_put(vin->dev);
+	if (vin_have_bridge(vin))
+		v4l2_pipeline_pm_use(&vin->vdev.entity, 0);
 err_open:
 	v4l2_fh_release(file);
 err_out:
@@ -904,6 +923,8 @@ static int rvin_release(struct file *file)
 	if (fh_singular) {
 		rvin_detach_subdevices(vin);
 		pm_runtime_put(vin->dev);
+		if (vin_have_bridge(vin))
+			v4l2_pipeline_pm_use(&vin->vdev.entity, 0);
 	}
 
 	mutex_unlock(&vin->lock);
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 30/32] media: rcar-vin: add Gen3 devicetree bindings documentation
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (28 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 29/32] media: rcar-vin: attach to CSI2 group when the video device is opened Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-07 12:47   ` Geert Uytterhoeven
  2016-11-02 13:23 ` [PATCH 31/32] media: rcar-vin: enable support for r8a7795 Niklas Söderlund
  2016-11-02 13:23 ` [PATCH 32/32] media: rcar-vin: enable support for r8a7796 Niklas Söderlund
  31 siblings, 1 reply; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Document the Gen3 devicetree bindings. The new bindings are all handled
in the port@1 node, if a endpoint is described as on Gen2 in port@0 the
driver will work in Gen2 mode and this is supported on Gen3. The new
CSI-2 video sources are only supported on Gen3.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 .../devicetree/bindings/media/rcar_vin.txt         | 116 +++++++++++++++++++--
 1 file changed, 106 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt
index 6a4e61c..a51cf70 100644
--- a/Documentation/devicetree/bindings/media/rcar_vin.txt
+++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
@@ -2,8 +2,12 @@ Renesas RCar Video Input driver (rcar_vin)
 ------------------------------------------
 
 The rcar_vin device provides video input capabilities for the Renesas R-Car
-family of devices. The current blocks are always slaves and suppot one input
-channel which can be either RGB, YUYV or BT656.
+family of devices.
+
+On Gen2 the current blocks are always slaves and support one input channel
+which can be either RGB, YUYV or BT656. On Gen3 the current blocks are
+always slaves and support multiple input channels which can be ether RGB,
+YUVU, BT656 or CSI-2.
 
  - compatible: Must be one or more of the following
    - "renesas,vin-r8a7795" for the R8A7795 device
@@ -28,7 +32,7 @@ channel which can be either RGB, YUYV or BT656.
 Additionally, an alias named vinX will need to be created to specify
 which video input device this is.
 
-The per-board settings:
+The per-board settings Gen2:
  - port sub-node describing a single endpoint connected to the vin
    as described in video-interfaces.txt[1]. Only the first one will
    be considered as each vin interface has one input port.
@@ -36,13 +40,22 @@ The per-board settings:
    These settings are used to work out video input format and widths
    into the system.
 
+The per-board settings Gen3:
+
+- ports
+        - port@0 - Digital video source (same as port node on Gen2)
+        - port@1 - CSI-2 video sources
+                -reg 0 - sub-node describing the endpoint which is CSI20
+                -reg 1 - sub-node describing the endpoint which is CSI21
+                -reg 2 - sub-node describing the endpoint which is CSI40
+                -reg 3 - sub-node describing the endpoint which is CSI41
 
-Device node example
--------------------
+Device node example Gen2
+------------------------
 
-	aliases {
-	       vin0 = &vin0;
-	};
+        aliases {
+                vin0 = &vin0;
+        };
 
         vin0: vin@0xe6ef0000 {
                 compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin";
@@ -52,8 +65,8 @@ Device node example
                 status = "disabled";
         };
 
-Board setup example (vin1 composite video input)
-------------------------------------------------
+Board setup example Gen2 (vin1 composite video input)
+-----------------------------------------------------
 
 &i2c2   {
         status = "ok";
@@ -92,6 +105,89 @@ Board setup example (vin1 composite video input)
         };
 };
 
+Device node example Gen3
+------------------------
+
+        aliases {
+                vin0 = &vin0;
+        };
+
+        vin1: video@e6ef1000 {
+                compatible = "renesas,vin-r8a7796";
+                reg =  <0 0xe6ef1000 0 0x1000>;
+                interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+                clocks = <&cpg CPG_MOD 810>;
+                power-domains = <&cpg>;
+                status = "disabled";
+
+                ports {
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+
+                        port@1 {
+                                #address-cells = <1>;
+                                #size-cells = <0>;
+
+                                reg = <1>;
+
+                                vin1csi20: endpoint@0 {
+                                        reg = <0>;
+                                        remote-endpoint= <&csi20vin1>;
+                                };
+                        };
+                };
+        };
+
+        csi20: csi2@fea80000 {
+                compatible = "renesas,r8a7796-csi2";
+                reg = <0 0xfea80000 0 0x10000>;
+                interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+                clocks = <&cpg CPG_MOD 714>;
+                power-domains = <&cpg>;
+                status = "disabled";
+
+                ports {
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+
+                        port@1 {
+                                #address-cells = <1>;
+                                #size-cells = <0>;
+
+                                reg = <1>;
+
+                                csi20vin1: endpoint@1 {
+                                        reg = <1>;
+                                        remote-endpoint = <&vin1csi20>;
+                                };
+                        };
+                };
+        };
+
 
+Board setup example Gen3 (CSI-2)
+--------------------------------
+
+        &vin0 {
+                status = "okay";
+        };
+
+        csi20 {
+                status = "okay";
+
+                ports {
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+
+                        port@0 {
+                                reg = <0>;
+                                csi20_in: endpoint@0 {
+                                        clock-lanes = <0>;
+                                        data-lanes = <1>;
+                                        remote-endpoint = <&adv7482_txb>;
+                                };
+                        };
+                };
+        };
 
 [1] video-interfaces.txt common video media interface
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 31/32] media: rcar-vin: enable support for r8a7795
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (29 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 30/32] media: rcar-vin: add Gen3 devicetree bindings documentation Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-07 12:42   ` Geert Uytterhoeven
  2016-11-02 13:23 ` [PATCH 32/32] media: rcar-vin: enable support for r8a7796 Niklas Söderlund
  31 siblings, 1 reply; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Add the SoC specific information for Renesas Salvator-X H3 (r8a7795)
board.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/Kconfig     |  2 +-
 drivers/media/platform/rcar-vin/rcar-core.c | 71 +++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/rcar-vin/Kconfig b/drivers/media/platform/rcar-vin/Kconfig
index 111d2a1..e0e981c 100644
--- a/drivers/media/platform/rcar-vin/Kconfig
+++ b/drivers/media/platform/rcar-vin/Kconfig
@@ -5,7 +5,7 @@ config VIDEO_RCAR_VIN
 	select VIDEOBUF2_DMA_CONTIG
 	---help---
 	  Support for Renesas R-Car Video Input (VIN) driver.
-	  Supports R-Car Gen2 SoCs.
+	  Supports R-Car Gen2 and Gen3 SoCs.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called rcar-vin.
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index a409157..2124f0a 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -1130,6 +1130,73 @@ static const struct rvin_info rcar_info_m1 = {
 	.max_height = 2048,
 };
 
+static const struct rvin_info rcar_info_r8a7795 = {
+	.chip = RCAR_GEN3,
+	.max_width = 4096,
+	.max_height = 4096,
+
+	.num_chsels = 6,
+	.chsels = {
+		{
+			{ .csi = RVIN_CSI40, .chan = 0 },
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_CSI21, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 0 },
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_CSI21, .chan = 0 },
+		}, {
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_CSI21, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 1 },
+			{ .csi = RVIN_CSI20, .chan = 1 },
+			{ .csi = RVIN_CSI21, .chan = 1 },
+		}, {
+			{ .csi = RVIN_CSI21, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 0 },
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 2 },
+			{ .csi = RVIN_CSI20, .chan = 2 },
+			{ .csi = RVIN_CSI21, .chan = 2 },
+		}, {
+			{ .csi = RVIN_CSI40, .chan = 1 },
+			{ .csi = RVIN_CSI20, .chan = 1 },
+			{ .csi = RVIN_CSI21, .chan = 1 },
+			{ .csi = RVIN_CSI40, .chan = 3 },
+			{ .csi = RVIN_CSI20, .chan = 3 },
+			{ .csi = RVIN_CSI21, .chan = 3 },
+		}, {
+			{ .csi = RVIN_CSI41, .chan = 0 },
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_CSI21, .chan = 0 },
+			{ .csi = RVIN_CSI41, .chan = 0 },
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_CSI21, .chan = 0 },
+		}, {
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_CSI21, .chan = 0 },
+			{ .csi = RVIN_CSI41, .chan = 0 },
+			{ .csi = RVIN_CSI41, .chan = 1 },
+			{ .csi = RVIN_CSI20, .chan = 1 },
+			{ .csi = RVIN_CSI21, .chan = 1 },
+		}, {
+			{ .csi = RVIN_CSI21, .chan = 0 },
+			{ .csi = RVIN_CSI41, .chan = 0 },
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_CSI41, .chan = 2 },
+			{ .csi = RVIN_CSI20, .chan = 2 },
+			{ .csi = RVIN_CSI21, .chan = 2 },
+		}, {
+			{ .csi = RVIN_CSI41, .chan = 1 },
+			{ .csi = RVIN_CSI20, .chan = 1 },
+			{ .csi = RVIN_CSI21, .chan = 1 },
+			{ .csi = RVIN_CSI41, .chan = 3 },
+			{ .csi = RVIN_CSI20, .chan = 3 },
+			{ .csi = RVIN_CSI21, .chan = 3 },
+		},
+	},
+};
+
 static const struct rvin_info rcar_info_gen2 = {
 	.chip = RCAR_GEN2,
 	.max_width = 2048,
@@ -1138,6 +1205,10 @@ static const struct rvin_info rcar_info_gen2 = {
 
 static const struct of_device_id rvin_of_id_table[] = {
 	{
+		.compatible = "renesas,vin-r8a7795",
+		.data = (void *)&rcar_info_r8a7795,
+	},
+	{
 		.compatible = "renesas,vin-r8a7794",
 		.data = (void *)&rcar_info_gen2,
 	},
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 32/32] media: rcar-vin: enable support for r8a7796
  2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
                   ` (30 preceding siblings ...)
  2016-11-02 13:23 ` [PATCH 31/32] media: rcar-vin: enable support for r8a7795 Niklas Söderlund
@ 2016-11-02 13:23 ` Niklas Söderlund
  2016-11-07 12:44   ` Geert Uytterhoeven
  31 siblings, 1 reply; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-02 13:23 UTC (permalink / raw)
  To: Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus,
	Niklas Söderlund

Add the SoC specific information for Renesas Salvator-X M3 (r8a7796)
board.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 .../devicetree/bindings/media/rcar_vin.txt         |  1 +
 drivers/media/platform/rcar-vin/rcar-core.c        | 63 ++++++++++++++++++++++
 2 files changed, 64 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt
index a51cf70..10865ef 100644
--- a/Documentation/devicetree/bindings/media/rcar_vin.txt
+++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
@@ -10,6 +10,7 @@ always slaves and support multiple input channels which can be ether RGB,
 YUVU, BT656 or CSI-2.
 
  - compatible: Must be one or more of the following
+   - "renesas,vin-r8a7796" for the R8A7796 device
    - "renesas,vin-r8a7795" for the R8A7795 device
    - "renesas,vin-r8a7794" for the R8A7794 device
    - "renesas,vin-r8a7793" for the R8A7793 device
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 2124f0a..ba3f31e 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -1197,6 +1197,65 @@ static const struct rvin_info rcar_info_r8a7795 = {
 	},
 };
 
+static const struct rvin_info rcar_info_r8a7796 = {
+	.chip = RCAR_GEN3,
+	.max_width = 4096,
+	.max_height = 4096,
+
+	.num_chsels = 5,
+	.chsels = {
+		{
+			{ .csi = RVIN_CSI40, .chan = 0 },
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_NOOPE, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 0 },
+			{ .csi = RVIN_CSI20, .chan = 0 },
+		}, {
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_NOOPE, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 1 },
+			{ .csi = RVIN_CSI20, .chan = 1 },
+		}, {
+			{ .csi = RVIN_NOOPE, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 0 },
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 2 },
+			{ .csi = RVIN_CSI20, .chan = 2 },
+		}, {
+			{ .csi = RVIN_CSI40, .chan = 1 },
+			{ .csi = RVIN_CSI20, .chan = 1 },
+			{ .csi = RVIN_NOOPE, .chan = 1 },
+			{ .csi = RVIN_CSI40, .chan = 3 },
+			{ .csi = RVIN_CSI20, .chan = 3 },
+		}, {
+			{ .csi = RVIN_CSI40, .chan = 0 },
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_NOOPE, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 0 },
+			{ .csi = RVIN_CSI20, .chan = 0 },
+		}, {
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_NOOPE, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 1 },
+			{ .csi = RVIN_CSI20, .chan = 1 },
+		}, {
+			{ .csi = RVIN_NOOPE, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 0 },
+			{ .csi = RVIN_CSI20, .chan = 0 },
+			{ .csi = RVIN_CSI40, .chan = 2 },
+			{ .csi = RVIN_CSI20, .chan = 2 },
+		}, {
+			{ .csi = RVIN_CSI40, .chan = 1 },
+			{ .csi = RVIN_CSI20, .chan = 1 },
+			{ .csi = RVIN_NOOPE, .chan = 1 },
+			{ .csi = RVIN_CSI40, .chan = 3 },
+			{ .csi = RVIN_CSI20, .chan = 3 },
+		},
+	},
+};
+
 static const struct rvin_info rcar_info_gen2 = {
 	.chip = RCAR_GEN2,
 	.max_width = 2048,
@@ -1209,6 +1268,10 @@ static const struct of_device_id rvin_of_id_table[] = {
 		.data = (void *)&rcar_info_r8a7795,
 	},
 	{
+		.compatible = "renesas,vin-r8a7796",
+		.data = (void *)&rcar_info_r8a7796,
+	},
+	{
 		.compatible = "renesas,vin-r8a7794",
 		.data = (void *)&rcar_info_gen2,
 	},
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* Re: [PATCH 03/32] media: rcar-vin: reset bytesperline and sizeimage when resetting format
  2016-11-02 13:23 ` [PATCH 03/32] media: rcar-vin: reset bytesperline and sizeimage when resetting format Niklas Söderlund
@ 2016-11-02 16:43   ` Sergei Shtylyov
  0 siblings, 0 replies; 43+ messages in thread
From: Sergei Shtylyov @ 2016-11-02 16:43 UTC (permalink / raw)
  To: Niklas Söderlund, Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus

Hello.

On 11/02/2016 04:23 PM, Niklas Söderlund wrote:

> These two fields where forgotten when refactoring the format reset code
> path. If they are not also reset at the same time as width and hight the
> format read using G_FMT will not match realty.

    Reality?

> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
[...]

MBR, Sergei


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 20/32] media: rcar-vin: expose a sink pad if we are on Gen3
  2016-11-02 13:23 ` [PATCH 20/32] media: rcar-vin: expose a sink pad if we are on Gen3 Niklas Söderlund
@ 2016-11-02 17:15   ` Sergei Shtylyov
  0 siblings, 0 replies; 43+ messages in thread
From: Sergei Shtylyov @ 2016-11-02 17:15 UTC (permalink / raw)
  To: Niklas Söderlund, Laurent Pinchart, Hans Verkuil
  Cc: linux-media, linux-renesas-soc, tomoharu.fukawa.eb, Sakari Ailus

On 11/02/2016 04:23 PM, Niklas Söderlund wrote:

> Refactor the probe code path to look for the digital subdevice, if one
> is found use it just like the driver did before (Gen2 mode) but if it's
> not found prepare for a Gen3 mode by registering a pad for the media
> controller API to use.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
>  drivers/media/platform/rcar-vin/rcar-core.c | 21 ++++++++++++++++++++-
>  drivers/media/platform/rcar-vin/rcar-vin.h  |  9 +++++++++
>  2 files changed, 29 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
> index f961957..ce8b59a 100644
> --- a/drivers/media/platform/rcar-vin/rcar-core.c
> +++ b/drivers/media/platform/rcar-vin/rcar-core.c
> @@ -308,6 +308,25 @@ static const struct of_device_id rvin_of_id_table[] = {
>  };
>  MODULE_DEVICE_TABLE(of, rvin_of_id_table);
>
> +static int rvin_graph_init(struct rvin_dev *vin)
> +{
> +	int ret;
> +
> +	/* Try to get digital video pipe */
> +	ret = rvin_digital_graph_init(vin);
> +
> +	/* No digital pipe and we are on Gen3 try to joint CSI2 group */
> +	if (ret == -ENODEV && vin->info->chip == RCAR_GEN3) {
> +
> +		vin->pads[RVIN_SINK].flags = MEDIA_PAD_FL_SINK;
> +		ret = media_entity_pads_init(&vin->vdev.entity, 1, vin->pads);
> +		if (ret)
> +			return ret;

    This *if* is not necessary, you'll return below anyway.

> +	}
> +
> +	return ret;
> +}
> +
>  static int rcar_vin_probe(struct platform_device *pdev)
>  {
>  	const struct of_device_id *match;
[...]

MBR, Sergei


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 14/32] media: rcar-vin: move chip information to own struct
  2016-11-02 13:23 ` [PATCH 14/32] media: rcar-vin: move chip information to own struct Niklas Söderlund
@ 2016-11-07 12:40   ` Geert Uytterhoeven
  0 siblings, 0 replies; 43+ messages in thread
From: Geert Uytterhoeven @ 2016-11-07 12:40 UTC (permalink / raw)
  To: Niklas Söderlund
  Cc: Laurent Pinchart, Hans Verkuil, Linux Media Mailing List,
	Linux-Renesas, Fukawa, Sakari Ailus

On Wed, Nov 2, 2016 at 2:23 PM, Niklas Söderlund
<niklas.soderlund+renesas@ragnatech.se> wrote:
> When Gen3 support is added to the driver more then chip id will be
> different for the different Soc. To avoid a lot of if statements in the
> code create a struct chip_info to contain this information.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
>  drivers/media/platform/rcar-vin/rcar-core.c | 49 ++++++++++++++++++++++++-----
>  drivers/media/platform/rcar-vin/rcar-v4l2.c |  3 +-
>  drivers/media/platform/rcar-vin/rcar-vin.h  | 12 +++++--
>  3 files changed, 53 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
> index 5807d8d..372443e 100644
> --- a/drivers/media/platform/rcar-vin/rcar-core.c
> +++ b/drivers/media/platform/rcar-vin/rcar-core.c
> @@ -253,14 +253,47 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
>   * Platform Device Driver
>   */
>
> +static const struct rvin_info rcar_info_h1 = {
> +       .chip = RCAR_H1,
> +};
> +
> +static const struct rvin_info rcar_info_m1 = {
> +       .chip = RCAR_M1,
> +};
> +
> +static const struct rvin_info rcar_info_gen2 = {
> +       .chip = RCAR_GEN2,
> +};
> +
>  static const struct of_device_id rvin_of_id_table[] = {
> -       { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
> -       { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
> -       { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
> -       { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
> -       { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
> -       { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
> -       { .compatible = "renesas,rcar-gen2-vin", .data = (void *)RCAR_GEN2 },
> +       {
> +               .compatible = "renesas,vin-r8a7794",
> +               .data = (void *)&rcar_info_gen2,

These casts are not needed.

> +       },
> +       {
> +               .compatible = "renesas,vin-r8a7793",
> +               .data = (void *)&rcar_info_gen2,
> +       },
> +       {
> +               .compatible = "renesas,vin-r8a7791",
> +               .data = (void *)&rcar_info_gen2,
> +       },
> +       {
> +               .compatible = "renesas,vin-r8a7790",
> +               .data = (void *)&rcar_info_gen2,
> +       },
> +       {
> +               .compatible = "renesas,vin-r8a7779",
> +               .data = (void *)&rcar_info_h1,
> +       },
> +       {
> +               .compatible = "renesas,vin-r8a7778",
> +               .data = (void *)&rcar_info_m1,
> +       },
> +       {
> +               .compatible = "renesas,rcar-gen2-vin",
> +               .data = (void *)&rcar_info_gen2,
> +       },
>         { },
>  };
>  MODULE_DEVICE_TABLE(of, rvin_of_id_table);
> @@ -281,7 +314,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
>                 return -ENODEV;
>
>         vin->dev = &pdev->dev;
> -       vin->chip = (enum chip_id)match->data;
> +       vin->info = (const struct rvin_info *)match->data;

This cast is not needed.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 31/32] media: rcar-vin: enable support for r8a7795
  2016-11-02 13:23 ` [PATCH 31/32] media: rcar-vin: enable support for r8a7795 Niklas Söderlund
@ 2016-11-07 12:42   ` Geert Uytterhoeven
  0 siblings, 0 replies; 43+ messages in thread
From: Geert Uytterhoeven @ 2016-11-07 12:42 UTC (permalink / raw)
  To: Niklas Söderlund
  Cc: Laurent Pinchart, Hans Verkuil, Linux Media Mailing List,
	Linux-Renesas, Fukawa, Sakari Ailus

On Wed, Nov 2, 2016 at 2:23 PM, Niklas Söderlund
<niklas.soderlund+renesas@ragnatech.se> wrote:
> Add the SoC specific information for Renesas Salvator-X H3 (r8a7795)
> board.

Salvator-X is the board, while the support you add is purely SoC-specific.

> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
>  drivers/media/platform/rcar-vin/Kconfig     |  2 +-
>  drivers/media/platform/rcar-vin/rcar-core.c | 71 +++++++++++++++++++++++++++++
>  2 files changed, 72 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/rcar-vin/Kconfig b/drivers/media/platform/rcar-vin/Kconfig
> index 111d2a1..e0e981c 100644
> --- a/drivers/media/platform/rcar-vin/Kconfig
> +++ b/drivers/media/platform/rcar-vin/Kconfig

> @@ -1138,6 +1205,10 @@ static const struct rvin_info rcar_info_gen2 = {
>
>  static const struct of_device_id rvin_of_id_table[] = {
>         {
> +               .compatible = "renesas,vin-r8a7795",
> +               .data = (void *)&rcar_info_r8a7795,

Cast not needed

> +       },

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 32/32] media: rcar-vin: enable support for r8a7796
  2016-11-02 13:23 ` [PATCH 32/32] media: rcar-vin: enable support for r8a7796 Niklas Söderlund
@ 2016-11-07 12:44   ` Geert Uytterhoeven
  0 siblings, 0 replies; 43+ messages in thread
From: Geert Uytterhoeven @ 2016-11-07 12:44 UTC (permalink / raw)
  To: Niklas Söderlund
  Cc: Laurent Pinchart, Hans Verkuil, Linux Media Mailing List,
	Linux-Renesas, Fukawa, Sakari Ailus

On Wed, Nov 2, 2016 at 2:23 PM, Niklas Söderlund
<niklas.soderlund+renesas@ragnatech.se> wrote:
> Add the SoC specific information for Renesas Salvator-X M3 (r8a7796)
> board.

Same comments as for patch 31/32.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 30/32] media: rcar-vin: add Gen3 devicetree bindings documentation
  2016-11-02 13:23 ` [PATCH 30/32] media: rcar-vin: add Gen3 devicetree bindings documentation Niklas Söderlund
@ 2016-11-07 12:47   ` Geert Uytterhoeven
  0 siblings, 0 replies; 43+ messages in thread
From: Geert Uytterhoeven @ 2016-11-07 12:47 UTC (permalink / raw)
  To: Niklas Söderlund
  Cc: Laurent Pinchart, Hans Verkuil, Linux Media Mailing List,
	Linux-Renesas, Fukawa, Sakari Ailus

On Wed, Nov 2, 2016 at 2:23 PM, Niklas Söderlund
<niklas.soderlund+renesas@ragnatech.se> wrote:
> Document the Gen3 devicetree bindings. The new bindings are all handled
> in the port@1 node, if a endpoint is described as on Gen2 in port@0 the

an endpoint

> driver will work in Gen2 mode and this is supported on Gen3. The new
> CSI-2 video sources are only supported on Gen3.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
>  .../devicetree/bindings/media/rcar_vin.txt         | 116 +++++++++++++++++++--
>  1 file changed, 106 insertions(+), 10 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt
> index 6a4e61c..a51cf70 100644
> --- a/Documentation/devicetree/bindings/media/rcar_vin.txt
> +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
> @@ -2,8 +2,12 @@ Renesas RCar Video Input driver (rcar_vin)
>  ------------------------------------------
>
>  The rcar_vin device provides video input capabilities for the Renesas R-Car
> -family of devices. The current blocks are always slaves and suppot one input
> -channel which can be either RGB, YUYV or BT656.
> +family of devices.
> +
> +On Gen2 the current blocks are always slaves and support one input channel
> +which can be either RGB, YUYV or BT656. On Gen3 the current blocks are
> +always slaves and support multiple input channels which can be ether RGB,

either

> +YUVU, BT656 or CSI-2.

> @@ -92,6 +105,89 @@ Board setup example (vin1 composite video input)
>          };
>  };
>
> +Device node example Gen3
> +------------------------
> +
> +        aliases {
> +                vin0 = &vin0;
> +        };
> +
> +        vin1: video@e6ef1000 {
> +                compatible = "renesas,vin-r8a7796";
> +                reg =  <0 0xe6ef1000 0 0x1000>;
> +                interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
> +                clocks = <&cpg CPG_MOD 810>;
> +                power-domains = <&cpg>;

Please update the power-domains property to match reality.

> +                status = "disabled";
> +
> +                ports {
> +                        #address-cells = <1>;
> +                        #size-cells = <0>;
> +
> +                        port@1 {
> +                                #address-cells = <1>;
> +                                #size-cells = <0>;
> +
> +                                reg = <1>;
> +
> +                                vin1csi20: endpoint@0 {
> +                                        reg = <0>;
> +                                        remote-endpoint= <&csi20vin1>;
> +                                };
> +                        };
> +                };
> +        };
> +
> +        csi20: csi2@fea80000 {
> +                compatible = "renesas,r8a7796-csi2";
> +                reg = <0 0xfea80000 0 0x10000>;
> +                interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
> +                clocks = <&cpg CPG_MOD 714>;
> +                power-domains = <&cpg>;

Likewise.

> +                status = "disabled";
> +
> +                ports {
> +                        #address-cells = <1>;
> +                        #size-cells = <0>;
> +
> +                        port@1 {
> +                                #address-cells = <1>;
> +                                #size-cells = <0>;
> +
> +                                reg = <1>;
> +
> +                                csi20vin1: endpoint@1 {
> +                                        reg = <1>;
> +                                        remote-endpoint = <&vin1csi20>;
> +                                };
> +                        };
> +                };
> +        };




-- 
Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 02/32] media: entity: Add media_entity_has_route() function
  2016-11-02 13:22 ` [PATCH 02/32] media: entity: Add media_entity_has_route() function Niklas Söderlund
@ 2016-11-08 12:42   ` Sakari Ailus
  2016-11-08 12:54     ` [PATCH 1/1] " Sakari Ailus
  0 siblings, 1 reply; 43+ messages in thread
From: Sakari Ailus @ 2016-11-08 12:42 UTC (permalink / raw)
  To: Niklas Söderlund
  Cc: Laurent Pinchart, Hans Verkuil, linux-media, linux-renesas-soc,
	tomoharu.fukawa.eb, Sakari Ailus, Michal Simek

Hi Niklas,

On Wed, Nov 02, 2016 at 02:22:59PM +0100, Niklas Söderlund wrote:
> From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> This is a wrapper around the media entity has_route operation.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
>  drivers/media/media-entity.c | 29 +++++++++++++++++++++++++++++
>  include/media/media-entity.h |  3 +++
>  2 files changed, 32 insertions(+)
> 
> diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
> index c68239e..4d03ea7 100644
> --- a/drivers/media/media-entity.c
> +++ b/drivers/media/media-entity.c
> @@ -242,6 +242,35 @@ EXPORT_SYMBOL_GPL(media_entity_pads_init);
>   * Graph traversal
>   */
>  
> +/**
> + * media_entity_has_route - Check if two entity pads are connected internally
> + * @entity: The entity
> + * @pad0: The first pad index
> + * @pad1: The second pad index
> + *
> + * This function can be used to check whether two pads of an entity are
> + * connected internally in the entity.
> + *
> + * The caller must hold entity->source->parent->mutex.
> + *
> + * Return: true if the pads are connected internally and false otherwise.
> + */
> +bool media_entity_has_route(struct media_entity *entity, unsigned int pad0,
> +			    unsigned int pad1)
> +{
> +	if (pad0 >= entity->num_pads || pad1 >= entity->num_pads)
> +		return false;
> +
> +	if (pad0 == pad1)
> +		return true;
> +
> +	if (!entity->ops || !entity->ops->has_route)
> +		return true;
> +
> +	return entity->ops->has_route(entity, pad0, pad1);
> +}
> +EXPORT_SYMBOL_GPL(media_entity_has_route);
> +
>  static struct media_entity *
>  media_entity_other(struct media_entity *entity, struct media_link *link)
>  {
> diff --git a/include/media/media-entity.h b/include/media/media-entity.h
> index 8f9fc85..5fb3f06 100644
> --- a/include/media/media-entity.h
> +++ b/include/media/media-entity.h
> @@ -851,6 +851,9 @@ void media_entity_graph_walk_cleanup(struct media_entity_graph *graph);
>   */
>  void media_entity_put(struct media_entity *entity);
>  
> +bool media_entity_has_route(struct media_entity *entity, unsigned int sink,
> +			    unsigned int source);

The Kerneldoc documentation should be found here, not in the .c file.

Also the arguments are different from the actual implementation.

That's the diff to what I happen to have here, feel free to use instead:

<URL:http://git.retiisi.org.uk/?p=~sailus/linux.git;a=commitdiff;h=7c3bdf5bde5ac8627c94841bef6c6db34d8d2b2a>

> +
>  /**
>   * media_entity_graph_walk_start - Start walking the media graph at a
>   *	given entity

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 01/32] media: entity: Add has_route entity operation
  2016-11-02 13:22 ` [PATCH 01/32] media: entity: Add has_route entity operation Niklas Söderlund
@ 2016-11-08 12:43   ` Sakari Ailus
  0 siblings, 0 replies; 43+ messages in thread
From: Sakari Ailus @ 2016-11-08 12:43 UTC (permalink / raw)
  To: Niklas Söderlund
  Cc: Laurent Pinchart, Hans Verkuil, linux-media, linux-renesas-soc,
	tomoharu.fukawa.eb, Sakari Ailus, Michal Simek

On Wed, Nov 02, 2016 at 02:22:58PM +0100, Niklas Söderlund wrote:
> From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> The optional operation can be used by entities to report whether two
> pads are internally connected.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>

Thanks!

Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 1/1] media: entity: Add media_entity_has_route() function
  2016-11-08 12:42   ` Sakari Ailus
@ 2016-11-08 12:54     ` Sakari Ailus
  2016-11-11 21:08       ` Niklas Söderlund
  0 siblings, 1 reply; 43+ messages in thread
From: Sakari Ailus @ 2016-11-08 12:54 UTC (permalink / raw)
  To: linux-media; +Cc: niklas.soderlund, Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

This is a wrapper around the media entity has_route operation.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
Hi Niklas,

There was actually another problem with the Kerneldoc comment related to
the mutex. Fixed that one as well.

Kind regards,
Sakari

 drivers/media/media-entity.c | 16 ++++++++++++++++
 include/media/media-entity.h | 17 +++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 5734bb9..7de08e1 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -242,6 +242,22 @@ EXPORT_SYMBOL_GPL(media_entity_pads_init);
  * Graph traversal
  */
 
+bool media_entity_has_route(struct media_entity *entity, unsigned int pad0,
+			    unsigned int pad1)
+{
+	if (pad0 >= entity->num_pads || pad1 >= entity->num_pads)
+		return false;
+
+	if (pad0 == pad1)
+		return true;
+
+	if (!entity->ops || !entity->ops->has_route)
+		return true;
+
+	return entity->ops->has_route(entity, pad0, pad1);
+}
+EXPORT_SYMBOL_GPL(media_entity_has_route);
+
 static struct media_entity *
 media_entity_other(struct media_entity *entity, struct media_link *link)
 {
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 2060e48..aa8d3c5 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -834,6 +834,23 @@ __must_check int media_entity_graph_walk_init(
 	struct media_entity_graph *graph, struct media_device *mdev);
 
 /**
+ * media_entity_has_route - Check if two entity pads are connected internally
+ *
+ * @entity: The entity
+ * @pad0: The first pad index
+ * @pad1: The second pad index
+ *
+ * This function can be used to check whether two pads of an entity are
+ * connected internally in the entity.
+ *
+ * The caller must hold entity->graph_obj.mdev->mutex.
+ *
+ * Return: true if the pads are connected internally and false otherwise.
+ */
+bool media_entity_has_route(struct media_entity *entity, unsigned int pad0,
+			    unsigned int pad1);
+
+/**
  * media_entity_graph_walk_cleanup - Release resources used by graph walk.
  *
  * @graph: Media graph structure that will be used to walk the graph
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* Re: [PATCH 1/1] media: entity: Add media_entity_has_route() function
  2016-11-08 12:54     ` [PATCH 1/1] " Sakari Ailus
@ 2016-11-11 21:08       ` Niklas Söderlund
  0 siblings, 0 replies; 43+ messages in thread
From: Niklas Söderlund @ 2016-11-11 21:08 UTC (permalink / raw)
  To: Sakari Ailus; +Cc: linux-media, Laurent Pinchart

Hi Sakari,

Thanks, I will use this one in my next iteration of the VIN patches.

On 2016-11-08 14:54:28 +0200, Sakari Ailus wrote:
> From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> This is a wrapper around the media entity has_route operation.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
> Hi Niklas,
> 
> There was actually another problem with the Kerneldoc comment related to
> the mutex. Fixed that one as well.
> 
> Kind regards,
> Sakari
> 
>  drivers/media/media-entity.c | 16 ++++++++++++++++
>  include/media/media-entity.h | 17 +++++++++++++++++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
> index 5734bb9..7de08e1 100644
> --- a/drivers/media/media-entity.c
> +++ b/drivers/media/media-entity.c
> @@ -242,6 +242,22 @@ EXPORT_SYMBOL_GPL(media_entity_pads_init);
>   * Graph traversal
>   */
>  
> +bool media_entity_has_route(struct media_entity *entity, unsigned int pad0,
> +			    unsigned int pad1)
> +{
> +	if (pad0 >= entity->num_pads || pad1 >= entity->num_pads)
> +		return false;
> +
> +	if (pad0 == pad1)
> +		return true;
> +
> +	if (!entity->ops || !entity->ops->has_route)
> +		return true;
> +
> +	return entity->ops->has_route(entity, pad0, pad1);
> +}
> +EXPORT_SYMBOL_GPL(media_entity_has_route);
> +
>  static struct media_entity *
>  media_entity_other(struct media_entity *entity, struct media_link *link)
>  {
> diff --git a/include/media/media-entity.h b/include/media/media-entity.h
> index 2060e48..aa8d3c5 100644
> --- a/include/media/media-entity.h
> +++ b/include/media/media-entity.h
> @@ -834,6 +834,23 @@ __must_check int media_entity_graph_walk_init(
>  	struct media_entity_graph *graph, struct media_device *mdev);
>  
>  /**
> + * media_entity_has_route - Check if two entity pads are connected internally
> + *
> + * @entity: The entity
> + * @pad0: The first pad index
> + * @pad1: The second pad index
> + *
> + * This function can be used to check whether two pads of an entity are
> + * connected internally in the entity.
> + *
> + * The caller must hold entity->graph_obj.mdev->mutex.
> + *
> + * Return: true if the pads are connected internally and false otherwise.
> + */
> +bool media_entity_has_route(struct media_entity *entity, unsigned int pad0,
> +			    unsigned int pad1);
> +
> +/**
>   * media_entity_graph_walk_cleanup - Release resources used by graph walk.
>   *
>   * @graph: Media graph structure that will be used to walk the graph
> -- 
> 2.7.4
> 

-- 
Regards,
Niklas Söderlund

^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2016-11-11 21:08 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-02 13:22 [PATCH 00/32] rcar-vin: Add Gen3 with media controller support Niklas Söderlund
2016-11-02 13:22 ` [PATCH 01/32] media: entity: Add has_route entity operation Niklas Söderlund
2016-11-08 12:43   ` Sakari Ailus
2016-11-02 13:22 ` [PATCH 02/32] media: entity: Add media_entity_has_route() function Niklas Söderlund
2016-11-08 12:42   ` Sakari Ailus
2016-11-08 12:54     ` [PATCH 1/1] " Sakari Ailus
2016-11-11 21:08       ` Niklas Söderlund
2016-11-02 13:23 ` [PATCH 03/32] media: rcar-vin: reset bytesperline and sizeimage when resetting format Niklas Söderlund
2016-11-02 16:43   ` Sergei Shtylyov
2016-11-02 13:23 ` [PATCH 04/32] media: rcar-vin: use rvin_reset_format() in S_DV_TIMINGS Niklas Söderlund
2016-11-02 13:23 ` [PATCH 05/32] media: rcar-vin: fix how pads are handled for v4l2 subdeivce operations Niklas Söderlund
2016-11-02 13:23 ` [PATCH 06/32] media: rcar-vin: fix standard in input enumeration Niklas Söderlund
2016-11-02 13:23 ` [PATCH 07/32] media: rcar-vin: add wrapper to get rvin_graph_entity Niklas Söderlund
2016-11-02 13:23 ` [PATCH 08/32] media: rcar-vin: move subdev source and sink pad index to rvin_graph_entity Niklas Söderlund
2016-11-02 13:23 ` [PATCH 09/32] media: rcar-vin: move pad number discovery to async complete handler Niklas Söderlund
2016-11-02 13:23 ` [PATCH 10/32] media: rcar-vin: use pad information when verifying media bus format Niklas Söderlund
2016-11-02 13:23 ` [PATCH 11/32] media: rcar-vin: refactor pad lookup code Niklas Söderlund
2016-11-02 13:23 ` [PATCH 12/32] media: rcar-vin: split rvin_s_fmt_vid_cap() Niklas Söderlund
2016-11-02 13:23 ` [PATCH 13/32] media: rcar-vin: register the video device early Niklas Söderlund
2016-11-02 13:23 ` [PATCH 14/32] media: rcar-vin: move chip information to own struct Niklas Söderlund
2016-11-07 12:40   ` Geert Uytterhoeven
2016-11-02 13:23 ` [PATCH 15/32] media: rcar-vin: move max width and height information to chip information Niklas Söderlund
2016-11-02 13:23 ` [PATCH 16/32] media: rcar-vin: change name of video device Niklas Söderlund
2016-11-02 13:23 ` [PATCH 17/32] media: rcar-vin: clarify error message from the digital notifier Niklas Söderlund
2016-11-02 13:23 ` [PATCH 18/32] media: rcar-vin: enable Gen3 hardware configuration Niklas Söderlund
2016-11-02 13:23 ` [PATCH 19/32] media: rcar-vin: add functions to manipulate Gen3 CHSEL value Niklas Söderlund
2016-11-02 13:23 ` [PATCH 20/32] media: rcar-vin: expose a sink pad if we are on Gen3 Niklas Söderlund
2016-11-02 17:15   ` Sergei Shtylyov
2016-11-02 13:23 ` [PATCH 21/32] media: rcar-vin: add group allocator functions Niklas Söderlund
2016-11-02 13:23 ` [PATCH 22/32] media: rcar-vin: add chsel information to rvin_info Niklas Söderlund
2016-11-02 13:23 ` [PATCH 23/32] media: rcar-vin: parse Gen3 OF and setup media graph Niklas Söderlund
2016-11-02 13:23 ` [PATCH 24/32] media: rcar-vin: add link notify for Gen3 Niklas Söderlund
2016-11-02 13:23 ` [PATCH 25/32] media: rcar-vin: enable CSI2 group subdevices in lookup helpers Niklas Söderlund
2016-11-02 13:23 ` [PATCH 26/32] media: rcar-vin: add helpers for bridge Niklas Söderlund
2016-11-02 13:23 ` [PATCH 27/32] media: rcar-vin: start/stop the CSI2 bridge stream Niklas Söderlund
2016-11-02 13:23 ` [PATCH 28/32] media: rcar-vin: propagate format to bridge Niklas Söderlund
2016-11-02 13:23 ` [PATCH 29/32] media: rcar-vin: attach to CSI2 group when the video device is opened Niklas Söderlund
2016-11-02 13:23 ` [PATCH 30/32] media: rcar-vin: add Gen3 devicetree bindings documentation Niklas Söderlund
2016-11-07 12:47   ` Geert Uytterhoeven
2016-11-02 13:23 ` [PATCH 31/32] media: rcar-vin: enable support for r8a7795 Niklas Söderlund
2016-11-07 12:42   ` Geert Uytterhoeven
2016-11-02 13:23 ` [PATCH 32/32] media: rcar-vin: enable support for r8a7796 Niklas Söderlund
2016-11-07 12:44   ` Geert Uytterhoeven

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).