[PATCH] gpio: Add a reference to CEC on GPIO

2018-04-14 Thread Linus Walleij
This adds a pointer to the CEC GPIO driver from the GPIO list of
examples of drivers on top of GPIO.

Cc: Hans Verkuil 
Cc: linux-media@vger.kernel.org
Signed-off-by: Linus Walleij 
---
 Documentation/driver-api/gpio/drivers-on-gpio.rst | 4 
 1 file changed, 4 insertions(+)

diff --git a/Documentation/driver-api/gpio/drivers-on-gpio.rst 
b/Documentation/driver-api/gpio/drivers-on-gpio.rst
index 7da0c1dd1f7a..f3a189320e11 100644
--- a/Documentation/driver-api/gpio/drivers-on-gpio.rst
+++ b/Documentation/driver-api/gpio/drivers-on-gpio.rst
@@ -85,6 +85,10 @@ hardware descriptions such as device tree or ACPI:
   any other serio bus to the system and makes it possible to connect drivers
   for e.g. keyboards and other PS/2 protocol based devices.
 
+- cec-gpio: drivers/media/platform/cec-gpio/ is used to interact with a CEC
+  Consumer Electronics Control bus using only GPIO. It is used to communicate
+  with devices on the HDMI bus.
+
 Apart from this there are special GPIO drivers in subsystems like MMC/SD to
 read card detect and write protect GPIO lines, and in the TTY serial subsystem
 to emulate MCTRL (modem control) signals CTS/RTS by using two GPIO lines. The
-- 
2.14.3



Re: Smatch and sparse errors

2018-04-14 Thread Mauro Carvalho Chehab
Em Sat, 14 Apr 2018 03:18:20 +0200
"Jasmin J."  escreveu:

> Hello Mauro/Hans!
> 
> > There is already an upstream patch for hidding it:  
> The patch from https://patchwork.kernel.org/patch/10334353 will not
> apply at the smatch tree.
> 
> Attached is an updated version for smatch.

Then you're probably not using the right version (or Dan applied some
other stuff yesterday).

Yesterday, I added both trees I'm using here at:

https://git.linuxtv.org/mchehab/sparse.git/
https://git.linuxtv.org/mchehab/smatch.git/

My sparse tree has just one extra patch over upstream.
That's needed after a change at max()/min() macros upstream.

At smatch, my tree has 4 extra patches:
https://git.linuxtv.org/mchehab/smatch.git/

They basically do:
1) rise the execution time/memory usage of sparse;
2) mask errors like "missing break", as gcc checks it already;
3) the same patch for sparse is needed on smatch;
4) disable this warning:
drivers/media/platform/sti/bdisp/bdisp-debug.c:594 
bdisp_dbg_perf() debug: sval_binop_signed: invalid divide LLONG_MIN/-1
   with is produced every time do_div64() & friends are called.

IMHO, all 4 patches are disabling false-positive only warnings,
although the 4th patch might have something useful, if fixed to
properly handle the 64-bit compat macros.

Thanks,
Mauro


Re: Smatch and sparse errors

2018-04-14 Thread Jasmin J.
Hello Mauro/Hans!

> Then you're probably not using the right version
Might be ...
The build script from Hans uses the Versions from here:
   git://repo.or.cz/smatch.git
   git://git.kernel.org/pub/scm/devel/sparse/sparse.git

> Yesterday, I added both trees I'm using here at:
>   https://git.linuxtv.org/mchehab/sparse.git/
>   https://git.linuxtv.org/mchehab/smatch.git/
Maybe we should use your version in the build script.
Hans?

> IMHO, all 4 patches are disabling false-positive only warnings,
> although the 4th patch might have something useful, if fixed to
> properly handle the 64-bit compat macros.
Another good reason for using your version. Doing so, you can fix/extend
sparse/smatch and the daily build will automatically use that.

BR,
   Jasmin


Re: [PATCH] gpio: Add a reference to CEC on GPIO

2018-04-14 Thread Hans Verkuil
On 04/14/2018 02:44 AM, Linus Walleij wrote:
> This adds a pointer to the CEC GPIO driver from the GPIO list of
> examples of drivers on top of GPIO.
> 
> Cc: Hans Verkuil 
> Cc: linux-media@vger.kernel.org
> Signed-off-by: Linus Walleij 

Acked-by: Hans Verkuil 

Thanks!

Hans

> ---
>  Documentation/driver-api/gpio/drivers-on-gpio.rst | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/driver-api/gpio/drivers-on-gpio.rst 
> b/Documentation/driver-api/gpio/drivers-on-gpio.rst
> index 7da0c1dd1f7a..f3a189320e11 100644
> --- a/Documentation/driver-api/gpio/drivers-on-gpio.rst
> +++ b/Documentation/driver-api/gpio/drivers-on-gpio.rst
> @@ -85,6 +85,10 @@ hardware descriptions such as device tree or ACPI:
>any other serio bus to the system and makes it possible to connect drivers
>for e.g. keyboards and other PS/2 protocol based devices.
>  
> +- cec-gpio: drivers/media/platform/cec-gpio/ is used to interact with a CEC
> +  Consumer Electronics Control bus using only GPIO. It is used to communicate
> +  with devices on the HDMI bus.
> +
>  Apart from this there are special GPIO drivers in subsystems like MMC/SD to
>  read card detect and write protect GPIO lines, and in the TTY serial 
> subsystem
>  to emulate MCTRL (modem control) signals CTS/RTS by using two GPIO lines. The
> 



Re: Smatch and sparse errors

2018-04-14 Thread Mauro Carvalho Chehab
Em Sat, 14 Apr 2018 12:06:34 +0200
"Jasmin J."  escreveu:

> Hello Mauro/Hans!
> 
> > Then you're probably not using the right version  
> Might be ...
> The build script from Hans uses the Versions from here:
>git://repo.or.cz/smatch.git

That's right. The last patch on this repo is:

53b881888d7b (origin/master, origin/HEAD) check_or_vs_and: ignore the 
kernel's min/max macros

And the patch that adds -Wpointer-arith applies cleanly at the top of
it.

>git://git.kernel.org/pub/scm/devel/sparse/sparse.git

That's wrong.

Sparse nowadays are getting updates on this dir:

url = 
git://git.kernel.org/pub/scm/devel/sparse/chrisl/sparse.git

I still track the old repo. My config for it is:

[core]
repositoryformatversion = 0
filemode = true
bare = false
[remote "origin"]
url = git://git.kernel.org/pub/scm/devel/sparse/sparse.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[remote "sparse-chris"]
url = git://git.kernel.org/pub/scm/devel/sparse/chrisl/sparse.git
fetch = +refs/heads/*:refs/remotes/sparse-chris/*

> 
> > Yesterday, I added both trees I'm using here at:
> > https://git.linuxtv.org/mchehab/sparse.git/
> > https://git.linuxtv.org/mchehab/smatch.git/  
> Maybe we should use your version in the build script.
> Hans?
> 
> > IMHO, all 4 patches are disabling false-positive only warnings,
> > although the 4th patch might have something useful, if fixed to
> > properly handle the 64-bit compat macros.  
> Another good reason for using your version. Doing so, you can fix/extend
> sparse/smatch and the daily build will automatically use that.
> 
> BR,
>Jasmin



Thanks,
Mauro


[PATCH v14 00/33] rcar-vin: Add Gen3 with media controller

2018-04-14 Thread Niklas Söderlund
Hi,

This series adds Gen3 VIN support to rcar-vin driver for Renesas r8a7795,
r8a7796 and r8a77970. It is based on the media-tree and depends on
Fabrizio Castro patches as they touches the order of the compatible
strings in the documentation to reduce merge conflicts. The dependencies
are included in this series.

The driver is tested on Renesas H3 (r8a7795, ES2.0),
M3-W (r8a7796) together with the rcar-csi2 driver (posted separately and
not yet upstream) and the Salvator-X onboard ADV7482. It is also tested
on the V3M (r8a77970) on the Eagle board together with its expansion
board with a ADV7482 and out of tree patches for GMSL capture using the
max9286 and rdacm20 drivers.

It is possible to capture both CVBS and HDMI video streams,
v4l2-compliance passes with no errors and media-ctl can be used to
change the routing and formats for the different entities in the media
graph.

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

For convenience the series can be fetched from:

  git://git.ragnatech.se/linux rcar/vin/mc-v14

I have started on a very basic test suite for the VIN driver at:

  https://git.ragnatech.se/vin-tests

And as before the state of the driver and information about how to test
it can be found on the elinux wiki:

  http://elinux.org/R-Car/Tests:rcar-vin

* Changes since v13
- rvin_reset_format() always returns 0, make it a void function and
  update all call-sites no to check the return value.
- Simplify how the source, compose and crop geometry is reset in 
  rvin_reset_format(), no change except making the code more readable, 
  thanks Laurent for a good suggestion.
- Split two single line declaration of multiple variables to multiple 
  lines, removing constructs like 'crop->top = crop->left = 0;' into two 
  separate statements.
- Make crop and compose arguments to rvin_try_format() optional to avoid
  having to declare local variables in rvin_try_fmt_vid_cap() which are
  not used.
- Remove VNCSI_IFMD_DES2 define as the later versions of the datasheet 
  have been updated to remove the register as pointed out by Koji Matsuoka.
- Do not set the VNCSI_IFMD_DES2 bit in the VNCSI_IFMD register as that 
  bit have been removed from later versions of the datasheet.
- Spelling dose -> does
- Add review tag from Laurent, big thanks!

* Changes from v12
- Rebase to latest media-tree/master changed a 'return ret' to a 'goto
  out' in rvin_start_streaming() to take recent changes to the VIN
  driver into account.
- Moved field != V4L2_FIELD_ANY in 'rcar-vin: set a default field to
  fallback on' check from a later commit 'rcar-vin: simplify how formats
  are set and reset' in the series. This is to avoid ignoring the field
  returned from the sensor if FIELD_ANY was requested by the user. This
  was only a problem between this change and a few patches later, but
  better to fix it now. Reported by Hans, thanks for spotting this.
- Fix spelling.
- Add review tags from Hans.

* Changes since v11
- Rewrote commit message for '[PATCH v11 22/32] rcar-vin: force default
  colorspace for media centric mode'. Also set fixed values for
  xfer_func, quantization and ycbcr_enc.
- Reorderd filed order in struct rvin_group_route.
- Renamed chan to channel in struct rvin_group_route.
- Rework 'rcar-vin: read subdevice format for crop only when
  needed' into 'rcar-vin: simplify how formats are set and reset'.
- Keep caching the source dimensions and drop all changes to
  rvin_g_selection() and rvin_s_selection().
- Inline rvin_get_vin_format_from_source() into rvin_reset_format()
  which now is the only user left.
- Add patch to cache the video standard instead of reading it at stream
  on.
- Fix error labels in rvin_mc_open().
- Fixed spelling in commit messages and comment, thanks Laurent!
- Added reviewed tags from Laurent, Thanks!

* Changes since v10
- Corrected spelling in comments and commit messages.
- Reworked 'rcar-vin: read subdevice format for crop only when needed'
  to only get the source format once per operation.
- Moved some patches around to make it easier to review, moved:
- rcar-vin: set a default field to fallback on
- rcar-vin: fix handling of single field frames (top, bottom and alternate 
fields)
- rcar-vin: update bytesperline and sizeimage calculation
- rcar-vin: break out format alignment and checking
- rcar-vin: update pixelformat check for M1
  Before:
- rcar-vin: read subdevice format for crop only when needed
- Rename variable 'code' to 'mbus_code' in struct rvin_dev.
- Add comment describing no locking is needed in
  rvin_set_channel_routing().
- Check return value of pm_runtime_get_sync() in
  rvin_set_channel_routing().
- Rework 'rcar-vin: add check for colorspace' to not try to check the
  format, instead force a default format. This should be revisited once
  either v4l2-compliance or v4l2 framework 

[PATCH v14 06/33] rcar-vin: move subdevice handling to async callbacks

2018-04-14 Thread Niklas Söderlund
In preparation for Gen3 support move the subdevice initialization and
clean up from rvin_v4l2_{register,unregister}() directly to the async
callbacks. This simplifies the addition of Gen3 support as the
rvin_v4l2_register() can be shared for both Gen2 and Gen3 while direct
subdevice control are only used on Gen2.

While moving this code drop a large comment which is copied from the
framework documentation and fold rvin_mbus_supported() into its only
caller. Also move the initialization and cleanup code to separate
functions to increase readability.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Hans Verkuil 

---

* Changes since v12
- 'shuld' -> should in comment to rvin_digital_subdevice_attach().
- Add review tag from Hans.
---
 drivers/media/platform/rcar-vin/rcar-core.c | 108 +++-
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  35 -
 2 files changed, 74 insertions(+), 69 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 47f06acde2e698f2..64daf92bc66dd81b 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -46,46 +46,88 @@ static int rvin_find_pad(struct v4l2_subdev *sd, int 
direction)
return -EINVAL;
 }
 
-static bool rvin_mbus_supported(struct rvin_graph_entity *entity)
+/* The vin lock should be held when calling the subdevice attach and detach */
+static int rvin_digital_subdevice_attach(struct rvin_dev *vin,
+struct v4l2_subdev *subdev)
 {
-   struct v4l2_subdev *sd = entity->subdev;
struct v4l2_subdev_mbus_code_enum code = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
};
+   int ret;
 
+   /* Find source and sink pad of remote subdevice */
+   ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);
+   if (ret < 0)
+   return ret;
+   vin->digital->source_pad = ret;
+
+   ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);
+   vin->digital->sink_pad = ret < 0 ? 0 : ret;
+
+   /* Find compatible subdevices mbus format */
+   vin->digital->code = 0;
code.index = 0;
-   code.pad = entity->source_pad;
-   while (!v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, )) {
+   code.pad = vin->digital->source_pad;
+   while (!vin->digital->code &&
+  !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, )) {
code.index++;
switch (code.code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
case MEDIA_BUS_FMT_UYVY8_2X8:
case MEDIA_BUS_FMT_UYVY10_2X10:
case MEDIA_BUS_FMT_RGB888_1X24:
-   entity->code = code.code;
-   return true;
+   vin->digital->code = code.code;
+   vin_dbg(vin, "Found media bus format for %s: %d\n",
+   subdev->name, vin->digital->code);
+   break;
default:
break;
}
}
 
-   return false;
-}
-
-static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
-{
-   struct rvin_dev *vin = notifier_to_vin(notifier);
-   int ret;
-
-   /* Verify subdevices mbus format */
-   if (!rvin_mbus_supported(vin->digital)) {
+   if (!vin->digital->code) {
vin_err(vin, "Unsupported media bus format for %s\n",
-   vin->digital->subdev->name);
+   subdev->name);
return -EINVAL;
}
 
-   vin_dbg(vin, "Found media bus format for %s: %d\n",
-   vin->digital->subdev->name, vin->digital->code);
+   /* Read tvnorms */
+   ret = v4l2_subdev_call(subdev, video, g_tvnorms, >vdev.tvnorms);
+   if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+   return ret;
+
+   /* Add the controls */
+   ret = v4l2_ctrl_handler_init(>ctrl_handler, 16);
+   if (ret < 0)
+   return ret;
+
+   ret = v4l2_ctrl_add_handler(>ctrl_handler, subdev->ctrl_handler,
+   NULL);
+   if (ret < 0) {
+   v4l2_ctrl_handler_free(>ctrl_handler);
+   return ret;
+   }
+
+   vin->vdev.ctrl_handler = >ctrl_handler;
+
+   vin->digital->subdev = subdev;
+
+   return 0;
+}
+
+static void rvin_digital_subdevice_detach(struct rvin_dev *vin)
+{
+   rvin_v4l2_unregister(vin);
+   v4l2_ctrl_handler_free(>ctrl_handler);
+
+   vin->vdev.ctrl_handler = NULL;
+   vin->digital->subdev = NULL;
+}
+
+static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
+{
+   struct rvin_dev *vin = notifier_to_vin(notifier);
+   int ret;
 
ret = 

[PATCH v14 05/33] rcar-vin: unregister video device on driver removal

2018-04-14 Thread Niklas Söderlund
If the video device was registered by the complete() callback it should
be unregistered when a device is unbound from the driver. Protect from
printing an uninitialized video device node name by adding a check in
rvin_v4l2_unregister() to identify that the video device is registered.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Kieran Bingham 
Reviewed-by: Hans Verkuil 
Acked-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 2 ++
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 2bedf20abcf3ca07..47f06acde2e698f2 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -272,6 +272,8 @@ static int rcar_vin_remove(struct platform_device *pdev)
 
pm_runtime_disable(>dev);
 
+   rvin_v4l2_unregister(vin);
+
v4l2_async_notifier_unregister(>notifier);
v4l2_async_notifier_cleanup(>notifier);
 
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 178aecc94962abe2..32a658214f48fa49 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -841,6 +841,9 @@ static const struct v4l2_file_operations rvin_fops = {
 
 void rvin_v4l2_unregister(struct rvin_dev *vin)
 {
+   if (!video_is_registered(>vdev))
+   return;
+
v4l2_info(>v4l2_dev, "Removing %s\n",
  video_device_node_name(>vdev));
 
-- 
2.16.2



[PATCH v14 04/33] rcar-vin: rename poorly named initialize and cleanup functions

2018-04-14 Thread Niklas Söderlund
The functions to register and unregister the hardware and video device
where poorly named from the start. Rename them to better describe their
intended function.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Kieran Bingham 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 10 +-
 drivers/media/platform/rcar-vin/rcar-dma.c  |  6 +++---
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  4 ++--
 drivers/media/platform/rcar-vin/rcar-vin.h  |  8 
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index f1fc7978d6d1523d..2bedf20abcf3ca07 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -93,7 +93,7 @@ static int rvin_digital_notify_complete(struct 
v4l2_async_notifier *notifier)
return ret;
}
 
-   return rvin_v4l2_probe(vin);
+   return rvin_v4l2_register(vin);
 }
 
 static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier,
@@ -103,7 +103,7 @@ static void rvin_digital_notify_unbind(struct 
v4l2_async_notifier *notifier,
struct rvin_dev *vin = notifier_to_vin(notifier);
 
vin_dbg(vin, "unbind digital subdev %s\n", subdev->name);
-   rvin_v4l2_remove(vin);
+   rvin_v4l2_unregister(vin);
vin->digital->subdev = NULL;
 }
 
@@ -245,7 +245,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
 
-   ret = rvin_dma_probe(vin, irq);
+   ret = rvin_dma_register(vin, irq);
if (ret)
return ret;
 
@@ -260,7 +260,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
 
return 0;
 error:
-   rvin_dma_remove(vin);
+   rvin_dma_unregister(vin);
v4l2_async_notifier_cleanup(>notifier);
 
return ret;
@@ -275,7 +275,7 @@ static int rcar_vin_remove(struct platform_device *pdev)
v4l2_async_notifier_unregister(>notifier);
v4l2_async_notifier_cleanup(>notifier);
 
-   rvin_dma_remove(vin);
+   rvin_dma_unregister(vin);
 
return 0;
 }
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 4a40e6ad1be7ed95..2aae3ca54eabac01 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -1087,14 +1087,14 @@ static const struct vb2_ops rvin_qops = {
.wait_finish= vb2_ops_wait_finish,
 };
 
-void rvin_dma_remove(struct rvin_dev *vin)
+void rvin_dma_unregister(struct rvin_dev *vin)
 {
mutex_destroy(>lock);
 
v4l2_device_unregister(>v4l2_dev);
 }
 
-int rvin_dma_probe(struct rvin_dev *vin, int irq)
+int rvin_dma_register(struct rvin_dev *vin, int irq)
 {
struct vb2_queue *q = >queue;
int i, ret;
@@ -1142,7 +1142,7 @@ int rvin_dma_probe(struct rvin_dev *vin, int irq)
 
return 0;
 error:
-   rvin_dma_remove(vin);
+   rvin_dma_unregister(vin);
 
return ret;
 }
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index b479b882da12f62d..178aecc94962abe2 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -839,7 +839,7 @@ static const struct v4l2_file_operations rvin_fops = {
.read   = vb2_fop_read,
 };
 
-void rvin_v4l2_remove(struct rvin_dev *vin)
+void rvin_v4l2_unregister(struct rvin_dev *vin)
 {
v4l2_info(>v4l2_dev, "Removing %s\n",
  video_device_node_name(>vdev));
@@ -866,7 +866,7 @@ static void rvin_notify(struct v4l2_subdev *sd,
}
 }
 
-int rvin_v4l2_probe(struct rvin_dev *vin)
+int rvin_v4l2_register(struct rvin_dev *vin)
 {
struct video_device *vdev = >vdev;
struct v4l2_subdev *sd = vin_to_source(vin);
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 95897127cc410d4f..385243e3d4da130b 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -153,11 +153,11 @@ struct rvin_dev {
 #define vin_warn(d, fmt, arg...)   dev_warn(d->dev, fmt, ##arg)
 #define vin_err(d, fmt, arg...)dev_err(d->dev, fmt, ##arg)
 
-int rvin_dma_probe(struct rvin_dev *vin, int irq);
-void rvin_dma_remove(struct rvin_dev *vin);
+int rvin_dma_register(struct rvin_dev *vin, int irq);
+void rvin_dma_unregister(struct rvin_dev *vin);
 
-int rvin_v4l2_probe(struct rvin_dev *vin);
-void rvin_v4l2_remove(struct rvin_dev *vin);
+int rvin_v4l2_register(struct rvin_dev *vin);
+void rvin_v4l2_unregister(struct rvin_dev *vin);
 
 const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat);
 

[PATCH v14 03/33] rcar-vin: add Gen3 devicetree bindings documentation

2018-04-14 Thread Niklas Söderlund
Document the devicetree bindings for the CSI-2 inputs available on Gen3.

There is a need to add a custom property 'renesas,id' and to define
which CSI-2 input is described in which endpoint under the port@1 node.
This information is needed since there are a set of predefined routes
between each VIN and CSI-2 block. This routing table will be kept
inside the driver but in order for it to act on it it must know which
VIN and CSI-2 is which.

Signed-off-by: Niklas Söderlund 
Acked-by: Rob Herring 
Reviewed-by: Laurent Pinchart 
---
 .../devicetree/bindings/media/rcar_vin.txt | 118 ++---
 1 file changed, 106 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt 
b/Documentation/devicetree/bindings/media/rcar_vin.txt
index 4c76d82905c9d3b8..ba31431d4b1fbdbb 100644
--- a/Documentation/devicetree/bindings/media/rcar_vin.txt
+++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
@@ -2,8 +2,12 @@ Renesas R-Car Video Input driver (rcar_vin)
 ---
 
 The rcar_vin device provides video input capabilities for the Renesas R-Car
-family of devices. The current blocks are always slaves and suppot one input
-channel which can be either RGB, YUYV or BT656.
+family of devices.
+
+Each VIN instance has a single parallel input that supports RGB and YUV video,
+with both external synchronization and BT.656 synchronization for the latter.
+Depending on the instance the VIN input is connected to external SoC pins, or
+on Gen3 platforms to a CSI-2 receiver.
 
  - compatible: Must be one or more of the following
- "renesas,vin-r8a7743" for the R8A7743 device
@@ -16,6 +20,8 @@ channel which can be either RGB, YUYV or BT656.
- "renesas,vin-r8a7793" for the R8A7793 device
- "renesas,vin-r8a7794" for the R8A7794 device
- "renesas,vin-r8a7795" for the R8A7795 device
+   - "renesas,vin-r8a7796" for the R8A7796 device
+   - "renesas,vin-r8a77970" for the R8A77970 device
- "renesas,rcar-gen2-vin" for a generic R-Car Gen2 or RZ/G1 compatible
  device.
- "renesas,rcar-gen3-vin" for a generic R-Car Gen3 compatible device.
@@ -31,21 +37,38 @@ channel which can be either RGB, YUYV or BT656.
 Additionally, an alias named vinX will need to be created to specify
 which video input device this is.
 
-The per-board settings:
+The per-board settings Gen2 platforms:
  - port sub-node describing a single endpoint connected to the vin
as described in video-interfaces.txt[1]. Only the first one will
be considered as each vin interface has one input port.
 
-   These settings are used to work out video input format and widths
-   into the system.
+The per-board settings Gen3 platforms:
 
+Gen3 platforms can support both a single connected parallel input source
+from external SoC pins (port0) and/or multiple parallel input sources
+from local SoC CSI-2 receivers (port1) depending on SoC.
 
-Device node example

+- renesas,id - ID number of the VIN, VINx in the documentation.
+- ports
+- port 0 - sub-node describing a single endpoint connected to the VIN
+  from external SoC pins described in video-interfaces.txt[1].
+  Describing more then one endpoint in port 0 is invalid. Only VIN
+  instances that are connected to external pins should have port 0.
+- port 1 - sub-nodes describing one or more endpoints connected to
+  the VIN from local SoC CSI-2 receivers. The endpoint numbers must
+  use the following schema.
 
-   aliases {
-  vin0 = 
-   };
+- Endpoint 0 - sub-node describing the endpoint connected to CSI20
+- Endpoint 1 - sub-node describing the endpoint connected to CSI21
+- Endpoint 2 - sub-node describing the endpoint connected to CSI40
+- Endpoint 3 - sub-node describing the endpoint connected to CSI41
+
+Device node example for Gen2 platforms
+--
+
+aliases {
+vin0 = 
+};
 
 vin0: vin@e6ef {
 compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin";
@@ -55,8 +78,8 @@ Device node example
 status = "disabled";
 };
 
-Board setup example (vin1 composite video input)
-
+Board setup example for Gen2 platforms (vin1 composite video input)
+---
 
{
 status = "okay";
@@ -95,6 +118,77 @@ Board setup example (vin1 composite video input)
 };
 };
 
+Device node example for Gen3 platforms
+--
 
+vin0: video@e6ef {
+compatible = "renesas,vin-r8a7795";
+reg = <0 0xe6ef 0 0x1000>;
+interrupts = ;
+clocks = < CPG_MOD 811>;
+power-domains = < 

[PATCH v14 02/33] dt-bindings: media: rcar_vin: add device tree support for r8a774[35]

2018-04-14 Thread Niklas Söderlund
From: Fabrizio Castro 

Add compatible strings for r8a7743 and r8a7745. No driver change
is needed as "renesas,rcar-gen2-vin" will activate the right code.
However, it is good practice to document compatible strings for the
specific SoC as this allows SoC specific changes to the driver if
needed, in addition to document SoC support and therefore allow
checkpatch.pl to validate compatible string values.

Signed-off-by: Fabrizio Castro 
Reviewed-by: Biju Das 
Reviewed-by: Simon Horman 
Acked-by: Rob Herring 
Reviewed-by: Geert Uytterhoeven 
Acked-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
---
 Documentation/devicetree/bindings/media/rcar_vin.txt | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt 
b/Documentation/devicetree/bindings/media/rcar_vin.txt
index d99b6f5dee418056..4c76d82905c9d3b8 100644
--- a/Documentation/devicetree/bindings/media/rcar_vin.txt
+++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
@@ -6,6 +6,8 @@ family of devices. The current blocks are always slaves and 
suppot one input
 channel which can be either RGB, YUYV or BT656.
 
  - compatible: Must be one or more of the following
+   - "renesas,vin-r8a7743" for the R8A7743 device
+   - "renesas,vin-r8a7745" for the R8A7745 device
- "renesas,vin-r8a7778" for the R8A7778 device
- "renesas,vin-r8a7779" for the R8A7779 device
- "renesas,vin-r8a7790" for the R8A7790 device
@@ -14,7 +16,8 @@ channel which can be either RGB, YUYV or BT656.
- "renesas,vin-r8a7793" for the R8A7793 device
- "renesas,vin-r8a7794" for the R8A7794 device
- "renesas,vin-r8a7795" for the R8A7795 device
-   - "renesas,rcar-gen2-vin" for a generic R-Car Gen2 compatible device.
+   - "renesas,rcar-gen2-vin" for a generic R-Car Gen2 or RZ/G1 compatible
+ device.
- "renesas,rcar-gen3-vin" for a generic R-Car Gen3 compatible device.
 
When compatible with the generic version nodes must list the
-- 
2.16.2



[PATCH v14 01/33] dt-bindings: media: rcar_vin: Reverse SoC part number list

2018-04-14 Thread Niklas Söderlund
From: Fabrizio Castro 

Change the sorting of the part numbers from descending to ascending to
match with other documentation.

Signed-off-by: Fabrizio Castro 
Reviewed-by: Biju Das 
Reviewed-by: Simon Horman 
Acked-by: Rob Herring 
Reviewed-by: Geert Uytterhoeven 
Acked-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
---
 Documentation/devicetree/bindings/media/rcar_vin.txt | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt 
b/Documentation/devicetree/bindings/media/rcar_vin.txt
index 1ce7ff9449c556d9..d99b6f5dee418056 100644
--- a/Documentation/devicetree/bindings/media/rcar_vin.txt
+++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
@@ -6,14 +6,14 @@ family of devices. The current blocks are always slaves and 
suppot one input
 channel which can be either RGB, YUYV or BT656.
 
  - compatible: Must be one or more of the following
-   - "renesas,vin-r8a7795" for the R8A7795 device
-   - "renesas,vin-r8a7794" for the R8A7794 device
-   - "renesas,vin-r8a7793" for the R8A7793 device
-   - "renesas,vin-r8a7792" for the R8A7792 device
-   - "renesas,vin-r8a7791" for the R8A7791 device
-   - "renesas,vin-r8a7790" for the R8A7790 device
-   - "renesas,vin-r8a7779" for the R8A7779 device
- "renesas,vin-r8a7778" for the R8A7778 device
+   - "renesas,vin-r8a7779" for the R8A7779 device
+   - "renesas,vin-r8a7790" for the R8A7790 device
+   - "renesas,vin-r8a7791" for the R8A7791 device
+   - "renesas,vin-r8a7792" for the R8A7792 device
+   - "renesas,vin-r8a7793" for the R8A7793 device
+   - "renesas,vin-r8a7794" for the R8A7794 device
+   - "renesas,vin-r8a7795" for the R8A7795 device
- "renesas,rcar-gen2-vin" for a generic R-Car Gen2 compatible device.
- "renesas,rcar-gen3-vin" for a generic R-Car Gen3 compatible device.
 
-- 
2.16.2



[PATCH v14 07/33] rcar-vin: move model information to own struct

2018-04-14 Thread Niklas Söderlund
When Gen3 support is added to the driver more than model ID will be
different for the different SoCs. To avoid a lot of if statements in the
code create a struct rvin_info to store this information.

While we are at it rename the poorly chosen enum which contains the
different model IDs from chip_id to model_id. Also sort the compatible
string entries and make use of of_device_get_match_data() which will
always work as the driver is DT only, so there's always a valid match.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Kieran Bingham 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 56 +
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  3 +-
 drivers/media/platform/rcar-vin/rcar-vin.h  | 14 ++--
 3 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 64daf92bc66dd81b..71d66916ce1b28ab 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -241,21 +241,53 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
  * Platform Device Driver
  */
 
+static const struct rvin_info rcar_info_h1 = {
+   .model = RCAR_H1,
+};
+
+static const struct rvin_info rcar_info_m1 = {
+   .model = RCAR_M1,
+};
+
+static const struct rvin_info rcar_info_gen2 = {
+   .model = RCAR_GEN2,
+};
+
 static const struct of_device_id rvin_of_id_table[] = {
-   { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
-   { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
-   { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
-   { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
-   { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
-   { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
-   { .compatible = "renesas,rcar-gen2-vin", .data = (void *)RCAR_GEN2 },
-   { },
+   {
+   .compatible = "renesas,vin-r8a7778",
+   .data = _info_m1,
+   },
+   {
+   .compatible = "renesas,vin-r8a7779",
+   .data = _info_h1,
+   },
+   {
+   .compatible = "renesas,vin-r8a7790",
+   .data = _info_gen2,
+   },
+   {
+   .compatible = "renesas,vin-r8a7791",
+   .data = _info_gen2,
+   },
+   {
+   .compatible = "renesas,vin-r8a7793",
+   .data = _info_gen2,
+   },
+   {
+   .compatible = "renesas,vin-r8a7794",
+   .data = _info_gen2,
+   },
+   {
+   .compatible = "renesas,rcar-gen2-vin",
+   .data = _info_gen2,
+   },
+   { /* Sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
 
 static int rcar_vin_probe(struct platform_device *pdev)
 {
-   const struct of_device_id *match;
struct rvin_dev *vin;
struct resource *mem;
int irq, ret;
@@ -264,12 +296,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
if (!vin)
return -ENOMEM;
 
-   match = of_match_device(of_match_ptr(rvin_of_id_table), >dev);
-   if (!match)
-   return -ENODEV;
-
vin->dev = >dev;
-   vin->chip = (enum chip_id)match->data;
+   vin->info = of_device_get_match_data(>dev);
 
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (mem == NULL)
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 4a0610a6b4503501..0a035667c0b0e93f 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -266,7 +266,8 @@ static int __rvin_try_format(struct rvin_dev *vin,
pix->sizeimage = max_t(u32, pix->sizeimage,
   rvin_format_sizeimage(pix));
 
-   if (vin->chip == RCAR_M1 && pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
+   if (vin->info->model == RCAR_M1 &&
+   pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
vin_err(vin, "pixel format XBGR32 not supported on M1\n");
return -EINVAL;
}
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 385243e3d4da130b..b63c4fce68adaae6 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -29,7 +29,7 @@
 /* Address alignment mask for HW buffers */
 #define HW_BUFFER_MASK 0x7f
 
-enum chip_id {
+enum model_id {
RCAR_H1,
RCAR_M1,
RCAR_GEN2,
@@ -86,11 +86,19 @@ struct rvin_graph_entity {
unsigned int sink_pad;
 };
 
+/**
+ * struct rvin_info - Information about the particular 

[PATCH v14 10/33] rcar-vin: all Gen2 boards can scale simplify logic

2018-04-14 Thread Niklas Söderlund
The logic to preserve the requested format width and height are too
complex and come from a premature optimization for Gen3. All Gen2 SoC
can scale and the Gen3 implementation will not use these functions at
all so simply preserve the width and height when interacting with the
subdevice much like the field is preserved simplifies the logic quite a
bit.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-dma.c  |  8 
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 25 +++--
 drivers/media/platform/rcar-vin/rcar-vin.h  |  2 --
 3 files changed, 11 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 23120901b0a062ed..4f48575f2008fe34 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -585,14 +585,6 @@ void rvin_crop_scale_comp(struct rvin_dev *vin)
0, 0);
 }
 
-void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix,
-   u32 width, u32 height)
-{
-   /* All VIN channels on Gen2 have scalers */
-   pix->width = width;
-   pix->height = height;
-}
-
 /* 
-
  * Hardware setup
  */
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 8805d7911a761019..c2265324c7c96308 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -166,6 +166,7 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
.which = which,
};
enum v4l2_field field;
+   u32 width, height;
int ret;
 
sd = vin_to_source(vin);
@@ -178,7 +179,10 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
 
format.pad = vin->digital->source_pad;
 
+   /* Allow the video device to override field and to scale */
field = pix->field;
+   width = pix->width;
+   height = pix->height;
 
ret = v4l2_subdev_call(sd, pad, set_fmt, pad_cfg, );
if (ret < 0 && ret != -ENOIOCTLCMD)
@@ -186,11 +190,13 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
 
v4l2_fill_pix_format(pix, );
 
-   pix->field = field;
-
source->width = pix->width;
source->height = pix->height;
 
+   pix->field = field;
+   pix->width = width;
+   pix->height = height;
+
vin_dbg(vin, "Source resolution: %ux%u\n", source->width,
source->height);
 
@@ -204,13 +210,9 @@ static int __rvin_try_format(struct rvin_dev *vin,
 struct v4l2_pix_format *pix,
 struct rvin_source_fmt *source)
 {
-   u32 rwidth, rheight, walign;
+   u32 walign;
int ret;
 
-   /* Requested */
-   rwidth = pix->width;
-   rheight = pix->height;
-
/* Keep current field if no specific one is asked for */
if (pix->field == V4L2_FIELD_ANY)
pix->field = vin->format.field;
@@ -248,10 +250,6 @@ static int __rvin_try_format(struct rvin_dev *vin,
break;
}
 
-   /* If source can't match format try if VIN can scale */
-   if (source->width != rwidth || source->height != rheight)
-   rvin_scale_try(vin, pix, rwidth, rheight);
-
/* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */
walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1;
 
@@ -270,9 +268,8 @@ static int __rvin_try_format(struct rvin_dev *vin,
return -EINVAL;
}
 
-   vin_dbg(vin, "Requested %ux%u Got %ux%u bpl: %d size: %d\n",
-   rwidth, rheight, pix->width, pix->height,
-   pix->bytesperline, pix->sizeimage);
+   vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n",
+   pix->width, pix->height, pix->bytesperline, pix->sizeimage);
 
return 0;
 }
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 8d135ed3f7abd855..1c91b774205a7750 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -175,8 +175,6 @@ void rvin_v4l2_unregister(struct rvin_dev *vin);
 const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat);
 
 /* Cropping, composing and scaling */
-void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix,
-   u32 width, u32 height);
 void rvin_crop_scale_comp(struct rvin_dev *vin);
 
 #endif
-- 
2.16.2



[PATCH v14 15/33] rcar-vin: break out format alignment and checking

2018-04-14 Thread Niklas Söderlund
Part of the format alignment and checking can be shared with the Gen3
format handling. Break that part out to a separate function.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 85 -
 1 file changed, 48 insertions(+), 37 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index d9231a074aa2c29d..f3a0310c43a9877f 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -87,6 +87,53 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix)
return pix->bytesperline * pix->height;
 }
 
+static int rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix)
+{
+   u32 walign;
+
+   if (!rvin_format_from_pixel(pix->pixelformat) ||
+   (vin->info->model == RCAR_M1 &&
+pix->pixelformat == V4L2_PIX_FMT_XBGR32))
+   pix->pixelformat = RVIN_DEFAULT_FORMAT;
+
+   switch (pix->field) {
+   case V4L2_FIELD_TOP:
+   case V4L2_FIELD_BOTTOM:
+   case V4L2_FIELD_NONE:
+   case V4L2_FIELD_INTERLACED_TB:
+   case V4L2_FIELD_INTERLACED_BT:
+   case V4L2_FIELD_INTERLACED:
+   break;
+   case V4L2_FIELD_ALTERNATE:
+   /*
+* Driver does not (yet) support outputting ALTERNATE to a
+* userspace. It does support outputting INTERLACED so use
+* the VIN hardware to combine the two fields.
+*/
+   pix->field = V4L2_FIELD_INTERLACED;
+   pix->height *= 2;
+   break;
+   default:
+   pix->field = RVIN_DEFAULT_FIELD;
+   break;
+   }
+
+   /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */
+   walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1;
+
+   /* Limit to VIN capabilities */
+   v4l_bound_align_image(>width, 2, vin->info->max_width, walign,
+ >height, 4, vin->info->max_height, 2, 0);
+
+   pix->bytesperline = rvin_format_bytesperline(pix);
+   pix->sizeimage = rvin_format_sizeimage(pix);
+
+   vin_dbg(vin, "Format %ux%u bpl: %u size: %u\n",
+   pix->width, pix->height, pix->bytesperline, pix->sizeimage);
+
+   return 0;
+}
+
 /* 
-
  * V4L2
  */
@@ -186,7 +233,6 @@ static int __rvin_try_format(struct rvin_dev *vin,
 struct v4l2_pix_format *pix,
 struct rvin_source_fmt *source)
 {
-   u32 walign;
int ret;
 
if (!rvin_format_from_pixel(pix->pixelformat) ||
@@ -199,42 +245,7 @@ static int __rvin_try_format(struct rvin_dev *vin,
if (ret)
return ret;
 
-   switch (pix->field) {
-   case V4L2_FIELD_TOP:
-   case V4L2_FIELD_BOTTOM:
-   case V4L2_FIELD_NONE:
-   case V4L2_FIELD_INTERLACED_TB:
-   case V4L2_FIELD_INTERLACED_BT:
-   case V4L2_FIELD_INTERLACED:
-   break;
-   case V4L2_FIELD_ALTERNATE:
-   /*
-* Driver does not (yet) support outputting ALTERNATE to a
-* userspace. It does support outputting INTERLACED so use
-* the VIN hardware to combine the two fields.
-*/
-   pix->field = V4L2_FIELD_INTERLACED;
-   pix->height *= 2;
-   break;
-   default:
-   pix->field = RVIN_DEFAULT_FIELD;
-   break;
-   }
-
-   /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */
-   walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1;
-
-   /* Limit to VIN capabilities */
-   v4l_bound_align_image(>width, 2, vin->info->max_width, walign,
- >height, 4, vin->info->max_height, 2, 0);
-
-   pix->bytesperline = rvin_format_bytesperline(pix);
-   pix->sizeimage = rvin_format_sizeimage(pix);
-
-   vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n",
-   pix->width, pix->height, pix->bytesperline, pix->sizeimage);
-
-   return 0;
+   return rvin_format_align(vin, pix);
 }
 
 static int rvin_querycap(struct file *file, void *priv,
-- 
2.16.2



[PATCH v14 11/33] rcar-vin: set a default field to fallback on

2018-04-14 Thread Niklas Söderlund
If the field is not supported by the driver it should not try to keep
the current field. Instead it should set it to a default fallback. Since
trying a format should always result in the same state regardless of the
current state of the device.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Hans Verkuil 

---

* Changes since v12
- Moved field != V4L2_FIELD_ANY check from a later commit 'rcar-vin:
  simplify how formats are set and reset' in the series. This is to
  avoid ignoring the field returned from the sensor if FIELD_ANY was
  requested by the user. This was only a problem between this change and
  a few patches later, but better to fix it now. Reported by Hans,
  thanks for spotting this.
- Add review tag from Hans.
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index c2265324c7c96308..16e895657c3f51c5 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -23,6 +23,7 @@
 #include "rcar-vin.h"
 
 #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV
+#define RVIN_DEFAULT_FIELD V4L2_FIELD_NONE
 
 /* 
-
  * Format Conversions
@@ -143,7 +144,7 @@ static int rvin_reset_format(struct rvin_dev *vin)
case V4L2_FIELD_INTERLACED:
break;
default:
-   vin->format.field = V4L2_FIELD_NONE;
+   vin->format.field = RVIN_DEFAULT_FIELD;
break;
}
 
@@ -193,7 +194,9 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
source->width = pix->width;
source->height = pix->height;
 
-   pix->field = field;
+   if (field != V4L2_FIELD_ANY)
+   pix->field = field;
+
pix->width = width;
pix->height = height;
 
@@ -213,10 +216,6 @@ static int __rvin_try_format(struct rvin_dev *vin,
u32 walign;
int ret;
 
-   /* Keep current field if no specific one is asked for */
-   if (pix->field == V4L2_FIELD_ANY)
-   pix->field = vin->format.field;
-
/* If requested format is not supported fallback to the default */
if (!rvin_format_from_pixel(pix->pixelformat)) {
vin_dbg(vin, "Format 0x%x not found, using default 0x%x\n",
@@ -246,7 +245,7 @@ static int __rvin_try_format(struct rvin_dev *vin,
case V4L2_FIELD_INTERLACED:
break;
default:
-   pix->field = V4L2_FIELD_NONE;
+   pix->field = RVIN_DEFAULT_FIELD;
break;
}
 
-- 
2.16.2



[PATCH v14 09/33] rcar-vin: move functions regarding scaling

2018-04-14 Thread Niklas Söderlund
In preparation of refactoring the scaling code move the code regarding
scaling to to the top of the file to avoid the need to add forward
declarations. No code is changed in this commit only whole functions
moved inside the same file.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 526 +++--
 1 file changed, 265 insertions(+), 261 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 2aae3ca54eabac01..23120901b0a062ed 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -138,267 +138,6 @@ static u32 rvin_read(struct rvin_dev *vin, u32 offset)
return ioread32(vin->base + offset);
 }
 
-static int rvin_setup(struct rvin_dev *vin)
-{
-   u32 vnmc, dmr, dmr2, interrupts;
-   v4l2_std_id std;
-   bool progressive = false, output_is_yuv = false, input_is_yuv = false;
-
-   switch (vin->format.field) {
-   case V4L2_FIELD_TOP:
-   vnmc = VNMC_IM_ODD;
-   break;
-   case V4L2_FIELD_BOTTOM:
-   vnmc = VNMC_IM_EVEN;
-   break;
-   case V4L2_FIELD_INTERLACED:
-   /* Default to TB */
-   vnmc = VNMC_IM_FULL;
-   /* Use BT if video standard can be read and is 60 Hz format */
-   if (!v4l2_subdev_call(vin_to_source(vin), video, g_std, )) {
-   if (std & V4L2_STD_525_60)
-   vnmc = VNMC_IM_FULL | VNMC_FOC;
-   }
-   break;
-   case V4L2_FIELD_INTERLACED_TB:
-   vnmc = VNMC_IM_FULL;
-   break;
-   case V4L2_FIELD_INTERLACED_BT:
-   vnmc = VNMC_IM_FULL | VNMC_FOC;
-   break;
-   case V4L2_FIELD_ALTERNATE:
-   case V4L2_FIELD_NONE:
-   vnmc = VNMC_IM_ODD_EVEN;
-   progressive = true;
-   break;
-   default:
-   vnmc = VNMC_IM_ODD;
-   break;
-   }
-
-   /*
-* Input interface
-*/
-   switch (vin->digital->code) {
-   case MEDIA_BUS_FMT_YUYV8_1X16:
-   /* BT.601/BT.1358 16bit YCbCr422 */
-   vnmc |= VNMC_INF_YUV16;
-   input_is_yuv = true;
-   break;
-   case MEDIA_BUS_FMT_UYVY8_2X8:
-   /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
-   vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ?
-   VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
-   input_is_yuv = true;
-   break;
-   case MEDIA_BUS_FMT_RGB888_1X24:
-   vnmc |= VNMC_INF_RGB888;
-   break;
-   case MEDIA_BUS_FMT_UYVY10_2X10:
-   /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
-   vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ?
-   VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
-   input_is_yuv = true;
-   break;
-   default:
-   break;
-   }
-
-   /* Enable VSYNC Field Toogle mode after one VSYNC input */
-   dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);
-
-   /* Hsync Signal Polarity Select */
-   if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
-   dmr2 |= VNDMR2_HPS;
-
-   /* Vsync Signal Polarity Select */
-   if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
-   dmr2 |= VNDMR2_VPS;
-
-   /*
-* Output format
-*/
-   switch (vin->format.pixelformat) {
-   case V4L2_PIX_FMT_NV16:
-   rvin_write(vin,
-  ALIGN(vin->format.width * vin->format.height, 0x80),
-  VNUVAOF_REG);
-   dmr = VNDMR_DTMD_YCSEP;
-   output_is_yuv = true;
-   break;
-   case V4L2_PIX_FMT_YUYV:
-   dmr = VNDMR_BPSM;
-   output_is_yuv = true;
-   break;
-   case V4L2_PIX_FMT_UYVY:
-   dmr = 0;
-   output_is_yuv = true;
-   break;
-   case V4L2_PIX_FMT_XRGB555:
-   dmr = VNDMR_DTMD_ARGB1555;
-   break;
-   case V4L2_PIX_FMT_RGB565:
-   dmr = 0;
-   break;
-   case V4L2_PIX_FMT_XBGR32:
-   /* Note: not supported on M1 */
-   dmr = VNDMR_EXRGB;
-   break;
-   default:
-   vin_err(vin, "Invalid pixelformat (0x%x)\n",
-   vin->format.pixelformat);
-   return -EINVAL;
-   }
-
-   /* Always update on field change */
-   vnmc |= VNMC_VUP;
-
-   /* If input and output use the same colorspace, use bypass mode */
-   if (input_is_yuv == 

[PATCH v14 12/33] rcar-vin: fix handling of single field frames (top, bottom and alternate fields)

2018-04-14 Thread Niklas Söderlund
There was never proper support in the VIN driver to deliver ALTERNATING
field format to user-space, remove this field option. The problem is
that ALTERNATING field order requires the sequence numbers of buffers
returned to userspace to reflect if fields were dropped or not,
something which is not possible with the VIN drivers capture logic.

The VIN driver can still capture from a video source which delivers
frames in ALTERNATING field order, but needs to combine them using the
VIN hardware into INTERLACED field order. Before this change if a source
was delivering fields using ALTERNATE the driver would default to
combining them using this hardware feature. Only if the user explicitly
requested ALTERNATE field order would incorrect frames be delivered.

The height should not be cut in half for the format for TOP or BOTTOM
fields settings. This was a mistake and it was made visible by the
scaling refactoring. Correct behavior is that the user should request a
frame size that fits the half height frame reflected in the field
setting. If not the VIN will do its best to scale the top or bottom to
the requested format and cropping and scaling do not work as expected.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 

---

* Changes since v13
- Spelling dose -> does
- Add review tag from Laurent

* Changes since v12
- Spelling where -> were.
- Add review tag from Hans.
---
 drivers/media/platform/rcar-vin/rcar-dma.c  | 15 +--
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 40 +++--
 2 files changed, 10 insertions(+), 45 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 4f48575f2008fe34..9233924e5b52de5f 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -617,7 +617,6 @@ static int rvin_setup(struct rvin_dev *vin)
case V4L2_FIELD_INTERLACED_BT:
vnmc = VNMC_IM_FULL | VNMC_FOC;
break;
-   case V4L2_FIELD_ALTERNATE:
case V4L2_FIELD_NONE:
vnmc = VNMC_IM_ODD_EVEN;
progressive = true;
@@ -745,18 +744,6 @@ static bool rvin_capture_active(struct rvin_dev *vin)
return rvin_read(vin, VNMS_REG) & VNMS_CA;
 }
 
-static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms)
-{
-   if (vin->format.field == V4L2_FIELD_ALTERNATE) {
-   /* If FS is set it's a Even field */
-   if (vnms & VNMS_FS)
-   return V4L2_FIELD_BOTTOM;
-   return V4L2_FIELD_TOP;
-   }
-
-   return vin->format.field;
-}
-
 static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr)
 {
const struct rvin_video_format *fmt;
@@ -892,7 +879,7 @@ static irqreturn_t rvin_irq(int irq, void *data)
 
/* Capture frame */
if (vin->queue_buf[slot]) {
-   vin->queue_buf[slot]->field = rvin_get_active_field(vin, vnms);
+   vin->queue_buf[slot]->field = vin->format.field;
vin->queue_buf[slot]->sequence = vin->sequence;
vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns();
vb2_buffer_done(>queue_buf[slot]->vb2_buf,
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 16e895657c3f51c5..81a9aec96e8e664a 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -121,33 +121,6 @@ static int rvin_reset_format(struct rvin_dev *vin)
vin->format.colorspace  = mf->colorspace;
vin->format.field   = mf->field;
 
-   /*
-* If the subdevice uses ALTERNATE field mode and G_STD is
-* implemented use the VIN HW to combine the two fields to
-* one INTERLACED frame. The ALTERNATE field mode can still
-* be requested in S_FMT and be respected, this is just the
-* default which is applied at probing or when S_STD is called.
-*/
-   if (vin->format.field == V4L2_FIELD_ALTERNATE &&
-   v4l2_subdev_has_op(vin_to_source(vin), video, g_std))
-   vin->format.field = V4L2_FIELD_INTERLACED;
-
-   switch (vin->format.field) {
-   case V4L2_FIELD_TOP:
-   case V4L2_FIELD_BOTTOM:
-   case V4L2_FIELD_ALTERNATE:
-   vin->format.height /= 2;
-   break;
-   case V4L2_FIELD_NONE:
-   case V4L2_FIELD_INTERLACED_TB:
-   case V4L2_FIELD_INTERLACED_BT:
-   case V4L2_FIELD_INTERLACED:
-   break;
-   default:
-   vin->format.field = RVIN_DEFAULT_FIELD;
-   break;
-   }
-
rvin_reset_crop_compose(vin);
 
vin->format.bytesperline = rvin_format_bytesperline(>format);
@@ -235,15 +208,20 @@ static int 

[PATCH v14 13/33] rcar-vin: update bytesperline and sizeimage calculation

2018-04-14 Thread Niklas Söderlund
Remove over complicated logic to calculate the value for bytesperline
and sizeimage that was carried over from the soc_camera port. There is
no need to find the max value of bytesperline and sizeimage from
user-space as they are set to 0 before the max_t() operation.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 81a9aec96e8e664a..907322e1eeb5f6a0 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -196,10 +196,6 @@ static int __rvin_try_format(struct rvin_dev *vin,
pix->pixelformat = RVIN_DEFAULT_FORMAT;
}
 
-   /* Always recalculate */
-   pix->bytesperline = 0;
-   pix->sizeimage = 0;
-
/* Limit to source capabilities */
ret = __rvin_try_format_source(vin, which, pix, source);
if (ret)
@@ -234,10 +230,8 @@ static int __rvin_try_format(struct rvin_dev *vin,
v4l_bound_align_image(>width, 2, vin->info->max_width, walign,
  >height, 4, vin->info->max_height, 2, 0);
 
-   pix->bytesperline = max_t(u32, pix->bytesperline,
- rvin_format_bytesperline(pix));
-   pix->sizeimage = max_t(u32, pix->sizeimage,
-  rvin_format_sizeimage(pix));
+   pix->bytesperline = rvin_format_bytesperline(pix);
+   pix->sizeimage = rvin_format_sizeimage(pix);
 
if (vin->info->model == RCAR_M1 &&
pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
-- 
2.16.2



[PATCH v14 08/33] rcar-vin: move max width and height information to chip information

2018-04-14 Thread Niklas Söderlund
On Gen3 the max supported width and height will be different from Gen2.
Move the limits to the struct rvin_info to prepare for Gen3 support.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Kieran Bingham 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 6 ++
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 6 ++
 drivers/media/platform/rcar-vin/rcar-vin.h  | 5 +
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 71d66916ce1b28ab..be49d8968f0a0cef 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -243,14 +243,20 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 
 static const struct rvin_info rcar_info_h1 = {
.model = RCAR_H1,
+   .max_width = 2048,
+   .max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_m1 = {
.model = RCAR_M1,
+   .max_width = 2048,
+   .max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_gen2 = {
.model = RCAR_GEN2,
+   .max_width = 2048,
+   .max_height = 2048,
 };
 
 static const struct of_device_id rvin_of_id_table[] = {
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 0a035667c0b0e93f..8805d7911a761019 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -23,8 +23,6 @@
 #include "rcar-vin.h"
 
 #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV
-#define RVIN_MAX_WIDTH 2048
-#define RVIN_MAX_HEIGHT2048
 
 /* 
-
  * Format Conversions
@@ -258,8 +256,8 @@ static int __rvin_try_format(struct rvin_dev *vin,
walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1;
 
/* Limit to VIN capabilities */
-   v4l_bound_align_image(>width, 2, RVIN_MAX_WIDTH, walign,
- >height, 4, RVIN_MAX_HEIGHT, 2, 0);
+   v4l_bound_align_image(>width, 2, vin->info->max_width, walign,
+ >height, 4, vin->info->max_height, 2, 0);
 
pix->bytesperline = max_t(u32, pix->bytesperline,
  rvin_format_bytesperline(pix));
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index b63c4fce68adaae6..8d135ed3f7abd855 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -89,9 +89,14 @@ struct rvin_graph_entity {
 /**
  * struct rvin_info - Information about the particular VIN implementation
  * @model: VIN model
+ * @max_width: max input width the VIN supports
+ * @max_height:max input height the VIN supports
  */
 struct rvin_info {
enum model_id model;
+
+   unsigned int max_width;
+   unsigned int max_height;
 };
 
 /**
-- 
2.16.2



[PATCH v14 14/33] rcar-vin: align pixelformat check

2018-04-14 Thread Niklas Söderlund
If the pixelformat is not supported it should not fail but be set to
something that works. While we are at it move the two different
checks of the pixelformat to the same statement.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 907322e1eeb5f6a0..d9231a074aa2c29d 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -189,12 +189,10 @@ static int __rvin_try_format(struct rvin_dev *vin,
u32 walign;
int ret;
 
-   /* If requested format is not supported fallback to the default */
-   if (!rvin_format_from_pixel(pix->pixelformat)) {
-   vin_dbg(vin, "Format 0x%x not found, using default 0x%x\n",
-   pix->pixelformat, RVIN_DEFAULT_FORMAT);
+   if (!rvin_format_from_pixel(pix->pixelformat) ||
+   (vin->info->model == RCAR_M1 &&
+pix->pixelformat == V4L2_PIX_FMT_XBGR32))
pix->pixelformat = RVIN_DEFAULT_FORMAT;
-   }
 
/* Limit to source capabilities */
ret = __rvin_try_format_source(vin, which, pix, source);
@@ -233,12 +231,6 @@ static int __rvin_try_format(struct rvin_dev *vin,
pix->bytesperline = rvin_format_bytesperline(pix);
pix->sizeimage = rvin_format_sizeimage(pix);
 
-   if (vin->info->model == RCAR_M1 &&
-   pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
-   vin_err(vin, "pixel format XBGR32 not supported on M1\n");
-   return -EINVAL;
-   }
-
vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n",
pix->width, pix->height, pix->bytesperline, pix->sizeimage);
 
-- 
2.16.2



[PATCH v14 16/33] rcar-vin: simplify how formats are set and reset

2018-04-14 Thread Niklas Söderlund
With the recent cleanup of the format code to prepare for Gen3 it's
possible to simplify the Gen2 format code path as well. Clean up the
process by defining two functions to handle the set format and reset of
format when the standard is changed.

While at it replace the driver local struct rvin_source_fmt with a
struct v4l2_rect as all it's used for is keep track of the source
dimensions.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 

---

* Changes since v13
- rvin_reset_format() always returns 0, make it a void function and
  update all call-sites no to check the return value.
- Simplify how the source, compose and crop geometry is reset in
  rvin_reset_format(), no change except making the code more readable,
  thanks Laurent for a good suggestion.
- Split two single line declaration of multiple variables to multiple
  lines, removing constructs like 'crop->top = crop->left = 0;' into two
  separate statements.
- Make crop and compose arguments to rvin_try_format() optional to avoid
  having to declare local variables in rvin_try_fmt_vid_cap() which are
  not used.
- Add review tag from Laurent, thanks!

* Changes since v11
- This patch where 'rcar-vin: read subdevice format for crop only when
  needed'
- Keep caching the source dimensions and drop all changes to
  rvin_g_selection() and rvin_s_selection().
- Inline rvin_get_vin_format_from_source() into rvin_reset_format()
  which now is the only user left.
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 120 
 drivers/media/platform/rcar-vin/rcar-vin.h  |  14 +---
 2 files changed, 53 insertions(+), 81 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index f3a0310c43a9877f..9eddc2d95ea7d341 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -87,7 +87,7 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix)
return pix->bytesperline * pix->height;
 }
 
-static int rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix)
+static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format 
*pix)
 {
u32 walign;
 
@@ -130,75 +130,63 @@ static int rvin_format_align(struct rvin_dev *vin, struct 
v4l2_pix_format *pix)
 
vin_dbg(vin, "Format %ux%u bpl: %u size: %u\n",
pix->width, pix->height, pix->bytesperline, pix->sizeimage);
-
-   return 0;
 }
 
 /* 
-
  * V4L2
  */
 
-static void rvin_reset_crop_compose(struct rvin_dev *vin)
-{
-   vin->crop.top = vin->crop.left = 0;
-   vin->crop.width = vin->source.width;
-   vin->crop.height = vin->source.height;
-
-   vin->compose.top = vin->compose.left = 0;
-   vin->compose.width = vin->format.width;
-   vin->compose.height = vin->format.height;
-}
-
 static int rvin_reset_format(struct rvin_dev *vin)
 {
struct v4l2_subdev_format fmt = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+   .pad = vin->digital->source_pad,
};
-   struct v4l2_mbus_framefmt *mf = 
int ret;
 
-   fmt.pad = vin->digital->source_pad;
-
ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, );
if (ret)
return ret;
 
-   vin->format.width   = mf->width;
-   vin->format.height  = mf->height;
-   vin->format.colorspace  = mf->colorspace;
-   vin->format.field   = mf->field;
+   v4l2_fill_pix_format(>format, );
 
-   rvin_reset_crop_compose(vin);
+   rvin_format_align(vin, >format);
 
-   vin->format.bytesperline = rvin_format_bytesperline(>format);
-   vin->format.sizeimage = rvin_format_sizeimage(>format);
+   vin->source.top = 0;
+   vin->source.left = 0;
+   vin->source.width = vin->format.width;
+   vin->source.height = vin->format.height;
+
+   vin->crop = vin->source;
+   vin->compose = vin->source;
 
return 0;
 }
 
-static int __rvin_try_format_source(struct rvin_dev *vin,
-   u32 which,
-   struct v4l2_pix_format *pix,
-   struct rvin_source_fmt *source)
+static int rvin_try_format(struct rvin_dev *vin, u32 which,
+  struct v4l2_pix_format *pix,
+  struct v4l2_rect *crop, struct v4l2_rect *compose)
 {
-   struct v4l2_subdev *sd;
+   struct v4l2_subdev *sd = vin_to_source(vin);
struct v4l2_subdev_pad_config *pad_cfg;
struct v4l2_subdev_format format = {
.which = which,
+   .pad = vin->digital->source_pad,
};
enum v4l2_field field;
u32 width, height;
int ret;
 
-   sd = 

[PATCH v14 17/33] rcar-vin: cache video standard

2018-04-14 Thread Niklas Söderlund
At stream on time the driver should not query the subdevice for which
standard are used. Instead it should be cached when userspace sets the
standard and used at stream on time.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-core.c |  6 ++
 drivers/media/platform/rcar-vin/rcar-dma.c  |  7 ++-
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 10 --
 drivers/media/platform/rcar-vin/rcar-vin.h  |  2 ++
 4 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index be49d8968f0a0cef..8c251687e81b345b 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -96,6 +96,12 @@ static int rvin_digital_subdevice_attach(struct rvin_dev 
*vin,
if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
return ret;
 
+   /* Read standard */
+   vin->std = V4L2_STD_UNKNOWN;
+   ret = v4l2_subdev_call(subdev, video, g_std, >std);
+   if (ret < 0 && ret != -ENOIOCTLCMD)
+   return ret;
+
/* Add the controls */
ret = v4l2_ctrl_handler_init(>ctrl_handler, 16);
if (ret < 0)
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 9233924e5b52de5f..79f4074b931b5aeb 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -592,7 +592,6 @@ void rvin_crop_scale_comp(struct rvin_dev *vin)
 static int rvin_setup(struct rvin_dev *vin)
 {
u32 vnmc, dmr, dmr2, interrupts;
-   v4l2_std_id std;
bool progressive = false, output_is_yuv = false, input_is_yuv = false;
 
switch (vin->format.field) {
@@ -606,10 +605,8 @@ static int rvin_setup(struct rvin_dev *vin)
/* Default to TB */
vnmc = VNMC_IM_FULL;
/* Use BT if video standard can be read and is 60 Hz format */
-   if (!v4l2_subdev_call(vin_to_source(vin), video, g_std, )) {
-   if (std & V4L2_STD_525_60)
-   vnmc = VNMC_IM_FULL | VNMC_FOC;
-   }
+   if (vin->std & V4L2_STD_525_60)
+   vnmc = VNMC_IM_FULL | VNMC_FOC;
break;
case V4L2_FIELD_INTERLACED_TB:
vnmc = VNMC_IM_FULL;
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 9eddc2d95ea7d341..ee8044992eca1a35 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -475,6 +475,8 @@ static int rvin_s_std(struct file *file, void *priv, 
v4l2_std_id a)
if (ret < 0)
return ret;
 
+   vin->std = a;
+
/* Changing the standard will change the width/height */
return rvin_reset_format(vin);
 }
@@ -482,9 +484,13 @@ static int rvin_s_std(struct file *file, void *priv, 
v4l2_std_id a)
 static int rvin_g_std(struct file *file, void *priv, v4l2_std_id *a)
 {
struct rvin_dev *vin = video_drvdata(file);
-   struct v4l2_subdev *sd = vin_to_source(vin);
 
-   return v4l2_subdev_call(sd, video, g_std, a);
+   if (v4l2_subdev_has_op(vin_to_source(vin), pad, dv_timings_cap))
+   return -ENOIOCTLCMD;
+
+   *a = vin->std;
+
+   return 0;
 }
 
 static int rvin_subscribe_event(struct v4l2_fh *fh,
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index e940366d7e8d0e76..06cec4f8e5ffaf2b 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -118,6 +118,7 @@ struct rvin_info {
  * @crop:  active cropping
  * @compose:   active composing
  * @source:active size of the video source
+ * @std:   active video standard of the video source
  */
 struct rvin_dev {
struct device *dev;
@@ -146,6 +147,7 @@ struct rvin_dev {
struct v4l2_rect crop;
struct v4l2_rect compose;
struct v4l2_rect source;
+   v4l2_std_id std;
 };
 
 #define vin_to_source(vin) ((vin)->digital->subdev)
-- 
2.16.2



[PATCH v14 18/33] rcar-vin: move media bus configuration to struct rvin_dev

2018-04-14 Thread Niklas Söderlund
Bus configuration will once the driver is extended to support Gen3
contain information not specific to only the directly connected parallel
subdevice. Move it to struct rvin_dev to show it's not always coupled
to the parallel subdevice.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 18 +-
 drivers/media/platform/rcar-vin/rcar-dma.c  | 10 +-
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  2 +-
 drivers/media/platform/rcar-vin/rcar-vin.h  |  9 -
 4 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 8c251687e81b345b..07a04d4bcc91b18b 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -65,10 +65,10 @@ static int rvin_digital_subdevice_attach(struct rvin_dev 
*vin,
vin->digital->sink_pad = ret < 0 ? 0 : ret;
 
/* Find compatible subdevices mbus format */
-   vin->digital->code = 0;
+   vin->mbus_code = 0;
code.index = 0;
code.pad = vin->digital->source_pad;
-   while (!vin->digital->code &&
+   while (!vin->mbus_code &&
   !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, )) {
code.index++;
switch (code.code) {
@@ -76,16 +76,16 @@ static int rvin_digital_subdevice_attach(struct rvin_dev 
*vin,
case MEDIA_BUS_FMT_UYVY8_2X8:
case MEDIA_BUS_FMT_UYVY10_2X10:
case MEDIA_BUS_FMT_RGB888_1X24:
-   vin->digital->code = code.code;
+   vin->mbus_code = code.code;
vin_dbg(vin, "Found media bus format for %s: %d\n",
-   subdev->name, vin->digital->code);
+   subdev->name, vin->mbus_code);
break;
default:
break;
}
}
 
-   if (!vin->digital->code) {
+   if (!vin->mbus_code) {
vin_err(vin, "Unsupported media bus format for %s\n",
subdev->name);
return -EINVAL;
@@ -196,16 +196,16 @@ static int rvin_digital_parse_v4l2(struct device *dev,
if (vep->base.port || vep->base.id)
return -ENOTCONN;
 
-   rvge->mbus_cfg.type = vep->bus_type;
+   vin->mbus_cfg.type = vep->bus_type;
 
-   switch (rvge->mbus_cfg.type) {
+   switch (vin->mbus_cfg.type) {
case V4L2_MBUS_PARALLEL:
vin_dbg(vin, "Found PARALLEL media bus\n");
-   rvge->mbus_cfg.flags = vep->bus.parallel.flags;
+   vin->mbus_cfg.flags = vep->bus.parallel.flags;
break;
case V4L2_MBUS_BT656:
vin_dbg(vin, "Found BT656 media bus\n");
-   rvge->mbus_cfg.flags = 0;
+   vin->mbus_cfg.flags = 0;
break;
default:
vin_err(vin, "Unknown media bus type\n");
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 79f4074b931b5aeb..41907a200037d5d5 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -626,7 +626,7 @@ static int rvin_setup(struct rvin_dev *vin)
/*
 * Input interface
 */
-   switch (vin->digital->code) {
+   switch (vin->mbus_code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
/* BT.601/BT.1358 16bit YCbCr422 */
vnmc |= VNMC_INF_YUV16;
@@ -634,7 +634,7 @@ static int rvin_setup(struct rvin_dev *vin)
break;
case MEDIA_BUS_FMT_UYVY8_2X8:
/* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
-   vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ?
+   vnmc |= vin->mbus_cfg.type == V4L2_MBUS_BT656 ?
VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
input_is_yuv = true;
break;
@@ -643,7 +643,7 @@ static int rvin_setup(struct rvin_dev *vin)
break;
case MEDIA_BUS_FMT_UYVY10_2X10:
/* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
-   vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ?
+   vnmc |= vin->mbus_cfg.type == V4L2_MBUS_BT656 ?
VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
input_is_yuv = true;
break;
@@ -655,11 +655,11 @@ static int rvin_setup(struct rvin_dev *vin)
dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);
 
/* Hsync Signal Polarity Select */
-   if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
+   if (!(vin->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
   

[PATCH v14 20/33] rcar-vin: add function to manipulate Gen3 chsel value

2018-04-14 Thread Niklas Söderlund
On Gen3 the CSI-2 routing is controlled by the VnCSI_IFMD register. One
feature of this register is that it's only present in the VIN0 and VIN4
instances. The register in VIN0 controls the routing for VIN0-3 and the
register in VIN4 controls routing for VIN4-7.

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

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Hans Verkuil 

---

* Changes since v13
- Do not set the VNCSI_IFMD_DES2 bit in the VNCSI_IFMD register as that
  bit have been removed from later versions of the datasheet.
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 37 ++
 drivers/media/platform/rcar-vin/rcar-vin.h |  2 ++
 2 files changed, 39 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 482d89bae657a88e..905d975b2909a867 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -16,6 +16,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -1157,3 +1158,39 @@ int rvin_dma_register(struct rvin_dev *vin, int irq)
 
return ret;
 }
+
+/* 
-
+ * Gen3 CHSEL manipulation
+ */
+
+/*
+ * There is no need to have locking around changing the routing
+ * as it's only possible to do so when no VIN in the group is
+ * streaming so nothing can race with the VNMC register.
+ */
+int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel)
+{
+   u32 ifmd, vnmc;
+   int ret;
+
+   ret = pm_runtime_get_sync(vin->dev);
+   if (ret < 0)
+   return ret;
+
+   /* Make register writes take effect immediately. */
+   vnmc = rvin_read(vin, VNMC_REG);
+   rvin_write(vin, vnmc & ~VNMC_VUP, VNMC_REG);
+
+   ifmd = VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0 | VNCSI_IFMD_CSI_CHSEL(chsel);
+
+   rvin_write(vin, ifmd, VNCSI_IFMD_REG);
+
+   vin_dbg(vin, "Set IFMD 0x%x\n", ifmd);
+
+   /* Restore VNMC. */
+   rvin_write(vin, vnmc, VNMC_REG);
+
+   pm_runtime_put(vin->dev);
+
+   return ret;
+}
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 321283f1618ae0b9..c19ddc5e08cbbea4 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -169,4 +169,6 @@ const struct rvin_video_format *rvin_format_from_pixel(u32 
pixelformat);
 /* Cropping, composing and scaling */
 void rvin_crop_scale_comp(struct rvin_dev *vin);
 
+int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel);
+
 #endif
-- 
2.16.2



[PATCH v14 19/33] rcar-vin: enable Gen3 hardware configuration

2018-04-14 Thread Niklas Söderlund
Add the register needed to work with Gen3 hardware. This patch adds
the logic for how to work with the Gen3 hardware. More work is required
to enable the subdevice structure needed to configure capturing.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 

---

* Changes since v13
- Remove VNCSI_IFMD_DES2 define as the later versions of the datasheet
  have been updated to remove the register as pointed out by Koji
  Matsuoka.
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 93 --
 drivers/media/platform/rcar-vin/rcar-vin.h |  1 +
 2 files changed, 63 insertions(+), 31 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 41907a200037d5d5..482d89bae657a88e 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -33,21 +33,23 @@
 #define VNELPRC_REG0x10/* Video n End Line Pre-Clip Register */
 #define VNSPPRC_REG0x14/* Video n Start Pixel Pre-Clip Register */
 #define VNEPPRC_REG0x18/* Video n End Pixel Pre-Clip Register */
-#define VNSLPOC_REG0x1C/* Video n Start Line Post-Clip Register */
-#define VNELPOC_REG0x20/* Video n End Line Post-Clip Register */
-#define VNSPPOC_REG0x24/* Video n Start Pixel Post-Clip Register */
-#define VNEPPOC_REG0x28/* Video n End Pixel Post-Clip Register */
 #define VNIS_REG   0x2C/* Video n Image Stride Register */
 #define VNMB_REG(m)(0x30 + ((m) << 2)) /* Video n Memory Base m Register */
 #define VNIE_REG   0x40/* Video n Interrupt Enable Register */
 #define VNINTS_REG 0x44/* Video n Interrupt Status Register */
 #define VNSI_REG   0x48/* Video n Scanline Interrupt Register */
 #define VNMTC_REG  0x4C/* Video n Memory Transfer Control Register */
-#define VNYS_REG   0x50/* Video n Y Scale Register */
-#define VNXS_REG   0x54/* Video n X Scale Register */
 #define VNDMR_REG  0x58/* Video n Data Mode Register */
 #define VNDMR2_REG 0x5C/* Video n Data Mode Register 2 */
 #define VNUVAOF_REG0x60/* Video n UV Address Offset Register */
+
+/* Register offsets specific for Gen2 */
+#define VNSLPOC_REG0x1C/* Video n Start Line Post-Clip Register */
+#define VNELPOC_REG0x20/* Video n End Line Post-Clip Register */
+#define VNSPPOC_REG0x24/* Video n Start Pixel Post-Clip Register */
+#define VNEPPOC_REG0x28/* Video n End Pixel Post-Clip Register */
+#define VNYS_REG   0x50/* Video n Y Scale Register */
+#define VNXS_REG   0x54/* Video n X Scale Register */
 #define VNC1A_REG  0x80/* Video n Coefficient Set C1A Register */
 #define VNC1B_REG  0x84/* Video n Coefficient Set C1B Register */
 #define VNC1C_REG  0x88/* Video n Coefficient Set C1C Register */
@@ -73,9 +75,13 @@
 #define VNC8B_REG  0xF4/* Video n Coefficient Set C8B Register */
 #define VNC8C_REG  0xF8/* Video n Coefficient Set C8C Register */
 
+/* Register offsets specific for Gen3 */
+#define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */
 
 /* Register bit fields for R-Car VIN */
 /* Video n Main Control Register bits */
+#define VNMC_DPINE (1 << 27) /* Gen3 specific */
+#define VNMC_SCLE  (1 << 26) /* Gen3 specific */
 #define VNMC_FOC   (1 << 21)
 #define VNMC_YCAL  (1 << 19)
 #define VNMC_INF_YUV8_BT656(0 << 16)
@@ -119,6 +125,12 @@
 #define VNDMR2_FTEV(1 << 17)
 #define VNDMR2_VLV(n)  ((n & 0xf) << 12)
 
+/* Video n CSI2 Interface Mode Register (Gen3) */
+#define VNCSI_IFMD_DES1(1 << 26)
+#define VNCSI_IFMD_DES0(1 << 25)
+#define VNCSI_IFMD_CSI_CHSEL(n) (((n) & 0xf) << 0)
+#define VNCSI_IFMD_CSI_CHSEL_MASK 0xf
+
 struct rvin_buffer {
struct vb2_v4l2_buffer vb;
struct list_head list;
@@ -514,28 +526,10 @@ static void rvin_set_coeff(struct rvin_dev *vin, unsigned 
short xs)
rvin_write(vin, p_set->coeff_set[23], VNC8C_REG);
 }
 
-void rvin_crop_scale_comp(struct rvin_dev *vin)
+static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin)
 {
u32 xs, ys;
 
-   /* Set Start/End Pixel/Line Pre-Clip */
-   rvin_write(vin, vin->crop.left, VNSPPRC_REG);
-   rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
-   switch (vin->format.field) {
-   case V4L2_FIELD_INTERLACED:
-   case V4L2_FIELD_INTERLACED_TB:
-   case V4L2_FIELD_INTERLACED_BT:
-   rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG);
-   rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1,
-  VNELPRC_REG);
-   break;
-   default:
-   rvin_write(vin, vin->crop.top, 

[PATCH v14 22/33] rcar-vin: use different v4l2 operations in media controller mode

2018-04-14 Thread Niklas Söderlund
When the driver runs in media controller mode it should not directly
control the subdevice instead userspace will be responsible for
configuring the pipeline. To be able to run in this mode a different set
of v4l2 operations needs to be used.

Add a new set of v4l2 operations to support operation without directly
interacting with the source subdevice.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 

---

* Changes since v13
- Add review from Laurent.

* Changes since v11
- Fixed error labels name in rvin_mc_open().
---
 drivers/media/platform/rcar-vin/rcar-dma.c  |   2 +-
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 158 +++-
 2 files changed, 156 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 905d975b2909a867..d70a689d9dd3713f 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -626,7 +626,7 @@ static int rvin_setup(struct rvin_dev *vin)
/* Default to TB */
vnmc = VNMC_IM_FULL;
/* Use BT if video standard can be read and is 60 Hz format */
-   if (vin->std & V4L2_STD_525_60)
+   if (!vin->info->use_mc && vin->std & V4L2_STD_525_60)
vnmc = VNMC_IM_FULL | VNMC_FOC;
break;
case V4L2_FIELD_INTERLACED_TB:
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index e4a99ef210044ab1..f07cb4e6fbdec4eb 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -18,12 +18,16 @@
 
 #include 
 #include 
+#include 
 #include 
 
 #include "rcar-vin.h"
 
 #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV
+#define RVIN_DEFAULT_WIDTH 800
+#define RVIN_DEFAULT_HEIGHT600
 #define RVIN_DEFAULT_FIELD V4L2_FIELD_NONE
+#define RVIN_DEFAULT_COLORSPACEV4L2_COLORSPACE_SRGB
 
 /* 
-
  * Format Conversions
@@ -654,6 +658,73 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = {
.vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
 };
 
+/* 
-
+ * V4L2 Media Controller
+ */
+
+static int rvin_mc_try_fmt_vid_cap(struct file *file, void *priv,
+  struct v4l2_format *f)
+{
+   struct rvin_dev *vin = video_drvdata(file);
+
+   rvin_format_align(vin, >fmt.pix);
+
+   return 0;
+}
+
+static int rvin_mc_s_fmt_vid_cap(struct file *file, void *priv,
+struct v4l2_format *f)
+{
+   struct rvin_dev *vin = video_drvdata(file);
+
+   if (vb2_is_busy(>queue))
+   return -EBUSY;
+
+   rvin_format_align(vin, >fmt.pix);
+
+   vin->format = f->fmt.pix;
+
+   return 0;
+}
+
+static int rvin_mc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *i)
+{
+   if (i->index != 0)
+   return -EINVAL;
+
+   i->type = V4L2_INPUT_TYPE_CAMERA;
+   strlcpy(i->name, "Camera", sizeof(i->name));
+
+   return 0;
+}
+
+static const struct v4l2_ioctl_ops rvin_mc_ioctl_ops = {
+   .vidioc_querycap= rvin_querycap,
+   .vidioc_try_fmt_vid_cap = rvin_mc_try_fmt_vid_cap,
+   .vidioc_g_fmt_vid_cap   = rvin_g_fmt_vid_cap,
+   .vidioc_s_fmt_vid_cap   = rvin_mc_s_fmt_vid_cap,
+   .vidioc_enum_fmt_vid_cap= rvin_enum_fmt_vid_cap,
+
+   .vidioc_enum_input  = rvin_mc_enum_input,
+   .vidioc_g_input = rvin_g_input,
+   .vidioc_s_input = rvin_s_input,
+
+   .vidioc_reqbufs = vb2_ioctl_reqbufs,
+   .vidioc_create_bufs = vb2_ioctl_create_bufs,
+   .vidioc_querybuf= vb2_ioctl_querybuf,
+   .vidioc_qbuf= vb2_ioctl_qbuf,
+   .vidioc_dqbuf   = vb2_ioctl_dqbuf,
+   .vidioc_expbuf  = vb2_ioctl_expbuf,
+   .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+   .vidioc_streamon= vb2_ioctl_streamon,
+   .vidioc_streamoff   = vb2_ioctl_streamoff,
+
+   .vidioc_log_status  = v4l2_ctrl_log_status,
+   .vidioc_subscribe_event = rvin_subscribe_event,
+   .vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
+};
+
 /* 
-
  * File Operations
  */
@@ -797,6 +868,74 @@ static const struct v4l2_file_operations rvin_fops = {
.read   = vb2_fop_read,
 };
 
+/* 

[PATCH v14 21/33] rcar-vin: add flag to switch to media controller mode

2018-04-14 Thread Niklas Söderlund
On Gen3 a media controller API needs to be used to allow userspace to
configure the subdevices in the pipeline instead of directly controlling
a single source subdevice, which is and will continue to be the mode of
operation on Gen2.

Prepare for these two modes of operation by adding a flag to struct
rvin_info which will control which mode to use.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 6 +-
 drivers/media/platform/rcar-vin/rcar-vin.h  | 2 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 07a04d4bcc91b18b..c0e0412e2ecd9487 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -249,18 +249,21 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 
 static const struct rvin_info rcar_info_h1 = {
.model = RCAR_H1,
+   .use_mc = false,
.max_width = 2048,
.max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_m1 = {
.model = RCAR_M1,
+   .use_mc = false,
.max_width = 2048,
.max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_gen2 = {
.model = RCAR_GEN2,
+   .use_mc = false,
.max_width = 2048,
.max_height = 2048,
 };
@@ -355,7 +358,8 @@ static int rcar_vin_remove(struct platform_device *pdev)
v4l2_async_notifier_unregister(>notifier);
v4l2_async_notifier_cleanup(>notifier);
 
-   v4l2_ctrl_handler_free(>ctrl_handler);
+   if (!vin->info->use_mc)
+   v4l2_ctrl_handler_free(>ctrl_handler);
 
rvin_dma_unregister(vin);
 
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index c19ddc5e08cbbea4..e5668c1120a67899 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -75,11 +75,13 @@ struct rvin_graph_entity {
 /**
  * struct rvin_info - Information about the particular VIN implementation
  * @model: VIN model
+ * @use_mc:use media controller instead of controlling subdevice
  * @max_width: max input width the VIN supports
  * @max_height:max input height the VIN supports
  */
 struct rvin_info {
enum model_id model;
+   bool use_mc;
 
unsigned int max_width;
unsigned int max_height;
-- 
2.16.2



[PATCH v14 29/33] rcar-vin: add link notify for Gen3

2018-04-14 Thread Niklas Söderlund
Add the ability to process media device link change requests. Link
enabling is a bit complicated on Gen3, whether or not it's possible to
enable a link depends on what other links already are enabled. On Gen3
the 8 VINs are split into two subgroup's (VIN0-3 and VIN4-7) and from a
routing perspective these two groups are independent of each other.
Each subgroup's routing is controlled by the subgroup VIN master
instance (VIN0 and VIN4).

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

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

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 

---

* Changes since v12
- Add review tag from Laurent.

* Changes since v11
- Fixed spelling
- Updated comment to clarify the intent that no link can be enabled if
any video node is open.
- Use container_of() instead of a loop to find struct vin_dev from the
video device.
---
 drivers/media/platform/rcar-vin/rcar-core.c | 147 
 1 file changed, 147 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 99f6301a778046df..0cc76d73115e9277 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -24,6 +24,7 @@
 
 #include 
 #include 
+#include 
 
 #include "rcar-vin.h"
 
@@ -44,6 +45,151 @@
  */
 #define rvin_group_id_to_master(vin) ((vin) < 4 ? 0 : 4)
 
+/* 
-
+ * Media Controller link notification
+ */
+
+/* group lock should be held when calling this function. */
+static int rvin_group_entity_to_csi_id(struct rvin_group *group,
+  struct media_entity *entity)
+{
+   struct v4l2_subdev *sd;
+   unsigned int i;
+
+   sd = media_entity_to_v4l2_subdev(entity);
+
+   for (i = 0; i < RVIN_CSI_MAX; i++)
+   if (group->csi[i].subdev == sd)
+   return i;
+
+   return -ENODEV;
+}
+
+static unsigned int rvin_group_get_mask(struct rvin_dev *vin,
+   enum rvin_csi_id csi_id,
+   unsigned char channel)
+{
+   const struct rvin_group_route *route;
+   unsigned int mask = 0;
+
+   for (route = vin->info->routes; route->mask; route++) {
+   if (route->vin == vin->id &&
+   route->csi == csi_id &&
+   route->channel == channel) {
+   vin_dbg(vin,
+   "Adding route: vin: %d csi: %d channel: %d\n",
+   route->vin, route->csi, route->channel);
+   mask |= route->mask;
+   }
+   }
+
+   return mask;
+}
+
+/*
+ * Link setup for the links between a VIN and a CSI-2 receiver is a bit
+ * complex. The reason for this is that the register controlling routing
+ * is not present in each VIN instance. There are special VINs which
+ * control routing for themselves and other VINs. There are not many
+ * different possible links combinations that can be enabled at the same
+ * time, therefor all already enabled links which are controlled by a
+ * master VIN need to be taken into account when making the decision
+ * if a new link can be enabled or not.
+ *
+ * 1. Find out which VIN the link the user tries to enable is connected to.
+ * 2. Lookup which master VIN controls the links for this VIN.
+ * 3. Start with a bitmask with all bits set.
+ * 4. For each previously enabled link from the master VIN bitwise AND its
+ *route mask (see documentation for mask in struct rvin_group_route)
+ *with the bitmask.
+ * 5. Bitwise AND the mask for the link the user tries to enable to the 
bitmask.
+ * 6. If the bitmask is not empty at this point the new link can be enabled
+ *while keeping all previous links enabled. Update the CHSEL value of the
+ *master VIN and inform the user that the link could be enabled.
+ *
+ * Please note that no link can be enabled if any VIN in the group is
+ * currently open.
+ */
+static int rvin_group_link_notify(struct media_link *link, u32 flags,
+ unsigned int notification)
+{
+   struct rvin_group *group = container_of(link->graph_obj.mdev,
+   struct rvin_group, mdev);
+   unsigned int master_id, channel, mask_new, i;
+   unsigned 

[PATCH v14 30/33] rcar-vin: extend {start,stop}_streaming to work with media controller

2018-04-14 Thread Niklas Söderlund
The procedure to start or stop streaming using the non-MC single
subdevice and the MC graph and multiple subdevices are quite different.
Create a new function to abstract which method is used based on which
mode the driver is running in and add logic to start the MC graph.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Hans Verkuil 

---

* Changes since v12
- Rebase to latest media-tree/master changed a 'return ret' to a 'goto
  out' in rvin_start_streaming().
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 135 +++--
 1 file changed, 127 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index d70a689d9dd3713f..4a3a195e7f59047c 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -996,10 +996,126 @@ static void rvin_buffer_queue(struct vb2_buffer *vb)
spin_unlock_irqrestore(>qlock, flags);
 }
 
+static int rvin_mc_validate_format(struct rvin_dev *vin, struct v4l2_subdev 
*sd,
+  struct media_pad *pad)
+{
+   struct v4l2_subdev_format fmt = {
+   .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+   };
+
+   fmt.pad = pad->index;
+   if (v4l2_subdev_call(sd, pad, get_fmt, NULL, ))
+   return -EPIPE;
+
+   switch (fmt.format.code) {
+   case MEDIA_BUS_FMT_YUYV8_1X16:
+   case MEDIA_BUS_FMT_UYVY8_2X8:
+   case MEDIA_BUS_FMT_UYVY10_2X10:
+   case MEDIA_BUS_FMT_RGB888_1X24:
+   vin->mbus_code = fmt.format.code;
+   break;
+   default:
+   return -EPIPE;
+   }
+
+   switch (fmt.format.field) {
+   case V4L2_FIELD_TOP:
+   case V4L2_FIELD_BOTTOM:
+   case V4L2_FIELD_NONE:
+   case V4L2_FIELD_INTERLACED_TB:
+   case V4L2_FIELD_INTERLACED_BT:
+   case V4L2_FIELD_INTERLACED:
+   case V4L2_FIELD_SEQ_TB:
+   case V4L2_FIELD_SEQ_BT:
+   /* Supported natively */
+   break;
+   case V4L2_FIELD_ALTERNATE:
+   switch (vin->format.field) {
+   case V4L2_FIELD_TOP:
+   case V4L2_FIELD_BOTTOM:
+   case V4L2_FIELD_NONE:
+   break;
+   case V4L2_FIELD_INTERLACED_TB:
+   case V4L2_FIELD_INTERLACED_BT:
+   case V4L2_FIELD_INTERLACED:
+   case V4L2_FIELD_SEQ_TB:
+   case V4L2_FIELD_SEQ_BT:
+   /* Use VIN hardware to combine the two fields */
+   fmt.format.height *= 2;
+   break;
+   default:
+   return -EPIPE;
+   }
+   break;
+   default:
+   return -EPIPE;
+   }
+
+   if (fmt.format.width != vin->format.width ||
+   fmt.format.height != vin->format.height ||
+   fmt.format.code != vin->mbus_code)
+   return -EPIPE;
+
+   return 0;
+}
+
+static int rvin_set_stream(struct rvin_dev *vin, int on)
+{
+   struct media_pipeline *pipe;
+   struct media_device *mdev;
+   struct v4l2_subdev *sd;
+   struct media_pad *pad;
+   int ret;
+
+   /* No media controller used, simply pass operation to subdevice. */
+   if (!vin->info->use_mc) {
+   ret = v4l2_subdev_call(vin->digital->subdev, video, s_stream,
+  on);
+
+   return ret == -ENOIOCTLCMD ? 0 : ret;
+   }
+
+   pad = media_entity_remote_pad(>pad);
+   if (!pad)
+   return -EPIPE;
+
+   sd = media_entity_to_v4l2_subdev(pad->entity);
+
+   if (!on) {
+   media_pipeline_stop(>vdev.entity);
+   return v4l2_subdev_call(sd, video, s_stream, 0);
+   }
+
+   ret = rvin_mc_validate_format(vin, sd, pad);
+   if (ret)
+   return ret;
+
+   /*
+* The graph lock needs to be taken to protect concurrent
+* starts of multiple VIN instances as they might share
+* a common subdevice down the line and then should use
+* the same pipe.
+*/
+   mdev = vin->vdev.entity.graph_obj.mdev;
+   mutex_lock(>graph_mutex);
+   pipe = sd->entity.pipe ? sd->entity.pipe : >vdev.pipe;
+   ret = __media_pipeline_start(>vdev.entity, pipe);
+   mutex_unlock(>graph_mutex);
+   if (ret)
+   return ret;
+
+   ret = v4l2_subdev_call(sd, video, s_stream, 1);
+   if (ret == -ENOIOCTLCMD)
+   ret = 0;
+   if (ret)
+   media_pipeline_stop(>vdev.entity);
+
+   return ret;
+}
+
 static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
struct rvin_dev *vin = vb2_get_drv_priv(vq);
-   struct v4l2_subdev *sd;
unsigned long flags;

[PATCH v14 27/33] rcar-vin: add chsel information to rvin_info

2018-04-14 Thread Niklas Söderlund
Each Gen3 SoC has a limited set of predefined routing possibilities for
which CSI-2 device and channel can be routed to which VIN instance.
Prepare to store this information in the struct rvin_info.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 

---

* Changes since v13
- Add review by Laurent.

* Changes since v11
- Fixed spelling.
- Reorderd filed order in struct rvin_group_route.
- Renamed chan to channel in struct rvin_group_route.
---
 drivers/media/platform/rcar-vin/rcar-vin.h | 42 ++
 1 file changed, 42 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index cf5c467d45e10847..93eb40856b866117 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -43,6 +43,14 @@ enum model_id {
RCAR_GEN3,
 };
 
+enum rvin_csi_id {
+   RVIN_CSI20,
+   RVIN_CSI21,
+   RVIN_CSI40,
+   RVIN_CSI41,
+   RVIN_CSI_MAX,
+};
+
 /**
  * STOPPED  - No operation in progress
  * RUNNING  - Operation in progress have buffers
@@ -79,12 +87,45 @@ struct rvin_graph_entity {
unsigned int sink_pad;
 };
 
+/**
+ * struct rvin_group_route - describes a route from a channel of a
+ * CSI-2 receiver to a VIN
+ *
+ * @csi:   CSI-2 receiver ID.
+ * @channel:   Output channel of the CSI-2 receiver.
+ * @vin:   VIN ID.
+ * @mask:  Bitmask of the different CHSEL register values that
+ * allow for a route from @csi + @chan to @vin.
+ *
+ * .. note::
+ * Each R-Car CSI-2 receiver has four output channels facing the VIN
+ * devices, each channel can carry one CSI-2 Virtual Channel (VC).
+ * There is no correlation between channel number and CSI-2 VC. It's
+ * up to the CSI-2 receiver driver to configure which VC is output
+ * on which channel, the VIN devices only care about output channels.
+ *
+ * There are in some cases multiple CHSEL register settings which would
+ * allow for the same route from @csi + @channel to @vin. For example
+ * on R-Car H3 both the CHSEL values 0 and 3 allow for a route from
+ * CSI40/VC0 to VIN0. All possible CHSEL values for a route need to be
+ * recorded as a bitmask in @mask, in this example bit 0 and 3 should
+ * be set.
+ */
+struct rvin_group_route {
+   enum rvin_csi_id csi;
+   unsigned int channel;
+   unsigned int vin;
+   unsigned int mask;
+};
+
 /**
  * struct rvin_info - Information about the particular VIN implementation
  * @model: VIN model
  * @use_mc:use media controller instead of controlling subdevice
  * @max_width: max input width the VIN supports
  * @max_height:max input height the VIN supports
+ * @routes:list of possible routes from the CSI-2 recivers to
+ * all VINs. The list mush be NULL terminated.
  */
 struct rvin_info {
enum model_id model;
@@ -92,6 +133,7 @@ struct rvin_info {
 
unsigned int max_width;
unsigned int max_height;
+   const struct rvin_group_route *routes;
 };
 
 /**
-- 
2.16.2



[PATCH v14 25/33] rcar-vin: add group allocator functions

2018-04-14 Thread Niklas Söderlund
In media controller mode all VIN instances needs to be part of the same
media graph. There is also a need for each VIN instance to know about
and in some cases be able to communicate with other VIN instances.

Add an allocator framework where the first VIN instance to be probed
creates a shared data structure and registers a media device.
Consecutive VINs insert themself into the global group.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 174 +++-
 drivers/media/platform/rcar-vin/rcar-vin.h  |  31 +
 2 files changed, 203 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index e0a33d372c500ccd..38eaa246e4c0a7b5 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -20,12 +20,174 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 
 #include "rcar-vin.h"
 
+/* 
-
+ * Gen3 CSI2 Group Allocator
+ */
+
+/* FIXME:  This should if we find a system that supports more
+ * than one group for the whole system be replaced with a linked
+ * list of groups. And eventually all of this should be replaced
+ * with a global device allocator API.
+ *
+ * But for now this works as on all supported systems there will
+ * be only one group for all instances.
+ */
+
+static DEFINE_MUTEX(rvin_group_lock);
+static struct rvin_group *rvin_group_data;
+
+static void rvin_group_cleanup(struct rvin_group *group)
+{
+   media_device_unregister(>mdev);
+   media_device_cleanup(>mdev);
+   mutex_destroy(>lock);
+}
+
+static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin)
+{
+   struct media_device *mdev = >mdev;
+   const struct of_device_id *match;
+   struct device_node *np;
+   int ret;
+
+   mutex_init(>lock);
+
+   /* Count number of VINs in the system */
+   group->count = 0;
+   for_each_matching_node(np, vin->dev->driver->of_match_table)
+   if (of_device_is_available(np))
+   group->count++;
+
+   vin_dbg(vin, "found %u enabled VIN's in DT", group->count);
+
+   mdev->dev = vin->dev;
+
+   match = of_match_node(vin->dev->driver->of_match_table,
+ vin->dev->of_node);
+
+   strlcpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name));
+   strlcpy(mdev->model, match->compatible, sizeof(mdev->model));
+   snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
+dev_name(mdev->dev));
+
+   media_device_init(mdev);
+
+   ret = media_device_register(>mdev);
+   if (ret)
+   rvin_group_cleanup(group);
+
+   return ret;
+}
+
+static void rvin_group_release(struct kref *kref)
+{
+   struct rvin_group *group =
+   container_of(kref, struct rvin_group, refcount);
+
+   mutex_lock(_group_lock);
+
+   rvin_group_data = NULL;
+
+   rvin_group_cleanup(group);
+
+   kfree(group);
+
+   mutex_unlock(_group_lock);
+}
+
+static int rvin_group_get(struct rvin_dev *vin)
+{
+   struct rvin_group *group;
+   u32 id;
+   int ret;
+
+   /* Make sure VIN id is present and sane */
+   ret = of_property_read_u32(vin->dev->of_node, "renesas,id", );
+   if (ret) {
+   vin_err(vin, "%pOF: No renesas,id property found\n",
+   vin->dev->of_node);
+   return -EINVAL;
+   }
+
+   if (id >= RCAR_VIN_NUM) {
+   vin_err(vin, "%pOF: Invalid renesas,id '%u'\n",
+   vin->dev->of_node, id);
+   return -EINVAL;
+   }
+
+   /* Join or create a VIN group */
+   mutex_lock(_group_lock);
+   if (rvin_group_data) {
+   group = rvin_group_data;
+   kref_get(>refcount);
+   } else {
+   group = kzalloc(sizeof(*group), GFP_KERNEL);
+   if (!group) {
+   ret = -ENOMEM;
+   goto err_group;
+   }
+
+   ret = rvin_group_init(group, vin);
+   if (ret) {
+   kfree(group);
+   vin_err(vin, "Failed to initialize group\n");
+   goto err_group;
+   }
+
+   kref_init(>refcount);
+
+   rvin_group_data = group;
+   }
+   mutex_unlock(_group_lock);
+
+   /* Add VIN to group */
+   mutex_lock(>lock);
+
+   if (group->vin[id]) {
+   vin_err(vin, "Duplicate renesas,id property value %u\n", id);
+   mutex_unlock(>lock);
+   kref_put(>refcount, rvin_group_release);
+   return -EINVAL;
+ 

[PATCH v14 28/33] rcar-vin: parse Gen3 OF and setup media graph

2018-04-14 Thread Niklas Söderlund
The parsing and registering CSI-2 subdevices with the v4l2 async
framework is a collaborative effort shared between the VIN instances
which are part of the group. When the last VIN in the group is probed it
asks all other VINs to parse its share of OF and record the async
subdevices it finds in the notifier belonging to the last probed VIN.

Once all CSI-2 subdevices in this notifier are bound proceed to register
all VIN video devices of the group and crate media device links between
all CSI-2 and VIN entities according to the SoC specific routing
configuration.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 246 +++-
 drivers/media/platform/rcar-vin/rcar-vin.h  |  12 +-
 2 files changed, 254 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 38eaa246e4c0a7b5..99f6301a778046df 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -27,6 +27,23 @@
 
 #include "rcar-vin.h"
 
+/*
+ * The companion CSI-2 receiver driver (rcar-csi2) is known
+ * and we know it has one source pad (pad 0) and four sink
+ * pads (pad 1-4). So to translate a pad on the remote
+ * CSI-2 receiver to/from the VIN internal channel number simply
+ * subtract/add one from the pad/channel number.
+ */
+#define rvin_group_csi_pad_to_channel(pad) ((pad) - 1)
+#define rvin_group_csi_channel_to_pad(channel) ((channel) + 1)
+
+/*
+ * Not all VINs are created equal, master VINs control the
+ * routing for other VIN's. We can figure out which VIN is
+ * master by looking at a VINs id.
+ */
+#define rvin_group_id_to_master(vin) ((vin) < 4 ? 0 : 4)
+
 /* 
-
  * Gen3 CSI2 Group Allocator
  */
@@ -409,6 +426,216 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
return 0;
 }
 
+/* 
-
+ * Group async notifier
+ */
+
+static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
+{
+   struct rvin_dev *vin = notifier_to_vin(notifier);
+   const struct rvin_group_route *route;
+   unsigned int i;
+   int ret;
+
+   ret = v4l2_device_register_subdev_nodes(>v4l2_dev);
+   if (ret) {
+   vin_err(vin, "Failed to register subdev nodes\n");
+   return ret;
+   }
+
+   /* Register all video nodes for the group. */
+   for (i = 0; i < RCAR_VIN_NUM; i++) {
+   if (vin->group->vin[i]) {
+   ret = rvin_v4l2_register(vin->group->vin[i]);
+   if (ret)
+   return ret;
+   }
+   }
+
+   /* Create all media device links between VINs and CSI-2's. */
+   mutex_lock(>group->lock);
+   for (route = vin->info->routes; route->mask; route++) {
+   struct media_pad *source_pad, *sink_pad;
+   struct media_entity *source, *sink;
+   unsigned int source_idx;
+
+   /* Check that VIN is part of the group. */
+   if (!vin->group->vin[route->vin])
+   continue;
+
+   /* Check that VIN' master is part of the group. */
+   if (!vin->group->vin[rvin_group_id_to_master(route->vin)])
+   continue;
+
+   /* Check that CSI-2 is part of the group. */
+   if (!vin->group->csi[route->csi].subdev)
+   continue;
+
+   source = >group->csi[route->csi].subdev->entity;
+   source_idx = rvin_group_csi_channel_to_pad(route->channel);
+   source_pad = >pads[source_idx];
+
+   sink = >group->vin[route->vin]->vdev.entity;
+   sink_pad = >pads[0];
+
+   /* Skip if link already exists. */
+   if (media_entity_find_link(source_pad, sink_pad))
+   continue;
+
+   ret = media_create_pad_link(source, source_idx, sink, 0, 0);
+   if (ret) {
+   vin_err(vin, "Error adding link from %s to %s\n",
+   source->name, sink->name);
+   break;
+   }
+   }
+   mutex_unlock(>group->lock);
+
+   return ret;
+}
+
+static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
+struct v4l2_subdev *subdev,
+struct v4l2_async_subdev *asd)
+{
+   struct rvin_dev *vin = notifier_to_vin(notifier);
+   unsigned int i;
+
+   for (i = 0; i < RCAR_VIN_NUM; i++)
+   if (vin->group->vin[i])
+   

[PATCH v14 23/33] rcar-vin: force default colorspace for media centric mode

2018-04-14 Thread Niklas Söderlund
The V4L2 specification clearly documents the colorspace fields as being
set by drivers for capture devices. Using the values supplied by
userspace thus wouldn't comply with the API. Until the API is updated to
allow for userspace to set these Hans wants the fields to be set by the
driver to fixed values.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index f07cb4e6fbdec4eb..2c28daf1c725e64c 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -662,12 +662,30 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = {
  * V4L2 Media Controller
  */
 
+static void rvin_mc_try_format(struct rvin_dev *vin,
+  struct v4l2_pix_format *pix)
+{
+   /*
+* The V4L2 specification clearly documents the colorspace fields
+* as being set by drivers for capture devices. Using the values
+* supplied by userspace thus wouldn't comply with the API. Until
+* the API is updated force fixed vaules.
+*/
+   pix->colorspace = RVIN_DEFAULT_COLORSPACE;
+   pix->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace);
+   pix->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace);
+   pix->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true, pix->colorspace,
+ pix->ycbcr_enc);
+
+   rvin_format_align(vin, pix);
+}
+
 static int rvin_mc_try_fmt_vid_cap(struct file *file, void *priv,
   struct v4l2_format *f)
 {
struct rvin_dev *vin = video_drvdata(file);
 
-   rvin_format_align(vin, >fmt.pix);
+   rvin_mc_try_format(vin, >fmt.pix);
 
return 0;
 }
@@ -680,7 +698,7 @@ static int rvin_mc_s_fmt_vid_cap(struct file *file, void 
*priv,
if (vb2_is_busy(>queue))
return -EBUSY;
 
-   rvin_format_align(vin, >fmt.pix);
+   rvin_mc_try_format(vin, >fmt.pix);
 
vin->format = f->fmt.pix;
 
-- 
2.16.2



[PATCH v14 33/33] rcar-vin: enable support for r8a77970

2018-04-14 Thread Niklas Söderlund
Add the SoC specific information for Renesas r8a77970.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 81c82793b1312aae..55b745ac86a5884d 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -971,6 +971,25 @@ static const struct rvin_info rcar_info_r8a7796 = {
.routes = rcar_info_r8a7796_routes,
 };
 
+static const struct rvin_group_route _rcar_info_r8a77970_routes[] = {
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
+   { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
+   { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
+   { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
+   { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
+   { /* Sentinel */ }
+};
+
+static const struct rvin_info rcar_info_r8a77970 = {
+   .model = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+   .routes = _rcar_info_r8a77970_routes,
+};
+
 static const struct of_device_id rvin_of_id_table[] = {
{
.compatible = "renesas,vin-r8a7778",
@@ -1008,6 +1027,10 @@ static const struct of_device_id rvin_of_id_table[] = {
.compatible = "renesas,vin-r8a7796",
.data = _info_r8a7796,
},
+   {
+   .compatible = "renesas,vin-r8a77970",
+   .data = _info_r8a77970,
+   },
{ /* Sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
-- 
2.16.2



[PATCH v14 26/33] rcar-vin: change name of video device

2018-04-14 Thread Niklas Söderlund
The rcar-vin driver needs to be part of a media controller to support
Gen3. Give each VIN instance a unique name so it can be referenced from
userspace.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 2c28daf1c725e64c..09d584d8e839b868 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -991,7 +991,7 @@ int rvin_v4l2_register(struct rvin_dev *vin)
/* video node */
vdev->v4l2_dev = >v4l2_dev;
vdev->queue = >queue;
-   strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name));
+   snprintf(vdev->name, sizeof(vdev->name), "VIN%u output", vin->id);
vdev->release = video_device_release_empty;
vdev->lock = >lock;
vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
-- 
2.16.2



[PATCH v14 24/33] rcar-vin: prepare for media controller mode initialization

2018-04-14 Thread Niklas Söderlund
Prepare for media controller by calling a different initialization then
when running in device centric mode. Add trivial configuration of
the mbus and creation of the media pad for the video device entity.

While we are at it clearly mark the digital device centric notifier
functions with a comment.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 20 ++--
 drivers/media/platform/rcar-vin/rcar-vin.h  |  4 
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index c0e0412e2ecd9487..e0a33d372c500ccd 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -46,6 +46,10 @@ static int rvin_find_pad(struct v4l2_subdev *sd, int 
direction)
return -EINVAL;
 }
 
+/* 
-
+ * Digital async notifier
+ */
+
 /* The vin lock should be held when calling the subdevice attach and detach */
 static int rvin_digital_subdevice_attach(struct rvin_dev *vin,
 struct v4l2_subdev *subdev)
@@ -243,6 +247,16 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
return 0;
 }
 
+static int rvin_mc_init(struct rvin_dev *vin)
+{
+   /* All our sources are CSI-2 */
+   vin->mbus_cfg.type = V4L2_MBUS_CSI2;
+   vin->mbus_cfg.flags = 0;
+
+   vin->pad.flags = MEDIA_PAD_FL_SINK;
+   return media_entity_pads_init(>vdev.entity, 1, >pad);
+}
+
 /* 
-
  * Platform Device Driver
  */
@@ -331,8 +345,10 @@ static int rcar_vin_probe(struct platform_device *pdev)
return ret;
 
platform_set_drvdata(pdev, vin);
-
-   ret = rvin_digital_graph_init(vin);
+   if (vin->info->use_mc)
+   ret = rvin_mc_init(vin);
+   else
+   ret = rvin_digital_graph_init(vin);
if (ret < 0)
goto error;
 
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index e5668c1120a67899..5102ad254bff515b 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -99,6 +99,8 @@ struct rvin_info {
  * @notifier:  V4L2 asynchronous subdevs notifier
  * @digital:   entity in the DT for local digital subdevice
  *
+ * @pad:   media pad for the video device entity
+ *
  * @lock:  protects @queue
  * @queue: vb2 buffers queue
  * @scratch:   cpu address for scratch buffer
@@ -131,6 +133,8 @@ struct rvin_dev {
struct v4l2_async_notifier notifier;
struct rvin_graph_entity *digital;
 
+   struct media_pad pad;
+
struct mutex lock;
struct vb2_queue queue;
void *scratch;
-- 
2.16.2



[PATCH v14 31/33] rcar-vin: enable support for r8a7795

2018-04-14 Thread Niklas Söderlund
Add the SoC specific information for Renesas r8a7795 ES1.x and ES2.0.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/Kconfig |   2 +-
 drivers/media/platform/rcar-vin/rcar-core.c | 120 
 2 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/rcar-vin/Kconfig 
b/drivers/media/platform/rcar-vin/Kconfig
index af4c98b44d2e22cb..8fa7ee468c63afb9 100644
--- a/drivers/media/platform/rcar-vin/Kconfig
+++ b/drivers/media/platform/rcar-vin/Kconfig
@@ -6,7 +6,7 @@ config VIDEO_RCAR_VIN
select V4L2_FWNODE
---help---
  Support for Renesas R-Car Video Input (VIN) driver.
- Supports R-Car Gen2 SoCs.
+ Supports R-Car Gen2 and Gen3 SoCs.
 
  To compile this driver as a module, choose M here: the
  module will be called rcar-vin.
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 0cc76d73115e9277..81119ae4402d0990 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -832,6 +833,104 @@ static const struct rvin_info rcar_info_gen2 = {
.max_height = 2048,
 };
 
+static const struct rvin_group_route rcar_info_r8a7795_routes[] = {
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
+   { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
+   { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
+   { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
+   { .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) },
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
+   { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
+   { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
+   { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) },
+   { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
+   { .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
+   { .csi = RVIN_CSI41, .channel = 1, .vin = 4, .mask = BIT(2) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
+   { .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
+   { .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
+   { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
+   { .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) },
+   { .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
+   { .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
+   { .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
+   { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) },
+   { .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
+   { /* Sentinel */ }
+};
+
+static const struct rvin_info rcar_info_r8a7795 = {
+   .model = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+   .routes = rcar_info_r8a7795_routes,
+};
+
+static const struct rvin_group_route rcar_info_r8a7795es1_routes[] = {
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
+   { .csi = RVIN_CSI21, .channel = 0, .vin = 0, .mask = BIT(2) | BIT(5) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
+   { .csi = RVIN_CSI21, .channel = 0, .vin = 1, .mask = BIT(1) },
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
+   { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
+   { .csi = RVIN_CSI21, .channel = 1, .vin = 1, .mask = BIT(5) },
+   { .csi = RVIN_CSI21, .channel = 0, .vin = 2, .mask = BIT(0) },
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) 

[PATCH v14 32/33] rcar-vin: enable support for r8a7796

2018-04-14 Thread Niklas Söderlund
Add the SoC specific information for Renesas r8a7796.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 44 +
 1 file changed, 44 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 81119ae4402d0990..81c82793b1312aae 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -931,6 +931,46 @@ static const struct rvin_info rcar_info_r8a7795es1 = {
.routes = rcar_info_r8a7795es1_routes,
 };
 
+static const struct rvin_group_route rcar_info_r8a7796_routes[] = {
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
+   { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
+   { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
+   { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
+   { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) },
+   { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
+   { .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
+   { .csi = RVIN_CSI40, .channel = 0, .vin = 6, .mask = BIT(1) },
+   { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
+   { .csi = RVIN_CSI40, .channel = 2, .vin = 6, .mask = BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
+   { .csi = RVIN_CSI40, .channel = 1, .vin = 7, .mask = BIT(0) },
+   { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) },
+   { .csi = RVIN_CSI40, .channel = 3, .vin = 7, .mask = BIT(3) },
+   { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
+   { /* Sentinel */ }
+};
+
+static const struct rvin_info rcar_info_r8a7796 = {
+   .model = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+   .routes = rcar_info_r8a7796_routes,
+};
+
 static const struct of_device_id rvin_of_id_table[] = {
{
.compatible = "renesas,vin-r8a7778",
@@ -964,6 +1004,10 @@ static const struct of_device_id rvin_of_id_table[] = {
.compatible = "renesas,vin-r8a7795",
.data = _info_r8a7795,
},
+   {
+   .compatible = "renesas,vin-r8a7796",
+   .data = _info_r8a7796,
+   },
{ /* Sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
-- 
2.16.2



cron job: media_tree daily build: OK

2018-04-14 Thread Hans Verkuil
This message is generated daily by a cron job that builds media_tree for
the kernels and architectures in the list below.

Results of the daily build of media_tree:

date:   Sun Apr 15 05:00:11 CEST 2018
media-tree git hash:b284d4d5a6785f8cd07eda2646a95782373cd01e
media_build git hash:   78d6ded165a133942a9615a80ca8e0d48749c592
v4l-utils git hash: 47d43b130dc6e9e0edc900759fb37649208371e4
gcc version:i686-linux-gcc (GCC) 7.3.0
sparse version: v0.5.2-rc1
smatch version: v0.5.0-4419-g3b5bf5c9
host hardware:  x86_64
host os:4.14.0-3-amd64

linux-git-arm-at91: OK
linux-git-arm-davinci: OK
linux-git-arm-multi: OK
linux-git-arm-pxa: OK
linux-git-arm-stm32: OK
linux-git-arm64: OK
linux-git-i686: OK
linux-git-mips: OK
linux-git-powerpc64: OK
linux-git-sh: OK
linux-git-x86_64: OK
linux-2.6.36.4-i686: OK
linux-2.6.36.4-x86_64: OK
linux-2.6.37.6-i686: OK
linux-2.6.37.6-x86_64: OK
linux-2.6.38.8-i686: OK
linux-2.6.38.8-x86_64: OK
linux-2.6.39.4-i686: OK
linux-2.6.39.4-x86_64: OK
linux-3.0.101-i686: OK
linux-3.0.101-x86_64: OK
linux-3.1.10-i686: OK
linux-3.1.10-x86_64: OK
linux-3.2.101-i686: OK
linux-3.2.101-x86_64: OK
linux-3.3.8-i686: OK
linux-3.3.8-x86_64: OK
linux-3.4.113-i686: OK
linux-3.4.113-x86_64: OK
linux-3.5.7-i686: OK
linux-3.5.7-x86_64: OK
linux-3.6.11-i686: OK
linux-3.6.11-x86_64: OK
linux-3.7.10-i686: OK
linux-3.7.10-x86_64: OK
linux-3.8.13-i686: OK
linux-3.8.13-x86_64: OK
linux-3.9.11-i686: OK
linux-3.9.11-x86_64: OK
linux-3.10.108-i686: OK
linux-3.10.108-x86_64: OK
linux-3.11.10-i686: OK
linux-3.11.10-x86_64: OK
linux-3.12.74-i686: OK
linux-3.12.74-x86_64: OK
linux-3.13.11-i686: OK
linux-3.13.11-x86_64: OK
linux-3.14.79-i686: OK
linux-3.14.79-x86_64: OK
linux-3.15.10-i686: OK
linux-3.15.10-x86_64: OK
linux-3.16.56-i686: OK
linux-3.16.56-x86_64: OK
linux-3.17.8-i686: OK
linux-3.17.8-x86_64: OK
linux-3.18.102-i686: OK
linux-3.18.102-x86_64: OK
linux-3.19.8-i686: OK
linux-3.19.8-x86_64: OK
linux-4.0.9-i686: OK
linux-4.0.9-x86_64: OK
linux-4.1.51-i686: OK
linux-4.1.51-x86_64: OK
linux-4.2.8-i686: OK
linux-4.2.8-x86_64: OK
linux-4.3.6-i686: OK
linux-4.3.6-x86_64: OK
linux-4.4.109-i686: OK
linux-4.4.109-x86_64: OK
linux-4.5.7-i686: OK
linux-4.5.7-x86_64: OK
linux-4.6.7-i686: OK
linux-4.6.7-x86_64: OK
linux-4.7.10-i686: OK
linux-4.7.10-x86_64: OK
linux-4.8.17-i686: OK
linux-4.8.17-x86_64: OK
linux-4.9.91-i686: OK
linux-4.9.91-x86_64: OK
linux-4.14.31-i686: OK
linux-4.14.31-x86_64: OK
linux-4.15.14-i686: OK
linux-4.15.14-x86_64: OK
linux-4.16-i686: OK
linux-4.16-x86_64: OK
apps: OK
spec-git: OK
sparse: WARNINGS

Detailed results are available here:

http://www.xs4all.nl/~hverkuil/logs/Sunday.log

Full logs are available here:

http://www.xs4all.nl/~hverkuil/logs/Sunday.tar.bz2

The Media Infrastructure API from this daily build is here:

http://www.xs4all.nl/~hverkuil/spec/index.html


[PATCH 1/2] media: rc: mce_kbd decoder: remove superfluous call to input_sync

2018-04-14 Thread Sean Young
There is nothing to sync in this code path.

Reported-by: Matthias Reichl 
Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-mce_kbd-decoder.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c 
b/drivers/media/rc/ir-mce_kbd-decoder.c
index 002b8323ae69..2fc78710a724 100644
--- a/drivers/media/rc/ir-mce_kbd-decoder.c
+++ b/drivers/media/rc/ir-mce_kbd-decoder.c
@@ -362,7 +362,6 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct 
ir_raw_event ev)
dev_dbg(>dev, "failed at state %i (%uus %s)\n",
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
-   input_sync(data->idev);
return -EINVAL;
 }
 
-- 
2.14.3



[PATCH 2/2] media: rc: mce_kbd decoder: fix race condition

2018-04-14 Thread Sean Young
The MCE keyboard sends both key down and key up events. We have a timeout
handler mce_kbd_rx_timeout() in case the keyup event is never received;
however, this may race with new key down events from occurring.

The race is that key down scancode arrives and key down events are
generated. The timeout handler races this and generates key up events
straight afterwards. Since the keyboard generates scancodes every 100ms,
most likely the keys will be repeated 100ms later, and now we have new
key down events and the user sees duplicate key presses.

Reported-by: Matthias Reichl 
Signed-off-by: Sean Young 
---
 drivers/media/rc/ir-mce_kbd-decoder.c | 23 ---
 drivers/media/rc/rc-core-priv.h   |  1 +
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c 
b/drivers/media/rc/ir-mce_kbd-decoder.c
index 2fc78710a724..9574c3dd90f2 100644
--- a/drivers/media/rc/ir-mce_kbd-decoder.c
+++ b/drivers/media/rc/ir-mce_kbd-decoder.c
@@ -119,19 +119,25 @@ static void mce_kbd_rx_timeout(struct timer_list *t)
 {
struct ir_raw_event_ctrl *raw = from_timer(raw, t, mce_kbd.rx_timeout);
unsigned char maskcode;
+   unsigned long flags;
int i;
 
dev_dbg(>dev->dev, "timer callback clearing all keys\n");
 
-   for (i = 0; i < 7; i++) {
-   maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i];
-   input_report_key(raw->mce_kbd.idev, maskcode, 0);
-   }
+   spin_lock_irqsave(>mce_kbd.keylock, flags);
 
-   for (i = 0; i < MCIR2_MASK_KEYS_START; i++)
-   input_report_key(raw->mce_kbd.idev, kbd_keycodes[i], 0);
+   if (time_is_before_eq_jiffies(raw->mce_kbd.rx_timeout.expires)) {
+   for (i = 0; i < 7; i++) {
+   maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i];
+   input_report_key(raw->mce_kbd.idev, maskcode, 0);
+   }
 
-   input_sync(raw->mce_kbd.idev);
+   for (i = 0; i < MCIR2_MASK_KEYS_START; i++)
+   input_report_key(raw->mce_kbd.idev, kbd_keycodes[i], 0);
+
+   input_sync(raw->mce_kbd.idev);
+   }
+   spin_unlock_irqrestore(>mce_kbd.keylock, flags);
 }
 
 static enum mce_kbd_mode mce_kbd_mode(struct mce_kbd_dec *data)
@@ -327,6 +333,7 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct 
ir_raw_event ev)
scancode = data->body & 0xff;
dev_dbg(>dev, "keyboard data 0x%08x\n",
data->body);
+   spin_lock(>keylock);
if (scancode) {
delay = nsecs_to_jiffies(dev->timeout) +
msecs_to_jiffies(100);
@@ -336,6 +343,7 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct 
ir_raw_event ev)
}
/* Pass data to keyboard buffer parser */
ir_mce_kbd_process_keyboard_data(dev, scancode);
+   spin_unlock(>keylock);
lsc.rc_proto = RC_PROTO_MCIR2_KBD;
break;
case MCIR2_MOUSE_NBITS:
@@ -400,6 +408,7 @@ static int ir_mce_kbd_register(struct rc_dev *dev)
set_bit(MSC_SCAN, idev->mscbit);
 
timer_setup(_kbd->rx_timeout, mce_kbd_rx_timeout, 0);
+   spin_lock_init(_kbd->keylock);
 
input_set_drvdata(idev, mce_kbd);
 
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index f78551344eca..8f21562ec446 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -106,6 +106,7 @@ struct ir_raw_event_ctrl {
struct mce_kbd_dec {
struct input_dev *idev;
struct timer_list rx_timeout;
+   spinlock_t keylock;
char name[64];
char phys[64];
int state;
-- 
2.14.3



Re: [RFCv3 15/17] v4l2: document the request API interface

2018-04-14 Thread Randy Dunlap
Hi,

A few comments below...

On 02/06/2018 05:48 PM, Alexandre Courbot wrote:
> Document how the request API can be used along with the existing V4L2
> interface.
> 
> Signed-off-by: Alexandre Courbot 
> ---
>  Documentation/media/uapi/v4l/buffer.rst|  10 +-
>  Documentation/media/uapi/v4l/common.rst|   1 +
>  Documentation/media/uapi/v4l/request-api.rst   | 236 
> +
>  .../media/uapi/v4l/vidioc-g-ext-ctrls.rst  |  16 +-
>  Documentation/media/uapi/v4l/vidioc-qbuf.rst   |  21 ++
>  5 files changed, 280 insertions(+), 4 deletions(-)
>  create mode 100644 Documentation/media/uapi/v4l/request-api.rst


> diff --git a/Documentation/media/uapi/v4l/request-api.rst 
> b/Documentation/media/uapi/v4l/request-api.rst
> new file mode 100644
> index ..4c61a0dbe3a9
> --- /dev/null
> +++ b/Documentation/media/uapi/v4l/request-api.rst
> @@ -0,0 +1,236 @@
> +.. -*- coding: utf-8; mode: rst -*-
> +
> +.. _media-request-api:
> +
> +Request API
> +===
> +
> +The Request API has been designed to allow V4L2 to deal with requirements of
> +modern devices (stateless codecs, MIPI cameras, ...) and APIs (Android Codec
> +v2). One such requirement is the ability for devices belonging to the same
> +pipeline to reconfigure and collaborate closely on a per-frame basis. 
> Another is
> +efficient support of stateless codecs, which need per-frame controls to be 
> set
> +asynchronously in order to be efficiently used.

   to be used efficiently.

> +
> +Supporting these features without the Request API is possible but terribly
> +inefficient: user-space would have to flush all activity on the media 
> pipeline,
> +reconfigure it for the next frame, queue the buffers to be processed with 
> that
> +configuration, and wait until they are all available for dequeing before

"dequeing" should be dequeueing or dequeuing.

> +considering the next frame. This defeats the purpose of having buffer queues
> +since in practice only one buffer would be queued at a time.
> +
> +The Request API allows a specific configuration of the pipeline (media
> +controller topology + controls for each device) to be associated with 
> specific
> +buffers. The parameters are applied by each participating device as buffers
> +associated to a request flow in. This allows user-space to schedule several
> +tasks ("requests") with different parameters in advance, knowing that the
> +parameters will be applied when needed to get the expected result. Controls
> +values at the time of request completion are also available for reading.
> +
> +Usage
> +=
> +
> +The Request API is used on top of standard media controller and V4L2 calls,
> +which are augmented with an extra ``request_fd`` parameter. All operations on
> +requests themselves are performed using the command parameter of the
> +:c:func:`MEDIA_IOC_REQUEST_CMD` ioctl.
> +
> +Request Allocation
> +--
> +
> +User-space allocates requests using the ``MEDIA_REQ_CMD_ALLOC`` command on
> +an opened media device. This returns a file descriptor representing the
> +request. Typically, several such requests will be allocated.
> +
> +Request Preparation
> +---
> +
> +Standard V4L2 ioctls can then receive a request file descriptor to express 
> the
> +fact that the ioctl is part of said request, and is not to be applied
> +immediately. V4L2 ioctls supporting this are :c:func:`VIDIOC_S_EXT_CTRLS` and
> +:c:func:`VIDIOC_QBUF`. Controls set with a request parameter are stored 
> instead
> +of being immediately applied, and queued buffers will block the buffer queue
> +until the request becomes active.
> +
> +RFC Note: currently several buffers can be queued to the same queue with the
> +same request. The request parameters will be only be applied when processing
> +the first buffer. Does it make more sense to allow at most one buffer per
> +request per queue instead?
> +
> +Request Submission
> +--
> +
> +Once the parameters and buffers of the request are specified, it can be
> +submitted with the ``MEDIA_REQ_CMD_SUBMIT`` command. This will make the 
> buffers
> +associated to the request available to their driver, which can then apply the
> +saved controls as buffers are processed. A submitted request cannot be 
> modified
> +anymore.
> +
> +If several devices are part of the request, individual drivers may 
> synchronize
> +so the requested pipeline's topology is applied before the buffers are
> +processed. This is at the discretion of the drivers and is not a requirement.
> +
> +Buffers queued without an associated request after a request-bound buffer 
> will
> +be processed using the state of the hardware at the time of the request
> +completion. All the same, controls set without a request are applied
> +immediately, regardless of whether a request is in use or not.
> +
> +User-space can ``poll()`` a request FD in order to wait until the request