linux-sh.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/32] VSP: Add R-Car Gen3 support
@ 2015-12-05  2:12 Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 01/32] v4l: vsp1: Change the type of the rwpf field in struct vsp1_video Laurent Pinchart
                   ` (32 more replies)
  0 siblings, 33 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Hello,

This patch set adds support for the Renesas R-Car Gen3 SoC family to the VSP1
driver. The large number of patches is caused by a change in the display
controller architecture that makes usage of the VSP mandatory as the display
controller has lost the ability to read data from memory.

Patch 01/32 to 27/32 prepare for the implementation of an API exported to the
DRM driver in patch 28/32. Patches 31/32 enables support for the R-Car Gen3
family, and patch 32/32 finally enhances perfomances by implementing support
for display lists.

The major change compared to v1 is the usage of the IP version register
instead of DT properties to configure device parameters such as the number of
BRU inputs or the availability of the BRU.

Laurent Pinchart (31):
  v4l: vsp1: Change the type of the rwpf field in struct vsp1_video
  v4l: vsp1: Store the memory format in struct vsp1_rwpf
  v4l: vsp1: Move video operations to vsp1_rwpf
  v4l: vsp1: Rename vsp1_video_buffer to vsp1_vb2_buffer
  v4l: vsp1: Move video device out of struct vsp1_rwpf
  v4l: vsp1: Make rwpf operations independent of video device
  v4l: vsp1: Support VSP1 instances without any UDS
  v4l: vsp1: Move vsp1_video pointer from vsp1_entity to vsp1_rwpf
  v4l: vsp1: Remove struct vsp1_pipeline num_video field
  v4l: vsp1: Decouple pipeline end of frame processing from vsp1_video
  v4l: vsp1: Split pipeline management code from vsp1_video.c
  v4l: vsp1: Rename video pipeline functions to use vsp1_video prefix
  v4l: vsp1: Extract pipeline initialization code into a function
  v4l: vsp1: Reuse local variable instead of recomputing it
  v4l: vsp1: Extract link creation to separate function
  v4l: vsp1: Document the vsp1_pipeline structure
  v4l: vsp1: Fix typo in VI6_DISP_IRQ_STA_DST register name
  v4l: vsp1: Set the SRU CTRL0 register when starting the stream
  v4l: vsp1: Remove unused module read functions
  v4l: vsp1: Move entity route setup function to vsp1_entity.c
  v4l: vsp1: Make number of BRU inputs configurable
  v4l: vsp1: Make the BRU optional
  v4l: vsp1: Move format info to vsp1_pipe.c
  v4l: vsp1: Make the userspace API optional
  v4l: vsp1: Make pipeline inputs array index by RPF index
  v4l: vsp1: Set the alpha value manually in RPF and WPF s_stream
    handlers
  v4l: vsp1: Don't validate links when the userspace API is disabled
  v4l: vsp1: Add VSP+DU support
  v4l: vsp1: Disconnect unused RPFs from the DRM pipeline
  v4l: vsp1: Implement atomic update for the DRM driver
  v4l: vsp1: Add support for the R-Car Gen3 VSP2

Takashi Saito (1):
  v4l: vsp1: Add display list support

 .../devicetree/bindings/media/renesas,vsp1.txt     |  21 +-
 drivers/media/platform/vsp1/Makefile               |   3 +-
 drivers/media/platform/vsp1/vsp1.h                 |  24 +
 drivers/media/platform/vsp1/vsp1_bru.c             |  33 +-
 drivers/media/platform/vsp1/vsp1_bru.h             |   3 +-
 drivers/media/platform/vsp1/vsp1_dl.c              | 304 +++++++++++
 drivers/media/platform/vsp1/vsp1_dl.h              |  42 ++
 drivers/media/platform/vsp1/vsp1_drm.c             | 595 +++++++++++++++++++++
 drivers/media/platform/vsp1/vsp1_drm.h             |  38 ++
 drivers/media/platform/vsp1/vsp1_drv.c             | 254 +++++++--
 drivers/media/platform/vsp1/vsp1_entity.c          |  31 +-
 drivers/media/platform/vsp1/vsp1_entity.h          |  14 +-
 drivers/media/platform/vsp1/vsp1_hsit.c            |   2 +-
 drivers/media/platform/vsp1/vsp1_lif.c             |  11 +-
 drivers/media/platform/vsp1/vsp1_lut.c             |   7 +-
 drivers/media/platform/vsp1/vsp1_pipe.c            | 405 ++++++++++++++
 drivers/media/platform/vsp1/vsp1_pipe.h            | 134 +++++
 drivers/media/platform/vsp1/vsp1_regs.h            |  32 +-
 drivers/media/platform/vsp1/vsp1_rpf.c             |  77 ++-
 drivers/media/platform/vsp1/vsp1_rwpf.h            |  24 +-
 drivers/media/platform/vsp1/vsp1_sru.c             |   9 +-
 drivers/media/platform/vsp1/vsp1_uds.c             |   8 +-
 drivers/media/platform/vsp1/vsp1_video.c           | 516 ++++--------------
 drivers/media/platform/vsp1/vsp1_video.h           | 111 +---
 drivers/media/platform/vsp1/vsp1_wpf.c             |  88 ++-
 include/media/vsp1.h                               |  33 ++
 26 files changed, 2069 insertions(+), 750 deletions(-)
 create mode 100644 drivers/media/platform/vsp1/vsp1_dl.c
 create mode 100644 drivers/media/platform/vsp1/vsp1_dl.h
 create mode 100644 drivers/media/platform/vsp1/vsp1_drm.c
 create mode 100644 drivers/media/platform/vsp1/vsp1_drm.h
 create mode 100644 drivers/media/platform/vsp1/vsp1_pipe.c
 create mode 100644 drivers/media/platform/vsp1/vsp1_pipe.h
 create mode 100644 include/media/vsp1.h

-- 
Regards,

Laurent Pinchart


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

* [PATCH v2 01/32] v4l: vsp1: Change the type of the rwpf field in struct vsp1_video
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 02/32] v4l: vsp1: Store the memory format in struct vsp1_rwpf Laurent Pinchart
                   ` (31 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

The rwpf field contains a pointer to the rpf or wpf associated with the
video node. Instead of storing it as a vsp1_entity, store the
corresponding vsp1_rwpf pointer to allow accessing the vsp1_rwpf fields
directly.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_rpf.c   | 2 +-
 drivers/media/platform/vsp1/vsp1_video.c | 4 ++--
 drivers/media/platform/vsp1/vsp1_video.h | 5 +++--
 drivers/media/platform/vsp1/vsp1_wpf.c   | 2 +-
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index cd5248a9a271..b57373a57dc6 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -271,7 +271,7 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 	video->vsp1 = vsp1;
 	video->ops = &rpf_vdev_ops;
 
-	ret = vsp1_video_init(video, &rpf->entity);
+	ret = vsp1_video_init(video, rpf);
 	if (ret < 0)
 		goto error;
 
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 5ce88e1f5d71..698cc8aecfbe 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -1190,7 +1190,7 @@ static struct v4l2_file_operations vsp1_video_fops = {
  * Initialization and Cleanup
  */
 
-int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf)
+int vsp1_video_init(struct vsp1_video *video, struct vsp1_rwpf *rwpf)
 {
 	const char *direction;
 	int ret;
@@ -1245,7 +1245,7 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf)
 	video->video.v4l2_dev = &video->vsp1->v4l2_dev;
 	video->video.fops = &vsp1_video_fops;
 	snprintf(video->video.name, sizeof(video->video.name), "%s %s",
-		 rwpf->subdev.name, direction);
+		 rwpf->entity.subdev.name, direction);
 	video->video.vfl_type = VFL_TYPE_GRABBER;
 	video->video.release = video_device_release_empty;
 	video->video.ioctl_ops = &vsp1_video_ioctl_ops;
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index a929aa81cdbf..c1d9771c55ed 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -20,6 +20,7 @@
 #include <media/media-entity.h>
 #include <media/videobuf2-v4l2.h>
 
+struct vsp1_rwpf;
 struct vsp1_video;
 
 /*
@@ -113,7 +114,7 @@ struct vsp1_video_operations {
 
 struct vsp1_video {
 	struct vsp1_device *vsp1;
-	struct vsp1_entity *rwpf;
+	struct vsp1_rwpf *rwpf;
 
 	const struct vsp1_video_operations *ops;
 
@@ -140,7 +141,7 @@ static inline struct vsp1_video *to_vsp1_video(struct video_device *vdev)
 	return container_of(vdev, struct vsp1_video, video);
 }
 
-int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf);
+int vsp1_video_init(struct vsp1_video *video, struct vsp1_rwpf *rwpf);
 void vsp1_video_cleanup(struct vsp1_video *video);
 
 void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe);
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 95b62f4f77e7..9ba5feee50de 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -271,7 +271,7 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 	video->vsp1 = vsp1;
 	video->ops = &wpf_vdev_ops;
 
-	ret = vsp1_video_init(video, &wpf->entity);
+	ret = vsp1_video_init(video, wpf);
 	if (ret < 0)
 		goto error;
 
-- 
2.4.10


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

* [PATCH v2 02/32] v4l: vsp1: Store the memory format in struct vsp1_rwpf
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 01/32] v4l: vsp1: Change the type of the rwpf field in struct vsp1_video Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 03/32] v4l: vsp1: Move video operations to vsp1_rwpf Laurent Pinchart
                   ` (30 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Move the format from struct vsp1_video to struct vsp1_rwpf to prepare
for VSPD KMS support that will not instantiate V4L2 video device nodes.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_bru.c   |  4 ++--
 drivers/media/platform/vsp1/vsp1_rpf.c   |  4 ++--
 drivers/media/platform/vsp1/vsp1_rwpf.h  |  2 ++
 drivers/media/platform/vsp1/vsp1_video.c | 40 ++++++++++++++++----------------
 drivers/media/platform/vsp1/vsp1_video.h |  2 --
 drivers/media/platform/vsp1/vsp1_wpf.c   |  4 ++--
 6 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index 7dd763311c0f..1308dfef0f92 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -94,7 +94,7 @@ static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
 	/* Disable dithering and enable color data normalization unless the
 	 * format at the pipeline output is premultiplied.
 	 */
-	flags = pipe->output ? pipe->output->video.format.flags : 0;
+	flags = pipe->output ? pipe->output->format.flags : 0;
 	vsp1_bru_write(bru, VI6_BRU_INCTRL,
 		       flags & V4L2_PIX_FMT_FLAG_PREMUL_ALPHA ?
 		       0 : VI6_BRU_INCTRL_NRM);
@@ -125,7 +125,7 @@ static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
 		if (bru->inputs[i].rpf) {
 			ctrl |= VI6_BRU_CTRL_RBC;
 
-			premultiplied = bru->inputs[i].rpf->video.format.flags
+			premultiplied = bru->inputs[i].rpf->format.flags
 				      & V4L2_PIX_FMT_FLAG_PREMUL_ALPHA;
 		} else {
 			ctrl |= VI6_BRU_CTRL_CROP(VI6_ROP_NOP)
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index b57373a57dc6..ae63dce38b0c 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -75,8 +75,8 @@ static const struct v4l2_ctrl_ops rpf_ctrl_ops = {
 static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
 {
 	struct vsp1_rwpf *rpf = to_rwpf(subdev);
-	const struct vsp1_format_info *fmtinfo = rpf->video.fmtinfo;
-	const struct v4l2_pix_format_mplane *format = &rpf->video.format;
+	const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
+	const struct v4l2_pix_format_mplane *format = &rpf->format;
 	const struct v4l2_rect *crop = &rpf->crop;
 	u32 pstride;
 	u32 infmt;
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index f452dce1a931..8609c3d02679 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -32,6 +32,8 @@ struct vsp1_rwpf {
 	unsigned int max_width;
 	unsigned int max_height;
 
+	struct v4l2_pix_format_mplane format;
+	const struct vsp1_format_info *fmtinfo;
 	struct {
 		unsigned int left;
 		unsigned int top;
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 698cc8aecfbe..3eaf06903495 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -185,9 +185,9 @@ static int vsp1_video_verify_format(struct vsp1_video *video)
 	if (ret < 0)
 		return ret = -ENOIOCTLCMD ? -EINVAL : ret;
 
-	if (video->fmtinfo->mbus != fmt.format.code ||
-	    video->format.height != fmt.format.height ||
-	    video->format.width != fmt.format.width)
+	if (video->rwpf->fmtinfo->mbus != fmt.format.code ||
+	    video->rwpf->format.height != fmt.format.height ||
+	    video->rwpf->format.width != fmt.format.width)
 		return -EINVAL;
 
 	return 0;
@@ -806,7 +806,7 @@ vsp1_video_queue_setup(struct vb2_queue *vq, const void *parg,
 
 		format = &pix_mp;
 	} else {
-		format = &video->format;
+		format = &video->rwpf->format;
 	}
 
 	*nplanes = format->num_planes;
@@ -824,7 +824,7 @@ static int vsp1_video_buffer_prepare(struct vb2_buffer *vb)
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 	struct vsp1_video *video = vb2_get_drv_priv(vb->vb2_queue);
 	struct vsp1_video_buffer *buf = to_vsp1_video_buffer(vbuf);
-	const struct v4l2_pix_format_mplane *format = &video->format;
+	const struct v4l2_pix_format_mplane *format = &video->rwpf->format;
 	unsigned int i;
 
 	if (vb->num_planes < format->num_planes)
@@ -907,7 +907,7 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)
 				struct vsp1_rwpf *rpf  					to_rwpf(&pipe->uds_input->subdev);
 
-				uds->scale_alpha = rpf->video.fmtinfo->alpha;
+				uds->scale_alpha = rpf->fmtinfo->alpha;
 			}
 		}
 
@@ -1011,7 +1011,7 @@ vsp1_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
 		return -EINVAL;
 
 	mutex_lock(&video->lock);
-	format->fmt.pix_mp = video->format;
+	format->fmt.pix_mp = video->rwpf->format;
 	mutex_unlock(&video->lock);
 
 	return 0;
@@ -1051,8 +1051,8 @@ vsp1_video_set_format(struct file *file, void *fh, struct v4l2_format *format)
 		goto done;
 	}
 
-	video->format = format->fmt.pix_mp;
-	video->fmtinfo = info;
+	video->rwpf->format = format->fmt.pix_mp;
+	video->rwpf->fmtinfo = info;
 
 done:
 	mutex_unlock(&video->lock);
@@ -1229,17 +1229,17 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_rwpf *rwpf)
 		return ret;
 
 	/* ... and the format ... */
-	video->fmtinfo = vsp1_get_format_info(VSP1_VIDEO_DEF_FORMAT);
-	video->format.pixelformat = video->fmtinfo->fourcc;
-	video->format.colorspace = V4L2_COLORSPACE_SRGB;
-	video->format.field = V4L2_FIELD_NONE;
-	video->format.width = VSP1_VIDEO_DEF_WIDTH;
-	video->format.height = VSP1_VIDEO_DEF_HEIGHT;
-	video->format.num_planes = 1;
-	video->format.plane_fmt[0].bytesperline -		video->format.width * video->fmtinfo->bpp[0] / 8;
-	video->format.plane_fmt[0].sizeimage -		video->format.plane_fmt[0].bytesperline * video->format.height;
+	rwpf->fmtinfo = vsp1_get_format_info(VSP1_VIDEO_DEF_FORMAT);
+	rwpf->format.pixelformat = rwpf->fmtinfo->fourcc;
+	rwpf->format.colorspace = V4L2_COLORSPACE_SRGB;
+	rwpf->format.field = V4L2_FIELD_NONE;
+	rwpf->format.width = VSP1_VIDEO_DEF_WIDTH;
+	rwpf->format.height = VSP1_VIDEO_DEF_HEIGHT;
+	rwpf->format.num_planes = 1;
+	rwpf->format.plane_fmt[0].bytesperline +		rwpf->format.width * rwpf->fmtinfo->bpp[0] / 8;
+	rwpf->format.plane_fmt[0].sizeimage +		rwpf->format.plane_fmt[0].bytesperline * rwpf->format.height;
 
 	/* ... and the video node... */
 	video->video.v4l2_dev = &video->vsp1->v4l2_dev;
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index c1d9771c55ed..56d0e7bd4327 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -123,8 +123,6 @@ struct vsp1_video {
 	struct media_pad pad;
 
 	struct mutex lock;
-	struct v4l2_pix_format_mplane format;
-	const struct vsp1_format_info *fmtinfo;
 
 	struct vsp1_pipeline pipe;
 	unsigned int pipe_index;
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 9ba5feee50de..e2afd9797e25 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -112,7 +112,7 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
 
 	/* Destination stride. */
 	if (!pipe->lif) {
-		struct v4l2_pix_format_mplane *format = &wpf->video.format;
+		struct v4l2_pix_format_mplane *format = &wpf->format;
 
 		vsp1_wpf_write(wpf, VI6_WPF_DSTM_STRIDE_Y,
 			       format->plane_fmt[0].bytesperline);
@@ -130,7 +130,7 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
 
 	/* Format */
 	if (!pipe->lif) {
-		const struct vsp1_format_info *fmtinfo = wpf->video.fmtinfo;
+		const struct vsp1_format_info *fmtinfo = wpf->fmtinfo;
 
 		outfmt = fmtinfo->hwfmt << VI6_WPF_OUTFMT_WRFMT_SHIFT;
 
-- 
2.4.10


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

* [PATCH v2 03/32] v4l: vsp1: Move video operations to vsp1_rwpf
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 01/32] v4l: vsp1: Change the type of the rwpf field in struct vsp1_video Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 02/32] v4l: vsp1: Store the memory format in struct vsp1_rwpf Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 04/32] v4l: vsp1: Rename vsp1_video_buffer to vsp1_vb2_buffer Laurent Pinchart
                   ` (29 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

This removes the dependency of vsp1_rpf and vsp1_wpf on vsp1_video,
making it possible to reuse the operations without a V4L2 video device
node.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_rpf.c   | 11 +++++------
 drivers/media/platform/vsp1/vsp1_rwpf.h  |  9 +++++++++
 drivers/media/platform/vsp1/vsp1_video.c |  4 ++--
 drivers/media/platform/vsp1/vsp1_video.h |  6 ------
 drivers/media/platform/vsp1/vsp1_wpf.c   | 12 +++++-------
 5 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index ae63dce38b0c..ee0a1472a13c 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -186,10 +186,8 @@ static struct v4l2_subdev_ops rpf_ops = {
  * Video Device Operations
  */
 
-static void rpf_vdev_queue(struct vsp1_video *video,
-			   struct vsp1_video_buffer *buf)
+static void rpf_buf_queue(struct vsp1_rwpf *rpf, struct vsp1_video_buffer *buf)
 {
-	struct vsp1_rwpf *rpf = container_of(video, struct vsp1_rwpf, video);
 	unsigned int i;
 
 	for (i = 0; i < 3; ++i)
@@ -208,8 +206,8 @@ static void rpf_vdev_queue(struct vsp1_video *video,
 			       buf->addr[2] + rpf->offsets[1]);
 }
 
-static const struct vsp1_video_operations rpf_vdev_ops = {
-	.queue = rpf_vdev_queue,
+static const struct vsp1_rwpf_operations rpf_vdev_ops = {
+	.queue = rpf_buf_queue,
 };
 
 /* -----------------------------------------------------------------------------
@@ -227,6 +225,8 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 	if (rpf = NULL)
 		return ERR_PTR(-ENOMEM);
 
+	rpf->ops = &rpf_vdev_ops;
+
 	rpf->max_width = RPF_MAX_WIDTH;
 	rpf->max_height = RPF_MAX_HEIGHT;
 
@@ -269,7 +269,6 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 
 	video->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
 	video->vsp1 = vsp1;
-	video->ops = &rpf_vdev_ops;
 
 	ret = vsp1_video_init(video, rpf);
 	if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 8609c3d02679..3cc80be03524 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -24,11 +24,20 @@
 #define RWPF_PAD_SINK				0
 #define RWPF_PAD_SOURCE				1
 
+struct vsp1_rwpf;
+struct vsp1_video_buffer;
+
+struct vsp1_rwpf_operations {
+	void (*queue)(struct vsp1_rwpf *rwpf, struct vsp1_video_buffer *buf);
+};
+
 struct vsp1_rwpf {
 	struct vsp1_entity entity;
 	struct vsp1_video video;
 	struct v4l2_ctrl_handler ctrls;
 
+	const struct vsp1_rwpf_operations *ops;
+
 	unsigned int max_width;
 	unsigned int max_height;
 
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 3eaf06903495..932225ec45f6 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -631,7 +631,7 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe,
 
 	spin_lock_irqsave(&pipe->irqlock, flags);
 
-	video->ops->queue(video, buf);
+	video->rwpf->ops->queue(video->rwpf, buf);
 	pipe->buffers_ready |= 1 << video->pipe_index;
 
 	spin_unlock_irqrestore(&pipe->irqlock, flags);
@@ -860,7 +860,7 @@ static void vsp1_video_buffer_queue(struct vb2_buffer *vb)
 
 	spin_lock_irqsave(&pipe->irqlock, flags);
 
-	video->ops->queue(video, buf);
+	video->rwpf->ops->queue(video->rwpf, buf);
 	pipe->buffers_ready |= 1 << video->pipe_index;
 
 	if (vb2_is_streaming(&video->queue) &&
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index 56d0e7bd4327..72be847f2df9 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -108,16 +108,10 @@ to_vsp1_video_buffer(struct vb2_v4l2_buffer *vbuf)
 	return container_of(vbuf, struct vsp1_video_buffer, buf);
 }
 
-struct vsp1_video_operations {
-	void (*queue)(struct vsp1_video *video, struct vsp1_video_buffer *buf);
-};
-
 struct vsp1_video {
 	struct vsp1_device *vsp1;
 	struct vsp1_rwpf *rwpf;
 
-	const struct vsp1_video_operations *ops;
-
 	struct video_device video;
 	enum v4l2_buf_type type;
 	struct media_pad pad;
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index e2afd9797e25..b25c5e6976ef 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -195,11 +195,8 @@ static struct v4l2_subdev_ops wpf_ops = {
  * Video Device Operations
  */
 
-static void wpf_vdev_queue(struct vsp1_video *video,
-			   struct vsp1_video_buffer *buf)
+static void wpf_buf_queue(struct vsp1_rwpf *wpf, struct vsp1_video_buffer *buf)
 {
-	struct vsp1_rwpf *wpf = container_of(video, struct vsp1_rwpf, video);
-
 	vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_Y, buf->addr[0]);
 	if (buf->buf.vb2_buf.num_planes > 1)
 		vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C0, buf->addr[1]);
@@ -207,8 +204,8 @@ static void wpf_vdev_queue(struct vsp1_video *video,
 		vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C1, buf->addr[2]);
 }
 
-static const struct vsp1_video_operations wpf_vdev_ops = {
-	.queue = wpf_vdev_queue,
+static const struct vsp1_rwpf_operations wpf_vdev_ops = {
+	.queue = wpf_buf_queue,
 };
 
 /* -----------------------------------------------------------------------------
@@ -227,6 +224,8 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 	if (wpf = NULL)
 		return ERR_PTR(-ENOMEM);
 
+	wpf->ops = &wpf_vdev_ops;
+
 	wpf->max_width = WPF_MAX_WIDTH;
 	wpf->max_height = WPF_MAX_HEIGHT;
 
@@ -269,7 +268,6 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 
 	video->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
 	video->vsp1 = vsp1;
-	video->ops = &wpf_vdev_ops;
 
 	ret = vsp1_video_init(video, wpf);
 	if (ret < 0)
-- 
2.4.10


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

* [PATCH v2 04/32] v4l: vsp1: Rename vsp1_video_buffer to vsp1_vb2_buffer
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (2 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 03/32] v4l: vsp1: Move video operations to vsp1_rwpf Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 05/32] v4l: vsp1: Move video device out of struct vsp1_rwpf Laurent Pinchart
                   ` (28 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

The structure represent a vsp1 videobuf2 buffer, name it accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_rpf.c   |  2 +-
 drivers/media/platform/vsp1/vsp1_rwpf.h  |  4 ++--
 drivers/media/platform/vsp1/vsp1_video.c | 20 ++++++++++----------
 drivers/media/platform/vsp1/vsp1_video.h |  8 ++++----
 drivers/media/platform/vsp1/vsp1_wpf.c   |  2 +-
 5 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index ee0a1472a13c..1f91fc4c4857 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -186,7 +186,7 @@ static struct v4l2_subdev_ops rpf_ops = {
  * Video Device Operations
  */
 
-static void rpf_buf_queue(struct vsp1_rwpf *rpf, struct vsp1_video_buffer *buf)
+static void rpf_buf_queue(struct vsp1_rwpf *rpf, struct vsp1_vb2_buffer *buf)
 {
 	unsigned int i;
 
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 3cc80be03524..aa22cc062ff3 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -25,10 +25,10 @@
 #define RWPF_PAD_SOURCE				1
 
 struct vsp1_rwpf;
-struct vsp1_video_buffer;
+struct vsp1_vb2_buffer;
 
 struct vsp1_rwpf_operations {
-	void (*queue)(struct vsp1_rwpf *rwpf, struct vsp1_video_buffer *buf);
+	void (*queue)(struct vsp1_rwpf *rwpf, struct vsp1_vb2_buffer *buf);
 };
 
 struct vsp1_rwpf {
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 932225ec45f6..e96160d90b35 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -577,12 +577,12 @@ static bool vsp1_pipeline_ready(struct vsp1_pipeline *pipe)
  *
  * Return the next queued buffer or NULL if the queue is empty.
  */
-static struct vsp1_video_buffer *
+static struct vsp1_vb2_buffer *
 vsp1_video_complete_buffer(struct vsp1_video *video)
 {
 	struct vsp1_pipeline *pipe = to_vsp1_pipeline(&video->video.entity);
-	struct vsp1_video_buffer *next = NULL;
-	struct vsp1_video_buffer *done;
+	struct vsp1_vb2_buffer *next = NULL;
+	struct vsp1_vb2_buffer *done;
 	unsigned long flags;
 	unsigned int i;
 
@@ -594,7 +594,7 @@ vsp1_video_complete_buffer(struct vsp1_video *video)
 	}
 
 	done = list_first_entry(&video->irqqueue,
-				struct vsp1_video_buffer, queue);
+				struct vsp1_vb2_buffer, queue);
 
 	/* In DU output mode reuse the buffer if the list is singular. */
 	if (pipe->lif && list_is_singular(&video->irqqueue)) {
@@ -606,7 +606,7 @@ vsp1_video_complete_buffer(struct vsp1_video *video)
 
 	if (!list_empty(&video->irqqueue))
 		next = list_first_entry(&video->irqqueue,
-					struct vsp1_video_buffer, queue);
+					struct vsp1_vb2_buffer, queue);
 
 	spin_unlock_irqrestore(&video->irqlock, flags);
 
@@ -622,7 +622,7 @@ vsp1_video_complete_buffer(struct vsp1_video *video)
 static void vsp1_video_frame_end(struct vsp1_pipeline *pipe,
 				 struct vsp1_video *video)
 {
-	struct vsp1_video_buffer *buf;
+	struct vsp1_vb2_buffer *buf;
 	unsigned long flags;
 
 	buf = vsp1_video_complete_buffer(video);
@@ -823,7 +823,7 @@ static int vsp1_video_buffer_prepare(struct vb2_buffer *vb)
 {
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 	struct vsp1_video *video = vb2_get_drv_priv(vb->vb2_queue);
-	struct vsp1_video_buffer *buf = to_vsp1_video_buffer(vbuf);
+	struct vsp1_vb2_buffer *buf = to_vsp1_vb2_buffer(vbuf);
 	const struct v4l2_pix_format_mplane *format = &video->rwpf->format;
 	unsigned int i;
 
@@ -846,7 +846,7 @@ static void vsp1_video_buffer_queue(struct vb2_buffer *vb)
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 	struct vsp1_video *video = vb2_get_drv_priv(vb->vb2_queue);
 	struct vsp1_pipeline *pipe = to_vsp1_pipeline(&video->video.entity);
-	struct vsp1_video_buffer *buf = to_vsp1_video_buffer(vbuf);
+	struct vsp1_vb2_buffer *buf = to_vsp1_vb2_buffer(vbuf);
 	unsigned long flags;
 	bool empty;
 
@@ -938,7 +938,7 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq)
 {
 	struct vsp1_video *video = vb2_get_drv_priv(vq);
 	struct vsp1_pipeline *pipe = to_vsp1_pipeline(&video->video.entity);
-	struct vsp1_video_buffer *buffer;
+	struct vsp1_vb2_buffer *buffer;
 	unsigned long flags;
 	int ret;
 
@@ -1263,7 +1263,7 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_rwpf *rwpf)
 	video->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
 	video->queue.lock = &video->lock;
 	video->queue.drv_priv = video;
-	video->queue.buf_struct_size = sizeof(struct vsp1_video_buffer);
+	video->queue.buf_struct_size = sizeof(struct vsp1_vb2_buffer);
 	video->queue.ops = &vsp1_video_queue_qops;
 	video->queue.mem_ops = &vb2_dma_contig_memops;
 	video->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index 72be847f2df9..c7e143125ef7 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -94,7 +94,7 @@ static inline struct vsp1_pipeline *to_vsp1_pipeline(struct media_entity *e)
 		return NULL;
 }
 
-struct vsp1_video_buffer {
+struct vsp1_vb2_buffer {
 	struct vb2_v4l2_buffer buf;
 	struct list_head queue;
 
@@ -102,10 +102,10 @@ struct vsp1_video_buffer {
 	unsigned int length[3];
 };
 
-static inline struct vsp1_video_buffer *
-to_vsp1_video_buffer(struct vb2_v4l2_buffer *vbuf)
+static inline struct vsp1_vb2_buffer *
+to_vsp1_vb2_buffer(struct vb2_v4l2_buffer *vbuf)
 {
-	return container_of(vbuf, struct vsp1_video_buffer, buf);
+	return container_of(vbuf, struct vsp1_vb2_buffer, buf);
 }
 
 struct vsp1_video {
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index b25c5e6976ef..e41d8bcd9d97 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -195,7 +195,7 @@ static struct v4l2_subdev_ops wpf_ops = {
  * Video Device Operations
  */
 
-static void wpf_buf_queue(struct vsp1_rwpf *wpf, struct vsp1_video_buffer *buf)
+static void wpf_buf_queue(struct vsp1_rwpf *wpf, struct vsp1_vb2_buffer *buf)
 {
 	vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_Y, buf->addr[0]);
 	if (buf->buf.vb2_buf.num_planes > 1)
-- 
2.4.10


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

* [PATCH v2 05/32] v4l: vsp1: Move video device out of struct vsp1_rwpf
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (3 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 04/32] v4l: vsp1: Rename vsp1_video_buffer to vsp1_vb2_buffer Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 06/32] v4l: vsp1: Make rwpf operations independent of video device Laurent Pinchart
                   ` (27 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

To make the video device nodes optional we need to decouple the [rw]pf
instances from the video devices. Move video devices out of struct
vsp1_rwpf and instantiate them dynamically in the core driver code.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1.h        |  1 +
 drivers/media/platform/vsp1/vsp1_bru.c    |  1 +
 drivers/media/platform/vsp1/vsp1_drv.c    | 63 +++++++++++++++++++++++++++++--
 drivers/media/platform/vsp1/vsp1_entity.c |  3 --
 drivers/media/platform/vsp1/vsp1_rpf.c    | 22 -----------
 drivers/media/platform/vsp1/vsp1_rwpf.h   |  2 -
 drivers/media/platform/vsp1/vsp1_video.c  | 45 ++++++++++++----------
 drivers/media/platform/vsp1/vsp1_video.h  |  4 +-
 drivers/media/platform/vsp1/vsp1_wpf.c    | 29 --------------
 9 files changed, 90 insertions(+), 80 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 989e96f7e360..b25032bd37a7 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -71,6 +71,7 @@ struct vsp1_device {
 	struct vsp1_rwpf *wpf[VSP1_MAX_WPF];
 
 	struct list_head entities;
+	struct list_head videos;
 
 	struct v4l2_device v4l2_dev;
 	struct media_device media_dev;
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index 1308dfef0f92..b4cc9bc478af 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -19,6 +19,7 @@
 #include "vsp1.h"
 #include "vsp1_bru.h"
 #include "vsp1_rwpf.h"
+#include "vsp1_video.h"
 
 #define BRU_MIN_SIZE				1U
 #define BRU_MAX_SIZE				8190U
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 4e61886384e3..de0b80e8d048 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -28,6 +28,7 @@
 #include "vsp1_rwpf.h"
 #include "vsp1_sru.h"
 #include "vsp1_uds.h"
+#include "vsp1_video.h"
 
 /* -----------------------------------------------------------------------------
  * Interrupt Handling
@@ -117,14 +118,19 @@ static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink)
 
 static void vsp1_destroy_entities(struct vsp1_device *vsp1)
 {
-	struct vsp1_entity *entity;
-	struct vsp1_entity *next;
+	struct vsp1_entity *entity, *_entity;
+	struct vsp1_video *video, *_video;
 
-	list_for_each_entry_safe(entity, next, &vsp1->entities, list_dev) {
+	list_for_each_entry_safe(entity, _entity, &vsp1->entities, list_dev) {
 		list_del(&entity->list_dev);
 		vsp1_entity_destroy(entity);
 	}
 
+	list_for_each_entry_safe(video, _video, &vsp1->videos, list) {
+		list_del(&video->list);
+		vsp1_video_cleanup(video);
+	}
+
 	v4l2_device_unregister(&vsp1->v4l2_dev);
 	media_device_unregister(&vsp1->media_dev);
 }
@@ -202,6 +208,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
+		struct vsp1_video *video;
 		struct vsp1_rwpf *rpf;
 
 		rpf = vsp1_rpf_create(vsp1, i);
@@ -212,6 +219,14 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 
 		vsp1->rpf[i] = rpf;
 		list_add_tail(&rpf->entity.list_dev, &vsp1->entities);
+
+		video = vsp1_video_create(vsp1, rpf);
+		if (IS_ERR(video)) {
+			ret = PTR_ERR(video);
+			goto done;
+		}
+
+		list_add_tail(&video->list, &vsp1->videos);
 	}
 
 	if (vsp1->pdata.features & VSP1_HAS_SRU) {
@@ -238,6 +253,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
+		struct vsp1_video *video;
 		struct vsp1_rwpf *wpf;
 
 		wpf = vsp1_wpf_create(vsp1, i);
@@ -248,6 +264,15 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 
 		vsp1->wpf[i] = wpf;
 		list_add_tail(&wpf->entity.list_dev, &vsp1->entities);
+
+		video = vsp1_video_create(vsp1, wpf);
+		if (IS_ERR(video)) {
+			ret = PTR_ERR(video);
+			goto done;
+		}
+
+		list_add_tail(&video->list, &vsp1->videos);
+		wpf->entity.sink = &video->video.entity;
 	}
 
 	/* Create links. */
@@ -261,6 +286,37 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 			goto done;
 	}
 
+	for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
+		struct vsp1_rwpf *rpf = vsp1->rpf[i];
+
+		ret = media_entity_create_link(&rpf->entity.video->video.entity,
+					       0, &rpf->entity.subdev.entity,
+					       RWPF_PAD_SINK,
+					       MEDIA_LNK_FL_ENABLED |
+					       MEDIA_LNK_FL_IMMUTABLE);
+		if (ret < 0)
+			goto done;
+	}
+
+	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
+		/* Connect the video device to the WPF. All connections are
+		 * immutable except for the WPF0 source link if a LIF is
+		 * present.
+		 */
+		struct vsp1_rwpf *wpf = vsp1->wpf[i];
+		unsigned int flags = MEDIA_LNK_FL_ENABLED;
+
+		if (!(vsp1->pdata.features & VSP1_HAS_LIF) || i != 0)
+			flags |= MEDIA_LNK_FL_IMMUTABLE;
+
+		ret = media_entity_create_link(&wpf->entity.subdev.entity,
+					       RWPF_PAD_SOURCE,
+					       &wpf->entity.video->video.entity,
+					       0, flags);
+		if (ret < 0)
+			goto done;
+	}
+
 	if (vsp1->pdata.features & VSP1_HAS_LIF) {
 		ret = media_entity_create_link(
 			&vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
@@ -486,6 +542,7 @@ static int vsp1_probe(struct platform_device *pdev)
 	vsp1->dev = &pdev->dev;
 	mutex_init(&vsp1->lock);
 	INIT_LIST_HEAD(&vsp1->entities);
+	INIT_LIST_HEAD(&vsp1->videos);
 
 	ret = vsp1_parse_dt(vsp1);
 	if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index fd95a75b04f4..0c52e4b71a98 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -20,7 +20,6 @@
 
 #include "vsp1.h"
 #include "vsp1_entity.h"
-#include "vsp1_video.h"
 
 bool vsp1_entity_is_streaming(struct vsp1_entity *entity)
 {
@@ -225,8 +224,6 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
 
 void vsp1_entity_destroy(struct vsp1_entity *entity)
 {
-	if (entity->video)
-		vsp1_video_cleanup(entity->video);
 	if (entity->subdev.ctrl_handler)
 		v4l2_ctrl_handler_free(entity->subdev.ctrl_handler);
 	media_entity_cleanup(&entity->subdev.entity);
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 1f91fc4c4857..085d10056297 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -217,7 +217,6 @@ static const struct vsp1_rwpf_operations rpf_vdev_ops = {
 struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 {
 	struct v4l2_subdev *subdev;
-	struct vsp1_video *video;
 	struct vsp1_rwpf *rpf;
 	int ret;
 
@@ -264,27 +263,6 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 		goto error;
 	}
 
-	/* Initialize the video device. */
-	video = &rpf->video;
-
-	video->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-	video->vsp1 = vsp1;
-
-	ret = vsp1_video_init(video, rpf);
-	if (ret < 0)
-		goto error;
-
-	rpf->entity.video = video;
-
-	/* Connect the video device to the RPF. */
-	ret = media_entity_create_link(&rpf->video.video.entity, 0,
-				       &rpf->entity.subdev.entity,
-				       RWPF_PAD_SINK,
-				       MEDIA_LNK_FL_ENABLED |
-				       MEDIA_LNK_FL_IMMUTABLE);
-	if (ret < 0)
-		goto error;
-
 	return rpf;
 
 error:
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index aa22cc062ff3..ee2a8bf269fa 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -19,7 +19,6 @@
 
 #include "vsp1.h"
 #include "vsp1_entity.h"
-#include "vsp1_video.h"
 
 #define RWPF_PAD_SINK				0
 #define RWPF_PAD_SOURCE				1
@@ -33,7 +32,6 @@ struct vsp1_rwpf_operations {
 
 struct vsp1_rwpf {
 	struct vsp1_entity entity;
-	struct vsp1_video video;
 	struct v4l2_ctrl_handler ctrls;
 
 	const struct vsp1_rwpf_operations *ops;
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index e96160d90b35..3086cdbeaf9a 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -435,11 +435,11 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 		if (e->type = VSP1_ENTITY_RPF) {
 			rwpf = to_rwpf(subdev);
 			pipe->inputs[pipe->num_inputs++] = rwpf;
-			rwpf->video.pipe_index = pipe->num_inputs;
+			rwpf->entity.video->pipe_index = pipe->num_inputs;
 		} else if (e->type = VSP1_ENTITY_WPF) {
 			rwpf = to_rwpf(subdev);
 			pipe->output = to_rwpf(subdev);
-			rwpf->video.pipe_index = 0;
+			rwpf->entity.video->pipe_index = 0;
 		} else if (e->type = VSP1_ENTITY_LIF) {
 			pipe->lif = e;
 		} else if (e->type = VSP1_ENTITY_BRU) {
@@ -648,10 +648,10 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
 
 	/* Complete buffers on all video nodes. */
 	for (i = 0; i < pipe->num_inputs; ++i)
-		vsp1_video_frame_end(pipe, &pipe->inputs[i]->video);
+		vsp1_video_frame_end(pipe, pipe->inputs[i]->entity.video);
 
 	if (!pipe->lif)
-		vsp1_video_frame_end(pipe, &pipe->output->video);
+		vsp1_video_frame_end(pipe, pipe->output->entity.video);
 
 	spin_lock_irqsave(&pipe->irqlock, flags);
 
@@ -1190,29 +1190,34 @@ static struct v4l2_file_operations vsp1_video_fops = {
  * Initialization and Cleanup
  */
 
-int vsp1_video_init(struct vsp1_video *video, struct vsp1_rwpf *rwpf)
+struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1,
+				     struct vsp1_rwpf *rwpf)
 {
+	struct vsp1_video *video;
 	const char *direction;
 	int ret;
 
-	switch (video->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		direction = "output";
-		video->pad.flags = MEDIA_PAD_FL_SINK;
-		break;
+	video = devm_kzalloc(vsp1->dev, sizeof(*video), GFP_KERNEL);
+	if (!video)
+		return ERR_PTR(-ENOMEM);
+
+	rwpf->entity.video = video;
+
+	video->vsp1 = vsp1;
+	video->rwpf = rwpf;
 
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+	if (rwpf->entity.type = VSP1_ENTITY_RPF) {
 		direction = "input";
+		video->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
 		video->pad.flags = MEDIA_PAD_FL_SOURCE;
 		video->video.vfl_dir = VFL_DIR_TX;
-		break;
-
-	default:
-		return -EINVAL;
+	} else {
+		direction = "output";
+		video->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+		video->pad.flags = MEDIA_PAD_FL_SINK;
+		video->video.vfl_dir = VFL_DIR_RX;
 	}
 
-	video->rwpf = rwpf;
-
 	mutex_init(&video->lock);
 	spin_lock_init(&video->irqlock);
 	INIT_LIST_HEAD(&video->irqqueue);
@@ -1226,7 +1231,7 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_rwpf *rwpf)
 	/* Initialize the media entity... */
 	ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
 	if (ret < 0)
-		return ret;
+		return ERR_PTR(ret);
 
 	/* ... and the format ... */
 	rwpf->fmtinfo = vsp1_get_format_info(VSP1_VIDEO_DEF_FORMAT);
@@ -1281,12 +1286,12 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_rwpf *rwpf)
 		goto error;
 	}
 
-	return 0;
+	return video;
 
 error:
 	vb2_dma_contig_cleanup_ctx(video->alloc_ctx);
 	vsp1_video_cleanup(video);
-	return ret;
+	return ERR_PTR(ret);
 }
 
 void vsp1_video_cleanup(struct vsp1_video *video)
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index c7e143125ef7..cbd44c336169 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -109,6 +109,7 @@ to_vsp1_vb2_buffer(struct vb2_v4l2_buffer *vbuf)
 }
 
 struct vsp1_video {
+	struct list_head list;
 	struct vsp1_device *vsp1;
 	struct vsp1_rwpf *rwpf;
 
@@ -133,7 +134,8 @@ static inline struct vsp1_video *to_vsp1_video(struct video_device *vdev)
 	return container_of(vdev, struct vsp1_video, video);
 }
 
-int vsp1_video_init(struct vsp1_video *video, struct vsp1_rwpf *rwpf);
+struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1,
+				     struct vsp1_rwpf *rwpf);
 void vsp1_video_cleanup(struct vsp1_video *video);
 
 void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe);
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index e41d8bcd9d97..a4c0888a1b46 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -215,9 +215,7 @@ static const struct vsp1_rwpf_operations wpf_vdev_ops = {
 struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 {
 	struct v4l2_subdev *subdev;
-	struct vsp1_video *video;
 	struct vsp1_rwpf *wpf;
-	unsigned int flags;
 	int ret;
 
 	wpf = devm_kzalloc(vsp1->dev, sizeof(*wpf), GFP_KERNEL);
@@ -263,33 +261,6 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 		goto error;
 	}
 
-	/* Initialize the video device. */
-	video = &wpf->video;
-
-	video->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-	video->vsp1 = vsp1;
-
-	ret = vsp1_video_init(video, wpf);
-	if (ret < 0)
-		goto error;
-
-	wpf->entity.video = video;
-
-	/* Connect the video device to the WPF. All connections are immutable
-	 * except for the WPF0 source link if a LIF is present.
-	 */
-	flags = MEDIA_LNK_FL_ENABLED;
-	if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0)
-		flags |= MEDIA_LNK_FL_IMMUTABLE;
-
-	ret = media_entity_create_link(&wpf->entity.subdev.entity,
-				       RWPF_PAD_SOURCE,
-				       &wpf->video.video.entity, 0, flags);
-	if (ret < 0)
-		goto error;
-
-	wpf->entity.sink = &wpf->video.video.entity;
-
 	return wpf;
 
 error:
-- 
2.4.10


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

* [PATCH v2 06/32] v4l: vsp1: Make rwpf operations independent of video device
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (4 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 05/32] v4l: vsp1: Move video device out of struct vsp1_rwpf Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 07/32] v4l: vsp1: Support VSP1 instances without any UDS Laurent Pinchart
                   ` (26 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

The rwpf queue operation doesn't queue a buffer but sets the memory
address for the next run. Rename it to set_memory and pass it a new
structure independent of the video buffer than only contains memory
information.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_rpf.c   | 16 ++++++++--------
 drivers/media/platform/vsp1/vsp1_rwpf.h  | 10 ++++++++--
 drivers/media/platform/vsp1/vsp1_video.c | 15 +++++++++------
 drivers/media/platform/vsp1/vsp1_video.h |  7 +++----
 drivers/media/platform/vsp1/vsp1_wpf.c   | 14 +++++++-------
 5 files changed, 35 insertions(+), 27 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 085d10056297..c0b7f76cd0b5 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -186,28 +186,28 @@ static struct v4l2_subdev_ops rpf_ops = {
  * Video Device Operations
  */
 
-static void rpf_buf_queue(struct vsp1_rwpf *rpf, struct vsp1_vb2_buffer *buf)
+static void rpf_set_memory(struct vsp1_rwpf *rpf, struct vsp1_rwpf_memory *mem)
 {
 	unsigned int i;
 
 	for (i = 0; i < 3; ++i)
-		rpf->buf_addr[i] = buf->addr[i];
+		rpf->buf_addr[i] = mem->addr[i];
 
 	if (!vsp1_entity_is_streaming(&rpf->entity))
 		return;
 
 	vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_Y,
-		       buf->addr[0] + rpf->offsets[0]);
-	if (buf->buf.vb2_buf.num_planes > 1)
+		       mem->addr[0] + rpf->offsets[0]);
+	if (mem->num_planes > 1)
 		vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C0,
-			       buf->addr[1] + rpf->offsets[1]);
-	if (buf->buf.vb2_buf.num_planes > 2)
+			       mem->addr[1] + rpf->offsets[1]);
+	if (mem->num_planes > 2)
 		vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C1,
-			       buf->addr[2] + rpf->offsets[1]);
+			       mem->addr[2] + rpf->offsets[1]);
 }
 
 static const struct vsp1_rwpf_operations rpf_vdev_ops = {
-	.queue = rpf_buf_queue,
+	.set_memory = rpf_set_memory,
 };
 
 /* -----------------------------------------------------------------------------
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index ee2a8bf269fa..0076920adb28 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -24,10 +24,16 @@
 #define RWPF_PAD_SOURCE				1
 
 struct vsp1_rwpf;
-struct vsp1_vb2_buffer;
+
+struct vsp1_rwpf_memory {
+	unsigned int num_planes;
+	dma_addr_t addr[3];
+	unsigned int length[3];
+};
 
 struct vsp1_rwpf_operations {
-	void (*queue)(struct vsp1_rwpf *rwpf, struct vsp1_vb2_buffer *buf);
+	void (*set_memory)(struct vsp1_rwpf *rwpf,
+			   struct vsp1_rwpf_memory *mem);
 };
 
 struct vsp1_rwpf {
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 3086cdbeaf9a..0d600b8de6b1 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -613,7 +613,8 @@ vsp1_video_complete_buffer(struct vsp1_video *video)
 	done->buf.sequence = video->sequence++;
 	v4l2_get_timestamp(&done->buf.timestamp);
 	for (i = 0; i < done->buf.vb2_buf.num_planes; ++i)
-		vb2_set_plane_payload(&done->buf.vb2_buf, i, done->length[i]);
+		vb2_set_plane_payload(&done->buf.vb2_buf, i,
+				      done->mem.length[i]);
 	vb2_buffer_done(&done->buf.vb2_buf, VB2_BUF_STATE_DONE);
 
 	return next;
@@ -631,7 +632,7 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe,
 
 	spin_lock_irqsave(&pipe->irqlock, flags);
 
-	video->rwpf->ops->queue(video->rwpf, buf);
+	video->rwpf->ops->set_memory(video->rwpf, &buf->mem);
 	pipe->buffers_ready |= 1 << video->pipe_index;
 
 	spin_unlock_irqrestore(&pipe->irqlock, flags);
@@ -830,11 +831,13 @@ static int vsp1_video_buffer_prepare(struct vb2_buffer *vb)
 	if (vb->num_planes < format->num_planes)
 		return -EINVAL;
 
+	buf->mem.num_planes = vb->num_planes;
+
 	for (i = 0; i < vb->num_planes; ++i) {
-		buf->addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
-		buf->length[i] = vb2_plane_size(vb, i);
+		buf->mem.addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
+		buf->mem.length[i] = vb2_plane_size(vb, i);
 
-		if (buf->length[i] < format->plane_fmt[i].sizeimage)
+		if (buf->mem.length[i] < format->plane_fmt[i].sizeimage)
 			return -EINVAL;
 	}
 
@@ -860,7 +863,7 @@ static void vsp1_video_buffer_queue(struct vb2_buffer *vb)
 
 	spin_lock_irqsave(&pipe->irqlock, flags);
 
-	video->rwpf->ops->queue(video->rwpf, buf);
+	video->rwpf->ops->set_memory(video->rwpf, &buf->mem);
 	pipe->buffers_ready |= 1 << video->pipe_index;
 
 	if (vb2_is_streaming(&video->queue) &&
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index cbd44c336169..21096d82af05 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -20,7 +20,8 @@
 #include <media/media-entity.h>
 #include <media/videobuf2-v4l2.h>
 
-struct vsp1_rwpf;
+#include "vsp1_rwpf.h"
+
 struct vsp1_video;
 
 /*
@@ -97,9 +98,7 @@ static inline struct vsp1_pipeline *to_vsp1_pipeline(struct media_entity *e)
 struct vsp1_vb2_buffer {
 	struct vb2_v4l2_buffer buf;
 	struct list_head queue;
-
-	dma_addr_t addr[3];
-	unsigned int length[3];
+	struct vsp1_rwpf_memory mem;
 };
 
 static inline struct vsp1_vb2_buffer *
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index a4c0888a1b46..d2537b46fc46 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -195,17 +195,17 @@ static struct v4l2_subdev_ops wpf_ops = {
  * Video Device Operations
  */
 
-static void wpf_buf_queue(struct vsp1_rwpf *wpf, struct vsp1_vb2_buffer *buf)
+static void wpf_set_memory(struct vsp1_rwpf *wpf, struct vsp1_rwpf_memory *mem)
 {
-	vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_Y, buf->addr[0]);
-	if (buf->buf.vb2_buf.num_planes > 1)
-		vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C0, buf->addr[1]);
-	if (buf->buf.vb2_buf.num_planes > 2)
-		vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C1, buf->addr[2]);
+	vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_Y, mem->addr[0]);
+	if (mem->num_planes > 1)
+		vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C0, mem->addr[1]);
+	if (mem->num_planes > 2)
+		vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C1, mem->addr[2]);
 }
 
 static const struct vsp1_rwpf_operations wpf_vdev_ops = {
-	.queue = wpf_buf_queue,
+	.set_memory = wpf_set_memory,
 };
 
 /* -----------------------------------------------------------------------------
-- 
2.4.10


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

* [PATCH v2 07/32] v4l: vsp1: Support VSP1 instances without any UDS
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (5 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 06/32] v4l: vsp1: Make rwpf operations independent of video device Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 08/32] v4l: vsp1: Move vsp1_video pointer from vsp1_entity to vsp1_rwpf Laurent Pinchart
                   ` (25 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Not all VSP1 instances include a UDS. Make the renesas,#uds DT property
optional and accept a number of UDS equal to 0 as valid.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 Documentation/devicetree/bindings/media/renesas,vsp1.txt | 3 ++-
 drivers/media/platform/vsp1/vsp1_drv.c                   | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/renesas,vsp1.txt b/Documentation/devicetree/bindings/media/renesas,vsp1.txt
index 87fe08abf36d..674c8c30d046 100644
--- a/Documentation/devicetree/bindings/media/renesas,vsp1.txt
+++ b/Documentation/devicetree/bindings/media/renesas,vsp1.txt
@@ -13,12 +13,13 @@ Required properties:
   - clocks: A phandle + clock-specifier pair for the VSP1 functional clock.
 
   - renesas,#rpf: Number of Read Pixel Formatter (RPF) modules in the VSP1.
-  - renesas,#uds: Number of Up Down Scaler (UDS) modules in the VSP1.
   - renesas,#wpf: Number of Write Pixel Formatter (WPF) modules in the VSP1.
 
 
 Optional properties:
 
+  - renesas,#uds: Number of Up Down Scaler (UDS) modules in the VSP1. Defaults
+    to 0 if not present.
   - renesas,has-lif: Boolean, indicates that the LCD Interface (LIF) module is
     available.
   - renesas,has-lut: Boolean, indicates that the Look Up Table (LUT) module is
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index de0b80e8d048..5f93cbdcb0f1 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -513,7 +513,7 @@ static int vsp1_parse_dt(struct vsp1_device *vsp1)
 		return -EINVAL;
 	}
 
-	if (pdata->uds_count <= 0 || pdata->uds_count > VSP1_MAX_UDS) {
+	if (pdata->uds_count > VSP1_MAX_UDS) {
 		dev_err(vsp1->dev, "invalid number of UDS (%u)\n",
 			pdata->uds_count);
 		return -EINVAL;
-- 
2.4.10


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

* [PATCH v2 08/32] v4l: vsp1: Move vsp1_video pointer from vsp1_entity to vsp1_rwpf
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (6 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 07/32] v4l: vsp1: Support VSP1 instances without any UDS Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 09/32] v4l: vsp1: Remove struct vsp1_pipeline num_video field Laurent Pinchart
                   ` (24 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Only RPFs and WPFs can be associated with video nodes, don't waste
memory by storing the video pointer in all entities.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_drv.c    |  6 +++---
 drivers/media/platform/vsp1/vsp1_entity.h |  3 ---
 drivers/media/platform/vsp1/vsp1_rwpf.h   |  3 +++
 drivers/media/platform/vsp1/vsp1_video.c  | 10 +++++-----
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 5f93cbdcb0f1..91ecf75119ba 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -289,8 +289,8 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
 		struct vsp1_rwpf *rpf = vsp1->rpf[i];
 
-		ret = media_entity_create_link(&rpf->entity.video->video.entity,
-					       0, &rpf->entity.subdev.entity,
+		ret = media_entity_create_link(&rpf->video->video.entity, 0,
+					       &rpf->entity.subdev.entity,
 					       RWPF_PAD_SINK,
 					       MEDIA_LNK_FL_ENABLED |
 					       MEDIA_LNK_FL_IMMUTABLE);
@@ -311,7 +311,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 
 		ret = media_entity_create_link(&wpf->entity.subdev.entity,
 					       RWPF_PAD_SOURCE,
-					       &wpf->entity.video->video.entity,
+					       &wpf->video->video.entity,
 					       0, flags);
 		if (ret < 0)
 			goto done;
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index 8867a5787c28..9c95507ec762 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -19,7 +19,6 @@
 #include <media/v4l2-subdev.h>
 
 struct vsp1_device;
-struct vsp1_video;
 
 enum vsp1_entity_type {
 	VSP1_ENTITY_BRU,
@@ -71,8 +70,6 @@ struct vsp1_entity {
 	struct v4l2_subdev subdev;
 	struct v4l2_mbus_framefmt *formats;
 
-	struct vsp1_video *video;
-
 	spinlock_t lock;		/* Protects the streaming field */
 	bool streaming;
 };
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 0076920adb28..1a90c7c8e972 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -24,6 +24,7 @@
 #define RWPF_PAD_SOURCE				1
 
 struct vsp1_rwpf;
+struct vsp1_video;
 
 struct vsp1_rwpf_memory {
 	unsigned int num_planes;
@@ -40,6 +41,8 @@ struct vsp1_rwpf {
 	struct vsp1_entity entity;
 	struct v4l2_ctrl_handler ctrls;
 
+	struct vsp1_video *video;
+
 	const struct vsp1_rwpf_operations *ops;
 
 	unsigned int max_width;
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 0d600b8de6b1..8ffe54260725 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -435,11 +435,11 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 		if (e->type = VSP1_ENTITY_RPF) {
 			rwpf = to_rwpf(subdev);
 			pipe->inputs[pipe->num_inputs++] = rwpf;
-			rwpf->entity.video->pipe_index = pipe->num_inputs;
+			rwpf->video->pipe_index = pipe->num_inputs;
 		} else if (e->type = VSP1_ENTITY_WPF) {
 			rwpf = to_rwpf(subdev);
 			pipe->output = to_rwpf(subdev);
-			rwpf->entity.video->pipe_index = 0;
+			rwpf->video->pipe_index = 0;
 		} else if (e->type = VSP1_ENTITY_LIF) {
 			pipe->lif = e;
 		} else if (e->type = VSP1_ENTITY_BRU) {
@@ -649,10 +649,10 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
 
 	/* Complete buffers on all video nodes. */
 	for (i = 0; i < pipe->num_inputs; ++i)
-		vsp1_video_frame_end(pipe, pipe->inputs[i]->entity.video);
+		vsp1_video_frame_end(pipe, pipe->inputs[i]->video);
 
 	if (!pipe->lif)
-		vsp1_video_frame_end(pipe, pipe->output->entity.video);
+		vsp1_video_frame_end(pipe, pipe->output->video);
 
 	spin_lock_irqsave(&pipe->irqlock, flags);
 
@@ -1204,7 +1204,7 @@ struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1,
 	if (!video)
 		return ERR_PTR(-ENOMEM);
 
-	rwpf->entity.video = video;
+	rwpf->video = video;
 
 	video->vsp1 = vsp1;
 	video->rwpf = rwpf;
-- 
2.4.10


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

* [PATCH v2 09/32] v4l: vsp1: Remove struct vsp1_pipeline num_video field
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (7 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 08/32] v4l: vsp1: Move vsp1_video pointer from vsp1_entity to vsp1_rwpf Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 10/32] v4l: vsp1: Decouple pipeline end of frame processing from vsp1_video Laurent Pinchart
                   ` (23 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

The field is always equal to the num_inputs field plus one, remove the
duplicate.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_video.c | 7 ++-----
 drivers/media/platform/vsp1/vsp1_video.h | 1 -
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 8ffe54260725..e9c5682b0d74 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -396,7 +396,6 @@ static void __vsp1_pipeline_cleanup(struct vsp1_pipeline *pipe)
 	INIT_LIST_HEAD(&pipe->entities);
 	pipe->state = VSP1_PIPELINE_STOPPED;
 	pipe->buffers_ready = 0;
-	pipe->num_video = 0;
 	pipe->num_inputs = 0;
 	pipe->output = NULL;
 	pipe->bru = NULL;
@@ -423,10 +422,8 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 		struct vsp1_rwpf *rwpf;
 		struct vsp1_entity *e;
 
-		if (media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV) {
-			pipe->num_video++;
+		if (media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 			continue;
-		}
 
 		subdev = media_entity_to_v4l2_subdev(entity);
 		e = to_vsp1_entity(subdev);
@@ -894,7 +891,7 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)
 	int ret;
 
 	mutex_lock(&pipe->lock);
-	if (pipe->stream_count = pipe->num_video - 1) {
+	if (pipe->stream_count = pipe->num_inputs) {
 		if (pipe->uds) {
 			struct vsp1_uds *uds = to_uds(&pipe->uds->subdev);
 
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index 21096d82af05..e9d0e1ab9162 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -75,7 +75,6 @@ struct vsp1_pipeline {
 	unsigned int stream_count;
 	unsigned int buffers_ready;
 
-	unsigned int num_video;
 	unsigned int num_inputs;
 	struct vsp1_rwpf *inputs[VSP1_MAX_RPF];
 	struct vsp1_rwpf *output;
-- 
2.4.10


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

* [PATCH v2 10/32] v4l: vsp1: Decouple pipeline end of frame processing from vsp1_video
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (8 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 09/32] v4l: vsp1: Remove struct vsp1_pipeline num_video field Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 11/32] v4l: vsp1: Split pipeline management code from vsp1_video.c Laurent Pinchart
                   ` (22 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

To make the pipeline structure and operations usable without video
devices the frame end processing must be decoupled from struct
vsp1_video. Implement this by calling the video frame end function
indirectly through a function pointer in struct vsp1_pipeline.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_video.c | 25 +++++++++++++++++--------
 drivers/media/platform/vsp1/vsp1_video.h |  2 ++
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index e9c5682b0d74..8f9807e6a606 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -618,8 +618,9 @@ vsp1_video_complete_buffer(struct vsp1_video *video)
 }
 
 static void vsp1_video_frame_end(struct vsp1_pipeline *pipe,
-				 struct vsp1_video *video)
+				 struct vsp1_rwpf *rwpf)
 {
+	struct vsp1_video *video = rwpf->video;
 	struct vsp1_vb2_buffer *buf;
 	unsigned long flags;
 
@@ -635,21 +636,28 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe,
 	spin_unlock_irqrestore(&pipe->irqlock, flags);
 }
 
+static void vsp1_video_pipeline_frame_end(struct vsp1_pipeline *pipe)
+{
+	unsigned int i;
+
+	/* Complete buffers on all video nodes. */
+	for (i = 0; i < pipe->num_inputs; ++i)
+		vsp1_video_frame_end(pipe, pipe->inputs[i]);
+
+	if (!pipe->lif)
+		vsp1_video_frame_end(pipe, pipe->output);
+}
+
 void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
 {
 	enum vsp1_pipeline_state state;
 	unsigned long flags;
-	unsigned int i;
 
 	if (pipe = NULL)
 		return;
 
-	/* Complete buffers on all video nodes. */
-	for (i = 0; i < pipe->num_inputs; ++i)
-		vsp1_video_frame_end(pipe, pipe->inputs[i]->video);
-
-	if (!pipe->lif)
-		vsp1_video_frame_end(pipe, pipe->output->video);
+	/* Signal frame end to the pipeline handler. */
+	pipe->frame_end(pipe);
 
 	spin_lock_irqsave(&pipe->irqlock, flags);
 
@@ -1227,6 +1235,7 @@ struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1,
 	INIT_LIST_HEAD(&video->pipe.entities);
 	init_waitqueue_head(&video->pipe.wq);
 	video->pipe.state = VSP1_PIPELINE_STOPPED;
+	video->pipe.frame_end = vsp1_video_pipeline_frame_end;
 
 	/* Initialize the media entity... */
 	ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index e9d0e1ab9162..b79fdaa7ebdc 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -70,6 +70,8 @@ struct vsp1_pipeline {
 	enum vsp1_pipeline_state state;
 	wait_queue_head_t wq;
 
+	void (*frame_end)(struct vsp1_pipeline *pipe);
+
 	struct mutex lock;
 	unsigned int use_count;
 	unsigned int stream_count;
-- 
2.4.10


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

* [PATCH v2 11/32] v4l: vsp1: Split pipeline management code from vsp1_video.c
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (9 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 10/32] v4l: vsp1: Decouple pipeline end of frame processing from vsp1_video Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 12/32] v4l: vsp1: Rename video pipeline functions to use vsp1_video prefix Laurent Pinchart
                   ` (21 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

The code will be used to control the vsp1 driver from the DU driver
without using video nodes.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/Makefile     |   3 +-
 drivers/media/platform/vsp1/vsp1_pipe.c  | 247 +++++++++++++++++++++++++++++++
 drivers/media/platform/vsp1/vsp1_pipe.h  |  85 +++++++++++
 drivers/media/platform/vsp1/vsp1_video.c | 223 +---------------------------
 drivers/media/platform/vsp1/vsp1_video.h |  59 +-------
 5 files changed, 338 insertions(+), 279 deletions(-)
 create mode 100644 drivers/media/platform/vsp1/vsp1_pipe.c
 create mode 100644 drivers/media/platform/vsp1/vsp1_pipe.h

diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
index 6a93f928dfde..0ef0b5384125 100644
--- a/drivers/media/platform/vsp1/Makefile
+++ b/drivers/media/platform/vsp1/Makefile
@@ -1,4 +1,5 @@
-vsp1-y					:= vsp1_drv.o vsp1_entity.o vsp1_video.o
+vsp1-y					:= vsp1_drv.o vsp1_entity.o vsp1_pipe.o
+vsp1-y					+= vsp1_video.o
 vsp1-y					+= vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
 vsp1-y					+= vsp1_hsit.o vsp1_lif.o vsp1_lut.o
 vsp1-y					+= vsp1_bru.o vsp1_sru.o vsp1_uds.o
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
new file mode 100644
index 000000000000..199d57f1fe06
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -0,0 +1,247 @@
+/*
+ * vsp1_pipe.c  --  R-Car VSP1 Pipeline
+ *
+ * Copyright (C) 2013-2015 Renesas Electronics Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/list.h>
+#include <linux/wait.h>
+
+#include <media/media-entity.h>
+#include <media/v4l2-subdev.h>
+
+#include "vsp1.h"
+#include "vsp1_bru.h"
+#include "vsp1_entity.h"
+#include "vsp1_pipe.h"
+#include "vsp1_rwpf.h"
+#include "vsp1_uds.h"
+
+/* -----------------------------------------------------------------------------
+ * Pipeline Management
+ */
+
+void vsp1_pipeline_reset(struct vsp1_pipeline *pipe)
+{
+	if (pipe->bru) {
+		struct vsp1_bru *bru = to_bru(&pipe->bru->subdev);
+		unsigned int i;
+
+		for (i = 0; i < ARRAY_SIZE(bru->inputs); ++i)
+			bru->inputs[i].rpf = NULL;
+	}
+
+	INIT_LIST_HEAD(&pipe->entities);
+	pipe->state = VSP1_PIPELINE_STOPPED;
+	pipe->buffers_ready = 0;
+	pipe->num_inputs = 0;
+	pipe->output = NULL;
+	pipe->bru = NULL;
+	pipe->lif = NULL;
+	pipe->uds = NULL;
+}
+
+void vsp1_pipeline_run(struct vsp1_pipeline *pipe)
+{
+	struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
+
+	vsp1_write(vsp1, VI6_CMD(pipe->output->entity.index), VI6_CMD_STRCMD);
+	pipe->state = VSP1_PIPELINE_RUNNING;
+	pipe->buffers_ready = 0;
+}
+
+bool vsp1_pipeline_stopped(struct vsp1_pipeline *pipe)
+{
+	unsigned long flags;
+	bool stopped;
+
+	spin_lock_irqsave(&pipe->irqlock, flags);
+	stopped = pipe->state = VSP1_PIPELINE_STOPPED,
+	spin_unlock_irqrestore(&pipe->irqlock, flags);
+
+	return stopped;
+}
+
+int vsp1_pipeline_stop(struct vsp1_pipeline *pipe)
+{
+	struct vsp1_entity *entity;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&pipe->irqlock, flags);
+	if (pipe->state = VSP1_PIPELINE_RUNNING)
+		pipe->state = VSP1_PIPELINE_STOPPING;
+	spin_unlock_irqrestore(&pipe->irqlock, flags);
+
+	ret = wait_event_timeout(pipe->wq, vsp1_pipeline_stopped(pipe),
+				 msecs_to_jiffies(500));
+	ret = ret = 0 ? -ETIMEDOUT : 0;
+
+	list_for_each_entry(entity, &pipe->entities, list_pipe) {
+		if (entity->route && entity->route->reg)
+			vsp1_write(entity->vsp1, entity->route->reg,
+				   VI6_DPR_NODE_UNUSED);
+
+		v4l2_subdev_call(&entity->subdev, video, s_stream, 0);
+	}
+
+	return ret;
+}
+
+bool vsp1_pipeline_ready(struct vsp1_pipeline *pipe)
+{
+	unsigned int mask;
+
+	mask = ((1 << pipe->num_inputs) - 1) << 1;
+	if (!pipe->lif)
+		mask |= 1 << 0;
+
+	return pipe->buffers_ready = mask;
+}
+
+void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
+{
+	enum vsp1_pipeline_state state;
+	unsigned long flags;
+
+	if (pipe = NULL)
+		return;
+
+	/* Signal frame end to the pipeline handler. */
+	pipe->frame_end(pipe);
+
+	spin_lock_irqsave(&pipe->irqlock, flags);
+
+	state = pipe->state;
+	pipe->state = VSP1_PIPELINE_STOPPED;
+
+	/* If a stop has been requested, mark the pipeline as stopped and
+	 * return.
+	 */
+	if (state = VSP1_PIPELINE_STOPPING) {
+		wake_up(&pipe->wq);
+		goto done;
+	}
+
+	/* Restart the pipeline if ready. */
+	if (vsp1_pipeline_ready(pipe))
+		vsp1_pipeline_run(pipe);
+
+done:
+	spin_unlock_irqrestore(&pipe->irqlock, flags);
+}
+
+/*
+ * Propagate the alpha value through the pipeline.
+ *
+ * As the UDS has restricted scaling capabilities when the alpha component needs
+ * to be scaled, we disable alpha scaling when the UDS input has a fixed alpha
+ * value. The UDS then outputs a fixed alpha value which needs to be programmed
+ * from the input RPF alpha.
+ */
+void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
+				   struct vsp1_entity *input,
+				   unsigned int alpha)
+{
+	struct vsp1_entity *entity;
+	struct media_pad *pad;
+
+	pad = media_entity_remote_pad(&input->pads[RWPF_PAD_SOURCE]);
+
+	while (pad) {
+		if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+			break;
+
+		entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
+
+		/* The BRU background color has a fixed alpha value set to 255,
+		 * the output alpha value is thus always equal to 255.
+		 */
+		if (entity->type = VSP1_ENTITY_BRU)
+			alpha = 255;
+
+		if (entity->type = VSP1_ENTITY_UDS) {
+			struct vsp1_uds *uds = to_uds(&entity->subdev);
+
+			vsp1_uds_set_alpha(uds, alpha);
+			break;
+		}
+
+		pad = &entity->pads[entity->source_pad];
+		pad = media_entity_remote_pad(pad);
+	}
+}
+
+void vsp1_pipelines_suspend(struct vsp1_device *vsp1)
+{
+	unsigned long flags;
+	unsigned int i;
+	int ret;
+
+	/* To avoid increasing the system suspend time needlessly, loop over the
+	 * pipelines twice, first to set them all to the stopping state, and
+	 * then to wait for the stop to complete.
+	 */
+	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
+		struct vsp1_rwpf *wpf = vsp1->wpf[i];
+		struct vsp1_pipeline *pipe;
+
+		if (wpf = NULL)
+			continue;
+
+		pipe = to_vsp1_pipeline(&wpf->entity.subdev.entity);
+		if (pipe = NULL)
+			continue;
+
+		spin_lock_irqsave(&pipe->irqlock, flags);
+		if (pipe->state = VSP1_PIPELINE_RUNNING)
+			pipe->state = VSP1_PIPELINE_STOPPING;
+		spin_unlock_irqrestore(&pipe->irqlock, flags);
+	}
+
+	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
+		struct vsp1_rwpf *wpf = vsp1->wpf[i];
+		struct vsp1_pipeline *pipe;
+
+		if (wpf = NULL)
+			continue;
+
+		pipe = to_vsp1_pipeline(&wpf->entity.subdev.entity);
+		if (pipe = NULL)
+			continue;
+
+		ret = wait_event_timeout(pipe->wq, vsp1_pipeline_stopped(pipe),
+					 msecs_to_jiffies(500));
+		if (ret = 0)
+			dev_warn(vsp1->dev, "pipeline %u stop timeout\n",
+				 wpf->entity.index);
+	}
+}
+
+void vsp1_pipelines_resume(struct vsp1_device *vsp1)
+{
+	unsigned int i;
+
+	/* Resume pipeline all running pipelines. */
+	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
+		struct vsp1_rwpf *wpf = vsp1->wpf[i];
+		struct vsp1_pipeline *pipe;
+
+		if (wpf = NULL)
+			continue;
+
+		pipe = to_vsp1_pipeline(&wpf->entity.subdev.entity);
+		if (pipe = NULL)
+			continue;
+
+		if (vsp1_pipeline_ready(pipe))
+			vsp1_pipeline_run(pipe);
+	}
+}
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
new file mode 100644
index 000000000000..f8a099fba973
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -0,0 +1,85 @@
+/*
+ * vsp1_pipe.h  --  R-Car VSP1 Pipeline
+ *
+ * Copyright (C) 2013-2015 Renesas Electronics Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __VSP1_PIPE_H__
+#define __VSP1_PIPE_H__
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+
+#include <media/media-entity.h>
+
+struct vsp1_rwpf;
+
+enum vsp1_pipeline_state {
+	VSP1_PIPELINE_STOPPED,
+	VSP1_PIPELINE_RUNNING,
+	VSP1_PIPELINE_STOPPING,
+};
+
+/*
+ * struct vsp1_pipeline - A VSP1 hardware pipeline
+ * @media: the media pipeline
+ * @irqlock: protects the pipeline state
+ * @lock: protects the pipeline use count and stream count
+ */
+struct vsp1_pipeline {
+	struct media_pipeline pipe;
+
+	spinlock_t irqlock;
+	enum vsp1_pipeline_state state;
+	wait_queue_head_t wq;
+
+	void (*frame_end)(struct vsp1_pipeline *pipe);
+
+	struct mutex lock;
+	unsigned int use_count;
+	unsigned int stream_count;
+	unsigned int buffers_ready;
+
+	unsigned int num_inputs;
+	struct vsp1_rwpf *inputs[VSP1_MAX_RPF];
+	struct vsp1_rwpf *output;
+	struct vsp1_entity *bru;
+	struct vsp1_entity *lif;
+	struct vsp1_entity *uds;
+	struct vsp1_entity *uds_input;
+
+	struct list_head entities;
+};
+
+static inline struct vsp1_pipeline *to_vsp1_pipeline(struct media_entity *e)
+{
+	if (likely(e->pipe))
+		return container_of(e->pipe, struct vsp1_pipeline, pipe);
+	else
+		return NULL;
+}
+
+void vsp1_pipeline_reset(struct vsp1_pipeline *pipe);
+
+void vsp1_pipeline_run(struct vsp1_pipeline *pipe);
+bool vsp1_pipeline_stopped(struct vsp1_pipeline *pipe);
+int vsp1_pipeline_stop(struct vsp1_pipeline *pipe);
+bool vsp1_pipeline_ready(struct vsp1_pipeline *pipe);
+
+void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe);
+
+void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
+				   struct vsp1_entity *input,
+				   unsigned int alpha);
+
+void vsp1_pipelines_suspend(struct vsp1_device *vsp1);
+void vsp1_pipelines_resume(struct vsp1_device *vsp1);
+
+#endif /* __VSP1_PIPE_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 8f9807e6a606..6a55eba88dba 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -30,6 +30,7 @@
 #include "vsp1.h"
 #include "vsp1_bru.h"
 #include "vsp1_entity.h"
+#include "vsp1_pipe.h"
 #include "vsp1_rwpf.h"
 #include "vsp1_uds.h"
 #include "vsp1_video.h"
@@ -383,26 +384,6 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,
 	return 0;
 }
 
-static void __vsp1_pipeline_cleanup(struct vsp1_pipeline *pipe)
-{
-	if (pipe->bru) {
-		struct vsp1_bru *bru = to_bru(&pipe->bru->subdev);
-		unsigned int i;
-
-		for (i = 0; i < ARRAY_SIZE(bru->inputs); ++i)
-			bru->inputs[i].rpf = NULL;
-	}
-
-	INIT_LIST_HEAD(&pipe->entities);
-	pipe->state = VSP1_PIPELINE_STOPPED;
-	pipe->buffers_ready = 0;
-	pipe->num_inputs = 0;
-	pipe->output = NULL;
-	pipe->bru = NULL;
-	pipe->lif = NULL;
-	pipe->uds = NULL;
-}
-
 static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 				  struct vsp1_video *video)
 {
@@ -465,7 +446,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 	return 0;
 
 error:
-	__vsp1_pipeline_cleanup(pipe);
+	vsp1_pipeline_reset(pipe);
 	return ret;
 }
 
@@ -497,69 +478,11 @@ static void vsp1_pipeline_cleanup(struct vsp1_pipeline *pipe)
 
 	/* If we're the last user clean up the pipeline. */
 	if (--pipe->use_count = 0)
-		__vsp1_pipeline_cleanup(pipe);
+		vsp1_pipeline_reset(pipe);
 
 	mutex_unlock(&pipe->lock);
 }
 
-static void vsp1_pipeline_run(struct vsp1_pipeline *pipe)
-{
-	struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
-
-	vsp1_write(vsp1, VI6_CMD(pipe->output->entity.index), VI6_CMD_STRCMD);
-	pipe->state = VSP1_PIPELINE_RUNNING;
-	pipe->buffers_ready = 0;
-}
-
-static bool vsp1_pipeline_stopped(struct vsp1_pipeline *pipe)
-{
-	unsigned long flags;
-	bool stopped;
-
-	spin_lock_irqsave(&pipe->irqlock, flags);
-	stopped = pipe->state = VSP1_PIPELINE_STOPPED,
-	spin_unlock_irqrestore(&pipe->irqlock, flags);
-
-	return stopped;
-}
-
-static int vsp1_pipeline_stop(struct vsp1_pipeline *pipe)
-{
-	struct vsp1_entity *entity;
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&pipe->irqlock, flags);
-	if (pipe->state = VSP1_PIPELINE_RUNNING)
-		pipe->state = VSP1_PIPELINE_STOPPING;
-	spin_unlock_irqrestore(&pipe->irqlock, flags);
-
-	ret = wait_event_timeout(pipe->wq, vsp1_pipeline_stopped(pipe),
-				 msecs_to_jiffies(500));
-	ret = ret = 0 ? -ETIMEDOUT : 0;
-
-	list_for_each_entry(entity, &pipe->entities, list_pipe) {
-		if (entity->route && entity->route->reg)
-			vsp1_write(entity->vsp1, entity->route->reg,
-				   VI6_DPR_NODE_UNUSED);
-
-		v4l2_subdev_call(&entity->subdev, video, s_stream, 0);
-	}
-
-	return ret;
-}
-
-static bool vsp1_pipeline_ready(struct vsp1_pipeline *pipe)
-{
-	unsigned int mask;
-
-	mask = ((1 << pipe->num_inputs) - 1) << 1;
-	if (!pipe->lif)
-		mask |= 1 << 0;
-
-	return pipe->buffers_ready = mask;
-}
-
 /*
  * vsp1_video_complete_buffer - Complete the current buffer
  * @video: the video node
@@ -648,146 +571,6 @@ static void vsp1_video_pipeline_frame_end(struct vsp1_pipeline *pipe)
 		vsp1_video_frame_end(pipe, pipe->output);
 }
 
-void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
-{
-	enum vsp1_pipeline_state state;
-	unsigned long flags;
-
-	if (pipe = NULL)
-		return;
-
-	/* Signal frame end to the pipeline handler. */
-	pipe->frame_end(pipe);
-
-	spin_lock_irqsave(&pipe->irqlock, flags);
-
-	state = pipe->state;
-	pipe->state = VSP1_PIPELINE_STOPPED;
-
-	/* If a stop has been requested, mark the pipeline as stopped and
-	 * return.
-	 */
-	if (state = VSP1_PIPELINE_STOPPING) {
-		wake_up(&pipe->wq);
-		goto done;
-	}
-
-	/* Restart the pipeline if ready. */
-	if (vsp1_pipeline_ready(pipe))
-		vsp1_pipeline_run(pipe);
-
-done:
-	spin_unlock_irqrestore(&pipe->irqlock, flags);
-}
-
-/*
- * Propagate the alpha value through the pipeline.
- *
- * As the UDS has restricted scaling capabilities when the alpha component needs
- * to be scaled, we disable alpha scaling when the UDS input has a fixed alpha
- * value. The UDS then outputs a fixed alpha value which needs to be programmed
- * from the input RPF alpha.
- */
-void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
-				   struct vsp1_entity *input,
-				   unsigned int alpha)
-{
-	struct vsp1_entity *entity;
-	struct media_pad *pad;
-
-	pad = media_entity_remote_pad(&input->pads[RWPF_PAD_SOURCE]);
-
-	while (pad) {
-		if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
-			break;
-
-		entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
-
-		/* The BRU background color has a fixed alpha value set to 255,
-		 * the output alpha value is thus always equal to 255.
-		 */
-		if (entity->type = VSP1_ENTITY_BRU)
-			alpha = 255;
-
-		if (entity->type = VSP1_ENTITY_UDS) {
-			struct vsp1_uds *uds = to_uds(&entity->subdev);
-
-			vsp1_uds_set_alpha(uds, alpha);
-			break;
-		}
-
-		pad = &entity->pads[entity->source_pad];
-		pad = media_entity_remote_pad(pad);
-	}
-}
-
-void vsp1_pipelines_suspend(struct vsp1_device *vsp1)
-{
-	unsigned long flags;
-	unsigned int i;
-	int ret;
-
-	/* To avoid increasing the system suspend time needlessly, loop over the
-	 * pipelines twice, first to set them all to the stopping state, and then
-	 * to wait for the stop to complete.
-	 */
-	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
-		struct vsp1_rwpf *wpf = vsp1->wpf[i];
-		struct vsp1_pipeline *pipe;
-
-		if (wpf = NULL)
-			continue;
-
-		pipe = to_vsp1_pipeline(&wpf->entity.subdev.entity);
-		if (pipe = NULL)
-			continue;
-
-		spin_lock_irqsave(&pipe->irqlock, flags);
-		if (pipe->state = VSP1_PIPELINE_RUNNING)
-			pipe->state = VSP1_PIPELINE_STOPPING;
-		spin_unlock_irqrestore(&pipe->irqlock, flags);
-	}
-
-	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
-		struct vsp1_rwpf *wpf = vsp1->wpf[i];
-		struct vsp1_pipeline *pipe;
-
-		if (wpf = NULL)
-			continue;
-
-		pipe = to_vsp1_pipeline(&wpf->entity.subdev.entity);
-		if (pipe = NULL)
-			continue;
-
-		ret = wait_event_timeout(pipe->wq, vsp1_pipeline_stopped(pipe),
-					 msecs_to_jiffies(500));
-		if (ret = 0)
-			dev_warn(vsp1->dev, "pipeline %u stop timeout\n",
-				 wpf->entity.index);
-	}
-}
-
-void vsp1_pipelines_resume(struct vsp1_device *vsp1)
-{
-	unsigned int i;
-
-	/* Resume pipeline all running pipelines. */
-	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
-		struct vsp1_rwpf *wpf = vsp1->wpf[i];
-		struct vsp1_pipeline *pipe;
-
-		if (wpf = NULL)
-			continue;
-
-		pipe = to_vsp1_pipeline(&wpf->entity.subdev.entity);
-		if (pipe = NULL)
-			continue;
-
-		if (vsp1_pipeline_ready(pipe))
-			vsp1_pipeline_run(pipe);
-	}
-}
-
 /* -----------------------------------------------------------------------------
  * videobuf2 Queue Operations
  */
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index b79fdaa7ebdc..faccb2aede5c 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -15,15 +15,12 @@
 
 #include <linux/list.h>
 #include <linux/spinlock.h>
-#include <linux/wait.h>
 
-#include <media/media-entity.h>
 #include <media/videobuf2-v4l2.h>
 
+#include "vsp1_pipe.h"
 #include "vsp1_rwpf.h"
 
-struct vsp1_video;
-
 /*
  * struct vsp1_format_info - VSP1 video format description
  * @mbus: media bus format code
@@ -51,51 +48,6 @@ struct vsp1_format_info {
 	bool alpha;
 };
 
-enum vsp1_pipeline_state {
-	VSP1_PIPELINE_STOPPED,
-	VSP1_PIPELINE_RUNNING,
-	VSP1_PIPELINE_STOPPING,
-};
-
-/*
- * struct vsp1_pipeline - A VSP1 hardware pipeline
- * @media: the media pipeline
- * @irqlock: protects the pipeline state
- * @lock: protects the pipeline use count and stream count
- */
-struct vsp1_pipeline {
-	struct media_pipeline pipe;
-
-	spinlock_t irqlock;
-	enum vsp1_pipeline_state state;
-	wait_queue_head_t wq;
-
-	void (*frame_end)(struct vsp1_pipeline *pipe);
-
-	struct mutex lock;
-	unsigned int use_count;
-	unsigned int stream_count;
-	unsigned int buffers_ready;
-
-	unsigned int num_inputs;
-	struct vsp1_rwpf *inputs[VSP1_MAX_RPF];
-	struct vsp1_rwpf *output;
-	struct vsp1_entity *bru;
-	struct vsp1_entity *lif;
-	struct vsp1_entity *uds;
-	struct vsp1_entity *uds_input;
-
-	struct list_head entities;
-};
-
-static inline struct vsp1_pipeline *to_vsp1_pipeline(struct media_entity *e)
-{
-	if (likely(e->pipe))
-		return container_of(e->pipe, struct vsp1_pipeline, pipe);
-	else
-		return NULL;
-}
-
 struct vsp1_vb2_buffer {
 	struct vb2_v4l2_buffer buf;
 	struct list_head queue;
@@ -138,13 +90,4 @@ struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1,
 				     struct vsp1_rwpf *rwpf);
 void vsp1_video_cleanup(struct vsp1_video *video);
 
-void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe);
-
-void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
-				   struct vsp1_entity *input,
-				   unsigned int alpha);
-
-void vsp1_pipelines_suspend(struct vsp1_device *vsp1);
-void vsp1_pipelines_resume(struct vsp1_device *vsp1);
-
 #endif /* __VSP1_VIDEO_H__ */
-- 
2.4.10


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

* [PATCH v2 12/32] v4l: vsp1: Rename video pipeline functions to use vsp1_video prefix
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (10 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 11/32] v4l: vsp1: Split pipeline management code from vsp1_video.c Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 13/32] v4l: vsp1: Extract pipeline initialization code into a function Laurent Pinchart
                   ` (20 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Those functions are specific to video nodes, rename them for
consistency.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_video.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 6a55eba88dba..cd4c2481e4ec 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -308,9 +308,9 @@ vsp1_video_format_adjust(struct vsp1_video *video,
  * Pipeline Management
  */
 
-static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,
-					 struct vsp1_rwpf *input,
-					 struct vsp1_rwpf *output)
+static int vsp1_video_pipeline_validate_branch(struct vsp1_pipeline *pipe,
+					       struct vsp1_rwpf *input,
+					       struct vsp1_rwpf *output)
 {
 	struct vsp1_entity *entity;
 	unsigned int entities = 0;
@@ -384,8 +384,8 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,
 	return 0;
 }
 
-static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
-				  struct vsp1_video *video)
+static int vsp1_video_pipeline_validate(struct vsp1_pipeline *pipe,
+					struct vsp1_video *video)
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
@@ -437,8 +437,8 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 	 * contains no loop and that all branches end at the output WPF.
 	 */
 	for (i = 0; i < pipe->num_inputs; ++i) {
-		ret = vsp1_pipeline_validate_branch(pipe, pipe->inputs[i],
-						    pipe->output);
+		ret = vsp1_video_pipeline_validate_branch(pipe, pipe->inputs[i],
+							  pipe->output);
 		if (ret < 0)
 			goto error;
 	}
@@ -450,8 +450,8 @@ error:
 	return ret;
 }
 
-static int vsp1_pipeline_init(struct vsp1_pipeline *pipe,
-			      struct vsp1_video *video)
+static int vsp1_video_pipeline_init(struct vsp1_pipeline *pipe,
+				    struct vsp1_video *video)
 {
 	int ret;
 
@@ -459,7 +459,7 @@ static int vsp1_pipeline_init(struct vsp1_pipeline *pipe,
 
 	/* If we're the first user validate and initialize the pipeline. */
 	if (pipe->use_count = 0) {
-		ret = vsp1_pipeline_validate(pipe, video);
+		ret = vsp1_video_pipeline_validate(pipe, video);
 		if (ret < 0)
 			goto done;
 	}
@@ -472,7 +472,7 @@ done:
 	return ret;
 }
 
-static void vsp1_pipeline_cleanup(struct vsp1_pipeline *pipe)
+static void vsp1_video_pipeline_cleanup(struct vsp1_pipeline *pipe)
 {
 	mutex_lock(&pipe->lock);
 
@@ -742,7 +742,7 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq)
 	}
 	mutex_unlock(&pipe->lock);
 
-	vsp1_pipeline_cleanup(pipe);
+	vsp1_video_pipeline_cleanup(pipe);
 	media_entity_pipeline_stop(&video->video.entity);
 
 	/* Remove all buffers from the IRQ queue. */
@@ -883,7 +883,7 @@ vsp1_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	if (ret < 0)
 		goto err_stop;
 
-	ret = vsp1_pipeline_init(pipe, video);
+	ret = vsp1_video_pipeline_init(pipe, video);
 	if (ret < 0)
 		goto err_stop;
 
@@ -895,7 +895,7 @@ vsp1_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	return 0;
 
 err_cleanup:
-	vsp1_pipeline_cleanup(pipe);
+	vsp1_video_pipeline_cleanup(pipe);
 err_stop:
 	media_entity_pipeline_stop(&video->video.entity);
 	return ret;
-- 
2.4.10


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

* [PATCH v2 13/32] v4l: vsp1: Extract pipeline initialization code into a function
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (11 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 12/32] v4l: vsp1: Rename video pipeline functions to use vsp1_video prefix Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 14/32] v4l: vsp1: Reuse local variable instead of recomputing it Laurent Pinchart
                   ` (19 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

The code will be reused outside of vsp1_video.c.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_pipe.c  | 10 ++++++++++
 drivers/media/platform/vsp1/vsp1_pipe.h  |  1 +
 drivers/media/platform/vsp1/vsp1_video.c |  6 +-----
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
index 199d57f1fe06..524420ed6333 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -48,6 +48,16 @@ void vsp1_pipeline_reset(struct vsp1_pipeline *pipe)
 	pipe->uds = NULL;
 }
 
+void vsp1_pipeline_init(struct vsp1_pipeline *pipe)
+{
+	mutex_init(&pipe->lock);
+	spin_lock_init(&pipe->irqlock);
+	init_waitqueue_head(&pipe->wq);
+
+	INIT_LIST_HEAD(&pipe->entities);
+	pipe->state = VSP1_PIPELINE_STOPPED;
+}
+
 void vsp1_pipeline_run(struct vsp1_pipeline *pipe)
 {
 	struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index f8a099fba973..8553d5a03aa3 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -67,6 +67,7 @@ static inline struct vsp1_pipeline *to_vsp1_pipeline(struct media_entity *e)
 }
 
 void vsp1_pipeline_reset(struct vsp1_pipeline *pipe);
+void vsp1_pipeline_init(struct vsp1_pipeline *pipe);
 
 void vsp1_pipeline_run(struct vsp1_pipeline *pipe);
 bool vsp1_pipeline_stopped(struct vsp1_pipeline *pipe);
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index cd4c2481e4ec..b82ff1a0371b 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -1013,11 +1013,7 @@ struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1,
 	spin_lock_init(&video->irqlock);
 	INIT_LIST_HEAD(&video->irqqueue);
 
-	mutex_init(&video->pipe.lock);
-	spin_lock_init(&video->pipe.irqlock);
-	INIT_LIST_HEAD(&video->pipe.entities);
-	init_waitqueue_head(&video->pipe.wq);
-	video->pipe.state = VSP1_PIPELINE_STOPPED;
+	vsp1_pipeline_init(&video->pipe);
 	video->pipe.frame_end = vsp1_video_pipeline_frame_end;
 
 	/* Initialize the media entity... */
-- 
2.4.10


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

* [PATCH v2 14/32] v4l: vsp1: Reuse local variable instead of recomputing it
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (12 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 13/32] v4l: vsp1: Extract pipeline initialization code into a function Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 15/32] v4l: vsp1: Extract link creation to separate function Laurent Pinchart
                   ` (18 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

No need to waste CPU cycles when the value we need is already available.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_video.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index b82ff1a0371b..c958ba6a20ce 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -416,7 +416,7 @@ static int vsp1_video_pipeline_validate(struct vsp1_pipeline *pipe,
 			rwpf->video->pipe_index = pipe->num_inputs;
 		} else if (e->type = VSP1_ENTITY_WPF) {
 			rwpf = to_rwpf(subdev);
-			pipe->output = to_rwpf(subdev);
+			pipe->output = rwpf;
 			rwpf->video->pipe_index = 0;
 		} else if (e->type = VSP1_ENTITY_LIF) {
 			pipe->lif = e;
-- 
2.4.10


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

* [PATCH v2 15/32] v4l: vsp1: Extract link creation to separate function
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (13 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 14/32] v4l: vsp1: Reuse local variable instead of recomputing it Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 16/32] v4l: vsp1: Document the vsp1_pipeline structure Laurent Pinchart
                   ` (17 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Link creation will be handled differently for the DU pipeline.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_drv.c | 114 ++++++++++++++++++---------------
 1 file changed, 64 insertions(+), 50 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 91ecf75119ba..d1e42260a871 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -67,7 +67,7 @@ static irqreturn_t vsp1_irq_handler(int irq, void *data)
  */
 
 /*
- * vsp1_create_links - Create links from all sources to the given sink
+ * vsp1_create_sink_links - Create links from all sources to the given sink
  *
  * This function creates media links from all valid sources to the given sink
  * pad. Links that would be invalid according to the VSP1 hardware capabilities
@@ -76,7 +76,8 @@ static irqreturn_t vsp1_irq_handler(int irq, void *data)
  * - from a UDS to a UDS (UDS entities can't be chained)
  * - from an entity to itself (no loops are allowed)
  */
-static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink)
+static int vsp1_create_sink_links(struct vsp1_device *vsp1,
+				  struct vsp1_entity *sink)
 {
 	struct media_entity *entity = &sink->subdev.entity;
 	struct vsp1_entity *source;
@@ -116,6 +117,64 @@ static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink)
 	return 0;
 }
 
+static int vsp1_create_links(struct vsp1_device *vsp1)
+{
+	struct vsp1_entity *entity;
+	unsigned int i;
+	int ret;
+
+	list_for_each_entry(entity, &vsp1->entities, list_dev) {
+		if (entity->type = VSP1_ENTITY_LIF ||
+		    entity->type = VSP1_ENTITY_RPF)
+			continue;
+
+		ret = vsp1_create_sink_links(vsp1, entity);
+		if (ret < 0)
+			return ret;
+	}
+
+	for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
+		struct vsp1_rwpf *rpf = vsp1->rpf[i];
+
+		ret = media_entity_create_link(&rpf->video->video.entity, 0,
+					       &rpf->entity.subdev.entity,
+					       RWPF_PAD_SINK,
+					       MEDIA_LNK_FL_ENABLED |
+					       MEDIA_LNK_FL_IMMUTABLE);
+		if (ret < 0)
+			return ret;
+	}
+
+	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
+		/* Connect the video device to the WPF. All connections are
+		 * immutable except for the WPF0 source link if a LIF is
+		 * present.
+		 */
+		struct vsp1_rwpf *wpf = vsp1->wpf[i];
+		unsigned int flags = MEDIA_LNK_FL_ENABLED;
+
+		if (!(vsp1->pdata.features & VSP1_HAS_LIF) || i != 0)
+			flags |= MEDIA_LNK_FL_IMMUTABLE;
+
+		ret = media_entity_create_link(&wpf->entity.subdev.entity,
+					       RWPF_PAD_SOURCE,
+					       &wpf->video->video.entity,
+					       0, flags);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (vsp1->pdata.features & VSP1_HAS_LIF) {
+		ret = media_entity_create_link(
+			&vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
+			&vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
 static void vsp1_destroy_entities(struct vsp1_device *vsp1)
 {
 	struct vsp1_entity *entity, *_entity;
@@ -276,54 +335,9 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	/* Create links. */
-	list_for_each_entry(entity, &vsp1->entities, list_dev) {
-		if (entity->type = VSP1_ENTITY_LIF ||
-		    entity->type = VSP1_ENTITY_RPF)
-			continue;
-
-		ret = vsp1_create_links(vsp1, entity);
-		if (ret < 0)
-			goto done;
-	}
-
-	for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
-		struct vsp1_rwpf *rpf = vsp1->rpf[i];
-
-		ret = media_entity_create_link(&rpf->video->video.entity, 0,
-					       &rpf->entity.subdev.entity,
-					       RWPF_PAD_SINK,
-					       MEDIA_LNK_FL_ENABLED |
-					       MEDIA_LNK_FL_IMMUTABLE);
-		if (ret < 0)
-			goto done;
-	}
-
-	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
-		/* Connect the video device to the WPF. All connections are
-		 * immutable except for the WPF0 source link if a LIF is
-		 * present.
-		 */
-		struct vsp1_rwpf *wpf = vsp1->wpf[i];
-		unsigned int flags = MEDIA_LNK_FL_ENABLED;
-
-		if (!(vsp1->pdata.features & VSP1_HAS_LIF) || i != 0)
-			flags |= MEDIA_LNK_FL_IMMUTABLE;
-
-		ret = media_entity_create_link(&wpf->entity.subdev.entity,
-					       RWPF_PAD_SOURCE,
-					       &wpf->video->video.entity,
-					       0, flags);
-		if (ret < 0)
-			goto done;
-	}
-
-	if (vsp1->pdata.features & VSP1_HAS_LIF) {
-		ret = media_entity_create_link(
-			&vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
-			&vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0);
-		if (ret < 0)
-			return ret;
-	}
+	ret = vsp1_create_links(vsp1);
+	if (ret < 0)
+		goto done;
 
 	/* Register all subdevs. */
 	list_for_each_entry(entity, &vsp1->entities, list_dev) {
-- 
2.4.10


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

* [PATCH v2 16/32] v4l: vsp1: Document the vsp1_pipeline structure
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (14 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 15/32] v4l: vsp1: Extract link creation to separate function Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 17/32] v4l: vsp1: Fix typo in VI6_DISP_IRQ_STA_DST register name Laurent Pinchart
                   ` (16 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_pipe.h | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index 8553d5a03aa3..9c8ded1c29f6 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -29,9 +29,23 @@ enum vsp1_pipeline_state {
 
 /*
  * struct vsp1_pipeline - A VSP1 hardware pipeline
- * @media: the media pipeline
+ * @pipe: the media pipeline
  * @irqlock: protects the pipeline state
+ * @state: current state
+ * @wq: work queue to wait for state change completion
+ * @frame_end: frame end interrupt handler
  * @lock: protects the pipeline use count and stream count
+ * @use_count: number of video nodes using the pipeline
+ * @stream_count: number of streaming video nodes
+ * @buffers_ready: bitmask of RPFs and WPFs with at least one buffer available
+ * @num_inputs: number of RPFs
+ * @inputs: array of RPFs in the pipeline
+ * @output: WPF at the output of the pipeline
+ * @bru: BRU entity, if present
+ * @lif: LIF entity, if present
+ * @uds: UDS entity, if present
+ * @uds_input: entity at the input of the UDS, if the UDS is present
+ * @entities: list of entities in the pipeline
  */
 struct vsp1_pipeline {
 	struct media_pipeline pipe;
-- 
2.4.10


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

* [PATCH v2 17/32] v4l: vsp1: Fix typo in VI6_DISP_IRQ_STA_DST register name
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (15 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 16/32] v4l: vsp1: Document the vsp1_pipeline structure Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05 21:47   ` Sergei Shtylyov
  2015-12-05  2:12 ` [PATCH v2 18/32] v4l: vsp1: Set the SRU CTRL0 register when starting the stream Laurent Pinchart
                   ` (15 subsequent siblings)
  32 siblings, 1 reply; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Rename the VI6_DISP_IRQ_STA_DSE register to VI6_DISP_IRQ_STA_DST to fix
a typo and match the datasheet.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_regs.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 25b48738b147..8173ceaab9f9 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -46,7 +46,7 @@
 #define VI6_DISP_IRQ_ENB_LNEE(n)	(1 << (n))
 
 #define VI6_DISP_IRQ_STA		0x007c
-#define VI6_DISP_IRQ_STA_DSE		(1 << 8)
+#define VI6_DISP_IRQ_STA_DST		(1 << 8)
 #define VI6_DISP_IRQ_STA_MAE		(1 << 5)
 #define VI6_DISP_IRQ_STA_LNE(n)		(1 << (n))
 
-- 
2.4.10


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

* [PATCH v2 18/32] v4l: vsp1: Set the SRU CTRL0 register when starting the stream
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (16 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 17/32] v4l: vsp1: Fix typo in VI6_DISP_IRQ_STA_DST register name Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 19/32] v4l: vsp1: Remove unused module read functions Laurent Pinchart
                   ` (14 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Commit 58f896d859ce ("[media] v4l: vsp1: sru: Make the intensity
controllable during streaming") refactored the stream start code and
removed the SRU CTRL0 register write by mistake. Add it back.

Fixes: 58f896d859ce ("[media] v4l: vsp1: sru: Make the intensity controllable during streaming")
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_sru.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index 6310acab60e7..d41ae950d1a1 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -154,6 +154,7 @@ static int sru_s_stream(struct v4l2_subdev *subdev, int enable)
 	mutex_lock(sru->ctrls.lock);
 	ctrl0 |= vsp1_sru_read(sru, VI6_SRU_CTRL0)
 	       & (VI6_SRU_CTRL0_PARAM0_MASK | VI6_SRU_CTRL0_PARAM1_MASK);
+	vsp1_sru_write(sru, VI6_SRU_CTRL0, ctrl0);
 	mutex_unlock(sru->ctrls.lock);
 
 	vsp1_sru_write(sru, VI6_SRU_CTRL1, VI6_SRU_CTRL1_PARAM5);
-- 
2.4.10


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

* [PATCH v2 19/32] v4l: vsp1: Remove unused module read functions
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (17 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 18/32] v4l: vsp1: Set the SRU CTRL0 register when starting the stream Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 20/32] v4l: vsp1: Move entity route setup function to vsp1_entity.c Laurent Pinchart
                   ` (13 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Several module read functions are not used, remove them.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_bru.c | 5 -----
 drivers/media/platform/vsp1/vsp1_lif.c | 5 -----
 drivers/media/platform/vsp1/vsp1_lut.c | 5 -----
 drivers/media/platform/vsp1/vsp1_rpf.c | 6 ------
 drivers/media/platform/vsp1/vsp1_uds.c | 6 ------
 5 files changed, 27 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index b4cc9bc478af..841bc6664bca 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -28,11 +28,6 @@
  * Device Access
  */
 
-static inline u32 vsp1_bru_read(struct vsp1_bru *bru, u32 reg)
-{
-	return vsp1_read(bru->entity.vsp1, reg);
-}
-
 static inline void vsp1_bru_write(struct vsp1_bru *bru, u32 reg, u32 data)
 {
 	vsp1_write(bru->entity.vsp1, reg, data);
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index 39fa5ef20fbb..b868bce08982 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -26,11 +26,6 @@
  * Device Access
  */
 
-static inline u32 vsp1_lif_read(struct vsp1_lif *lif, u32 reg)
-{
-	return vsp1_read(lif->entity.vsp1, reg);
-}
-
 static inline void vsp1_lif_write(struct vsp1_lif *lif, u32 reg, u32 data)
 {
 	vsp1_write(lif->entity.vsp1, reg, data);
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
index 656ec272a414..9e33caa9c616 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.c
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -27,11 +27,6 @@
  * Device Access
  */
 
-static inline u32 vsp1_lut_read(struct vsp1_lut *lut, u32 reg)
-{
-	return vsp1_read(lut->entity.vsp1, reg);
-}
-
 static inline void vsp1_lut_write(struct vsp1_lut *lut, u32 reg, u32 data)
 {
 	vsp1_write(lut->entity.vsp1, reg, data);
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index c0b7f76cd0b5..b9c39f9e4458 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -26,12 +26,6 @@
  * Device Access
  */
 
-static inline u32 vsp1_rpf_read(struct vsp1_rwpf *rpf, u32 reg)
-{
-	return vsp1_read(rpf->entity.vsp1,
-			 reg + rpf->entity.index * VI6_RPF_OFFSET);
-}
-
 static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf, u32 reg, u32 data)
 {
 	vsp1_write(rpf->entity.vsp1,
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
index ccc8243e3493..27ad07466ebd 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/vsp1/vsp1_uds.c
@@ -29,12 +29,6 @@
  * Device Access
  */
 
-static inline u32 vsp1_uds_read(struct vsp1_uds *uds, u32 reg)
-{
-	return vsp1_read(uds->entity.vsp1,
-			 reg + uds->entity.index * VI6_UDS_OFFSET);
-}
-
 static inline void vsp1_uds_write(struct vsp1_uds *uds, u32 reg, u32 data)
 {
 	vsp1_write(uds->entity.vsp1,
-- 
2.4.10


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

* [PATCH v2 20/32] v4l: vsp1: Move entity route setup function to vsp1_entity.c
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (18 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 19/32] v4l: vsp1: Remove unused module read functions Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 21/32] v4l: vsp1: Make number of BRU inputs configurable Laurent Pinchart
                   ` (12 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

The function will be used by the DU code, move it out of vsp1_video.c.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_entity.c | 12 ++++++++++++
 drivers/media/platform/vsp1/vsp1_entity.h |  2 ++
 drivers/media/platform/vsp1/vsp1_video.c  | 12 ------------
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 0c52e4b71a98..cb9d480d8ee5 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -58,6 +58,18 @@ int vsp1_entity_set_streaming(struct vsp1_entity *entity, bool streaming)
 	return ret;
 }
 
+void vsp1_entity_route_setup(struct vsp1_entity *source)
+{
+	struct vsp1_entity *sink;
+
+	if (source->route->reg = 0)
+		return;
+
+	sink = container_of(source->sink, struct vsp1_entity, subdev.entity);
+	vsp1_write(source->vsp1, source->route->reg,
+		   sink->route->inputs[source->sink_pad]);
+}
+
 /* -----------------------------------------------------------------------------
  * V4L2 Subdevice Operations
  */
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index 9c95507ec762..9606d0d21263 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -96,4 +96,6 @@ void vsp1_entity_init_formats(struct v4l2_subdev *subdev,
 bool vsp1_entity_is_streaming(struct vsp1_entity *entity);
 int vsp1_entity_set_streaming(struct vsp1_entity *entity, bool streaming);
 
+void vsp1_entity_route_setup(struct vsp1_entity *source);
+
 #endif /* __VSP1_ENTITY_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index c958ba6a20ce..a9b7bafc5fa2 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -661,18 +661,6 @@ static void vsp1_video_buffer_queue(struct vb2_buffer *vb)
 	spin_unlock_irqrestore(&pipe->irqlock, flags);
 }
 
-static void vsp1_entity_route_setup(struct vsp1_entity *source)
-{
-	struct vsp1_entity *sink;
-
-	if (source->route->reg = 0)
-		return;
-
-	sink = container_of(source->sink, struct vsp1_entity, subdev.entity);
-	vsp1_write(source->vsp1, source->route->reg,
-		   sink->route->inputs[source->sink_pad]);
-}
-
 static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
 	struct vsp1_video *video = vb2_get_drv_priv(vq);
-- 
2.4.10


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

* [PATCH v2 21/32] v4l: vsp1: Make number of BRU inputs configurable
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (19 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 20/32] v4l: vsp1: Move entity route setup function to vsp1_entity.c Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 22/32] v4l: vsp1: Make the BRU optional Laurent Pinchart
                   ` (11 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

The R-Car Gen3 family has 5-inputs BRUs, support them by making the
number of BRU inputs configurable.

As the driver assumes that the number of BRU inputs is equal to the
number of RPFs, replace the BRU_MAX_INPUTS macro with VSP1_MAX_RPF to
make the assumption apparent.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

---

Changes since v1:

- Store the number of BRU inputs in the vsp1_platform_data structure

---
 drivers/media/platform/vsp1/vsp1.h        |  1 +
 drivers/media/platform/vsp1/vsp1_bru.c    | 19 ++++++++++---------
 drivers/media/platform/vsp1/vsp1_bru.h    |  3 +--
 drivers/media/platform/vsp1/vsp1_drv.c    |  3 +++
 drivers/media/platform/vsp1/vsp1_entity.h |  4 +++-
 5 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index b25032bd37a7..29a8fd94a0aa 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -48,6 +48,7 @@ struct vsp1_platform_data {
 	unsigned int rpf_count;
 	unsigned int uds_count;
 	unsigned int wpf_count;
+	unsigned int num_bru_inputs;
 };
 
 struct vsp1_device {
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index 841bc6664bca..baebfbbef61d 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -79,7 +79,7 @@ static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
 	if (!enable)
 		return 0;
 
-	format = &bru->entity.formats[BRU_PAD_SOURCE];
+	format = &bru->entity.formats[bru->entity.source_pad];
 
 	/* The hardware is extremely flexible but we have no userspace API to
 	 * expose all the parameters, nor is it clear whether we would have use
@@ -109,7 +109,7 @@ static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
 		       VI6_BRU_ROP_CROP(VI6_ROP_NOP) |
 		       VI6_BRU_ROP_AROP(VI6_ROP_NOP));
 
-	for (i = 0; i < 4; ++i) {
+	for (i = 0; i < bru->entity.source_pad; ++i) {
 		bool premultiplied = false;
 		u32 ctrl = 0;
 
@@ -291,7 +291,7 @@ static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_con
 	*format = fmt->format;
 
 	/* Reset the compose rectangle */
-	if (fmt->pad != BRU_PAD_SOURCE) {
+	if (fmt->pad != bru->entity.source_pad) {
 		struct v4l2_rect *compose;
 
 		compose = bru_get_compose(bru, cfg, fmt->pad, fmt->which);
@@ -305,7 +305,7 @@ static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_con
 	if (fmt->pad = BRU_PAD_SINK(0)) {
 		unsigned int i;
 
-		for (i = 0; i <= BRU_PAD_SOURCE; ++i) {
+		for (i = 0; i <= bru->entity.source_pad; ++i) {
 			format = vsp1_entity_get_pad_format(&bru->entity, cfg,
 							    i, fmt->which);
 			format->code = fmt->format.code;
@@ -321,7 +321,7 @@ static int bru_get_selection(struct v4l2_subdev *subdev,
 {
 	struct vsp1_bru *bru = to_bru(subdev);
 
-	if (sel->pad = BRU_PAD_SOURCE)
+	if (sel->pad = bru->entity.source_pad)
 		return -EINVAL;
 
 	switch (sel->target) {
@@ -349,7 +349,7 @@ static int bru_set_selection(struct v4l2_subdev *subdev,
 	struct v4l2_mbus_framefmt *format;
 	struct v4l2_rect *compose;
 
-	if (sel->pad = BRU_PAD_SOURCE)
+	if (sel->pad = bru->entity.source_pad)
 		return -EINVAL;
 
 	if (sel->target != V4L2_SEL_TGT_COMPOSE)
@@ -358,8 +358,8 @@ static int bru_set_selection(struct v4l2_subdev *subdev,
 	/* The compose rectangle top left corner must be inside the output
 	 * frame.
 	 */
-	format = vsp1_entity_get_pad_format(&bru->entity, cfg, BRU_PAD_SOURCE,
-					    sel->which);
+	format = vsp1_entity_get_pad_format(&bru->entity, cfg,
+					    bru->entity.source_pad, sel->which);
 	sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
 	sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
 
@@ -415,7 +415,8 @@ struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
 
 	bru->entity.type = VSP1_ENTITY_BRU;
 
-	ret = vsp1_entity_init(vsp1, &bru->entity, 5);
+	ret = vsp1_entity_init(vsp1, &bru->entity,
+			       vsp1->pdata.num_bru_inputs + 1);
 	if (ret < 0)
 		return ERR_PTR(ret);
 
diff --git a/drivers/media/platform/vsp1/vsp1_bru.h b/drivers/media/platform/vsp1/vsp1_bru.h
index 16b1c6554911..dbac9686ea69 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.h
+++ b/drivers/media/platform/vsp1/vsp1_bru.h
@@ -23,7 +23,6 @@ struct vsp1_device;
 struct vsp1_rwpf;
 
 #define BRU_PAD_SINK(n)				(n)
-#define BRU_PAD_SOURCE				4
 
 struct vsp1_bru {
 	struct vsp1_entity entity;
@@ -33,7 +32,7 @@ struct vsp1_bru {
 	struct {
 		struct vsp1_rwpf *rpf;
 		struct v4l2_rect compose;
-	} inputs[4];
+	} inputs[VSP1_MAX_RPF];
 };
 
 static inline struct vsp1_bru *to_bru(struct v4l2_subdev *subdev)
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index d1e42260a871..53a32f6ccbc0 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
 
@@ -539,6 +540,8 @@ static int vsp1_parse_dt(struct vsp1_device *vsp1)
 		return -EINVAL;
 	}
 
+	pdata->num_bru_inputs = 4;
+
 	return 0;
 }
 
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index 9606d0d21263..360a2e668ac2 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -32,6 +32,8 @@ enum vsp1_entity_type {
 	VSP1_ENTITY_WPF,
 };
 
+#define VSP1_ENTITY_MAX_INPUTS		5	/* For the BRU */
+
 /*
  * struct vsp1_route - Entity routing configuration
  * @type: Entity type this routing entry is associated with
@@ -48,7 +50,7 @@ struct vsp1_route {
 	enum vsp1_entity_type type;
 	unsigned int index;
 	unsigned int reg;
-	unsigned int inputs[4];
+	unsigned int inputs[VSP1_ENTITY_MAX_INPUTS];
 };
 
 struct vsp1_entity {
-- 
2.4.10


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

* [PATCH v2 22/32] v4l: vsp1: Make the BRU optional
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (20 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 21/32] v4l: vsp1: Make number of BRU inputs configurable Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 23/32] v4l: vsp1: Move format info to vsp1_pipe.c Laurent Pinchart
                   ` (10 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Not all VSP instances have a BRU on R-Car Gen3, make it optional. Set
the feature unconditionally for now, this will be fixed when adding Gen3
support.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---

Changes since v1:

- Don't add a new DT property

---
 drivers/media/platform/vsp1/vsp1.h     |  1 +
 drivers/media/platform/vsp1/vsp1_drv.c | 15 +++++++++------
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 29a8fd94a0aa..d980f32aac0b 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -42,6 +42,7 @@ struct vsp1_uds;
 #define VSP1_HAS_LIF		(1 << 0)
 #define VSP1_HAS_LUT		(1 << 1)
 #define VSP1_HAS_SRU		(1 << 2)
+#define VSP1_HAS_BRU		(1 << 3)
 
 struct vsp1_platform_data {
 	unsigned int features;
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 53a32f6ccbc0..42b6a106cbbb 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -223,13 +223,15 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	/* Instantiate all the entities. */
-	vsp1->bru = vsp1_bru_create(vsp1);
-	if (IS_ERR(vsp1->bru)) {
-		ret = PTR_ERR(vsp1->bru);
-		goto done;
-	}
+	if (vsp1->pdata.features & VSP1_HAS_BRU) {
+		vsp1->bru = vsp1_bru_create(vsp1);
+		if (IS_ERR(vsp1->bru)) {
+			ret = PTR_ERR(vsp1->bru);
+			goto done;
+		}
 
-	list_add_tail(&vsp1->bru->entity.list_dev, &vsp1->entities);
+		list_add_tail(&vsp1->bru->entity.list_dev, &vsp1->entities);
+	}
 
 	vsp1->hsi = vsp1_hsit_create(vsp1, true);
 	if (IS_ERR(vsp1->hsi)) {
@@ -540,6 +542,7 @@ static int vsp1_parse_dt(struct vsp1_device *vsp1)
 		return -EINVAL;
 	}
 
+	pdata->features |= VSP1_HAS_BRU;
 	pdata->num_bru_inputs = 4;
 
 	return 0;
-- 
2.4.10


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

* [PATCH v2 23/32] v4l: vsp1: Move format info to vsp1_pipe.c
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (21 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 22/32] v4l: vsp1: Make the BRU optional Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 24/32] v4l: vsp1: Make the userspace API optional Laurent Pinchart
                   ` (9 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Format information and the related helper function are not specific to
the V4L2 API, move them from vsp1_video.c to vsp1_pipe.c.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_pipe.c  | 110 +++++++++++++++++++++++++++++++
 drivers/media/platform/vsp1/vsp1_pipe.h  |  29 ++++++++
 drivers/media/platform/vsp1/vsp1_video.c | 107 ------------------------------
 drivers/media/platform/vsp1/vsp1_video.h |  27 --------
 4 files changed, 139 insertions(+), 134 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
index 524420ed6333..df11259dcc0a 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -25,6 +25,116 @@
 #include "vsp1_uds.h"
 
 /* -----------------------------------------------------------------------------
+ * Helper Functions
+ */
+
+static const struct vsp1_format_info vsp1_video_formats[] = {
+	{ V4L2_PIX_FMT_RGB332, MEDIA_BUS_FMT_ARGB8888_1X32,
+	  VI6_FMT_RGB_332, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  1, { 8, 0, 0 }, false, false, 1, 1, false },
+	{ V4L2_PIX_FMT_ARGB444, MEDIA_BUS_FMT_ARGB8888_1X32,
+	  VI6_FMT_ARGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS,
+	  1, { 16, 0, 0 }, false, false, 1, 1, true },
+	{ V4L2_PIX_FMT_XRGB444, MEDIA_BUS_FMT_ARGB8888_1X32,
+	  VI6_FMT_XRGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS,
+	  1, { 16, 0, 0 }, false, false, 1, 1, true },
+	{ V4L2_PIX_FMT_ARGB555, MEDIA_BUS_FMT_ARGB8888_1X32,
+	  VI6_FMT_ARGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS,
+	  1, { 16, 0, 0 }, false, false, 1, 1, true },
+	{ V4L2_PIX_FMT_XRGB555, MEDIA_BUS_FMT_ARGB8888_1X32,
+	  VI6_FMT_XRGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS,
+	  1, { 16, 0, 0 }, false, false, 1, 1, false },
+	{ V4L2_PIX_FMT_RGB565, MEDIA_BUS_FMT_ARGB8888_1X32,
+	  VI6_FMT_RGB_565, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS,
+	  1, { 16, 0, 0 }, false, false, 1, 1, false },
+	{ V4L2_PIX_FMT_BGR24, MEDIA_BUS_FMT_ARGB8888_1X32,
+	  VI6_FMT_BGR_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  1, { 24, 0, 0 }, false, false, 1, 1, false },
+	{ V4L2_PIX_FMT_RGB24, MEDIA_BUS_FMT_ARGB8888_1X32,
+	  VI6_FMT_RGB_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  1, { 24, 0, 0 }, false, false, 1, 1, false },
+	{ V4L2_PIX_FMT_ABGR32, MEDIA_BUS_FMT_ARGB8888_1X32,
+	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS,
+	  1, { 32, 0, 0 }, false, false, 1, 1, true },
+	{ V4L2_PIX_FMT_XBGR32, MEDIA_BUS_FMT_ARGB8888_1X32,
+	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS,
+	  1, { 32, 0, 0 }, false, false, 1, 1, false },
+	{ V4L2_PIX_FMT_ARGB32, MEDIA_BUS_FMT_ARGB8888_1X32,
+	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  1, { 32, 0, 0 }, false, false, 1, 1, true },
+	{ V4L2_PIX_FMT_XRGB32, MEDIA_BUS_FMT_ARGB8888_1X32,
+	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  1, { 32, 0, 0 }, false, false, 1, 1, false },
+	{ V4L2_PIX_FMT_UYVY, MEDIA_BUS_FMT_AYUV8_1X32,
+	  VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  1, { 16, 0, 0 }, false, false, 2, 1, false },
+	{ V4L2_PIX_FMT_VYUY, MEDIA_BUS_FMT_AYUV8_1X32,
+	  VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  1, { 16, 0, 0 }, false, true, 2, 1, false },
+	{ V4L2_PIX_FMT_YUYV, MEDIA_BUS_FMT_AYUV8_1X32,
+	  VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  1, { 16, 0, 0 }, true, false, 2, 1, false },
+	{ V4L2_PIX_FMT_YVYU, MEDIA_BUS_FMT_AYUV8_1X32,
+	  VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  1, { 16, 0, 0 }, true, true, 2, 1, false },
+	{ V4L2_PIX_FMT_NV12M, MEDIA_BUS_FMT_AYUV8_1X32,
+	  VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  2, { 8, 16, 0 }, false, false, 2, 2, false },
+	{ V4L2_PIX_FMT_NV21M, MEDIA_BUS_FMT_AYUV8_1X32,
+	  VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  2, { 8, 16, 0 }, false, true, 2, 2, false },
+	{ V4L2_PIX_FMT_NV16M, MEDIA_BUS_FMT_AYUV8_1X32,
+	  VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  2, { 8, 16, 0 }, false, false, 2, 1, false },
+	{ V4L2_PIX_FMT_NV61M, MEDIA_BUS_FMT_AYUV8_1X32,
+	  VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  2, { 8, 16, 0 }, false, true, 2, 1, false },
+	{ V4L2_PIX_FMT_YUV420M, MEDIA_BUS_FMT_AYUV8_1X32,
+	  VI6_FMT_Y_U_V_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+	  3, { 8, 8, 8 }, false, false, 2, 2, false },
+};
+
+/*
+ * vsp1_get_format_info - Retrieve format information for a 4CC
+ * @fourcc: the format 4CC
+ *
+ * Return a pointer to the format information structure corresponding to the
+ * given V4L2 format 4CC, or NULL if no corresponding format can be found.
+ */
+const struct vsp1_format_info *vsp1_get_format_info(u32 fourcc)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(vsp1_video_formats); ++i) {
+		const struct vsp1_format_info *info = &vsp1_video_formats[i];
+
+		if (info->fourcc = fourcc)
+			return info;
+	}
+
+	return NULL;
+}
+
+/* -----------------------------------------------------------------------------
  * Pipeline Management
  */
 
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index 9c8ded1c29f6..f9035c739e9a 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -21,6 +21,33 @@
 
 struct vsp1_rwpf;
 
+/*
+ * struct vsp1_format_info - VSP1 video format description
+ * @mbus: media bus format code
+ * @fourcc: V4L2 pixel format FCC identifier
+ * @planes: number of planes
+ * @bpp: bits per pixel
+ * @hwfmt: VSP1 hardware format
+ * @swap_yc: the Y and C components are swapped (Y comes before C)
+ * @swap_uv: the U and V components are swapped (V comes before U)
+ * @hsub: horizontal subsampling factor
+ * @vsub: vertical subsampling factor
+ * @alpha: has an alpha channel
+ */
+struct vsp1_format_info {
+	u32 fourcc;
+	unsigned int mbus;
+	unsigned int hwfmt;
+	unsigned int swap;
+	unsigned int planes;
+	unsigned int bpp[3];
+	bool swap_yc;
+	bool swap_uv;
+	unsigned int hsub;
+	unsigned int vsub;
+	bool alpha;
+};
+
 enum vsp1_pipeline_state {
 	VSP1_PIPELINE_STOPPED,
 	VSP1_PIPELINE_RUNNING,
@@ -97,4 +124,6 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
 void vsp1_pipelines_suspend(struct vsp1_device *vsp1);
 void vsp1_pipelines_resume(struct vsp1_device *vsp1);
 
+const struct vsp1_format_info *vsp1_get_format_info(u32 fourcc);
+
 #endif /* __VSP1_PIPE_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index a9b7bafc5fa2..141e489a8aa9 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -48,113 +48,6 @@
  * Helper functions
  */
 
-static const struct vsp1_format_info vsp1_video_formats[] = {
-	{ V4L2_PIX_FMT_RGB332, MEDIA_BUS_FMT_ARGB8888_1X32,
-	  VI6_FMT_RGB_332, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 8, 0, 0 }, false, false, 1, 1, false },
-	{ V4L2_PIX_FMT_ARGB444, MEDIA_BUS_FMT_ARGB8888_1X32,
-	  VI6_FMT_ARGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS,
-	  1, { 16, 0, 0 }, false, false, 1, 1, true },
-	{ V4L2_PIX_FMT_XRGB444, MEDIA_BUS_FMT_ARGB8888_1X32,
-	  VI6_FMT_XRGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS,
-	  1, { 16, 0, 0 }, false, false, 1, 1, true },
-	{ V4L2_PIX_FMT_ARGB555, MEDIA_BUS_FMT_ARGB8888_1X32,
-	  VI6_FMT_ARGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS,
-	  1, { 16, 0, 0 }, false, false, 1, 1, true },
-	{ V4L2_PIX_FMT_XRGB555, MEDIA_BUS_FMT_ARGB8888_1X32,
-	  VI6_FMT_XRGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS,
-	  1, { 16, 0, 0 }, false, false, 1, 1, false },
-	{ V4L2_PIX_FMT_RGB565, MEDIA_BUS_FMT_ARGB8888_1X32,
-	  VI6_FMT_RGB_565, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS,
-	  1, { 16, 0, 0 }, false, false, 1, 1, false },
-	{ V4L2_PIX_FMT_BGR24, MEDIA_BUS_FMT_ARGB8888_1X32,
-	  VI6_FMT_BGR_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 24, 0, 0 }, false, false, 1, 1, false },
-	{ V4L2_PIX_FMT_RGB24, MEDIA_BUS_FMT_ARGB8888_1X32,
-	  VI6_FMT_RGB_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 24, 0, 0 }, false, false, 1, 1, false },
-	{ V4L2_PIX_FMT_ABGR32, MEDIA_BUS_FMT_ARGB8888_1X32,
-	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS,
-	  1, { 32, 0, 0 }, false, false, 1, 1, true },
-	{ V4L2_PIX_FMT_XBGR32, MEDIA_BUS_FMT_ARGB8888_1X32,
-	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS,
-	  1, { 32, 0, 0 }, false, false, 1, 1, false },
-	{ V4L2_PIX_FMT_ARGB32, MEDIA_BUS_FMT_ARGB8888_1X32,
-	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 32, 0, 0 }, false, false, 1, 1, true },
-	{ V4L2_PIX_FMT_XRGB32, MEDIA_BUS_FMT_ARGB8888_1X32,
-	  VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 32, 0, 0 }, false, false, 1, 1, false },
-	{ V4L2_PIX_FMT_UYVY, MEDIA_BUS_FMT_AYUV8_1X32,
-	  VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 16, 0, 0 }, false, false, 2, 1, false },
-	{ V4L2_PIX_FMT_VYUY, MEDIA_BUS_FMT_AYUV8_1X32,
-	  VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 16, 0, 0 }, false, true, 2, 1, false },
-	{ V4L2_PIX_FMT_YUYV, MEDIA_BUS_FMT_AYUV8_1X32,
-	  VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 16, 0, 0 }, true, false, 2, 1, false },
-	{ V4L2_PIX_FMT_YVYU, MEDIA_BUS_FMT_AYUV8_1X32,
-	  VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  1, { 16, 0, 0 }, true, true, 2, 1, false },
-	{ V4L2_PIX_FMT_NV12M, MEDIA_BUS_FMT_AYUV8_1X32,
-	  VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  2, { 8, 16, 0 }, false, false, 2, 2, false },
-	{ V4L2_PIX_FMT_NV21M, MEDIA_BUS_FMT_AYUV8_1X32,
-	  VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  2, { 8, 16, 0 }, false, true, 2, 2, false },
-	{ V4L2_PIX_FMT_NV16M, MEDIA_BUS_FMT_AYUV8_1X32,
-	  VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  2, { 8, 16, 0 }, false, false, 2, 1, false },
-	{ V4L2_PIX_FMT_NV61M, MEDIA_BUS_FMT_AYUV8_1X32,
-	  VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  2, { 8, 16, 0 }, false, true, 2, 1, false },
-	{ V4L2_PIX_FMT_YUV420M, MEDIA_BUS_FMT_AYUV8_1X32,
-	  VI6_FMT_Y_U_V_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
-	  VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
-	  3, { 8, 8, 8 }, false, false, 2, 2, false },
-};
-
-/*
- * vsp1_get_format_info - Retrieve format information for a 4CC
- * @fourcc: the format 4CC
- *
- * Return a pointer to the format information structure corresponding to the
- * given V4L2 format 4CC, or NULL if no corresponding format can be found.
- */
-static const struct vsp1_format_info *vsp1_get_format_info(u32 fourcc)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(vsp1_video_formats); ++i) {
-		const struct vsp1_format_info *info = &vsp1_video_formats[i];
-
-		if (info->fourcc = fourcc)
-			return info;
-	}
-
-	return NULL;
-}
-
-
 static struct v4l2_subdev *
 vsp1_video_remote_subdev(struct media_pad *local, u32 *pad)
 {
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index faccb2aede5c..64abd39ee1e7 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -21,33 +21,6 @@
 #include "vsp1_pipe.h"
 #include "vsp1_rwpf.h"
 
-/*
- * struct vsp1_format_info - VSP1 video format description
- * @mbus: media bus format code
- * @fourcc: V4L2 pixel format FCC identifier
- * @planes: number of planes
- * @bpp: bits per pixel
- * @hwfmt: VSP1 hardware format
- * @swap_yc: the Y and C components are swapped (Y comes before C)
- * @swap_uv: the U and V components are swapped (V comes before U)
- * @hsub: horizontal subsampling factor
- * @vsub: vertical subsampling factor
- * @alpha: has an alpha channel
- */
-struct vsp1_format_info {
-	u32 fourcc;
-	unsigned int mbus;
-	unsigned int hwfmt;
-	unsigned int swap;
-	unsigned int planes;
-	unsigned int bpp[3];
-	bool swap_yc;
-	bool swap_uv;
-	unsigned int hsub;
-	unsigned int vsub;
-	bool alpha;
-};
-
 struct vsp1_vb2_buffer {
 	struct vb2_v4l2_buffer buf;
 	struct list_head queue;
-- 
2.4.10


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

* [PATCH v2 24/32] v4l: vsp1: Make the userspace API optional
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (22 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 23/32] v4l: vsp1: Move format info to vsp1_pipe.c Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:12 ` [PATCH v2 25/32] v4l: vsp1: Make pipeline inputs array index by RPF index Laurent Pinchart
                   ` (8 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

The R-Car Gen3 SoCs include VSP instances dedicated to the DU that will
be controlled entirely by the rcar-du-drm driver through the KMS API. To
support that use case make the userspace V4L2 API optional.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---

Changes since v1:

- Store the uapi property in the vsp1_platform_data structure

---
 drivers/media/platform/vsp1/vsp1.h        |  1 +
 drivers/media/platform/vsp1/vsp1_drv.c    | 57 ++++++++++++++++++-------------
 drivers/media/platform/vsp1/vsp1_entity.c |  2 +-
 drivers/media/platform/vsp1/vsp1_sru.c    |  6 ++--
 drivers/media/platform/vsp1/vsp1_wpf.c    |  6 ++--
 5 files changed, 43 insertions(+), 29 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index d980f32aac0b..4fd4386a7049 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -50,6 +50,7 @@ struct vsp1_platform_data {
 	unsigned int uds_count;
 	unsigned int wpf_count;
 	unsigned int num_bru_inputs;
+	bool uapi;
 };
 
 struct vsp1_device {
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 42b6a106cbbb..3c8de1d5c80e 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -134,6 +134,17 @@ static int vsp1_create_links(struct vsp1_device *vsp1)
 			return ret;
 	}
 
+	if (vsp1->pdata.features & VSP1_HAS_LIF) {
+		ret = media_entity_create_link(
+			&vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
+			&vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (!vsp1->pdata.uapi)
+		return 0;
+
 	for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
 		struct vsp1_rwpf *rpf = vsp1->rpf[i];
 
@@ -165,14 +176,6 @@ static int vsp1_create_links(struct vsp1_device *vsp1)
 			return ret;
 	}
 
-	if (vsp1->pdata.features & VSP1_HAS_LIF) {
-		ret = media_entity_create_link(
-			&vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
-			&vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0);
-		if (ret < 0)
-			return ret;
-	}
-
 	return 0;
 }
 
@@ -270,7 +273,6 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
-		struct vsp1_video *video;
 		struct vsp1_rwpf *rpf;
 
 		rpf = vsp1_rpf_create(vsp1, i);
@@ -282,13 +284,16 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 		vsp1->rpf[i] = rpf;
 		list_add_tail(&rpf->entity.list_dev, &vsp1->entities);
 
-		video = vsp1_video_create(vsp1, rpf);
-		if (IS_ERR(video)) {
-			ret = PTR_ERR(video);
-			goto done;
-		}
+		if (vsp1->pdata.uapi) {
+			struct vsp1_video *video = vsp1_video_create(vsp1, rpf);
 
-		list_add_tail(&video->list, &vsp1->videos);
+			if (IS_ERR(video)) {
+				ret = PTR_ERR(video);
+				goto done;
+			}
+
+			list_add_tail(&video->list, &vsp1->videos);
+		}
 	}
 
 	if (vsp1->pdata.features & VSP1_HAS_SRU) {
@@ -315,7 +320,6 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
-		struct vsp1_video *video;
 		struct vsp1_rwpf *wpf;
 
 		wpf = vsp1_wpf_create(vsp1, i);
@@ -327,14 +331,17 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 		vsp1->wpf[i] = wpf;
 		list_add_tail(&wpf->entity.list_dev, &vsp1->entities);
 
-		video = vsp1_video_create(vsp1, wpf);
-		if (IS_ERR(video)) {
-			ret = PTR_ERR(video);
-			goto done;
-		}
+		if (vsp1->pdata.uapi) {
+			struct vsp1_video *video = vsp1_video_create(vsp1, wpf);
+
+			if (IS_ERR(video)) {
+				ret = PTR_ERR(video);
+				goto done;
+			}
 
-		list_add_tail(&video->list, &vsp1->videos);
-		wpf->entity.sink = &video->video.entity;
+			list_add_tail(&video->list, &vsp1->videos);
+			wpf->entity.sink = &video->video.entity;
+		}
 	}
 
 	/* Create links. */
@@ -350,7 +357,8 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 			goto done;
 	}
 
-	ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev);
+	if (vsp1->pdata.uapi)
+		ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev);
 
 done:
 	if (ret < 0)
@@ -544,6 +552,7 @@ static int vsp1_parse_dt(struct vsp1_device *vsp1)
 
 	pdata->features |= VSP1_HAS_BRU;
 	pdata->num_bru_inputs = 4;
+	pdata->uapi = true;
 
 	return 0;
 }
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index cb9d480d8ee5..75bf85693f35 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -45,7 +45,7 @@ int vsp1_entity_set_streaming(struct vsp1_entity *entity, bool streaming)
 	if (!streaming)
 		return 0;
 
-	if (!entity->subdev.ctrl_handler)
+	if (!entity->vsp1->pdata.uapi || !entity->subdev.ctrl_handler)
 		return 0;
 
 	ret = v4l2_ctrl_handler_setup(entity->subdev.ctrl_handler);
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index d41ae950d1a1..cff4a1d82e3b 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -151,11 +151,13 @@ static int sru_s_stream(struct v4l2_subdev *subdev, int enable)
 	/* Take the control handler lock to ensure that the CTRL0 value won't be
 	 * changed behind our back by a set control operation.
 	 */
-	mutex_lock(sru->ctrls.lock);
+	if (sru->entity.vsp1->pdata.uapi)
+		mutex_lock(sru->ctrls.lock);
 	ctrl0 |= vsp1_sru_read(sru, VI6_SRU_CTRL0)
 	       & (VI6_SRU_CTRL0_PARAM0_MASK | VI6_SRU_CTRL0_PARAM1_MASK);
 	vsp1_sru_write(sru, VI6_SRU_CTRL0, ctrl0);
-	mutex_unlock(sru->ctrls.lock);
+	if (sru->entity.vsp1->pdata.uapi)
+		mutex_unlock(sru->ctrls.lock);
 
 	vsp1_sru_write(sru, VI6_SRU_CTRL1, VI6_SRU_CTRL1_PARAM5);
 
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index d2537b46fc46..184a7e01aad5 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -151,10 +151,12 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
 	/* Take the control handler lock to ensure that the PDV value won't be
 	 * changed behind our back by a set control operation.
 	 */
-	mutex_lock(wpf->ctrls.lock);
+	if (vsp1->pdata.uapi)
+		mutex_lock(wpf->ctrls.lock);
 	outfmt |= vsp1_wpf_read(wpf, VI6_WPF_OUTFMT) & VI6_WPF_OUTFMT_PDV_MASK;
 	vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, outfmt);
-	mutex_unlock(wpf->ctrls.lock);
+	if (vsp1->pdata.uapi)
+		mutex_unlock(wpf->ctrls.lock);
 
 	vsp1_write(vsp1, VI6_DPR_WPF_FPORCH(wpf->entity.index),
 		   VI6_DPR_WPF_FPORCH_FP_WPFN);
-- 
2.4.10


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

* [PATCH v2 25/32] v4l: vsp1: Make pipeline inputs array index by RPF index
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (23 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 24/32] v4l: vsp1: Make the userspace API optional Laurent Pinchart
@ 2015-12-05  2:12 ` Laurent Pinchart
  2015-12-05  2:13 ` [PATCH v2 26/32] v4l: vsp1: Set the alpha value manually in RPF and WPF s_stream handlers Laurent Pinchart
                   ` (7 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:12 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

The pipeline inputs array stores pointers to all RPFs contained in the
pipeline. It's currently indexed contiguously by adding RPFs in the
order they are found during graph walk. This can't easily support
dynamic addition and removal of RPFs while streaming, which will be
required for combined VSP+DU support.

Make the array indexed by RPF index instead and skip NULL elements when
iterating over RPFs.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_pipe.c  |  6 +++++-
 drivers/media/platform/vsp1/vsp1_pipe.h  |  2 +-
 drivers/media/platform/vsp1/vsp1_video.c | 16 ++++++++++++----
 drivers/media/platform/vsp1/vsp1_wpf.c   |  5 ++++-
 4 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
index df11259dcc0a..d41e4ca94a02 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -140,14 +140,18 @@ const struct vsp1_format_info *vsp1_get_format_info(u32 fourcc)
 
 void vsp1_pipeline_reset(struct vsp1_pipeline *pipe)
 {
+	unsigned int i;
+
 	if (pipe->bru) {
 		struct vsp1_bru *bru = to_bru(&pipe->bru->subdev);
-		unsigned int i;
 
 		for (i = 0; i < ARRAY_SIZE(bru->inputs); ++i)
 			bru->inputs[i].rpf = NULL;
 	}
 
+	for (i = 0; i < ARRAY_SIZE(pipe->inputs); ++i)
+		pipe->inputs[i] = NULL;
+
 	INIT_LIST_HEAD(&pipe->entities);
 	pipe->state = VSP1_PIPELINE_STOPPED;
 	pipe->buffers_ready = 0;
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index f9035c739e9a..c4c300561c5c 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -66,7 +66,7 @@ enum vsp1_pipeline_state {
  * @stream_count: number of streaming video nodes
  * @buffers_ready: bitmask of RPFs and WPFs with at least one buffer available
  * @num_inputs: number of RPFs
- * @inputs: array of RPFs in the pipeline
+ * @inputs: array of RPFs in the pipeline (indexed by RPF index)
  * @output: WPF at the output of the pipeline
  * @bru: BRU entity, if present
  * @lif: LIF entity, if present
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 141e489a8aa9..d3335eb24cce 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -305,8 +305,8 @@ static int vsp1_video_pipeline_validate(struct vsp1_pipeline *pipe,
 
 		if (e->type = VSP1_ENTITY_RPF) {
 			rwpf = to_rwpf(subdev);
-			pipe->inputs[pipe->num_inputs++] = rwpf;
-			rwpf->video->pipe_index = pipe->num_inputs;
+			pipe->inputs[rwpf->entity.index] = rwpf;
+			rwpf->video->pipe_index = ++pipe->num_inputs;
 		} else if (e->type = VSP1_ENTITY_WPF) {
 			rwpf = to_rwpf(subdev);
 			pipe->output = rwpf;
@@ -329,7 +329,10 @@ static int vsp1_video_pipeline_validate(struct vsp1_pipeline *pipe,
 	/* Follow links downstream for each input and make sure the graph
 	 * contains no loop and that all branches end at the output WPF.
 	 */
-	for (i = 0; i < pipe->num_inputs; ++i) {
+	for (i = 0; i < video->vsp1->pdata.rpf_count; ++i) {
+		if (!pipe->inputs[i])
+			continue;
+
 		ret = vsp1_video_pipeline_validate_branch(pipe, pipe->inputs[i],
 							  pipe->output);
 		if (ret < 0)
@@ -454,11 +457,16 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe,
 
 static void vsp1_video_pipeline_frame_end(struct vsp1_pipeline *pipe)
 {
+	struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
 	unsigned int i;
 
 	/* Complete buffers on all video nodes. */
-	for (i = 0; i < pipe->num_inputs; ++i)
+	for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
+		if (!pipe->inputs[i])
+			continue;
+
 		vsp1_video_frame_end(pipe, pipe->inputs[i]);
+	}
 
 	if (!pipe->lif)
 		vsp1_video_frame_end(pipe, pipe->output);
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 184a7e01aad5..d0edcde721bd 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -97,9 +97,12 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
 	 * inputs as sub-layers and select the virtual RPF as the master
 	 * layer.
 	 */
-	for (i = 0; i < pipe->num_inputs; ++i) {
+	for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
 		struct vsp1_rwpf *input = pipe->inputs[i];
 
+		if (!input)
+			continue;
+
 		srcrpf |= (!pipe->bru && pipe->num_inputs = 1)
 			? VI6_WPF_SRCRPF_RPF_ACT_MST(input->entity.index)
 			: VI6_WPF_SRCRPF_RPF_ACT_SUB(input->entity.index);
-- 
2.4.10


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

* [PATCH v2 26/32] v4l: vsp1: Set the alpha value manually in RPF and WPF s_stream handlers
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (24 preceding siblings ...)
  2015-12-05  2:12 ` [PATCH v2 25/32] v4l: vsp1: Make pipeline inputs array index by RPF index Laurent Pinchart
@ 2015-12-05  2:13 ` Laurent Pinchart
  2015-12-05  2:13 ` [PATCH v2 27/32] v4l: vsp1: Don't validate links when the userspace API is disabled Laurent Pinchart
                   ` (6 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:13 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

The RPF and WPF alpha values are set through V4L2 controls and applied
when starting the video stream by a call to v4l2_ctrl_handler_setup().
As that function uses the control handler mutex it can't be called in
interrupt context, where the VSP+DU pipeline handler might need to
reconfigure the pipeline.

Set the alpha value manually in the RPF and WPF s_stream handler to
ensure that the hardware is properly configured even when controlled
without the userspace API. If the userspace API is enabled protect that
with the control lock to avoid race conditions with userspace.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_rpf.c  | 16 ++++++++++++++--
 drivers/media/platform/vsp1/vsp1_rwpf.h |  2 ++
 drivers/media/platform/vsp1/vsp1_wpf.c  |  7 ++++---
 3 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index b9c39f9e4458..b1d4a46f230e 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -68,7 +68,9 @@ static const struct v4l2_ctrl_ops rpf_ctrl_ops = {
 
 static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
 {
+	struct vsp1_pipeline *pipe = to_vsp1_pipeline(&subdev->entity);
 	struct vsp1_rwpf *rpf = to_rwpf(subdev);
+	struct vsp1_device *vsp1 = rpf->entity.vsp1;
 	const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
 	const struct v4l2_pix_format_mplane *format = &rpf->format;
 	const struct v4l2_rect *crop = &rpf->crop;
@@ -148,6 +150,15 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
 	vsp1_rpf_write(rpf, VI6_RPF_ALPH_SEL, VI6_RPF_ALPH_SEL_AEXT_EXT |
 		       (fmtinfo->alpha ? VI6_RPF_ALPH_SEL_ASEL_PACKED
 				       : VI6_RPF_ALPH_SEL_ASEL_FIXED));
+
+	if (vsp1->pdata.uapi)
+		mutex_lock(rpf->ctrls.lock);
+	vsp1_rpf_write(rpf, VI6_RPF_VRTCOL_SET,
+		       rpf->alpha->cur.val << VI6_RPF_VRTCOL_SET_LAYA_SHIFT);
+	vsp1_pipeline_propagate_alpha(pipe, &rpf->entity, rpf->alpha->cur.val);
+	if (vsp1->pdata.uapi)
+		mutex_unlock(rpf->ctrls.lock);
+
 	vsp1_rpf_write(rpf, VI6_RPF_MSK_CTRL, 0);
 	vsp1_rpf_write(rpf, VI6_RPF_CKEY_CTRL, 0);
 
@@ -245,8 +256,9 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 
 	/* Initialize the control handler. */
 	v4l2_ctrl_handler_init(&rpf->ctrls, 1);
-	v4l2_ctrl_new_std(&rpf->ctrls, &rpf_ctrl_ops, V4L2_CID_ALPHA_COMPONENT,
-			  0, 255, 1, 255);
+	rpf->alpha = v4l2_ctrl_new_std(&rpf->ctrls, &rpf_ctrl_ops,
+				       V4L2_CID_ALPHA_COMPONENT,
+				       0, 255, 1, 255);
 
 	rpf->entity.subdev.ctrl_handler = &rpf->ctrls;
 
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 1a90c7c8e972..8e8235682ada 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -23,6 +23,7 @@
 #define RWPF_PAD_SINK				0
 #define RWPF_PAD_SOURCE				1
 
+struct v4l2_ctrl;
 struct vsp1_rwpf;
 struct vsp1_video;
 
@@ -40,6 +41,7 @@ struct vsp1_rwpf_operations {
 struct vsp1_rwpf {
 	struct vsp1_entity entity;
 	struct v4l2_ctrl_handler ctrls;
+	struct v4l2_ctrl *alpha;
 
 	struct vsp1_video *video;
 
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index d0edcde721bd..40eeaf2d76d2 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -156,7 +156,7 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
 	 */
 	if (vsp1->pdata.uapi)
 		mutex_lock(wpf->ctrls.lock);
-	outfmt |= vsp1_wpf_read(wpf, VI6_WPF_OUTFMT) & VI6_WPF_OUTFMT_PDV_MASK;
+	outfmt |= wpf->alpha->cur.val << VI6_WPF_OUTFMT_PDV_SHIFT;
 	vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, outfmt);
 	if (vsp1->pdata.uapi)
 		mutex_unlock(wpf->ctrls.lock);
@@ -254,8 +254,9 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 
 	/* Initialize the control handler. */
 	v4l2_ctrl_handler_init(&wpf->ctrls, 1);
-	v4l2_ctrl_new_std(&wpf->ctrls, &wpf_ctrl_ops, V4L2_CID_ALPHA_COMPONENT,
-			  0, 255, 1, 255);
+	wpf->alpha = v4l2_ctrl_new_std(&wpf->ctrls, &wpf_ctrl_ops,
+				       V4L2_CID_ALPHA_COMPONENT,
+				       0, 255, 1, 255);
 
 	wpf->entity.subdev.ctrl_handler = &wpf->ctrls;
 
-- 
2.4.10


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

* [PATCH v2 27/32] v4l: vsp1: Don't validate links when the userspace API is disabled
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (25 preceding siblings ...)
  2015-12-05  2:13 ` [PATCH v2 26/32] v4l: vsp1: Set the alpha value manually in RPF and WPF s_stream handlers Laurent Pinchart
@ 2015-12-05  2:13 ` Laurent Pinchart
  2015-12-05  2:13 ` [PATCH v2 28/32] v4l: vsp1: Add VSP+DU support Laurent Pinchart
                   ` (5 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:13 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

As the pipeline is configured internally by the driver when the
userspace API is disabled its configuration can be trusted and link
validation isn't needed.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1.h        |  2 ++
 drivers/media/platform/vsp1/vsp1_bru.c    |  2 +-
 drivers/media/platform/vsp1/vsp1_drv.c    | 10 ++++++++++
 drivers/media/platform/vsp1/vsp1_entity.c | 11 +++--------
 drivers/media/platform/vsp1/vsp1_entity.h |  5 ++++-
 drivers/media/platform/vsp1/vsp1_hsit.c   |  2 +-
 drivers/media/platform/vsp1/vsp1_lif.c    |  2 +-
 drivers/media/platform/vsp1/vsp1_lut.c    |  2 +-
 drivers/media/platform/vsp1/vsp1_rpf.c    |  2 +-
 drivers/media/platform/vsp1/vsp1_sru.c    |  2 +-
 drivers/media/platform/vsp1/vsp1_uds.c    |  2 +-
 drivers/media/platform/vsp1/vsp1_wpf.c    |  2 +-
 12 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 4fd4386a7049..454201bf59ee 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -78,6 +78,8 @@ struct vsp1_device {
 
 	struct v4l2_device v4l2_dev;
 	struct media_device media_dev;
+
+	struct media_entity_operations media_ops;
 };
 
 int vsp1_device_get(struct vsp1_device *vsp1);
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index baebfbbef61d..848bfb5a42ff 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -424,7 +424,7 @@ struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
 	subdev = &bru->entity.subdev;
 	v4l2_subdev_init(subdev, &bru_ops);
 
-	subdev->entity.ops = &vsp1_media_ops;
+	subdev->entity.ops = &vsp1->media_ops;
 	subdev->internal_ops = &vsp1_subdev_internal_ops;
 	snprintf(subdev->name, sizeof(subdev->name), "%s bru",
 		 dev_name(vsp1->dev));
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 3c8de1d5c80e..6d086c048975 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -21,6 +21,8 @@
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
 
+#include <media/v4l2-subdev.h>
+
 #include "vsp1.h"
 #include "vsp1_bru.h"
 #include "vsp1_hsit.h"
@@ -217,6 +219,14 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 		return ret;
 	}
 
+	vsp1->media_ops.link_setup = vsp1_entity_link_setup;
+	/* Don't perform link validation when the userspace API is disabled as
+	 * the pipeline is configured internally by the driver in that case, and
+	 * its configuration can thus be trusted.
+	 */
+	if (vsp1->pdata.uapi)
+		vsp1->media_ops.link_validate = v4l2_subdev_link_validate;
+
 	vdev->mdev = mdev;
 	ret = v4l2_device_register(vsp1->dev, vdev);
 	if (ret < 0) {
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 75bf85693f35..38a496f43050 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -131,9 +131,9 @@ const struct v4l2_subdev_internal_ops vsp1_subdev_internal_ops = {
  * Media Operations
  */
 
-static int vsp1_entity_link_setup(struct media_entity *entity,
-				  const struct media_pad *local,
-				  const struct media_pad *remote, u32 flags)
+int vsp1_entity_link_setup(struct media_entity *entity,
+			   const struct media_pad *local,
+			   const struct media_pad *remote, u32 flags)
 {
 	struct vsp1_entity *source;
 
@@ -158,11 +158,6 @@ static int vsp1_entity_link_setup(struct media_entity *entity,
 	return 0;
 }
 
-const struct media_entity_operations vsp1_media_ops = {
-	.link_setup = vsp1_entity_link_setup,
-	.link_validate = v4l2_subdev_link_validate,
-};
-
 /* -----------------------------------------------------------------------------
  * Initialization
  */
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index 360a2e668ac2..83570dfde8ec 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -86,7 +86,10 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
 void vsp1_entity_destroy(struct vsp1_entity *entity);
 
 extern const struct v4l2_subdev_internal_ops vsp1_subdev_internal_ops;
-extern const struct media_entity_operations vsp1_media_ops;
+
+int vsp1_entity_link_setup(struct media_entity *entity,
+			   const struct media_pad *local,
+			   const struct media_pad *remote, u32 flags);
 
 struct v4l2_mbus_framefmt *
 vsp1_entity_get_pad_format(struct vsp1_entity *entity,
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c
index 8ffb817ae525..c1087cff31a0 100644
--- a/drivers/media/platform/vsp1/vsp1_hsit.c
+++ b/drivers/media/platform/vsp1/vsp1_hsit.c
@@ -203,7 +203,7 @@ struct vsp1_hsit *vsp1_hsit_create(struct vsp1_device *vsp1, bool inverse)
 	subdev = &hsit->entity.subdev;
 	v4l2_subdev_init(subdev, &hsit_ops);
 
-	subdev->entity.ops = &vsp1_media_ops;
+	subdev->entity.ops = &vsp1->media_ops;
 	subdev->internal_ops = &vsp1_subdev_internal_ops;
 	snprintf(subdev->name, sizeof(subdev->name), "%s %s",
 		 dev_name(vsp1->dev), inverse ? "hsi" : "hst");
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index b868bce08982..b8e73d32d14d 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -223,7 +223,7 @@ struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1)
 	subdev = &lif->entity.subdev;
 	v4l2_subdev_init(subdev, &lif_ops);
 
-	subdev->entity.ops = &vsp1_media_ops;
+	subdev->entity.ops = &vsp1->media_ops;
 	subdev->internal_ops = &vsp1_subdev_internal_ops;
 	snprintf(subdev->name, sizeof(subdev->name), "%s lif",
 		 dev_name(vsp1->dev));
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
index 9e33caa9c616..4b89095e7b5f 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.c
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -237,7 +237,7 @@ struct vsp1_lut *vsp1_lut_create(struct vsp1_device *vsp1)
 	subdev = &lut->entity.subdev;
 	v4l2_subdev_init(subdev, &lut_ops);
 
-	subdev->entity.ops = &vsp1_media_ops;
+	subdev->entity.ops = &vsp1->media_ops;
 	subdev->internal_ops = &vsp1_subdev_internal_ops;
 	snprintf(subdev->name, sizeof(subdev->name), "%s lut",
 		 dev_name(vsp1->dev));
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index b1d4a46f230e..3992da09e466 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -245,7 +245,7 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 	subdev = &rpf->entity.subdev;
 	v4l2_subdev_init(subdev, &rpf_ops);
 
-	subdev->entity.ops = &vsp1_media_ops;
+	subdev->entity.ops = &vsp1->media_ops;
 	subdev->internal_ops = &vsp1_subdev_internal_ops;
 	snprintf(subdev->name, sizeof(subdev->name), "%s rpf.%u",
 		 dev_name(vsp1->dev), index);
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index cff4a1d82e3b..6dcf76a1ca57 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -363,7 +363,7 @@ struct vsp1_sru *vsp1_sru_create(struct vsp1_device *vsp1)
 	subdev = &sru->entity.subdev;
 	v4l2_subdev_init(subdev, &sru_ops);
 
-	subdev->entity.ops = &vsp1_media_ops;
+	subdev->entity.ops = &vsp1->media_ops;
 	subdev->internal_ops = &vsp1_subdev_internal_ops;
 	snprintf(subdev->name, sizeof(subdev->name), "%s sru",
 		 dev_name(vsp1->dev));
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
index 27ad07466ebd..bba67770cf95 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/vsp1/vsp1_uds.c
@@ -338,7 +338,7 @@ struct vsp1_uds *vsp1_uds_create(struct vsp1_device *vsp1, unsigned int index)
 	subdev = &uds->entity.subdev;
 	v4l2_subdev_init(subdev, &uds_ops);
 
-	subdev->entity.ops = &vsp1_media_ops;
+	subdev->entity.ops = &vsp1->media_ops;
 	subdev->internal_ops = &vsp1_subdev_internal_ops;
 	snprintf(subdev->name, sizeof(subdev->name), "%s uds.%u",
 		 dev_name(vsp1->dev), index);
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 40eeaf2d76d2..849ed81d86a1 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -243,7 +243,7 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 	subdev = &wpf->entity.subdev;
 	v4l2_subdev_init(subdev, &wpf_ops);
 
-	subdev->entity.ops = &vsp1_media_ops;
+	subdev->entity.ops = &vsp1->media_ops;
 	subdev->internal_ops = &vsp1_subdev_internal_ops;
 	snprintf(subdev->name, sizeof(subdev->name), "%s wpf.%u",
 		 dev_name(vsp1->dev), index);
-- 
2.4.10


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

* [PATCH v2 28/32] v4l: vsp1: Add VSP+DU support
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (26 preceding siblings ...)
  2015-12-05  2:13 ` [PATCH v2 27/32] v4l: vsp1: Don't validate links when the userspace API is disabled Laurent Pinchart
@ 2015-12-05  2:13 ` Laurent Pinchart
  2015-12-05  2:13 ` [PATCH v2 29/32] v4l: vsp1: Disconnect unused RPFs from the DRM pipeline Laurent Pinchart
                   ` (4 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:13 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Implement internal control of the VSP pipeline to be used by the DU
DRM/KMS driver when using the VSP as an internal composer handled
through DRM/KMS only.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

---
 drivers/media/platform/vsp1/Makefile   |   2 +-
 drivers/media/platform/vsp1/vsp1.h     |   3 +-
 drivers/media/platform/vsp1/vsp1_drm.c | 550 +++++++++++++++++++++++++++++++++
 drivers/media/platform/vsp1/vsp1_drm.h |  26 ++
 drivers/media/platform/vsp1/vsp1_drv.c |  13 +-
 include/media/vsp1.h                   |  30 ++
 6 files changed, 617 insertions(+), 7 deletions(-)
 create mode 100644 drivers/media/platform/vsp1/vsp1_drm.c
 create mode 100644 drivers/media/platform/vsp1/vsp1_drm.h
 create mode 100644 include/media/vsp1.h

diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
index 0ef0b5384125..447e72a2ef43 100644
--- a/drivers/media/platform/vsp1/Makefile
+++ b/drivers/media/platform/vsp1/Makefile
@@ -1,5 +1,5 @@
 vsp1-y					:= vsp1_drv.o vsp1_entity.o vsp1_pipe.o
-vsp1-y					+= vsp1_video.o
+vsp1-y					+= vsp1_drm.o vsp1_video.o
 vsp1-y					+= vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
 vsp1-y					+= vsp1_hsit.o vsp1_lif.o vsp1_lut.o
 vsp1-y					+= vsp1_bru.o vsp1_sru.o vsp1_uds.o
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 454201bf59ee..67a026ae88cb 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -26,6 +26,7 @@
 struct clk;
 struct device;
 
+struct vsp1_drm;
 struct vsp1_platform_data;
 struct vsp1_bru;
 struct vsp1_hsit;
@@ -78,8 +79,8 @@ struct vsp1_device {
 
 	struct v4l2_device v4l2_dev;
 	struct media_device media_dev;
-
 	struct media_entity_operations media_ops;
+	struct vsp1_drm *drm;
 };
 
 int vsp1_device_get(struct vsp1_device *vsp1);
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
new file mode 100644
index 000000000000..2969d570f462
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -0,0 +1,550 @@
+/*
+ * vsp1_drm.c  --  R-Car VSP1 DRM API
+ *
+ * Copyright (C) 2015 Renesas Electronics Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/vsp1.h>
+
+#include <media/media-entity.h>
+#include <media/v4l2-subdev.h>
+
+#include "vsp1.h"
+#include "vsp1_bru.h"
+#include "vsp1_drm.h"
+#include "vsp1_lif.h"
+#include "vsp1_pipe.h"
+#include "vsp1_rwpf.h"
+
+/* -----------------------------------------------------------------------------
+ * Runtime Handling
+ */
+
+static int vsp1_drm_pipeline_run(struct vsp1_pipeline *pipe)
+{
+	struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
+	int ret;
+
+	if (vsp1->drm->update) {
+		struct vsp1_entity *entity;
+
+		list_for_each_entry(entity, &pipe->entities, list_pipe) {
+			/* Skip unused RPFs. */
+			if (entity->type = VSP1_ENTITY_RPF) {
+				struct vsp1_rwpf *rpf +					to_rwpf(&entity->subdev);
+
+				if (!pipe->inputs[rpf->entity.index])
+					continue;
+			}
+
+			vsp1_entity_route_setup(entity);
+
+			ret = v4l2_subdev_call(&entity->subdev, video,
+					       s_stream, 1);
+			if (ret < 0) {
+				dev_err(vsp1->dev,
+					"DRM pipeline start failure on entity %s\n",
+					entity->subdev.name);
+				return ret;
+			}
+		}
+
+		vsp1->drm->update = false;
+	}
+
+	vsp1_pipeline_run(pipe);
+
+	return 0;
+}
+
+static void vsp1_drm_pipeline_frame_end(struct vsp1_pipeline *pipe)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pipe->irqlock, flags);
+	if (pipe->num_inputs)
+		vsp1_drm_pipeline_run(pipe);
+	spin_unlock_irqrestore(&pipe->irqlock, flags);
+}
+
+/* -----------------------------------------------------------------------------
+ * DU Driver API
+ */
+
+int vsp1_du_init(struct device *dev)
+{
+	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
+
+	if (!vsp1)
+		return -EPROBE_DEFER;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(vsp1_du_init);
+
+/**
+ * vsp1_du_setup_lif - Setup the output part of the VSP pipeline
+ * @dev: the VSP device
+ * @width: output frame width in pixels
+ * @height: output frame height in pixels
+ *
+ * Configure the output part of VSP DRM pipeline for the given frame @width and
+ * @height. This sets up formats on the BRU source pad, the WPF0 sink and source
+ * pads, and the LIF sink pad.
+ *
+ * As the media bus code on the BRU source pad is conditioned by the
+ * configuration of the BRU sink 0 pad, we also set up the formats on all BRU
+ * sinks, even if the configuration will be overwritten later by
+ * vsp1_du_setup_rpf(). This ensures that the BRU configuration is set to a well
+ * defined state.
+ *
+ * Return 0 on success or a negative error code on failure.
+ */
+int vsp1_du_setup_lif(struct device *dev, unsigned int width,
+		      unsigned int height)
+{
+	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
+	struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
+	struct vsp1_bru *bru = vsp1->bru;
+	struct v4l2_subdev_format format;
+	unsigned int i;
+	int ret;
+
+	dev_dbg(vsp1->dev, "%s: configuring LIF with format %ux%u\n",
+		__func__, width, height);
+
+	if (width = 0 || height = 0) {
+		/* Zero width or height means the CRTC is being disabled, stop
+		 * the pipeline and turn the light off.
+		 */
+		ret = vsp1_pipeline_stop(pipe);
+		if (ret = -ETIMEDOUT)
+			dev_err(vsp1->dev, "DRM pipeline stop timeout\n");
+
+		media_entity_pipeline_stop(&pipe->output->entity.subdev.entity);
+
+		for (i = 0; i < bru->entity.source_pad; ++i) {
+			bru->inputs[i].rpf = NULL;
+			pipe->inputs[i] = NULL;
+		}
+
+		pipe->num_inputs = 0;
+
+		vsp1_device_put(vsp1);
+
+		dev_dbg(vsp1->dev, "%s: pipeline disabled\n", __func__);
+
+		return 0;
+	}
+
+	/* Configure the format at the BRU sinks and propagate it through the
+	 * pipeline.
+	 */
+	memset(&format, 0, sizeof(format));
+	format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+
+	for (i = 0; i < bru->entity.source_pad; ++i) {
+		format.pad = i;
+
+		format.format.width = width;
+		format.format.height = height;
+		format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
+		format.format.field = V4L2_FIELD_NONE;
+
+		ret = v4l2_subdev_call(&bru->entity.subdev, pad,
+				       set_fmt, NULL, &format);
+		if (ret < 0)
+			return ret;
+
+		dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
+			__func__, format.format.width, format.format.height,
+			format.format.code, i);
+	}
+
+	format.pad = bru->entity.source_pad;
+	format.format.width = width;
+	format.format.height = height;
+	format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
+	format.format.field = V4L2_FIELD_NONE;
+
+	ret = v4l2_subdev_call(&bru->entity.subdev, pad, set_fmt, NULL,
+			       &format);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
+		__func__, format.format.width, format.format.height,
+		format.format.code, i);
+
+	format.pad = RWPF_PAD_SINK;
+	ret = v4l2_subdev_call(&vsp1->wpf[0]->entity.subdev, pad, set_fmt, NULL,
+			       &format);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on WPF0 sink\n",
+		__func__, format.format.width, format.format.height,
+		format.format.code);
+
+	format.pad = RWPF_PAD_SOURCE;
+	ret = v4l2_subdev_call(&vsp1->wpf[0]->entity.subdev, pad, get_fmt, NULL,
+			       &format);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(vsp1->dev, "%s: got format %ux%u (%x) on WPF0 source\n",
+		__func__, format.format.width, format.format.height,
+		format.format.code);
+
+	format.pad = LIF_PAD_SINK;
+	ret = v4l2_subdev_call(&vsp1->lif->entity.subdev, pad, set_fmt, NULL,
+			       &format);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on LIF sink\n",
+		__func__, format.format.width, format.format.height,
+		format.format.code);
+
+	/* Verify that the format at the output of the pipeline matches the
+	 * requested frame size and media bus code.
+	 */
+	if (format.format.width != width || format.format.height != height ||
+	    format.format.code != MEDIA_BUS_FMT_ARGB8888_1X32) {
+		dev_dbg(vsp1->dev, "%s: format mismatch\n", __func__);
+		return -EPIPE;
+	}
+
+	/* Mark the pipeline as streaming and enable the VSP1. This will store
+	 * the pipeline pointer in all entities, which the s_stream handlers
+	 * will need. We don't start the entities themselves right at this point
+	 * as there's no plane configured yet, so we can't start processing
+	 * buffers.
+	 */
+	ret = vsp1_device_get(vsp1);
+	if (ret < 0)
+		return ret;
+
+	ret = media_entity_pipeline_start(&pipe->output->entity.subdev.entity,
+					  &pipe->pipe);
+	if (ret < 0) {
+		dev_dbg(vsp1->dev, "%s: pipeline start failed\n", __func__);
+		vsp1_device_put(vsp1);
+		return ret;
+	}
+
+	dev_dbg(vsp1->dev, "%s: pipeline enabled\n", __func__);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(vsp1_du_setup_lif);
+
+/**
+ * vsp1_du_setup_rpf - Setup one RPF input of the VSP pipeline
+ * @dev: the VSP device
+ * @rpf_index: index of the RPF to setup (0-based)
+ * @pixelformat: V4L2 pixel format for the RPF memory input
+ * @pitch: number of bytes per line in the image stored in memory
+ * @mem: DMA addresses of the memory buffers (one per plane)
+ * @src: the source crop rectangle for the RPF
+ * @dst: the destination compose rectangle for the BRU input
+ *
+ * Configure the VSP to perform composition of the image referenced by @mem
+ * through RPF @rpf_index, using the @src crop rectangle and the @dst
+ * composition rectangle. The Z-order is fixed with RPF 0 at the bottom.
+ *
+ * Image format as stored in memory is expressed as a V4L2 @pixelformat value.
+ * As a special case, setting the pixel format to 0 will disable the RPF. The
+ * @pitch, @mem, @src and @dst parameters are ignored in that case. Calling the
+ * function on a disabled RPF is allowed.
+ *
+ * The memory pitch is configurable to allow for padding at end of lines, or
+ * simple for images that extend beyond the crop rectangle boundaries. The
+ * @pitch value is expressed in bytes and applies to all planes for multiplanar
+ * formats.
+ *
+ * The source memory buffer is referenced by the DMA address of its planes in
+ * the @mem array. Up to two planes are supported. The second plane DMA address
+ * is ignored for formats using a single plane.
+ *
+ * This function isn't reentrant, the caller needs to serialize calls.
+ *
+ * TODO: Implement Z-order control by decoupling the RPF index from the BRU
+ * input index.
+ *
+ * Return 0 on success or a negative error code on failure.
+ */
+int vsp1_du_setup_rpf(struct device *dev, unsigned int rpf_index,
+		      u32 pixelformat, unsigned int pitch,
+		      dma_addr_t mem[2], const struct v4l2_rect *src,
+		      const struct v4l2_rect *dst)
+{
+	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
+	struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
+	const struct vsp1_format_info *fmtinfo;
+	struct v4l2_subdev_selection sel;
+	struct v4l2_subdev_format format;
+	struct vsp1_rwpf_memory memory;
+	struct vsp1_rwpf *rpf;
+	unsigned long flags;
+	bool start_stop = false;
+	int ret;
+
+	if (rpf_index >= vsp1->pdata.rpf_count)
+		return -EINVAL;
+
+	rpf = vsp1->rpf[rpf_index];
+
+	if (pixelformat = 0) {
+		dev_dbg(vsp1->dev, "%s: RPF%u: disable requested\n", __func__,
+			rpf_index);
+
+		spin_lock_irqsave(&pipe->irqlock, flags);
+
+		if (pipe->inputs[rpf_index]) {
+			/* Remove the RPF from the pipeline if it was previously
+			 * enabled.
+			 */
+			vsp1->bru->inputs[rpf_index].rpf = NULL;
+			pipe->inputs[rpf_index] = NULL;
+
+			vsp1->drm->update = true;
+			start_stop = --pipe->num_inputs = 0;
+		}
+
+		spin_unlock_irqrestore(&pipe->irqlock, flags);
+
+		/* Stop the pipeline if we're the last user. */
+		if (start_stop)
+			vsp1_pipeline_stop(pipe);
+
+		return 0;
+	}
+
+	dev_dbg(vsp1->dev,
+		"%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad }\n",
+		__func__, rpf_index,
+		src->left, src->top, src->width, src->height,
+		dst->left, dst->top, dst->width, dst->height,
+		pixelformat, pitch, &mem[0], &mem[1]);
+
+	/* Set the stride at the RPF input. */
+	fmtinfo = vsp1_get_format_info(pixelformat);
+	if (!fmtinfo) {
+		dev_dbg(vsp1->dev, "Unsupport pixel format %08x for RPF\n",
+			pixelformat);
+		return -EINVAL;
+	}
+
+	rpf->fmtinfo = fmtinfo;
+	rpf->format.num_planes = fmtinfo->planes;
+	rpf->format.plane_fmt[0].bytesperline = pitch;
+	rpf->format.plane_fmt[1].bytesperline = pitch;
+
+	/* Configure the format on the RPF sink pad and propagate it up to the
+	 * BRU sink pad.
+	 */
+	memset(&format, 0, sizeof(format));
+	format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	format.pad = RWPF_PAD_SINK;
+	format.format.width = src->width + src->left;
+	format.format.height = src->height + src->top;
+	format.format.code = fmtinfo->mbus;
+	format.format.field = V4L2_FIELD_NONE;
+
+	ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
+			       &format);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(vsp1->dev,
+		"%s: set format %ux%u (%x) on RPF%u sink\n",
+		__func__, format.format.width, format.format.height,
+		format.format.code, rpf->entity.index);
+
+	memset(&sel, 0, sizeof(sel));
+	sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	sel.pad = RWPF_PAD_SINK;
+	sel.target = V4L2_SEL_TGT_CROP;
+	sel.r = *src;
+
+	ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_selection, NULL,
+			       &sel);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(vsp1->dev,
+		"%s: set selection (%u,%u)/%ux%u on RPF%u sink\n",
+		__func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
+		rpf->entity.index);
+
+	/* RPF source, hardcode the format to ARGB8888 to turn on format
+	 * conversion if needed.
+	 */
+	format.pad = RWPF_PAD_SOURCE;
+
+	ret = v4l2_subdev_call(&rpf->entity.subdev, pad, get_fmt, NULL,
+			       &format);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(vsp1->dev,
+		"%s: got format %ux%u (%x) on RPF%u source\n",
+		__func__, format.format.width, format.format.height,
+		format.format.code, rpf->entity.index);
+
+	format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
+
+	ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
+			       &format);
+	if (ret < 0)
+		return ret;
+
+	/* BRU sink, propagate the format from the RPF source. */
+	format.pad = rpf->entity.index;
+
+	ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_fmt, NULL,
+			       &format);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
+		__func__, format.format.width, format.format.height,
+		format.format.code, format.pad);
+
+	sel.pad = rpf->entity.index;
+	sel.target = V4L2_SEL_TGT_COMPOSE;
+	sel.r = *dst;
+
+	ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_selection,
+			       NULL, &sel);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(vsp1->dev,
+		"%s: set selection (%u,%u)/%ux%u on BRU pad %u\n",
+		__func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
+		sel.pad);
+
+	/* Store the compose rectangle coordinates in the RPF. */
+	rpf->location.left = dst->left;
+	rpf->location.top = dst->top;
+
+	/* Set the memory buffer address. */
+	memory.num_planes = fmtinfo->planes;
+	memory.addr[0] = mem[0];
+	memory.addr[1] = mem[1];
+
+	rpf->ops->set_memory(rpf, &memory);
+
+	spin_lock_irqsave(&pipe->irqlock, flags);
+
+	/* If the RPF was previously stopped set the BRU input to the RPF and
+	 * store the RPF in the pipeline inputs array.
+	 */
+	if (!pipe->inputs[rpf->entity.index]) {
+		vsp1->bru->inputs[rpf_index].rpf = rpf;
+		pipe->inputs[rpf->entity.index] = rpf;
+		start_stop = pipe->num_inputs++ = 0;
+	}
+
+	/* Start the pipeline if it's currently stopped. */
+	vsp1->drm->update = true;
+	if (start_stop)
+		vsp1_drm_pipeline_run(pipe);
+
+	spin_unlock_irqrestore(&pipe->irqlock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(vsp1_du_setup_rpf);
+
+/* -----------------------------------------------------------------------------
+ * Initialization
+ */
+
+int vsp1_drm_create_links(struct vsp1_device *vsp1)
+{
+	const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
+	unsigned int i;
+	int ret;
+
+	/* VSPD instances require a BRU to perform composition. */
+	if (!vsp1->bru)
+		return -ENXIO;
+
+	for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
+		struct vsp1_rwpf *rpf = vsp1->rpf[i];
+
+		ret = media_entity_create_link(&rpf->entity.subdev.entity,
+					       RWPF_PAD_SOURCE,
+					       &vsp1->bru->entity.subdev.entity,
+					       i, flags);
+		if (ret < 0)
+			return ret;
+
+		rpf->entity.sink = &vsp1->bru->entity.subdev.entity;
+		rpf->entity.sink_pad = i;
+	}
+
+	ret = media_entity_create_link(&vsp1->bru->entity.subdev.entity,
+				       vsp1->bru->entity.source_pad,
+				       &vsp1->wpf[0]->entity.subdev.entity,
+				       RWPF_PAD_SINK, flags);
+	if (ret < 0)
+		return ret;
+
+	vsp1->bru->entity.sink = &vsp1->wpf[0]->entity.subdev.entity;
+	vsp1->bru->entity.sink_pad = RWPF_PAD_SINK;
+
+	ret = media_entity_create_link(&vsp1->wpf[0]->entity.subdev.entity,
+				       RWPF_PAD_SOURCE,
+				       &vsp1->lif->entity.subdev.entity,
+				       LIF_PAD_SINK, flags);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int vsp1_drm_init(struct vsp1_device *vsp1)
+{
+	struct vsp1_pipeline *pipe;
+	unsigned int i;
+
+	vsp1->drm = devm_kzalloc(vsp1->dev, sizeof(*vsp1->drm), GFP_KERNEL);
+	if (!vsp1->drm)
+		return -ENOMEM;
+
+	pipe = &vsp1->drm->pipe;
+
+	vsp1_pipeline_init(pipe);
+	pipe->frame_end = vsp1_drm_pipeline_frame_end;
+
+	/* The DRM pipeline is static, add entities manually. */
+	for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
+		struct vsp1_rwpf *input = vsp1->rpf[i];
+
+		list_add_tail(&input->entity.list_pipe, &pipe->entities);
+	}
+
+	list_add_tail(&vsp1->bru->entity.list_pipe, &pipe->entities);
+	list_add_tail(&vsp1->wpf[0]->entity.list_pipe, &pipe->entities);
+	list_add_tail(&vsp1->lif->entity.list_pipe, &pipe->entities);
+
+	pipe->bru = &vsp1->bru->entity;
+	pipe->lif = &vsp1->lif->entity;
+	pipe->output = vsp1->wpf[0];
+
+	return 0;
+}
diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
new file mode 100644
index 000000000000..2ad320ab1e45
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_drm.h
@@ -0,0 +1,26 @@
+/*
+ * vsp1_drm.h  --  R-Car VSP1 DRM/KMS Interface
+ *
+ * Copyright (C) 2015 Renesas Electronics Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __VSP1_DRM_H__
+#define __VSP1_DRM_H__
+
+#include "vsp1_pipe.h"
+
+struct vsp1_drm {
+	struct vsp1_pipeline pipe;
+	bool update;
+};
+
+int vsp1_drm_init(struct vsp1_device *vsp1);
+int vsp1_drm_create_links(struct vsp1_device *vsp1);
+
+#endif /* __VSP1_DRM_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 6d086c048975..377b167892e3 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -25,6 +25,7 @@
 
 #include "vsp1.h"
 #include "vsp1_bru.h"
+#include "vsp1_drm.h"
 #include "vsp1_hsit.h"
 #include "vsp1_lif.h"
 #include "vsp1_lut.h"
@@ -120,7 +121,7 @@ static int vsp1_create_sink_links(struct vsp1_device *vsp1,
 	return 0;
 }
 
-static int vsp1_create_links(struct vsp1_device *vsp1)
+static int vsp1_uapi_create_links(struct vsp1_device *vsp1)
 {
 	struct vsp1_entity *entity;
 	unsigned int i;
@@ -144,9 +145,6 @@ static int vsp1_create_links(struct vsp1_device *vsp1)
 			return ret;
 	}
 
-	if (!vsp1->pdata.uapi)
-		return 0;
-
 	for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
 		struct vsp1_rwpf *rpf = vsp1->rpf[i];
 
@@ -355,7 +353,10 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	/* Create links. */
-	ret = vsp1_create_links(vsp1);
+	if (vsp1->pdata.uapi)
+		ret = vsp1_uapi_create_links(vsp1);
+	else
+		ret = vsp1_drm_create_links(vsp1);
 	if (ret < 0)
 		goto done;
 
@@ -369,6 +370,8 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 
 	if (vsp1->pdata.uapi)
 		ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev);
+	else
+		ret = vsp1_drm_init(vsp1);
 
 done:
 	if (ret < 0)
diff --git a/include/media/vsp1.h b/include/media/vsp1.h
new file mode 100644
index 000000000000..2c1aea7066be
--- /dev/null
+++ b/include/media/vsp1.h
@@ -0,0 +1,30 @@
+/*
+ * vsp1.h  --  R-Car VSP1 API
+ *
+ * Copyright (C) 2015 Renesas Electronics Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __MEDIA_VSP1_H__
+#define __MEDIA_VSP1_H__
+
+#include <linux/types.h>
+
+struct device;
+struct v4l2_rect;
+
+int vsp1_du_init(struct device *dev);
+
+int vsp1_du_setup_lif(struct device *dev, unsigned int width,
+		      unsigned int height);
+
+int vsp1_du_setup_rpf(struct device *dev, unsigned int rpf, u32 pixelformat,
+		      unsigned int pitch, dma_addr_t mem[2],
+		      const struct v4l2_rect *src, const struct v4l2_rect *dst);
+
+#endif /* __MEDIA_VSP1_H__ */
-- 
2.4.10


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

* [PATCH v2 29/32] v4l: vsp1: Disconnect unused RPFs from the DRM pipeline
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (27 preceding siblings ...)
  2015-12-05  2:13 ` [PATCH v2 28/32] v4l: vsp1: Add VSP+DU support Laurent Pinchart
@ 2015-12-05  2:13 ` Laurent Pinchart
  2015-12-05  2:13 ` [PATCH v2 30/32] v4l: vsp1: Implement atomic update for the DRM driver Laurent Pinchart
                   ` (3 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:13 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_drm.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 2969d570f462..5cef619b708d 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -38,13 +38,17 @@ static int vsp1_drm_pipeline_run(struct vsp1_pipeline *pipe)
 		struct vsp1_entity *entity;
 
 		list_for_each_entry(entity, &pipe->entities, list_pipe) {
-			/* Skip unused RPFs. */
+			/* Disconnect unused RPFs from the pipeline. */
 			if (entity->type = VSP1_ENTITY_RPF) {
 				struct vsp1_rwpf *rpf  					to_rwpf(&entity->subdev);
 
-				if (!pipe->inputs[rpf->entity.index])
+				if (!pipe->inputs[rpf->entity.index]) {
+					vsp1_write(entity->vsp1,
+						   entity->route->reg,
+						   VI6_DPR_NODE_UNUSED);
 					continue;
+				}
 			}
 
 			vsp1_entity_route_setup(entity);
-- 
2.4.10


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

* [PATCH v2 30/32] v4l: vsp1: Implement atomic update for the DRM driver
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (28 preceding siblings ...)
  2015-12-05  2:13 ` [PATCH v2 29/32] v4l: vsp1: Disconnect unused RPFs from the DRM pipeline Laurent Pinchart
@ 2015-12-05  2:13 ` Laurent Pinchart
  2015-12-05  2:13 ` [PATCH v2 31/32] v4l: vsp1: Add support for the R-Car Gen3 VSP2 Laurent Pinchart
                   ` (2 subsequent siblings)
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:13 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Add two API functions named vsp1_du_atomic_begin() and
vsp1_du_atomic_flush() to signal the start and end of an atomic update.
The vsp1_du_setup_rpf() function is renamed to vsp1_du_atomic_update()
for consistency.

With this new API, the driver will reprogram all modified inputs
atomically before restarting the video stream.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/platform/vsp1/vsp1_drm.c | 70 +++++++++++++++++++++++++---------
 drivers/media/platform/vsp1/vsp1_drm.h |  7 ++++
 include/media/vsp1.h                   |  9 +++--
 3 files changed, 66 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 5cef619b708d..ef8e91d65209 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -254,7 +254,26 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width,
 EXPORT_SYMBOL_GPL(vsp1_du_setup_lif);
 
 /**
- * vsp1_du_setup_rpf - Setup one RPF input of the VSP pipeline
+ * vsp1_du_atomic_begin - Prepare for an atomic update
+ * @dev: the VSP device
+ */
+void vsp1_du_atomic_begin(struct device *dev)
+{
+	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
+	struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pipe->irqlock, flags);
+
+	vsp1->drm->num_inputs = pipe->num_inputs;
+	vsp1->drm->update = false;
+
+	spin_unlock_irqrestore(&pipe->irqlock, flags);
+}
+EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin);
+
+/**
+ * vsp1_du_atomic_update - Setup one RPF input of the VSP pipeline
  * @dev: the VSP device
  * @rpf_index: index of the RPF to setup (0-based)
  * @pixelformat: V4L2 pixel format for the RPF memory input
@@ -288,10 +307,10 @@ EXPORT_SYMBOL_GPL(vsp1_du_setup_lif);
  *
  * Return 0 on success or a negative error code on failure.
  */
-int vsp1_du_setup_rpf(struct device *dev, unsigned int rpf_index,
-		      u32 pixelformat, unsigned int pitch,
-		      dma_addr_t mem[2], const struct v4l2_rect *src,
-		      const struct v4l2_rect *dst)
+int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
+			  u32 pixelformat, unsigned int pitch,
+			  dma_addr_t mem[2], const struct v4l2_rect *src,
+			  const struct v4l2_rect *dst)
 {
 	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
 	struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
@@ -301,7 +320,6 @@ int vsp1_du_setup_rpf(struct device *dev, unsigned int rpf_index,
 	struct vsp1_rwpf_memory memory;
 	struct vsp1_rwpf *rpf;
 	unsigned long flags;
-	bool start_stop = false;
 	int ret;
 
 	if (rpf_index >= vsp1->pdata.rpf_count)
@@ -322,16 +340,11 @@ int vsp1_du_setup_rpf(struct device *dev, unsigned int rpf_index,
 			vsp1->bru->inputs[rpf_index].rpf = NULL;
 			pipe->inputs[rpf_index] = NULL;
 
-			vsp1->drm->update = true;
-			start_stop = --pipe->num_inputs = 0;
+			pipe->num_inputs--;
 		}
 
 		spin_unlock_irqrestore(&pipe->irqlock, flags);
 
-		/* Stop the pipeline if we're the last user. */
-		if (start_stop)
-			vsp1_pipeline_stop(pipe);
-
 		return 0;
 	}
 
@@ -459,19 +472,42 @@ int vsp1_du_setup_rpf(struct device *dev, unsigned int rpf_index,
 	if (!pipe->inputs[rpf->entity.index]) {
 		vsp1->bru->inputs[rpf_index].rpf = rpf;
 		pipe->inputs[rpf->entity.index] = rpf;
-		start_stop = pipe->num_inputs++ = 0;
+		pipe->num_inputs++;
 	}
 
-	/* Start the pipeline if it's currently stopped. */
+	spin_unlock_irqrestore(&pipe->irqlock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
+
+/**
+ * vsp1_du_atomic_flush - Commit an atomic update
+ * @dev: the VSP device
+ */
+void vsp1_du_atomic_flush(struct device *dev)
+{
+	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
+	struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
+	unsigned long flags;
+	bool stop = false;
+
+	spin_lock_irqsave(&pipe->irqlock, flags);
+
 	vsp1->drm->update = true;
-	if (start_stop)
+
+	/* Start or stop the pipeline if needed. */
+	if (!vsp1->drm->num_inputs && pipe->num_inputs)
 		vsp1_drm_pipeline_run(pipe);
+	else if (vsp1->drm->num_inputs && !pipe->num_inputs)
+		stop = true;
 
 	spin_unlock_irqrestore(&pipe->irqlock, flags);
 
-	return 0;
+	if (stop)
+		vsp1_pipeline_stop(pipe);
 }
-EXPORT_SYMBOL_GPL(vsp1_du_setup_rpf);
+EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush);
 
 /* -----------------------------------------------------------------------------
  * Initialization
diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
index 2ad320ab1e45..25d7f017feb4 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.h
+++ b/drivers/media/platform/vsp1/vsp1_drm.h
@@ -15,8 +15,15 @@
 
 #include "vsp1_pipe.h"
 
+/**
+ * vsp1_drm - State for the API exposed to the DRM driver
+ * @pipe: the VSP1 pipeline used for display
+ * @num_inputs: number of active pipeline inputs at the beginning of an update
+ * @update: the pipeline configuration has been updated
+ */
 struct vsp1_drm {
 	struct vsp1_pipeline pipe;
+	unsigned int num_inputs;
 	bool update;
 };
 
diff --git a/include/media/vsp1.h b/include/media/vsp1.h
index 2c1aea7066be..cc541753896f 100644
--- a/include/media/vsp1.h
+++ b/include/media/vsp1.h
@@ -23,8 +23,11 @@ int vsp1_du_init(struct device *dev);
 int vsp1_du_setup_lif(struct device *dev, unsigned int width,
 		      unsigned int height);
 
-int vsp1_du_setup_rpf(struct device *dev, unsigned int rpf, u32 pixelformat,
-		      unsigned int pitch, dma_addr_t mem[2],
-		      const struct v4l2_rect *src, const struct v4l2_rect *dst);
+int vsp1_du_atomic_begin(struct device *dev);
+int vsp1_du_atomic_update(struct device *dev, unsigned int rpf, u32 pixelformat,
+			  unsigned int pitch, dma_addr_t mem[2],
+			  const struct v4l2_rect *src,
+			  const struct v4l2_rect *dst);
+int vsp1_du_atomic_flush(struct device *dev);
 
 #endif /* __MEDIA_VSP1_H__ */
-- 
2.4.10


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

* [PATCH v2 31/32] v4l: vsp1: Add support for the R-Car Gen3 VSP2
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (29 preceding siblings ...)
  2015-12-05  2:13 ` [PATCH v2 30/32] v4l: vsp1: Implement atomic update for the DRM driver Laurent Pinchart
@ 2015-12-05  2:13 ` Laurent Pinchart
  2015-12-05  2:13 ` [PATCH v2 32/32] v4l: vsp1: Add display list support Laurent Pinchart
  2015-12-05 10:57 ` [PATCH v2 00/32] VSP: Add R-Car Gen3 support Geert Uytterhoeven
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:13 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

Add DT compatible strings for the VSP2 instances found in the R-Car Gen3
SoCs and support them in the vsp1 driver.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---

Changes since v1:

- Configure device parameters based on the version register

---
 .../devicetree/bindings/media/renesas,vsp1.txt     | 20 ++++++++-------
 drivers/media/platform/vsp1/vsp1_drv.c             | 25 ++++++++++++++++++
 drivers/media/platform/vsp1/vsp1_entity.c          |  3 ++-
 drivers/media/platform/vsp1/vsp1_regs.h            | 30 +++++++++++++++++-----
 4 files changed, 62 insertions(+), 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/renesas,vsp1.txt b/Documentation/devicetree/bindings/media/renesas,vsp1.txt
index 674c8c30d046..fe74fb38e4d5 100644
--- a/Documentation/devicetree/bindings/media/renesas,vsp1.txt
+++ b/Documentation/devicetree/bindings/media/renesas,vsp1.txt
@@ -1,24 +1,26 @@
-* Renesas VSP1 Video Processing Engine
+* Renesas VSP Video Processing Engine
 
-The VSP1 is a video processing engine that supports up-/down-scaling, alpha
+The VSP is a video processing engine that supports up-/down-scaling, alpha
 blending, color space conversion and various other image processing features.
 It can be found in the Renesas R-Car second generation SoCs.
 
 Required properties:
 
-  - compatible: Must contain "renesas,vsp1"
+  - compatible: Must contain one of the following values
+    - "renesas,vsp1" for the R-Car Gen2 VSP1
+    - "renesas,vsp2" for the R-Car Gen3 VSP2
 
-  - reg: Base address and length of the registers block for the VSP1.
-  - interrupts: VSP1 interrupt specifier.
-  - clocks: A phandle + clock-specifier pair for the VSP1 functional clock.
+  - reg: Base address and length of the registers block for the VSP.
+  - interrupts: VSP interrupt specifier.
+  - clocks: A phandle + clock-specifier pair for the VSP functional clock.
 
-  - renesas,#rpf: Number of Read Pixel Formatter (RPF) modules in the VSP1.
-  - renesas,#wpf: Number of Write Pixel Formatter (WPF) modules in the VSP1.
+  - renesas,#rpf: Number of Read Pixel Formatter (RPF) modules in the VSP.
+  - renesas,#wpf: Number of Write Pixel Formatter (WPF) modules in the VSP.
 
 
 Optional properties:
 
-  - renesas,#uds: Number of Up Down Scaler (UDS) modules in the VSP1. Defaults
+  - renesas,#uds: Number of Up Down Scaler (UDS) modules in the VSP. Defaults
     to 0 if not present.
   - renesas,has-lif: Boolean, indicates that the LCD Interface (LIF) module is
     available.
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 377b167892e3..9a30c96dc642 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -575,6 +575,7 @@ static int vsp1_probe(struct platform_device *pdev)
 	struct vsp1_device *vsp1;
 	struct resource *irq;
 	struct resource *io;
+	u32 version;
 	int ret;
 
 	vsp1 = devm_kzalloc(&pdev->dev, sizeof(*vsp1), GFP_KERNEL);
@@ -615,6 +616,29 @@ static int vsp1_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	/* Configure device parameters based on the version register. */
+	ret = clk_prepare_enable(vsp1->clock);
+	if (ret < 0)
+		return ret;
+
+	version = vsp1_read(vsp1, VI6_IP_VERSION);
+	clk_disable_unprepare(vsp1->clock);
+
+	dev_dbg(&pdev->dev, "IP version 0x%08x\n", version);
+
+	switch (version & VI6_IP_VERSION_MODEL_MASK) {
+	case VI6_IP_VERSION_MODEL_VSPD_GEN3:
+		vsp1->pdata.num_bru_inputs = 5;
+		vsp1->pdata.uapi = false;
+		break;
+
+	case VI6_IP_VERSION_MODEL_VSPI_GEN3:
+	case VI6_IP_VERSION_MODEL_VSPBD_GEN3:
+	case VI6_IP_VERSION_MODEL_VSPBC_GEN3:
+		vsp1->pdata.features &= ~VSP1_HAS_BRU;
+		break;
+	}
+
 	/* Instanciate entities */
 	ret = vsp1_create_entities(vsp1);
 	if (ret < 0) {
@@ -638,6 +662,7 @@ static int vsp1_remove(struct platform_device *pdev)
 
 static const struct of_device_id vsp1_of_match[] = {
 	{ .compatible = "renesas,vsp1" },
+	{ .compatible = "renesas,vsp2" },
 	{ },
 };
 
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 38a496f43050..4b46cb0e0e8a 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -165,7 +165,8 @@ int vsp1_entity_link_setup(struct media_entity *entity,
 static const struct vsp1_route vsp1_routes[] = {
 	{ VSP1_ENTITY_BRU, 0, VI6_DPR_BRU_ROUTE,
 	  { VI6_DPR_NODE_BRU_IN(0), VI6_DPR_NODE_BRU_IN(1),
-	    VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3), } },
+	    VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3),
+	    VI6_DPR_NODE_BRU_IN(4) } },
 	{ VSP1_ENTITY_HSI, 0, VI6_DPR_HSI_ROUTE, { VI6_DPR_NODE_HSI, } },
 	{ VSP1_ENTITY_HST, 0, VI6_DPR_HST_ROUTE, { VI6_DPR_NODE_HST, } },
 	{ VSP1_ENTITY_LIF, 0, 0, { VI6_DPR_NODE_LIF, } },
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 8173ceaab9f9..a3a0a15d9997 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -322,7 +322,7 @@
 #define VI6_DPR_NODE_SRU		16
 #define VI6_DPR_NODE_UDS(n)		(17 + (n))
 #define VI6_DPR_NODE_LUT		22
-#define VI6_DPR_NODE_BRU_IN(n)		(23 + (n))
+#define VI6_DPR_NODE_BRU_IN(n)		(((n) <= 3) ? 23 + (n) : 49)
 #define VI6_DPR_NODE_BRU_OUT		27
 #define VI6_DPR_NODE_CLU		29
 #define VI6_DPR_NODE_HST		30
@@ -504,12 +504,12 @@
 #define VI6_BRU_VIRRPF_COL_BCB_MASK	(0xff << 0)
 #define VI6_BRU_VIRRPF_COL_BCB_SHIFT	0
 
-#define VI6_BRU_CTRL(n)			(0x2c10 + (n) * 8)
+#define VI6_BRU_CTRL(n)			(0x2c10 + (n) * 8 + ((n) <= 3 ? 0 : 4))
 #define VI6_BRU_CTRL_RBC		(1 << 31)
-#define VI6_BRU_CTRL_DSTSEL_BRUIN(n)	((n) << 20)
+#define VI6_BRU_CTRL_DSTSEL_BRUIN(n)	(((n) <= 3 ? (n) : (n)+1) << 20)
 #define VI6_BRU_CTRL_DSTSEL_VRPF	(4 << 20)
 #define VI6_BRU_CTRL_DSTSEL_MASK	(7 << 20)
-#define VI6_BRU_CTRL_SRCSEL_BRUIN(n)	((n) << 16)
+#define VI6_BRU_CTRL_SRCSEL_BRUIN(n)	(((n) <= 3 ? (n) : (n)+1) << 16)
 #define VI6_BRU_CTRL_SRCSEL_VRPF	(4 << 16)
 #define VI6_BRU_CTRL_SRCSEL_MASK	(7 << 16)
 #define VI6_BRU_CTRL_CROP(rop)		((rop) << 4)
@@ -517,7 +517,7 @@
 #define VI6_BRU_CTRL_AROP(rop)		((rop) << 0)
 #define VI6_BRU_CTRL_AROP_MASK		(0xf << 0)
 
-#define VI6_BRU_BLD(n)			(0x2c14 + (n) * 8)
+#define VI6_BRU_BLD(n)			(0x2c14 + (n) * 8 + ((n) <= 3 ? 0 : 4))
 #define VI6_BRU_BLD_CBES		(1 << 31)
 #define VI6_BRU_BLD_CCMDX_DST_A		(0 << 28)
 #define VI6_BRU_BLD_CCMDX_255_DST_A	(1 << 28)
@@ -551,7 +551,7 @@
 #define VI6_BRU_BLD_COEFY_SHIFT		0
 
 #define VI6_BRU_ROP			0x2c30
-#define VI6_BRU_ROP_DSTSEL_BRUIN(n)	((n) << 20)
+#define VI6_BRU_ROP_DSTSEL_BRUIN(n)	(((n) <= 3 ? (n) : (n)+1) << 20)
 #define VI6_BRU_ROP_DSTSEL_VRPF		(4 << 20)
 #define VI6_BRU_ROP_DSTSEL_MASK		(7 << 20)
 #define VI6_BRU_ROP_CROP(rop)		((rop) << 4)
@@ -625,6 +625,24 @@
 #define VI6_SECURITY_CTRL1		0x3d04
 
 /* -----------------------------------------------------------------------------
+ * IP Version Registers
+ */
+
+#define VI6_IP_VERSION			0x3f00
+#define VI6_IP_VERSION_MODEL_MASK	(0xff << 8)
+#define VI6_IP_VERSION_MODEL_VSPS_H2	(0x09 << 8)
+#define VI6_IP_VERSION_MODEL_VSPR_GEN2	(0x0a << 8)
+#define VI6_IP_VERSION_MODEL_VSPD_H2	(0x0b << 8)
+#define VI6_IP_VERSION_MODEL_VSPS_M2	(0x0c << 8)
+#define VI6_IP_VERSION_MODEL_VSPI_GEN3	(0x14 << 8)
+#define VI6_IP_VERSION_MODEL_VSPBD_GEN3	(0x15 << 8)
+#define VI6_IP_VERSION_MODEL_VSPBC_GEN3	(0x16 << 8)
+#define VI6_IP_VERSION_MODEL_VSPD_GEN3	(0x17 << 8)
+#define VI6_IP_VERSION_SOC_MASK		(0xff << 0)
+#define VI6_IP_VERSION_SOC_H		(0x01 << 0)
+#define VI6_IP_VERSION_SOC_M		(0x02 << 0)
+
+/* -----------------------------------------------------------------------------
  * RPF CLUT Registers
  */
 
-- 
2.4.10


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

* [PATCH v2 32/32] v4l: vsp1: Add display list support
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (30 preceding siblings ...)
  2015-12-05  2:13 ` [PATCH v2 31/32] v4l: vsp1: Add support for the R-Car Gen3 VSP2 Laurent Pinchart
@ 2015-12-05  2:13 ` Laurent Pinchart
  2015-12-05 10:57 ` [PATCH v2 00/32] VSP: Add R-Car Gen3 support Geert Uytterhoeven
  32 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05  2:13 UTC (permalink / raw)
  To: linux-media; +Cc: linux-sh

From: Takashi Saito <takashi.saitou.ry@renesas.com>

Display lists contain lists of registers and associated values to be
applied atomically by the hardware. They lower the pressure on interrupt
processing delays when reprogramming the device as settings can be
prepared well in advance and queued to the hardware without waiting for
the end of the current frame.

Display list support is currently limited to the DRM pipeline.

Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

---

Changes since v1:

- Squash with commit 'v4l: vsp1: Initialize display list when preparing
  for atomic update'
---
 drivers/media/platform/vsp1/Makefile      |   2 +-
 drivers/media/platform/vsp1/vsp1.h        |  17 ++
 drivers/media/platform/vsp1/vsp1_bru.c    |   2 +-
 drivers/media/platform/vsp1/vsp1_dl.c     | 304 ++++++++++++++++++++++++++++++
 drivers/media/platform/vsp1/vsp1_dl.h     |  42 +++++
 drivers/media/platform/vsp1/vsp1_drm.c    | 105 ++++++-----
 drivers/media/platform/vsp1/vsp1_drm.h    |   5 +
 drivers/media/platform/vsp1/vsp1_drv.c    |  76 +++++---
 drivers/media/platform/vsp1/vsp1_entity.c |   4 +-
 drivers/media/platform/vsp1/vsp1_lif.c    |   4 +-
 drivers/media/platform/vsp1/vsp1_pipe.c   |  54 +++++-
 drivers/media/platform/vsp1/vsp1_pipe.h   |   5 +
 drivers/media/platform/vsp1/vsp1_rpf.c    |   4 +-
 drivers/media/platform/vsp1/vsp1_wpf.c    |  13 +-
 14 files changed, 542 insertions(+), 95 deletions(-)
 create mode 100644 drivers/media/platform/vsp1/vsp1_dl.c
 create mode 100644 drivers/media/platform/vsp1/vsp1_dl.h

diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
index 447e72a2ef43..95b3ac2ea7ef 100644
--- a/drivers/media/platform/vsp1/Makefile
+++ b/drivers/media/platform/vsp1/Makefile
@@ -1,5 +1,5 @@
 vsp1-y					:= vsp1_drv.o vsp1_entity.o vsp1_pipe.o
-vsp1-y					+= vsp1_drm.o vsp1_video.o
+vsp1-y					+= vsp1_dl.o vsp1_drm.o vsp1_video.o
 vsp1-y					+= vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
 vsp1-y					+= vsp1_hsit.o vsp1_lif.o vsp1_lut.o
 vsp1-y					+= vsp1_bru.o vsp1_sru.o vsp1_uds.o
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 67a026ae88cb..5b210b69f09c 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -26,7 +26,9 @@
 struct clk;
 struct device;
 
+struct vsp1_dl;
 struct vsp1_drm;
+struct vsp1_entity;
 struct vsp1_platform_data;
 struct vsp1_bru;
 struct vsp1_hsit;
@@ -80,12 +82,17 @@ struct vsp1_device {
 	struct v4l2_device v4l2_dev;
 	struct media_device media_dev;
 	struct media_entity_operations media_ops;
+
 	struct vsp1_drm *drm;
+
+	bool use_dl;
 };
 
 int vsp1_device_get(struct vsp1_device *vsp1);
 void vsp1_device_put(struct vsp1_device *vsp1);
 
+int vsp1_reset_wpf(struct vsp1_device *vsp1, unsigned int index);
+
 static inline u32 vsp1_read(struct vsp1_device *vsp1, u32 reg)
 {
 	return ioread32(vsp1->mmio + reg);
@@ -96,4 +103,14 @@ static inline void vsp1_write(struct vsp1_device *vsp1, u32 reg, u32 data)
 	iowrite32(data, vsp1->mmio + reg);
 }
 
+#include "vsp1_dl.h"
+
+static inline void vsp1_mod_write(struct vsp1_entity *e, u32 reg, u32 data)
+{
+	if (e->vsp1->use_dl)
+		vsp1_dl_add(e, reg, data);
+	else
+		vsp1_write(e->vsp1, reg, data);
+}
+
 #endif /* __VSP1_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index 848bfb5a42ff..32e2009c215a 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -30,7 +30,7 @@
 
 static inline void vsp1_bru_write(struct vsp1_bru *bru, u32 reg, u32 data)
 {
-	vsp1_write(bru->entity.vsp1, reg, data);
+	vsp1_mod_write(&bru->entity, reg, data);
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
new file mode 100644
index 000000000000..a4dcccf0778b
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -0,0 +1,304 @@
+/*
+ * vsp1_dl.h  --  R-Car VSP1 Display List
+ *
+ * Copyright (C) 2015 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
+
+#include "vsp1.h"
+#include "vsp1_dl.h"
+#include "vsp1_pipe.h"
+
+/*
+ * Global resources
+ *
+ * - Display-related interrupts (can be used for vblank evasion ?)
+ * - Display-list enable
+ * - Header-less for WPF0
+ * - DL swap
+ */
+
+#define VSP1_DL_BODY_SIZE		(2 * 4 * 256)
+#define VSP1_DL_NUM_LISTS		3
+
+struct vsp1_dl_entry {
+	u32 addr;
+	u32 data;
+} __attribute__((__packed__));
+
+struct vsp1_dl_list {
+	size_t size;
+	int reg_count;
+
+	bool in_use;
+
+	struct vsp1_dl_entry *body;
+	dma_addr_t dma;
+};
+
+/**
+ * struct vsp1_dl - Display List manager
+ * @vsp1: the VSP1 device
+ * @lock: protects the active, queued and pending lists
+ * @lists.all: array of all allocate display lists
+ * @lists.active: list currently being processed (loaded) by hardware
+ * @lists.queued: list queued to the hardware (written to the DL registers)
+ * @lists.pending: list waiting to be queued to the hardware
+ * @lists.write: list being written to by software
+ */
+struct vsp1_dl {
+	struct vsp1_device *vsp1;
+
+	spinlock_t lock;
+
+	size_t size;
+	dma_addr_t dma;
+	void *mem;
+
+	struct {
+		struct vsp1_dl_list all[VSP1_DL_NUM_LISTS];
+
+		struct vsp1_dl_list *active;
+		struct vsp1_dl_list *queued;
+		struct vsp1_dl_list *pending;
+		struct vsp1_dl_list *write;
+	} lists;
+};
+
+/* -----------------------------------------------------------------------------
+ * Display List Transaction Management
+ */
+
+static void vsp1_dl_free_list(struct vsp1_dl_list *list)
+{
+	if (!list)
+		return;
+
+	list->in_use = false;
+}
+
+void vsp1_dl_reset(struct vsp1_dl *dl)
+{
+	unsigned int i;
+
+	dl->lists.active = NULL;
+	dl->lists.queued = NULL;
+	dl->lists.pending = NULL;
+	dl->lists.write = NULL;
+
+	for (i = 0; i < ARRAY_SIZE(dl->lists.all); ++i)
+		dl->lists.all[i].in_use = false;
+}
+
+void vsp1_dl_begin(struct vsp1_dl *dl)
+{
+	struct vsp1_dl_list *list = NULL;
+	unsigned long flags;
+	unsigned int i;
+
+	spin_lock_irqsave(&dl->lock, flags);
+
+	for (i = 0; i < ARRAY_SIZE(dl->lists.all); ++i) {
+		if (!dl->lists.all[i].in_use) {
+			list = &dl->lists.all[i];
+			break;
+		}
+	}
+
+	if (!list) {
+		list = dl->lists.pending;
+		dl->lists.pending = NULL;
+	}
+
+	spin_unlock_irqrestore(&dl->lock, flags);
+
+	dl->lists.write = list;
+
+	list->in_use = true;
+	list->reg_count = 0;
+}
+
+void vsp1_dl_add(struct vsp1_entity *e, u32 reg, u32 data)
+{
+	struct vsp1_pipeline *pipe = to_vsp1_pipeline(&e->subdev.entity);
+	struct vsp1_dl *dl = pipe->dl;
+	struct vsp1_dl_list *list = dl->lists.write;
+
+	list->body[list->reg_count].addr = reg;
+	list->body[list->reg_count].data = data;
+	list->reg_count++;
+}
+
+void vsp1_dl_commit(struct vsp1_dl *dl)
+{
+	struct vsp1_device *vsp1 = dl->vsp1;
+	struct vsp1_dl_list *list;
+	unsigned long flags;
+	bool update;
+
+	list = dl->lists.write;
+	dl->lists.write = NULL;
+
+	spin_lock_irqsave(&dl->lock, flags);
+
+	/* Once the UPD bit has been set the hardware can start processing the
+	 * display list at any time and we can't touch the address and size
+	 * registers. In that case mark the update as pending, it will be
+	 * queued up to the hardware by the frame end interrupt handler.
+	 */
+	update = !!(vsp1_read(vsp1, VI6_DL_BODY_SIZE) & VI6_DL_BODY_SIZE_UPD);
+	if (update) {
+		vsp1_dl_free_list(dl->lists.pending);
+		dl->lists.pending = list;
+		goto done;
+	}
+
+	/* Program the hardware with the display list body address and size.
+	 * The UPD bit will be cleared by the device when the display list is
+	 * processed.
+	 */
+	vsp1_write(vsp1, VI6_DL_HDR_ADDR(0), list->dma);
+	vsp1_write(vsp1, VI6_DL_BODY_SIZE, VI6_DL_BODY_SIZE_UPD |
+		   (list->reg_count * 8));
+
+	vsp1_dl_free_list(dl->lists.queued);
+	dl->lists.queued = list;
+
+done:
+	spin_unlock_irqrestore(&dl->lock, flags);
+}
+
+/* -----------------------------------------------------------------------------
+ * Interrupt Handling
+ */
+
+void vsp1_dl_irq_display_start(struct vsp1_dl *dl)
+{
+	spin_lock(&dl->lock);
+
+	/* The display start interrupt signals the end of the display list
+	 * processing by the device. The active display list, if any, won't be
+	 * accessed anymore and can be reused.
+	 */
+	if (dl->lists.active) {
+		vsp1_dl_free_list(dl->lists.active);
+		dl->lists.active = NULL;
+	}
+
+	spin_unlock(&dl->lock);
+}
+
+void vsp1_dl_irq_frame_end(struct vsp1_dl *dl)
+{
+	struct vsp1_device *vsp1 = dl->vsp1;
+
+	spin_lock(&dl->lock);
+
+	/* The UPD bit set indicates that the commit operation raced with the
+	 * interrupt and occurred after the frame end event and UPD clear but
+	 * before interrupt processing. The hardware hasn't taken the update
+	 * into account yet, we'll thus skip one frame and retry.
+	 */
+	if (vsp1_read(vsp1, VI6_DL_BODY_SIZE) & VI6_DL_BODY_SIZE_UPD)
+		goto done;
+
+	/* The device starts processing the queued display list right after the
+	 * frame end interrupt. The display list thus becomes active.
+	 */
+	if (dl->lists.queued) {
+		WARN_ON(dl->lists.active);
+		dl->lists.active = dl->lists.queued;
+		dl->lists.queued = NULL;
+	}
+
+	/* Now that the UPD bit has been cleared we can queue the next display
+	 * list to the hardware if one has been prepared.
+	 */
+	if (dl->lists.pending) {
+		struct vsp1_dl_list *list = dl->lists.pending;
+
+		vsp1_write(vsp1, VI6_DL_HDR_ADDR(0), list->dma);
+		vsp1_write(vsp1, VI6_DL_BODY_SIZE, VI6_DL_BODY_SIZE_UPD |
+			   (list->reg_count * 8));
+
+		dl->lists.queued = list;
+		dl->lists.pending = NULL;
+	}
+
+done:
+	spin_unlock(&dl->lock);
+}
+
+/* -----------------------------------------------------------------------------
+ * Hardware Setup
+ */
+
+void vsp1_dl_setup(struct vsp1_device *vsp1)
+{
+	u32 ctrl = (256 << VI6_DL_CTRL_AR_WAIT_SHIFT)
+		 | VI6_DL_CTRL_DC2 | VI6_DL_CTRL_DC1 | VI6_DL_CTRL_DC0
+		 | VI6_DL_CTRL_DLE;
+
+	/* The DRM pipeline operates with header-less display lists in
+	 * Continuous Frame Mode.
+	 */
+	if (vsp1->drm)
+		ctrl |= VI6_DL_CTRL_CFM0 | VI6_DL_CTRL_NH0;
+
+	vsp1_write(vsp1, VI6_DL_CTRL, ctrl);
+	vsp1_write(vsp1, VI6_DL_SWAP, VI6_DL_SWAP_LWS);
+}
+
+/* -----------------------------------------------------------------------------
+ * Initialization and Cleanup
+ */
+
+struct vsp1_dl *vsp1_dl_create(struct vsp1_device *vsp1)
+{
+	struct vsp1_dl *dl;
+	unsigned int i;
+
+	dl = kzalloc(sizeof(*dl), GFP_KERNEL);
+	if (!dl)
+		return NULL;
+
+	spin_lock_init(&dl->lock);
+
+	dl->vsp1 = vsp1;
+	dl->size = VSP1_DL_BODY_SIZE * ARRAY_SIZE(dl->lists.all);
+
+	dl->mem = dma_alloc_writecombine(vsp1->dev, dl->size, &dl->dma,
+					 GFP_KERNEL);
+	if (!dl->mem) {
+		kfree(dl);
+		return NULL;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(dl->lists.all); ++i) {
+		struct vsp1_dl_list *list = &dl->lists.all[i];
+
+		list->size = VSP1_DL_BODY_SIZE;
+		list->reg_count = 0;
+		list->in_use = false;
+		list->dma = dl->dma + VSP1_DL_BODY_SIZE * i;
+		list->body = dl->mem + VSP1_DL_BODY_SIZE * i;
+	}
+
+	return dl;
+}
+
+void vsp1_dl_destroy(struct vsp1_dl *dl)
+{
+	dma_free_writecombine(dl->vsp1->dev, dl->size, dl->mem, dl->dma);
+	kfree(dl);
+}
diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h
new file mode 100644
index 000000000000..448c4250e54c
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_dl.h
@@ -0,0 +1,42 @@
+/*
+ * vsp1_dl.h  --  R-Car VSP1 Display List
+ *
+ * Copyright (C) 2015 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __VSP1_DL_H__
+#define __VSP1_DL_H__
+
+#include "vsp1_entity.h"
+
+struct vsp1_device;
+struct vsp1_dl;
+
+struct vsp1_dl *vsp1_dl_create(struct vsp1_device *vsp1);
+void vsp1_dl_destroy(struct vsp1_dl *dl);
+
+void vsp1_dl_setup(struct vsp1_device *vsp1);
+
+void vsp1_dl_reset(struct vsp1_dl *dl);
+void vsp1_dl_begin(struct vsp1_dl *dl);
+void vsp1_dl_add(struct vsp1_entity *e, u32 reg, u32 data);
+void vsp1_dl_commit(struct vsp1_dl *dl);
+
+void vsp1_dl_irq_display_start(struct vsp1_dl *dl);
+void vsp1_dl_irq_frame_end(struct vsp1_dl *dl);
+
+static inline void vsp1_dl_mod_write(struct vsp1_entity *e, u32 reg, u32 data)
+{
+	if (e->vsp1->use_dl)
+		vsp1_dl_add(e, reg, data);
+	else
+		vsp1_write(e->vsp1, reg, data);
+}
+
+#endif /* __VSP1_DL_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index ef8e91d65209..ae32da7d0ff7 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -20,6 +20,7 @@
 
 #include "vsp1.h"
 #include "vsp1_bru.h"
+#include "vsp1_dl.h"
 #include "vsp1_drm.h"
 #include "vsp1_lif.h"
 #include "vsp1_pipe.h"
@@ -29,55 +30,13 @@
  * Runtime Handling
  */
 
-static int vsp1_drm_pipeline_run(struct vsp1_pipeline *pipe)
-{
-	struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
-	int ret;
-
-	if (vsp1->drm->update) {
-		struct vsp1_entity *entity;
-
-		list_for_each_entry(entity, &pipe->entities, list_pipe) {
-			/* Disconnect unused RPFs from the pipeline. */
-			if (entity->type = VSP1_ENTITY_RPF) {
-				struct vsp1_rwpf *rpf -					to_rwpf(&entity->subdev);
-
-				if (!pipe->inputs[rpf->entity.index]) {
-					vsp1_write(entity->vsp1,
-						   entity->route->reg,
-						   VI6_DPR_NODE_UNUSED);
-					continue;
-				}
-			}
-
-			vsp1_entity_route_setup(entity);
-
-			ret = v4l2_subdev_call(&entity->subdev, video,
-					       s_stream, 1);
-			if (ret < 0) {
-				dev_err(vsp1->dev,
-					"DRM pipeline start failure on entity %s\n",
-					entity->subdev.name);
-				return ret;
-			}
-		}
-
-		vsp1->drm->update = false;
-	}
-
-	vsp1_pipeline_run(pipe);
-
-	return 0;
-}
-
 static void vsp1_drm_pipeline_frame_end(struct vsp1_pipeline *pipe)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&pipe->irqlock, flags);
 	if (pipe->num_inputs)
-		vsp1_drm_pipeline_run(pipe);
+		vsp1_pipeline_run(pipe);
 	spin_unlock_irqrestore(&pipe->irqlock, flags);
 }
 
@@ -151,6 +110,8 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width,
 		return 0;
 	}
 
+	vsp1_dl_reset(vsp1->drm->dl);
+
 	/* Configure the format at the BRU sinks and propagate it through the
 	 * pipeline.
 	 */
@@ -266,9 +227,11 @@ void vsp1_du_atomic_begin(struct device *dev)
 	spin_lock_irqsave(&pipe->irqlock, flags);
 
 	vsp1->drm->num_inputs = pipe->num_inputs;
-	vsp1->drm->update = false;
 
 	spin_unlock_irqrestore(&pipe->irqlock, flags);
+
+	/* Prepare the display list. */
+	vsp1_dl_begin(vsp1->drm->dl);
 }
 EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin);
 
@@ -489,23 +452,54 @@ void vsp1_du_atomic_flush(struct device *dev)
 {
 	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
 	struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
+	struct vsp1_entity *entity;
 	unsigned long flags;
 	bool stop = false;
+	int ret;
 
-	spin_lock_irqsave(&pipe->irqlock, flags);
+	list_for_each_entry(entity, &pipe->entities, list_pipe) {
+		/* Disconnect unused RPFs from the pipeline. */
+		if (entity->type = VSP1_ENTITY_RPF) {
+			struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
+
+			if (!pipe->inputs[rpf->entity.index]) {
+				vsp1_mod_write(entity, entity->route->reg,
+					   VI6_DPR_NODE_UNUSED);
+				continue;
+			}
+		}
+
+		vsp1_entity_route_setup(entity);
+
+		ret = v4l2_subdev_call(&entity->subdev, video,
+				       s_stream, 1);
+		if (ret < 0) {
+			dev_err(vsp1->dev,
+				"DRM pipeline start failure on entity %s\n",
+				entity->subdev.name);
+			return;
+		}
+	}
+
+	vsp1_dl_commit(vsp1->drm->dl);
 
-	vsp1->drm->update = true;
+	spin_lock_irqsave(&pipe->irqlock, flags);
 
 	/* Start or stop the pipeline if needed. */
-	if (!vsp1->drm->num_inputs && pipe->num_inputs)
-		vsp1_drm_pipeline_run(pipe);
-	else if (vsp1->drm->num_inputs && !pipe->num_inputs)
+	if (!vsp1->drm->num_inputs && pipe->num_inputs) {
+		vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0);
+		vsp1_write(vsp1, VI6_DISP_IRQ_ENB, VI6_DISP_IRQ_ENB_DSTE);
+		vsp1_pipeline_run(pipe);
+	} else if (vsp1->drm->num_inputs && !pipe->num_inputs) {
 		stop = true;
+	}
 
 	spin_unlock_irqrestore(&pipe->irqlock, flags);
 
-	if (stop)
+	if (stop) {
+		vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
 		vsp1_pipeline_stop(pipe);
+	}
 }
 EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush);
 
@@ -566,6 +560,10 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
 	if (!vsp1->drm)
 		return -ENOMEM;
 
+	vsp1->drm->dl = vsp1_dl_create(vsp1);
+	if (!vsp1->drm->dl)
+		return -ENOMEM;
+
 	pipe = &vsp1->drm->pipe;
 
 	vsp1_pipeline_init(pipe);
@@ -586,5 +584,12 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
 	pipe->lif = &vsp1->lif->entity;
 	pipe->output = vsp1->wpf[0];
 
+	pipe->dl = vsp1->drm->dl;
+
 	return 0;
 }
+
+void vsp1_drm_cleanup(struct vsp1_device *vsp1)
+{
+	vsp1_dl_destroy(vsp1->drm->dl);
+}
diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
index 25d7f017feb4..7704038c3add 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.h
+++ b/drivers/media/platform/vsp1/vsp1_drm.h
@@ -15,19 +15,24 @@
 
 #include "vsp1_pipe.h"
 
+struct vsp1_dl;
+
 /**
  * vsp1_drm - State for the API exposed to the DRM driver
+ * @dl: display list for DRM pipeline operation
  * @pipe: the VSP1 pipeline used for display
  * @num_inputs: number of active pipeline inputs at the beginning of an update
  * @update: the pipeline configuration has been updated
  */
 struct vsp1_drm {
+	struct vsp1_dl *dl;
 	struct vsp1_pipeline pipe;
 	unsigned int num_inputs;
 	bool update;
 };
 
 int vsp1_drm_init(struct vsp1_device *vsp1);
+void vsp1_drm_cleanup(struct vsp1_device *vsp1);
 int vsp1_drm_create_links(struct vsp1_device *vsp1);
 
 #endif /* __VSP1_DRM_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 9a30c96dc642..9c8fca6a8b35 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -25,6 +25,7 @@
 
 #include "vsp1.h"
 #include "vsp1_bru.h"
+#include "vsp1_dl.h"
 #include "vsp1_drm.h"
 #include "vsp1_hsit.h"
 #include "vsp1_lif.h"
@@ -44,11 +45,11 @@ static irqreturn_t vsp1_irq_handler(int irq, void *data)
 	struct vsp1_device *vsp1 = data;
 	irqreturn_t ret = IRQ_NONE;
 	unsigned int i;
+	u32 status;
 
 	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
 		struct vsp1_rwpf *wpf = vsp1->wpf[i];
 		struct vsp1_pipeline *pipe;
-		u32 status;
 
 		if (wpf = NULL)
 			continue;
@@ -63,6 +64,21 @@ static irqreturn_t vsp1_irq_handler(int irq, void *data)
 		}
 	}
 
+	status = vsp1_read(vsp1, VI6_DISP_IRQ_STA);
+	vsp1_write(vsp1, VI6_DISP_IRQ_STA, ~status & VI6_DISP_IRQ_STA_DST);
+
+	if (status & VI6_DISP_IRQ_STA_DST) {
+		struct vsp1_rwpf *wpf = vsp1->wpf[0];
+		struct vsp1_pipeline *pipe;
+
+		if (wpf) {
+			pipe = to_vsp1_pipeline(&wpf->entity.subdev.entity);
+			vsp1_pipeline_display_start(pipe);
+		}
+
+		ret = IRQ_HANDLED;
+	}
+
 	return ret;
 }
 
@@ -196,6 +212,9 @@ static void vsp1_destroy_entities(struct vsp1_device *vsp1)
 
 	v4l2_device_unregister(&vsp1->v4l2_dev);
 	media_device_unregister(&vsp1->media_dev);
+
+	if (!vsp1->pdata.uapi)
+		vsp1_drm_cleanup(vsp1);
 }
 
 static int vsp1_create_entities(struct vsp1_device *vsp1)
@@ -368,10 +387,13 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 			goto done;
 	}
 
-	if (vsp1->pdata.uapi)
+	if (vsp1->pdata.uapi) {
+		vsp1->use_dl = false;
 		ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev);
-	else
+	} else {
+		vsp1->use_dl = true;
 		ret = vsp1_drm_init(vsp1);
+	}
 
 done:
 	if (ret < 0)
@@ -380,33 +402,42 @@ done:
 	return ret;
 }
 
-static int vsp1_device_init(struct vsp1_device *vsp1)
+int vsp1_reset_wpf(struct vsp1_device *vsp1, unsigned int index)
 {
-	unsigned int i;
+	unsigned int timeout;
 	u32 status;
 
-	/* Reset any channel that might be running. */
 	status = vsp1_read(vsp1, VI6_STATUS);
+	if (!(status & VI6_STATUS_SYS_ACT(index)))
+		return 0;
 
-	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
-		unsigned int timeout;
+	vsp1_write(vsp1, VI6_SRESET, VI6_SRESET_SRTS(index));
+	for (timeout = 10; timeout > 0; --timeout) {
+		status = vsp1_read(vsp1, VI6_STATUS);
+		if (!(status & VI6_STATUS_SYS_ACT(index)))
+			break;
 
-		if (!(status & VI6_STATUS_SYS_ACT(i)))
-			continue;
+		usleep_range(1000, 2000);
+	}
 
-		vsp1_write(vsp1, VI6_SRESET, VI6_SRESET_SRTS(i));
-		for (timeout = 10; timeout > 0; --timeout) {
-			status = vsp1_read(vsp1, VI6_STATUS);
-			if (!(status & VI6_STATUS_SYS_ACT(i)))
-				break;
+	if (!timeout) {
+		dev_err(vsp1->dev, "failed to reset wpf.%u\n", index);
+		return -ETIMEDOUT;
+	}
 
-			usleep_range(1000, 2000);
-		}
+	return 0;
+}
 
-		if (!timeout) {
-			dev_err(vsp1->dev, "failed to reset wpf.%u\n", i);
-			return -ETIMEDOUT;
-		}
+static int vsp1_device_init(struct vsp1_device *vsp1)
+{
+	unsigned int i;
+	int ret;
+
+	/* Reset any channel that might be running. */
+	for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
+		ret = vsp1_reset_wpf(vsp1, i);
+		if (ret < 0)
+			return ret;
 	}
 
 	vsp1_write(vsp1, VI6_CLK_DCSWT, (8 << VI6_CLK_DCSWT_CSTPW_SHIFT) |
@@ -430,6 +461,9 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
 	vsp1_write(vsp1, VI6_DPR_HGT_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
 		   (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT));
 
+	if (vsp1->use_dl)
+		vsp1_dl_setup(vsp1);
+
 	return 0;
 }
 
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 4b46cb0e0e8a..da4e7b82d0ca 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -66,8 +66,8 @@ void vsp1_entity_route_setup(struct vsp1_entity *source)
 		return;
 
 	sink = container_of(source->sink, struct vsp1_entity, subdev.entity);
-	vsp1_write(source->vsp1, source->route->reg,
-		   sink->route->inputs[source->sink_pad]);
+	vsp1_mod_write(source, source->route->reg,
+		       sink->route->inputs[source->sink_pad]);
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index b8e73d32d14d..433853ce8dbf 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -28,7 +28,7 @@
 
 static inline void vsp1_lif_write(struct vsp1_lif *lif, u32 reg, u32 data)
 {
-	vsp1_write(lif->entity.vsp1, reg, data);
+	vsp1_mod_write(&lif->entity, reg, data);
 }
 
 /* -----------------------------------------------------------------------------
@@ -44,7 +44,7 @@ static int lif_s_stream(struct v4l2_subdev *subdev, int enable)
 	unsigned int lbth = 200;
 
 	if (!enable) {
-		vsp1_lif_write(lif, VI6_LIF_CTRL, 0);
+		vsp1_write(lif->entity.vsp1, VI6_LIF_CTRL, 0);
 		return 0;
 	}
 
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
index d41e4ca94a02..2e4a31072100 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -11,6 +11,7 @@
  * (at your option) any later version.
  */
 
+#include <linux/delay.h>
 #include <linux/list.h>
 #include <linux/wait.h>
 
@@ -19,6 +20,7 @@
 
 #include "vsp1.h"
 #include "vsp1_bru.h"
+#include "vsp1_dl.h"
 #include "vsp1_entity.h"
 #include "vsp1_pipe.h"
 #include "vsp1_rwpf.h"
@@ -176,8 +178,12 @@ void vsp1_pipeline_run(struct vsp1_pipeline *pipe)
 {
 	struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
 
-	vsp1_write(vsp1, VI6_CMD(pipe->output->entity.index), VI6_CMD_STRCMD);
-	pipe->state = VSP1_PIPELINE_RUNNING;
+	if (pipe->state = VSP1_PIPELINE_STOPPED) {
+		vsp1_write(vsp1, VI6_CMD(pipe->output->entity.index),
+			   VI6_CMD_STRCMD);
+		pipe->state = VSP1_PIPELINE_RUNNING;
+	}
+
 	pipe->buffers_ready = 0;
 }
 
@@ -199,14 +205,28 @@ int vsp1_pipeline_stop(struct vsp1_pipeline *pipe)
 	unsigned long flags;
 	int ret;
 
-	spin_lock_irqsave(&pipe->irqlock, flags);
-	if (pipe->state = VSP1_PIPELINE_RUNNING)
-		pipe->state = VSP1_PIPELINE_STOPPING;
-	spin_unlock_irqrestore(&pipe->irqlock, flags);
+	if (pipe->dl) {
+		/* When using display lists in continuous frame mode the only
+		 * way to stop the pipeline is to reset the hardware.
+		 */
+		ret = vsp1_reset_wpf(pipe->output->entity.vsp1,
+				     pipe->output->entity.index);
+		if (ret = 0) {
+			spin_lock_irqsave(&pipe->irqlock, flags);
+			pipe->state = VSP1_PIPELINE_STOPPED;
+			spin_unlock_irqrestore(&pipe->irqlock, flags);
+		}
+	} else {
+		/* Otherwise just request a stop and wait. */
+		spin_lock_irqsave(&pipe->irqlock, flags);
+		if (pipe->state = VSP1_PIPELINE_RUNNING)
+			pipe->state = VSP1_PIPELINE_STOPPING;
+		spin_unlock_irqrestore(&pipe->irqlock, flags);
 
-	ret = wait_event_timeout(pipe->wq, vsp1_pipeline_stopped(pipe),
-				 msecs_to_jiffies(500));
-	ret = ret = 0 ? -ETIMEDOUT : 0;
+		ret = wait_event_timeout(pipe->wq, vsp1_pipeline_stopped(pipe),
+					 msecs_to_jiffies(500));
+		ret = ret = 0 ? -ETIMEDOUT : 0;
+	}
 
 	list_for_each_entry(entity, &pipe->entities, list_pipe) {
 		if (entity->route && entity->route->reg)
@@ -230,6 +250,12 @@ bool vsp1_pipeline_ready(struct vsp1_pipeline *pipe)
 	return pipe->buffers_ready = mask;
 }
 
+void vsp1_pipeline_display_start(struct vsp1_pipeline *pipe)
+{
+	if (pipe->dl)
+		vsp1_dl_irq_display_start(pipe->dl);
+}
+
 void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
 {
 	enum vsp1_pipeline_state state;
@@ -238,13 +264,21 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
 	if (pipe = NULL)
 		return;
 
+	if (pipe->dl)
+		vsp1_dl_irq_frame_end(pipe->dl);
+
 	/* Signal frame end to the pipeline handler. */
 	pipe->frame_end(pipe);
 
 	spin_lock_irqsave(&pipe->irqlock, flags);
 
 	state = pipe->state;
-	pipe->state = VSP1_PIPELINE_STOPPED;
+
+	/* When using display lists in continuous frame mode the pipeline is
+	 * automatically restarted by the hardware.
+	 */
+	if (!pipe->dl)
+		pipe->state = VSP1_PIPELINE_STOPPED;
 
 	/* If a stop has been requested, mark the pipeline as stopped and
 	 * return.
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index c4c300561c5c..b2f3a8a896c9 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -19,6 +19,7 @@
 
 #include <media/media-entity.h>
 
+struct vsp1_dl;
 struct vsp1_rwpf;
 
 /*
@@ -73,6 +74,7 @@ enum vsp1_pipeline_state {
  * @uds: UDS entity, if present
  * @uds_input: entity at the input of the UDS, if the UDS is present
  * @entities: list of entities in the pipeline
+ * @dl: display list associated with the pipeline
  */
 struct vsp1_pipeline {
 	struct media_pipeline pipe;
@@ -97,6 +99,8 @@ struct vsp1_pipeline {
 	struct vsp1_entity *uds_input;
 
 	struct list_head entities;
+
+	struct vsp1_dl *dl;
 };
 
 static inline struct vsp1_pipeline *to_vsp1_pipeline(struct media_entity *e)
@@ -115,6 +119,7 @@ bool vsp1_pipeline_stopped(struct vsp1_pipeline *pipe);
 int vsp1_pipeline_stop(struct vsp1_pipeline *pipe);
 bool vsp1_pipeline_ready(struct vsp1_pipeline *pipe);
 
+void vsp1_pipeline_display_start(struct vsp1_pipeline *pipe);
 void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe);
 
 void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 3992da09e466..1eb9a3ef05c8 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -28,8 +28,8 @@
 
 static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf, u32 reg, u32 data)
 {
-	vsp1_write(rpf->entity.vsp1,
-		   reg + rpf->entity.index * VI6_RPF_OFFSET, data);
+	vsp1_mod_write(&rpf->entity, reg + rpf->entity.index * VI6_RPF_OFFSET,
+		       data);
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 849ed81d86a1..4a741a597878 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -34,8 +34,8 @@ static inline u32 vsp1_wpf_read(struct vsp1_rwpf *wpf, u32 reg)
 
 static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf, u32 reg, u32 data)
 {
-	vsp1_write(wpf->entity.vsp1,
-		   reg + wpf->entity.index * VI6_WPF_OFFSET, data);
+	vsp1_mod_write(&wpf->entity,
+		       reg + wpf->entity.index * VI6_WPF_OFFSET, data);
 }
 
 /* -----------------------------------------------------------------------------
@@ -88,7 +88,8 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
 
 	if (!enable) {
 		vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index), 0);
-		vsp1_wpf_write(wpf, VI6_WPF_SRCRPF, 0);
+		vsp1_write(vsp1, wpf->entity.index * VI6_WPF_OFFSET +
+			   VI6_WPF_SRCRPF, 0);
 		return 0;
 	}
 
@@ -161,10 +162,10 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
 	if (vsp1->pdata.uapi)
 		mutex_unlock(wpf->ctrls.lock);
 
-	vsp1_write(vsp1, VI6_DPR_WPF_FPORCH(wpf->entity.index),
-		   VI6_DPR_WPF_FPORCH_FP_WPFN);
+	vsp1_mod_write(&wpf->entity, VI6_DPR_WPF_FPORCH(wpf->entity.index),
+		       VI6_DPR_WPF_FPORCH_FP_WPFN);
 
-	vsp1_write(vsp1, VI6_WPF_WRBCK_CTRL, 0);
+	vsp1_mod_write(&wpf->entity, VI6_WPF_WRBCK_CTRL, 0);
 
 	/* Enable interrupts */
 	vsp1_write(vsp1, VI6_WPF_IRQ_STA(wpf->entity.index), 0);
-- 
2.4.10


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

* Re: [PATCH v2 00/32] VSP: Add R-Car Gen3 support
  2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
                   ` (31 preceding siblings ...)
  2015-12-05  2:13 ` [PATCH v2 32/32] v4l: vsp1: Add display list support Laurent Pinchart
@ 2015-12-05 10:57 ` Geert Uytterhoeven
  2015-12-05 22:54   ` Laurent Pinchart
  32 siblings, 1 reply; 42+ messages in thread
From: Geert Uytterhoeven @ 2015-12-05 10:57 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Linux Media Mailing List, Linux-sh list

Hi Laurent,

On Sat, Dec 5, 2015 at 3:12 AM, Laurent Pinchart
<laurent.pinchart+renesas@ideasonboard.com> wrote:
> This patch set adds support for the Renesas R-Car Gen3 SoC family to the VSP1
> driver. The large number of patches is caused by a change in the display
> controller architecture that makes usage of the VSP mandatory as the display
> controller has lost the ability to read data from memory.
>
> Patch 01/32 to 27/32 prepare for the implementation of an API exported to the
> DRM driver in patch 28/32. Patches 31/32 enables support for the R-Car Gen3
> family, and patch 32/32 finally enhances perfomances by implementing support
> for display lists.
>
> The major change compared to v1 is the usage of the IP version register
> instead of DT properties to configure device parameters such as the number of
> BRU inputs or the availability of the BRU.

Thanks for your series!

As http://git.linuxtv.org/pinchartl/media.git/tag/?id=vsp1-kms-20151112 is
getting old, and has lots of conflicts with recent -next, do you plan to publish
this in a branch, and a separate branch for integration, to ease integration
in renesas-drivers?

Alternatively, I can just import the series you posted, but having the
broken-out integration part would be nice.

Thanks again!

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] 42+ messages in thread

* Re: [PATCH v2 17/32] v4l: vsp1: Fix typo in VI6_DISP_IRQ_STA_DST register name
  2015-12-05  2:12 ` [PATCH v2 17/32] v4l: vsp1: Fix typo in VI6_DISP_IRQ_STA_DST register name Laurent Pinchart
@ 2015-12-05 21:47   ` Sergei Shtylyov
  2015-12-05 22:20     ` Laurent Pinchart
  0 siblings, 1 reply; 42+ messages in thread
From: Sergei Shtylyov @ 2015-12-05 21:47 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media; +Cc: linux-sh

Hello.

On 12/5/2015 5:12 AM, Laurent Pinchart wrote:

> Rename the VI6_DISP_IRQ_STA_DSE register

    Register bit, perhaps?

> to VI6_DISP_IRQ_STA_DST to fix
> a typo and match the datasheet.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>   drivers/media/platform/vsp1/vsp1_regs.h | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
> index 25b48738b147..8173ceaab9f9 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -46,7 +46,7 @@
>   #define VI6_DISP_IRQ_ENB_LNEE(n)	(1 << (n))
>
>   #define VI6_DISP_IRQ_STA		0x007c
> -#define VI6_DISP_IRQ_STA_DSE		(1 << 8)
> +#define VI6_DISP_IRQ_STA_DST		(1 << 8)
>   #define VI6_DISP_IRQ_STA_MAE		(1 << 5)
>   #define VI6_DISP_IRQ_STA_LNE(n)		(1 << (n))
>

MBR, Sergei


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

* Re: [PATCH v2 17/32] v4l: vsp1: Fix typo in VI6_DISP_IRQ_STA_DST register name
  2015-12-05 21:47   ` Sergei Shtylyov
@ 2015-12-05 22:20     ` Laurent Pinchart
  0 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05 22:20 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: Laurent Pinchart, linux-media, linux-sh

Hi Sergio,

On Sunday 06 December 2015 00:47:21 Sergei Shtylyov wrote:
> On 12/5/2015 5:12 AM, Laurent Pinchart wrote:
> > Rename the VI6_DISP_IRQ_STA_DSE register
> 
>     Register bit, perhaps?

Indeed. I know I can count on you to catch even such small issues :-)

I'll fix it for the next version (or the pull request if no issue that require 
a new review round is found).

> > to VI6_DISP_IRQ_STA_DST to fix
> > a typo and match the datasheet.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >   drivers/media/platform/vsp1/vsp1_regs.h | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_regs.h
> > b/drivers/media/platform/vsp1/vsp1_regs.h index
> > 25b48738b147..8173ceaab9f9 100644
> > --- a/drivers/media/platform/vsp1/vsp1_regs.h
> > +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> > @@ -46,7 +46,7 @@
> > 
> >   #define VI6_DISP_IRQ_ENB_LNEE(n)	(1 << (n))
> >   
> >   #define VI6_DISP_IRQ_STA		0x007c
> > 
> > -#define VI6_DISP_IRQ_STA_DSE		(1 << 8)
> > +#define VI6_DISP_IRQ_STA_DST		(1 << 8)
> > 
> >   #define VI6_DISP_IRQ_STA_MAE		(1 << 5)
> >   #define VI6_DISP_IRQ_STA_LNE(n)		(1 << (n))
> 
> MBR, Sergei

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH v2 00/32] VSP: Add R-Car Gen3 support
  2015-12-05 10:57 ` [PATCH v2 00/32] VSP: Add R-Car Gen3 support Geert Uytterhoeven
@ 2015-12-05 22:54   ` Laurent Pinchart
  2015-12-11  8:43     ` Khiem Nguyen
  2015-12-16  8:39     ` Geert Uytterhoeven
  0 siblings, 2 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-05 22:54 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Linux Media Mailing List, Linux-sh list

Hi Geert,

On Saturday 05 December 2015 11:57:49 Geert Uytterhoeven wrote:
> On Sat, Dec 5, 2015 at 3:12 AM, Laurent Pinchart wrote:
> > This patch set adds support for the Renesas R-Car Gen3 SoC family to the
> > VSP1 driver. The large number of patches is caused by a change in the
> > display controller architecture that makes usage of the VSP mandatory as
> > the display controller has lost the ability to read data from memory.
> > 
> > Patch 01/32 to 27/32 prepare for the implementation of an API exported to
> > the DRM driver in patch 28/32. Patches 31/32 enables support for the
> > R-Car Gen3 family, and patch 32/32 finally enhances perfomances by
> > implementing support for display lists.
> > 
> > The major change compared to v1 is the usage of the IP version register
> > instead of DT properties to configure device parameters such as the number
> > of BRU inputs or the availability of the BRU.
> 
> Thanks for your series!
> 
> As http://git.linuxtv.org/pinchartl/media.git/tag/?id=vsp1-kms-20151112 is
> getting old, and has lots of conflicts with recent -next, do you plan to
> publish this in a branch, and a separate branch for integration, to ease
> integration in renesas-drivers?
> 
> Alternatively, I can just import the series you posted, but having the
> broken-out integration part would be nice.

The issue I'm facing is that there's more than just two series. Beside the 
base VSP patches from this series, I have a series of DRM patches that depend 
on this one, a series of V4L2 core patches, another series of VSP patches that 
I still need to finish and a bunch of integration patches. As some of these 
have dependencies on H3 CCF support that hasn't landed in Simon's tree yet, I 
have merged your topic/cpg-mssr-v6 and topic/r8a7795-drivers-sh-v1 branches 
into my tree for development.

I could keep all series in separate branches and merge the two topic branches 
last, but that's not very handy during development when I have to continuously 
rebase my patches. Is there a way I could handle this that would make your 
life easier while not making mine more difficult ?

In the meantime I've pushed vsp1-kms-20151206 to 
git://linuxtv.org/pinchartl/media.git.

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH v2 00/32] VSP: Add R-Car Gen3 support
  2015-12-05 22:54   ` Laurent Pinchart
@ 2015-12-11  8:43     ` Khiem Nguyen
  2015-12-13 18:53       ` Laurent Pinchart
  2015-12-16  8:39     ` Geert Uytterhoeven
  1 sibling, 1 reply; 42+ messages in thread
From: Khiem Nguyen @ 2015-12-11  8:43 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Geert Uytterhoeven, Linux Media Mailing List, Linux-sh list,
	Khiem Nguyen, Toru Oishi

Hi Laurent,

On 12/6/2015 5:54 AM, Laurent Pinchart wrote:
> Hi Geert,
>
> On Saturday 05 December 2015 11:57:49 Geert Uytterhoeven wrote:
>> On Sat, Dec 5, 2015 at 3:12 AM, Laurent Pinchart wrote:
>>> This patch set adds support for the Renesas R-Car Gen3 SoC family to the
>>> VSP1 driver. The large number of patches is caused by a change in the
>>> display controller architecture that makes usage of the VSP mandatory as
>>> the display controller has lost the ability to read data from memory.
>>>
>>> Patch 01/32 to 27/32 prepare for the implementation of an API exported to
>>> the DRM driver in patch 28/32. Patches 31/32 enables support for the
>>> R-Car Gen3 family, and patch 32/32 finally enhances perfomances by
>>> implementing support for display lists.
>>>
>>> The major change compared to v1 is the usage of the IP version register
>>> instead of DT properties to configure device parameters such as the number
>>> of BRU inputs or the availability of the BRU.
>>
>> Thanks for your series!
>>
>> As http://git.linuxtv.org/pinchartl/media.git/tag/?id=vsp1-kms-20151112 is
>> getting old, and has lots of conflicts with recent -next, do you plan to
>> publish this in a branch, and a separate branch for integration, to ease
>> integration in renesas-drivers?
>>
>> Alternatively, I can just import the series you posted, but having the
>> broken-out integration part would be nice.
>
> The issue I'm facing is that there's more than just two series. Beside the
> base VSP patches from this series, I have a series of DRM patches that depend
> on this one, a series of V4L2 core patches, another series of VSP patches that
> I still need to finish and a bunch of integration patches. As some of these
> have dependencies on H3 CCF support that hasn't landed in Simon's tree yet, I
> have merged your topic/cpg-mssr-v6 and topic/r8a7795-drivers-sh-v1 branches
> into my tree for development.
>
> I could keep all series in separate branches and merge the two topic branches
> last, but that's not very handy during development when I have to continuously
> rebase my patches. Is there a way I could handle this that would make your
> life easier while not making mine more difficult ?
>
> In the meantime I've pushed vsp1-kms-20151206 to
> git://linuxtv.org/pinchartl/media.git.

I failed to confirm DU (VGA port) with above branch.

To make DU (VGA port) work,
it seems I need to merge more branches like topic/cpg-mssr-v6
and topic/r8a7795-drivers-sh-v1 branches from renesas-drivers repo, is 
it correct ?

Thanks.

-- 
Best regards,
KHIEM Nguyen

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

* Re: [PATCH v2 00/32] VSP: Add R-Car Gen3 support
  2015-12-11  8:43     ` Khiem Nguyen
@ 2015-12-13 18:53       ` Laurent Pinchart
  2015-12-14  1:58         ` Khiem Nguyen
  0 siblings, 1 reply; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-13 18:53 UTC (permalink / raw)
  To: Khiem Nguyen
  Cc: Geert Uytterhoeven, Linux Media Mailing List, Linux-sh list,
	Toru Oishi

Hello Khiem,

On Friday 11 December 2015 15:43:27 Khiem Nguyen wrote:
> On 12/6/2015 5:54 AM, Laurent Pinchart wrote:
> > On Saturday 05 December 2015 11:57:49 Geert Uytterhoeven wrote:
> >> On Sat, Dec 5, 2015 at 3:12 AM, Laurent Pinchart wrote:
> >>> This patch set adds support for the Renesas R-Car Gen3 SoC family to the
> >>> VSP1 driver. The large number of patches is caused by a change in the
> >>> display controller architecture that makes usage of the VSP mandatory as
> >>> the display controller has lost the ability to read data from memory.
> >>> 
> >>> Patch 01/32 to 27/32 prepare for the implementation of an API exported
> >>> to the DRM driver in patch 28/32. Patches 31/32 enables support for the
> >>> R-Car Gen3 family, and patch 32/32 finally enhances perfomances by
> >>> implementing support for display lists.
> >>> 
> >>> The major change compared to v1 is the usage of the IP version register
> >>> instead of DT properties to configure device parameters such as the
> >>> number of BRU inputs or the availability of the BRU.
> >> 
> >> Thanks for your series!
> >> 
> >> As http://git.linuxtv.org/pinchartl/media.git/tag/?id=vsp1-kms-20151112
> >> is getting old, and has lots of conflicts with recent -next, do you plan
> >> to publish this in a branch, and a separate branch for integration, to
> >> ease integration in renesas-drivers?
> >> 
> >> Alternatively, I can just import the series you posted, but having the
> >> broken-out integration part would be nice.
> > 
> > The issue I'm facing is that there's more than just two series. Beside the
> > base VSP patches from this series, I have a series of DRM patches that
> > depend on this one, a series of V4L2 core patches, another series of VSP
> > patches that I still need to finish and a bunch of integration patches.
> > As some of these have dependencies on H3 CCF support that hasn't landed
> > in Simon's tree yet, I have merged your topic/cpg-mssr-v6 and
> > topic/r8a7795-drivers-sh-v1 branches into my tree for development.
> > 
> > I could keep all series in separate branches and merge the two topic
> > branches last, but that's not very handy during development when I have
> > to continuously rebase my patches. Is there a way I could handle this
> > that would make your life easier while not making mine more difficult ?
> > 
> > In the meantime I've pushed vsp1-kms-20151206 to
> > git://linuxtv.org/pinchartl/media.git.
> 
> I failed to confirm DU (VGA port) with above branch.
> 
> To make DU (VGA port) work,
> it seems I need to merge more branches like topic/cpg-mssr-v6
> and topic/r8a7795-drivers-sh-v1 branches from renesas-drivers repo, is
> it correct ?

The

	git://linuxtv.org/pinchartl/media.git vsp1-kms-20151206

branch already contains topic/r8a7795-drivers-sh-v1 and topic/cpg-mssr-v6. 
What is the failure you're seeing ?

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH v2 00/32] VSP: Add R-Car Gen3 support
  2015-12-13 18:53       ` Laurent Pinchart
@ 2015-12-14  1:58         ` Khiem Nguyen
  0 siblings, 0 replies; 42+ messages in thread
From: Khiem Nguyen @ 2015-12-14  1:58 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Geert Uytterhoeven, Linux Media Mailing List, Linux-sh list,
	Toru Oishi, Khiem Nguyen

On 12/14/2015 1:53 AM, Laurent Pinchart wrote:
> Hello Khiem,
>
> On Friday 11 December 2015 15:43:27 Khiem Nguyen wrote:
>> On 12/6/2015 5:54 AM, Laurent Pinchart wrote:
>>> On Saturday 05 December 2015 11:57:49 Geert Uytterhoeven wrote:
>>>> On Sat, Dec 5, 2015 at 3:12 AM, Laurent Pinchart wrote:
>>>>> This patch set adds support for the Renesas R-Car Gen3 SoC family to the
>>>>> VSP1 driver. The large number of patches is caused by a change in the
>>>>> display controller architecture that makes usage of the VSP mandatory as
>>>>> the display controller has lost the ability to read data from memory.
>>>>>
>>>>> Patch 01/32 to 27/32 prepare for the implementation of an API exported
>>>>> to the DRM driver in patch 28/32. Patches 31/32 enables support for the
>>>>> R-Car Gen3 family, and patch 32/32 finally enhances perfomances by
>>>>> implementing support for display lists.
>>>>>
>>>>> The major change compared to v1 is the usage of the IP version register
>>>>> instead of DT properties to configure device parameters such as the
>>>>> number of BRU inputs or the availability of the BRU.
>>>>
>>>> Thanks for your series!
>>>>
>>>> As http://git.linuxtv.org/pinchartl/media.git/tag/?id=vsp1-kms-20151112
>>>> is getting old, and has lots of conflicts with recent -next, do you plan
>>>> to publish this in a branch, and a separate branch for integration, to
>>>> ease integration in renesas-drivers?
>>>>
>>>> Alternatively, I can just import the series you posted, but having the
>>>> broken-out integration part would be nice.
>>>
>>> The issue I'm facing is that there's more than just two series. Beside the
>>> base VSP patches from this series, I have a series of DRM patches that
>>> depend on this one, a series of V4L2 core patches, another series of VSP
>>> patches that I still need to finish and a bunch of integration patches.
>>> As some of these have dependencies on H3 CCF support that hasn't landed
>>> in Simon's tree yet, I have merged your topic/cpg-mssr-v6 and
>>> topic/r8a7795-drivers-sh-v1 branches into my tree for development.
>>>
>>> I could keep all series in separate branches and merge the two topic
>>> branches last, but that's not very handy during development when I have
>>> to continuously rebase my patches. Is there a way I could handle this
>>> that would make your life easier while not making mine more difficult ?
>>>
>>> In the meantime I've pushed vsp1-kms-20151206 to
>>> git://linuxtv.org/pinchartl/media.git.
>>
>> I failed to confirm DU (VGA port) with above branch.
>>
>> To make DU (VGA port) work,
>> it seems I need to merge more branches like topic/cpg-mssr-v6
>> and topic/r8a7795-drivers-sh-v1 branches from renesas-drivers repo, is
>> it correct ?
>
> The
>
> 	git://linuxtv.org/pinchartl/media.git vsp1-kms-20151206
>
> branch already contains topic/r8a7795-drivers-sh-v1 and topic/cpg-mssr-v6.
> What is the failure you're seeing ?
>

Honestly, I tried some configurations but there's no output to VGA port 
(the display is blank).
1. The default 'defconfig' of this tag.
2. Enable DRM, CMA, RCAR_DU
3. Enable DRM, CMA, RCAR_DU, VSP1
      -> I got kernel build error in file 
drivers/media/platform/vsp1/vsp1_pipe.c

I also tried another tag vsp1-kms-request-20151206 which have more 
patches on top of vsp1-kms-20151206.
After enabling all DRM, CMA, RCAR_DU, VSP1, kernel build is OK.
Got a 'green color' display and no kernel log output.

With the same u-boot and IPL, it's able to see display output normally 
if using Gen3 BSP version.
Therefore, I guess it's no impact to DU operation.

Please let me know your procedure to test DU operation with your tag.

-- 
Best regards,
KHIEM Nguyen


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

* Re: [PATCH v2 00/32] VSP: Add R-Car Gen3 support
  2015-12-05 22:54   ` Laurent Pinchart
  2015-12-11  8:43     ` Khiem Nguyen
@ 2015-12-16  8:39     ` Geert Uytterhoeven
  2015-12-16 10:37       ` Laurent Pinchart
  1 sibling, 1 reply; 42+ messages in thread
From: Geert Uytterhoeven @ 2015-12-16  8:39 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: Linux Media Mailing List, Linux-sh list

Hi Laurent,

On Sat, Dec 5, 2015 at 11:54 PM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Saturday 05 December 2015 11:57:49 Geert Uytterhoeven wrote:
>> As http://git.linuxtv.org/pinchartl/media.git/tag/?id=vsp1-kms-20151112 is
>> getting old, and has lots of conflicts with recent -next, do you plan to
>> publish this in a branch, and a separate branch for integration, to ease
>> integration in renesas-drivers?
>>
>> Alternatively, I can just import the series you posted, but having the
>> broken-out integration part would be nice.
>
> The issue I'm facing is that there's more than just two series. Beside the
> base VSP patches from this series, I have a series of DRM patches that depend
> on this one, a series of V4L2 core patches, another series of VSP patches that
> I still need to finish and a bunch of integration patches. As some of these
> have dependencies on H3 CCF support that hasn't landed in Simon's tree yet, I
> have merged your topic/cpg-mssr-v6 and topic/r8a7795-drivers-sh-v1 branches
> into my tree for development.
>
> I could keep all series in separate branches and merge the two topic branches
> last, but that's not very handy during development when I have to continuously
> rebase my patches. Is there a way I could handle this that would make your
> life easier while not making mine more difficult ?

I feel your pain...

For development, committing to a single branch and rebasing interactively is
also my workflow. But after a few 100 commits, rebasing takes a long time.
And you can't publish that tree.

I started moving "finished" stuff to separate topic branches (this is the
stuff published/imported into renesas-drivers topic branches, or kept in
private branches for the parts I don't want to publish it yet), and merging
them early on.
Actual development is still done on top with frequent rebasing.

The problem starts when updating that. Instead of a simple rebase -i, it now
involves:
  - Duplicating the old topic branch, version number increased,
  - Interactively rebasing the new topic branch, including/squashing commits
    from recent development,
  - Merging in the new topic branch "early on", and rebasing all other private
    development on top of that.
For "big" changes that's OK. For adding a bunch of Acked-by's it's a lot of
work.

> In the meantime I've pushed vsp1-kms-20151206 to
> git://linuxtv.org/pinchartl/media.git.

Hadn't thanked you yet for that: Thanks!

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] 42+ messages in thread

* Re: [PATCH v2 00/32] VSP: Add R-Car Gen3 support
  2015-12-16  8:39     ` Geert Uytterhoeven
@ 2015-12-16 10:37       ` Laurent Pinchart
  0 siblings, 0 replies; 42+ messages in thread
From: Laurent Pinchart @ 2015-12-16 10:37 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Linux Media Mailing List, Linux-sh list

Hi Geert,

On Wednesday 16 December 2015 09:39:29 Geert Uytterhoeven wrote:
> On Sat, Dec 5, 2015 at 11:54 PM, Laurent Pinchart wrote:
> > On Saturday 05 December 2015 11:57:49 Geert Uytterhoeven wrote:
> >> As http://git.linuxtv.org/pinchartl/media.git/tag/?id=vsp1-kms-20151112
> >> is getting old, and has lots of conflicts with recent -next, do you plan
> >> to publish this in a branch, and a separate branch for integration, to
> >> ease integration in renesas-drivers?
> >> 
> >> Alternatively, I can just import the series you posted, but having the
> >> broken-out integration part would be nice.
> > 
> > The issue I'm facing is that there's more than just two series. Beside the
> > base VSP patches from this series, I have a series of DRM patches that
> > depend on this one, a series of V4L2 core patches, another series of VSP
> > patches that I still need to finish and a bunch of integration patches.
> > As some of these have dependencies on H3 CCF support that hasn't landed
> > in Simon's tree yet, I have merged your topic/cpg-mssr-v6 and
> > topic/r8a7795-drivers-sh-v1 branches into my tree for development.
> > 
> > I could keep all series in separate branches and merge the two topic
> > branches last, but that's not very handy during development when I have
> > to continuously rebase my patches. Is there a way I could handle this
> > that would make your life easier while not making mine more difficult ?
> 
> I feel your pain...
> 
> For development, committing to a single branch and rebasing interactively is
> also my workflow. But after a few 100 commits, rebasing takes a long time.
> And you can't publish that tree.
> 
> I started moving "finished" stuff to separate topic branches (this is the
> stuff published/imported into renesas-drivers topic branches, or kept in
> private branches for the parts I don't want to publish it yet), and merging
> them early on.

The issue here is that there is only a single batch of patches I consider as 
finished, and those are already present in a branch based directly on top of 
linuxtv/master that I then merge into my working branches. On a side note I've 
now sent a pull request for that.

The rest is not considered finished yet, I've modified the oldest branches no 
later than today. The code is stabilizing though, and I expect to send a pull 
request for a first batch of DU patches after the v4.5 merge window closes.

> Actual development is still done on top with frequent rebasing.
> 
> The problem starts when updating that. Instead of a simple rebase -i, it now
> involves:
>   - Duplicating the old topic branch, version number increased,
>   - Interactively rebasing the new topic branch, including/squashing commits
> from recent development,
>   - Merging in the new topic branch "early on", and rebasing all other
> private development on top of that.
> For "big" changes that's OK. For adding a bunch of Acked-by's it's a lot of
> work.
> 
> > In the meantime I've pushed vsp1-kms-20151206 to
> > git://linuxtv.org/pinchartl/media.git.
> 
> Hadn't thanked you yet for that: Thanks!

You're welcome, and there's now vsp1-kms-20151216 :-)

-- 
Regards,

Laurent Pinchart


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

end of thread, other threads:[~2015-12-16 10:37 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-05  2:12 [PATCH v2 00/32] VSP: Add R-Car Gen3 support Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 01/32] v4l: vsp1: Change the type of the rwpf field in struct vsp1_video Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 02/32] v4l: vsp1: Store the memory format in struct vsp1_rwpf Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 03/32] v4l: vsp1: Move video operations to vsp1_rwpf Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 04/32] v4l: vsp1: Rename vsp1_video_buffer to vsp1_vb2_buffer Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 05/32] v4l: vsp1: Move video device out of struct vsp1_rwpf Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 06/32] v4l: vsp1: Make rwpf operations independent of video device Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 07/32] v4l: vsp1: Support VSP1 instances without any UDS Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 08/32] v4l: vsp1: Move vsp1_video pointer from vsp1_entity to vsp1_rwpf Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 09/32] v4l: vsp1: Remove struct vsp1_pipeline num_video field Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 10/32] v4l: vsp1: Decouple pipeline end of frame processing from vsp1_video Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 11/32] v4l: vsp1: Split pipeline management code from vsp1_video.c Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 12/32] v4l: vsp1: Rename video pipeline functions to use vsp1_video prefix Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 13/32] v4l: vsp1: Extract pipeline initialization code into a function Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 14/32] v4l: vsp1: Reuse local variable instead of recomputing it Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 15/32] v4l: vsp1: Extract link creation to separate function Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 16/32] v4l: vsp1: Document the vsp1_pipeline structure Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 17/32] v4l: vsp1: Fix typo in VI6_DISP_IRQ_STA_DST register name Laurent Pinchart
2015-12-05 21:47   ` Sergei Shtylyov
2015-12-05 22:20     ` Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 18/32] v4l: vsp1: Set the SRU CTRL0 register when starting the stream Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 19/32] v4l: vsp1: Remove unused module read functions Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 20/32] v4l: vsp1: Move entity route setup function to vsp1_entity.c Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 21/32] v4l: vsp1: Make number of BRU inputs configurable Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 22/32] v4l: vsp1: Make the BRU optional Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 23/32] v4l: vsp1: Move format info to vsp1_pipe.c Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 24/32] v4l: vsp1: Make the userspace API optional Laurent Pinchart
2015-12-05  2:12 ` [PATCH v2 25/32] v4l: vsp1: Make pipeline inputs array index by RPF index Laurent Pinchart
2015-12-05  2:13 ` [PATCH v2 26/32] v4l: vsp1: Set the alpha value manually in RPF and WPF s_stream handlers Laurent Pinchart
2015-12-05  2:13 ` [PATCH v2 27/32] v4l: vsp1: Don't validate links when the userspace API is disabled Laurent Pinchart
2015-12-05  2:13 ` [PATCH v2 28/32] v4l: vsp1: Add VSP+DU support Laurent Pinchart
2015-12-05  2:13 ` [PATCH v2 29/32] v4l: vsp1: Disconnect unused RPFs from the DRM pipeline Laurent Pinchart
2015-12-05  2:13 ` [PATCH v2 30/32] v4l: vsp1: Implement atomic update for the DRM driver Laurent Pinchart
2015-12-05  2:13 ` [PATCH v2 31/32] v4l: vsp1: Add support for the R-Car Gen3 VSP2 Laurent Pinchart
2015-12-05  2:13 ` [PATCH v2 32/32] v4l: vsp1: Add display list support Laurent Pinchart
2015-12-05 10:57 ` [PATCH v2 00/32] VSP: Add R-Car Gen3 support Geert Uytterhoeven
2015-12-05 22:54   ` Laurent Pinchart
2015-12-11  8:43     ` Khiem Nguyen
2015-12-13 18:53       ` Laurent Pinchart
2015-12-14  1:58         ` Khiem Nguyen
2015-12-16  8:39     ` Geert Uytterhoeven
2015-12-16 10:37       ` Laurent Pinchart

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).