Re: [PATCH v10 1/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver documentation

2017-11-10 Thread Niklas Söderlund
Hej Sakari,

Tack för din feedback.

On 2017-11-11 00:11:13 +0200, Sakari Ailus wrote:
> Hejssan,
> 
> On Fri, Nov 10, 2017 at 02:31:36PM +0100, Niklas Söderlund wrote:
> > Documentation for Renesas R-Car MIPI CSI-2 receiver. The CSI-2 receivers
> > are located between the video sources (CSI-2 transmitters) and the video
> > grabbers (VIN) on Gen3 of Renesas R-Car SoC.
> > 
> > Each CSI-2 device is connected to more then one VIN device which
> > simultaneously can receive video from the same CSI-2 device. Each VIN
> > device can also be connected to more then one CSI-2 device. The routing
> > of which link are used are controlled by the VIN devices. There are only
> > a few possible routes which are set by hardware limitations, which are
> > different for each SoC in the Gen3 family.
> > 
> > To work with the limitations of routing possibilities it is necessary
> > for the DT bindings to describe which VIN device is connected to which
> > CSI-2 device. This is why port 1 needs to to assign reg numbers for each
> > VIN device that be connected to it. To setup and to know which links are
> > valid for each SoC is the responsibility of the VIN driver since the
> > register to configure it belongs to the VIN hardware.
> > 
> > Signed-off-by: Niklas Söderlund 
> > ---
> >  .../devicetree/bindings/media/rcar-csi2.txt| 104 
> > +
> >  MAINTAINERS|   1 +
> >  2 files changed, 105 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/media/rcar-csi2.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/media/rcar-csi2.txt 
> > b/Documentation/devicetree/bindings/media/rcar-csi2.txt
> > new file mode 100644
> > index ..24705d8997b14a10
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/rcar-csi2.txt
> 
> How about using vendor prefix and comma for the file name? Most others in
> the directory do so, including other Renesas bindings.

To be clear you are suggesting a rename to 'renesas,rcar-csi2.txt'?  I'm 
not oppose to that but chose this name as this driver is closely tied to 
the rcar-vin driver which is documented in:

Documentation/devicetree/bindings/media/rcar_vin.txt

You also had comments on patch 2/2 so I will resend this series once 
more addressing them so will rename this as you suggests.

> 
> > @@ -0,0 +1,104 @@
> > +Renesas R-Car MIPI CSI-2
> > +
> > +
> > +The rcar-csi2 device provides MIPI CSI-2 capabilities for the Renesas R-Car
> > +family of devices. It is to be used in conjunction with the R-Car VIN 
> > module,
> > +which provides the video capture capabilities.
> > +
> > +Mandatory properties
> > +
> > + - compatible: Must be one or more of the following
> > +   - "renesas,r8a7795-csi2" for the R8A7795 device.
> > +   - "renesas,r8a7796-csi2" for the R8A7796 device.
> > +
> > + - reg: the register base and size for the device registers
> > + - interrupts: the interrupt for the device
> > + - clocks: Reference to the parent clock
> > +
> > +The device node shall contain two 'port' child nodes according to the
> > +bindings defined in Documentation/devicetree/bindings/media/
> > +video-interfaces.txt. Port 0 shall connect the node that is the video
> > +source for to the CSI-2. Port 1 shall connect all the R-Car VIN
> > +modules, which can make use of the CSI-2 module.
> > +
> > +- Port 0 - Video source (Mandatory)
> > +   - Endpoint 0 - sub-node describing the endpoint that is the video source
> > +
> > +- Port 1 - VIN instances (Mandatory for all VIN present in the SoC)
> > +   - Endpoint 0 - sub-node describing the endpoint that is VIN0
> > +   - Endpoint 1 - sub-node describing the endpoint that is VIN1
> > +   - Endpoint 2 - sub-node describing the endpoint that is VIN2
> > +   - Endpoint 3 - sub-node describing the endpoint that is VIN3
> > +   - Endpoint 4 - sub-node describing the endpoint that is VIN4
> > +   - Endpoint 5 - sub-node describing the endpoint that is VIN5
> > +   - Endpoint 6 - sub-node describing the endpoint that is VIN6
> > +   - Endpoint 7 - sub-node describing the endpoint that is VIN7
> > +
> > +Example:
> > +
> > +   csi20: csi2@fea8 {
> > +   compatible = "renesas,r8a7796-csi2", "renesas,rcar-gen3-csi2";
> > +   reg = <0 0xfea8 0 0x1>;
> > +   interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
> > +

Re: [PATCH v10 2/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver

2017-11-10 Thread Niklas Söderlund
Hej Sakari,

On 2017-11-11 00:32:27 +0200, Sakari Ailus wrote:
> Hej Niklas,
> 
> Tack för uppdaterade lappar! Jag har några kommentar nedan... det ser bra
> ut överallt.

Tack för din feedback!

> 
> On Fri, Nov 10, 2017 at 02:31:37PM +0100, Niklas Söderlund wrote:
> > A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver
> > supports the rcar-vin driver on R-Car Gen3 SoCs where separate CSI-2
> > hardware blocks are connected between the video sources and the video
> > grabbers (VIN).
> > 
> > Driver is based on a prototype by Koji Matsuoka in the Renesas BSP.
> > 
> > Signed-off-by: Niklas Söderlund 
> > ---
> >  drivers/media/platform/rcar-vin/Kconfig |  12 +
> >  drivers/media/platform/rcar-vin/Makefile|   1 +
> >  drivers/media/platform/rcar-vin/rcar-csi2.c | 934 
> > 
> >  3 files changed, 947 insertions(+)
> >  create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c
> > 
> > diff --git a/drivers/media/platform/rcar-vin/Kconfig 
> > b/drivers/media/platform/rcar-vin/Kconfig
> > index af4c98b44d2e22cb..6875f30c1ae42631 100644
> > --- a/drivers/media/platform/rcar-vin/Kconfig
> > +++ b/drivers/media/platform/rcar-vin/Kconfig
> > @@ -1,3 +1,15 @@
> > +config VIDEO_RCAR_CSI2
> > +   tristate "R-Car MIPI CSI-2 Receiver"
> > +   depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
> > +   depends on ARCH_RENESAS || COMPILE_TEST
> > +   select V4L2_FWNODE
> > +   ---help---
> > + Support for Renesas R-Car MIPI CSI-2 receiver.
> > + Supports R-Car Gen3 SoCs.
> > +
> > + To compile this driver as a module, choose M here: the
> > + module will be called rcar-csi2.
> > +
> >  config VIDEO_RCAR_VIN
> > tristate "R-Car Video Input (VIN) Driver"
> > depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && 
> > MEDIA_CONTROLLER
> > diff --git a/drivers/media/platform/rcar-vin/Makefile 
> > b/drivers/media/platform/rcar-vin/Makefile
> > index 48c5632c21dc060b..5ab803d3e7c1aa57 100644
> > --- a/drivers/media/platform/rcar-vin/Makefile
> > +++ b/drivers/media/platform/rcar-vin/Makefile
> > @@ -1,3 +1,4 @@
> >  rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o
> >  
> > +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o
> >  obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o
> > diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
> > b/drivers/media/platform/rcar-vin/rcar-csi2.c
> > new file mode 100644
> > index ..27d09da191a09b39
> > --- /dev/null
> > +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
> > @@ -0,0 +1,934 @@
> > +/*
> > + * Driver for Renesas R-Car MIPI CSI-2 Receiver
> > + *
> > + * Copyright (C) 2017 Renesas Electronics Corp.
> > + *
> > + * This program is free software; you can redistribute  it and/or modify it
> > + * under  the terms of  the GNU General  Public License as published by the
> > + * Free Software Foundation;  either version 2 of the  License, or (at your
> > + * option) any later version.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +/* Register offsets and bits */
> > +
> > +/* Control Timing Select */
> > +#define TREF_REG   0x00
> > +#define TREF_TREF  BIT(0)
> > +
> > +/* Software Reset */
> > +#define SRST_REG   0x04
> > +#define SRST_SRST  BIT(0)
> > +
> > +/* PHY Operation Control */
> > +#define PHYCNT_REG 0x08
> > +#define PHYCNT_SHUTDOWNZ   BIT(17)
> > +#define PHYCNT_RSTZBIT(16)
> > +#define PHYCNT_ENABLECLK   BIT(4)
> > +#define PHYCNT_ENABLE_3BIT(3)
> > +#define PHYCNT_ENABLE_2BIT(2)
> > +#define PHYCNT_ENABLE_1BIT(1)
> > +#define PHYCNT_ENABLE_0BIT(0)
> > +
> > +/* Checksum Control */
> > +#define CHKSUM_REG 0x0c
> > +#define CHKSUM_ECC_EN  BIT(1)
> > +#define CHKSUM_CRC_EN  BIT(0)
> > +
> > +/*
> > + * Channel Data Type Select
> > + * VCDT[0-15]:  Channel 1

[PATCH v11 0/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2

2017-11-10 Thread Niklas Söderlund
nce v3:
- Update DT binding documentation with input from Geert Uytterhoeven,
  thanks!

Changes since v2:
- Added media control pads as this is needed by the new rcar-vin driver.
- Update DT bindings after review comments and to add r8a7796 support.
- Add get_fmt handler.
- Fix media bus format error s/YUYV8/UYVY8/

Changes since v1:
- Drop dependency on a pad aware s_stream operation.
- Use the DT bindings format "renesas,-", thanks Geert
  for pointing this out.

1. http://elinux.org/R-Car/Tests:rcar-vin
Niklas Söderlund (2):
  media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver documentation
  media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver

 .../bindings/media/renesas,rcar-csi2.txt   | 104 +++
 MAINTAINERS|   1 +
 drivers/media/platform/rcar-vin/Kconfig|  12 +
 drivers/media/platform/rcar-vin/Makefile   |   1 +
 drivers/media/platform/rcar-vin/rcar-csi2.c| 896 +
 5 files changed, 1014 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
 create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c

-- 
2.15.0



[PATCH v11 2/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver

2017-11-10 Thread Niklas Söderlund
A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver
supports the rcar-vin driver on R-Car Gen3 SoCs where separate CSI-2
hardware blocks are connected between the video sources and the video
grabbers (VIN).

Driver is based on a prototype by Koji Matsuoka in the Renesas BSP.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/Kconfig |  12 +
 drivers/media/platform/rcar-vin/Makefile|   1 +
 drivers/media/platform/rcar-vin/rcar-csi2.c | 896 
 3 files changed, 909 insertions(+)
 create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c

diff --git a/drivers/media/platform/rcar-vin/Kconfig 
b/drivers/media/platform/rcar-vin/Kconfig
index af4c98b44d2e22cb..6875f30c1ae42631 100644
--- a/drivers/media/platform/rcar-vin/Kconfig
+++ b/drivers/media/platform/rcar-vin/Kconfig
@@ -1,3 +1,15 @@
+config VIDEO_RCAR_CSI2
+   tristate "R-Car MIPI CSI-2 Receiver"
+   depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
+   depends on ARCH_RENESAS || COMPILE_TEST
+   select V4L2_FWNODE
+   ---help---
+ Support for Renesas R-Car MIPI CSI-2 receiver.
+ Supports R-Car Gen3 SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rcar-csi2.
+
 config VIDEO_RCAR_VIN
tristate "R-Car Video Input (VIN) Driver"
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && 
MEDIA_CONTROLLER
diff --git a/drivers/media/platform/rcar-vin/Makefile 
b/drivers/media/platform/rcar-vin/Makefile
index 48c5632c21dc060b..5ab803d3e7c1aa57 100644
--- a/drivers/media/platform/rcar-vin/Makefile
+++ b/drivers/media/platform/rcar-vin/Makefile
@@ -1,3 +1,4 @@
 rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o
 
+obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o
 obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o
diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
b/drivers/media/platform/rcar-vin/rcar-csi2.c
new file mode 100644
index ..4202c60b4d0aa7f7
--- /dev/null
+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
@@ -0,0 +1,896 @@
+/*
+ * Driver for Renesas R-Car MIPI CSI-2 Receiver
+ *
+ * Copyright (C) 2017 Renesas Electronics Corp.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Register offsets and bits */
+
+/* Control Timing Select */
+#define TREF_REG   0x00
+#define TREF_TREF  BIT(0)
+
+/* Software Reset */
+#define SRST_REG   0x04
+#define SRST_SRST  BIT(0)
+
+/* PHY Operation Control */
+#define PHYCNT_REG 0x08
+#define PHYCNT_SHUTDOWNZ   BIT(17)
+#define PHYCNT_RSTZBIT(16)
+#define PHYCNT_ENABLECLK   BIT(4)
+#define PHYCNT_ENABLE_3BIT(3)
+#define PHYCNT_ENABLE_2BIT(2)
+#define PHYCNT_ENABLE_1BIT(1)
+#define PHYCNT_ENABLE_0BIT(0)
+
+/* Checksum Control */
+#define CHKSUM_REG 0x0c
+#define CHKSUM_ECC_EN  BIT(1)
+#define CHKSUM_CRC_EN  BIT(0)
+
+/*
+ * Channel Data Type Select
+ * VCDT[0-15]:  Channel 1 VCDT[16-31]:  Channel 2
+ * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4
+ */
+#define VCDT_REG   0x10
+#define VCDT2_REG  0x14
+#define VCDT_VCDTN_EN  BIT(15)
+#define VCDT_SEL_VC(n) (((n) & 0x3) << 8)
+#define VCDT_SEL_DTN_ONBIT(6)
+#define VCDT_SEL_DT(n) (((n) & 0x3f) << 0)
+
+/* Frame Data Type Select */
+#define FRDT_REG   0x18
+
+/* Field Detection Control */
+#define FLD_REG0x1c
+#define FLD_FLD_NUM(n) (((n) & 0xff) << 16)
+#define FLD_FLD_EN4BIT(3)
+#define FLD_FLD_EN3BIT(2)
+#define FLD_FLD_EN2BIT(1)
+#define FLD_FLD_EN BIT(0)
+
+/* Automatic Standby Control */
+#define ASTBY_REG  0x20
+
+/* Long Data Type Setting 0 */
+#define LNGDT0_REG 0x28
+
+/* Long Data Type Setting 1 */
+#define LNGDT1_REG 0x2c
+
+/* Interrupt Enable */
+#define INTEN_REG  0x30
+
+/* Interrupt Source Mask */
+#define INTCLOSE_REG   0x34
+
+/* Interrupt Status Monitor */
+#define INTSTATE_REG   0x38
+#define INTSTATE_INT_ULPS_START

[PATCH v11 1/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver documentation

2017-11-10 Thread Niklas Söderlund
Documentation for Renesas R-Car MIPI CSI-2 receiver. The CSI-2 receivers
are located between the video sources (CSI-2 transmitters) and the video
grabbers (VIN) on Gen3 of Renesas R-Car SoC.

Each CSI-2 device is connected to more then one VIN device which
simultaneously can receive video from the same CSI-2 device. Each VIN
device can also be connected to more then one CSI-2 device. The routing
of which link are used are controlled by the VIN devices. There are only
a few possible routes which are set by hardware limitations, which are
different for each SoC in the Gen3 family.

To work with the limitations of routing possibilities it is necessary
for the DT bindings to describe which VIN device is connected to which
CSI-2 device. This is why port 1 needs to to assign reg numbers for each
VIN device that be connected to it. To setup and to know which links are
valid for each SoC is the responsibility of the VIN driver since the
register to configure it belongs to the VIN hardware.

Signed-off-by: Niklas Söderlund 
---
 .../bindings/media/renesas,rcar-csi2.txt   | 104 +
 MAINTAINERS|   1 +
 2 files changed, 105 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt

diff --git a/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt 
b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
new file mode 100644
index ..24705d8997b14a10
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
@@ -0,0 +1,104 @@
+Renesas R-Car MIPI CSI-2
+
+
+The rcar-csi2 device provides MIPI CSI-2 capabilities for the Renesas R-Car
+family of devices. It is to be used in conjunction with the R-Car VIN module,
+which provides the video capture capabilities.
+
+Mandatory properties
+
+ - compatible: Must be one or more of the following
+   - "renesas,r8a7795-csi2" for the R8A7795 device.
+   - "renesas,r8a7796-csi2" for the R8A7796 device.
+
+ - reg: the register base and size for the device registers
+ - interrupts: the interrupt for the device
+ - clocks: Reference to the parent clock
+
+The device node shall contain two 'port' child nodes according to the
+bindings defined in Documentation/devicetree/bindings/media/
+video-interfaces.txt. Port 0 shall connect the node that is the video
+source for to the CSI-2. Port 1 shall connect all the R-Car VIN
+modules, which can make use of the CSI-2 module.
+
+- Port 0 - Video source (Mandatory)
+   - Endpoint 0 - sub-node describing the endpoint that is the video source
+
+- Port 1 - VIN instances (Mandatory for all VIN present in the SoC)
+   - Endpoint 0 - sub-node describing the endpoint that is VIN0
+   - Endpoint 1 - sub-node describing the endpoint that is VIN1
+   - Endpoint 2 - sub-node describing the endpoint that is VIN2
+   - Endpoint 3 - sub-node describing the endpoint that is VIN3
+   - Endpoint 4 - sub-node describing the endpoint that is VIN4
+   - Endpoint 5 - sub-node describing the endpoint that is VIN5
+   - Endpoint 6 - sub-node describing the endpoint that is VIN6
+   - Endpoint 7 - sub-node describing the endpoint that is VIN7
+
+Example:
+
+   csi20: csi2@fea8 {
+   compatible = "renesas,r8a7796-csi2", "renesas,rcar-gen3-csi2";
+   reg = <0 0xfea8 0 0x1>;
+   interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+   clocks = <&cpg CPG_MOD 714>;
+   power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+   resets = <&cpg 714>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   reg = <0>;
+
+   csi20_in: endpoint@0 {
+   clock-lanes = <0>;
+   data-lanes = <1>;
+   remote-endpoint = <&adv7482_txb>;
+   };
+   };
+
+   port@1 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   reg = <1>;
+
+   csi20vin0: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <&vin0csi20>;
+   };
+   csi20vin1: endpoint@1 {
+   reg = <1>;
+  

[PATCH v7 22/25] rcar-vin: add link notify for Gen3

2017-11-10 Thread Niklas Söderlund
Add the ability to process media device link change request. 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 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 205 
 1 file changed, 205 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 78a9766eb7114959..79b0334d8c563328 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -27,6 +27,209 @@
 
 #include "rcar-vin.h"
 
+/* 
-
+ * Media Controller link notification
+ */
+
+static unsigned int rvin_group_csi_pad_to_chan(unsigned int pad)
+{
+   /*
+* The companion CSI-2 receiver driver (rcar-csi2) is known
+* and we know it have one source pad (pad 0) and four sink
+* pads (pad 1-4). So to translate a pad on the remote
+* CSI-2 receiver to the VIN internal channel number simply
+* subtract one from the pad number.
+*/
+   return pad - 1;
+}
+
+/* group lock should be held when calling this function */
+static int rvin_group_entity_to_vin_num(struct rvin_group *group,
+   struct media_entity *entity)
+{
+   struct video_device *vdev;
+   int i;
+
+   if (!is_media_entity_v4l2_video_device(entity))
+   return -ENODEV;
+
+   vdev = media_entity_to_video_device(entity);
+
+   for (i = 0; i < RCAR_VIN_NUM; i++) {
+   if (!group->vin[i])
+   continue;
+
+   if (&group->vin[i]->vdev == vdev)
+   return i;
+   }
+
+   return -ENODEV;
+}
+
+/* group lock should be held when calling this function */
+static int rvin_group_entity_to_csi_num(struct rvin_group *group,
+   struct media_entity *entity)
+{
+   struct v4l2_subdev *sd;
+   int i;
+
+   if (!is_media_entity_v4l2_subdev(entity))
+   return -ENODEV;
+
+   sd = media_entity_to_v4l2_subdev(entity);
+
+   for (i = 0; i < RVIN_CSI_MAX; i++)
+   if (group->csi[i].subdev == sd)
+   return i;
+
+   return -ENODEV;
+}
+
+/* group lock should be held when calling this function */
+static void __rvin_group_build_link_list(struct rvin_group *group,
+struct rvin_group_chsel *map,
+int start, int len)
+{
+   struct media_pad *vin_pad, *remote_pad;
+   unsigned int n;
+
+   for (n = 0; n < len; n++) {
+   map[n].csi = -1;
+   map[n].chan = -1;
+
+   if (!group->vin[start + n])
+   continue;
+
+   vin_pad = &group->vin[start + n]->vdev.entity.pads[0];
+
+   remote_pad = media_entity_remote_pad(vin_pad);
+   if (!remote_pad)
+   continue;
+
+   map[n].csi =
+   rvin_group_entity_to_csi_num(group, remote_pad->entity);
+   map[n].chan = rvin_group_csi_pad_to_chan(remote_pad->index);
+   }
+}
+
+/* group lock should be held when calling this function */
+static int __rvin_group_try_get_chsel(struct rvin_group *group,
+ struct rvin_group_chsel *map,
+ int start, int len)
+{
+   const struct rvin_group_chsel *sel;
+   unsigned int i, n;
+   int chsel;
+
+   for (i = 0; i < group->vin[start]->info->num_chsels; i++) {
+   chsel = i;
+   for (n = 0; n < len; n++) {
+
+   /* If the link is not active it's OK */
+   if (map[n].csi == -1)
+   continue;
+
+   /* Check if chsel matches requested link */
+   sel = &group->vin[start]->info->chsels[start + n][i];

[PATCH v7 25/25] rcar-vin: enable support for r8a7796

2017-11-10 Thread Niklas Söderlund
Add the SoC specific information for Renesas r8a7796.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
---
 .../devicetree/bindings/media/rcar_vin.txt |  1 +
 drivers/media/platform/rcar-vin/rcar-core.c| 64 ++
 2 files changed, 65 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt 
b/Documentation/devicetree/bindings/media/rcar_vin.txt
index df1abd0fb20386f8..ddf249c2276600d2 100644
--- a/Documentation/devicetree/bindings/media/rcar_vin.txt
+++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
@@ -10,6 +10,7 @@ Depending on the instance the VIN input is connected to 
external SoC pins, or
 on Gen3 to a CSI-2 receiver.
 
  - compatible: Must be one or more of the following
+   - "renesas,vin-r8a7796" for the R8A7796 device
- "renesas,vin-r8a7795" for the R8A7795 device
- "renesas,vin-r8a7794" for the R8A7794 device
- "renesas,vin-r8a7793" for the R8A7793 device
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index b22f6596700d2479..e329de4ce0172e8d 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -1084,6 +1084,66 @@ static const struct rvin_info rcar_info_r8a7795es1 = {
},
 };
 
+static const struct rvin_info rcar_info_r8a7796 = {
+   .chip = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+
+   .num_chsels = 5,
+   .chsels = {
+   {
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   }, {
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 2 },
+   { .csi = RVIN_CSI20, .chan = 2 },
+   }, {
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_NC, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 3 },
+   { .csi = RVIN_CSI20, .chan = 3 },
+   }, {
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   }, {
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 2 },
+   { .csi = RVIN_CSI20, .chan = 2 },
+   }, {
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_NC, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 3 },
+   { .csi = RVIN_CSI20, .chan = 3 },
+   },
+   },
+};
+
 static const struct of_device_id rvin_of_id_table[] = {
{
.compatible = "renesas,vin-r8a7778",
@@ -1117,6 +1177,10 @@ static const struct of_device_id rvin_of_id_table[] = {
.compatible = "renesas,vin-r8a7795",
.data = &rcar_info_r8a7795,
},
+   {
+   .compatible = "renesas,vin-r8a7796",
+   .data = &rcar_info_r8a7796,
+   },
{ },
 };
 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
-- 
2.15.0



[PATCH v7 12/25] rcar-vin: move media bus configuration to struct rvin_info

2017-11-10 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_info to show it's not always coupled
to the parallel subdevice.

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

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index cb761057459caa3f..fa76f494ec0c4bd2 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -100,10 +100,10 @@ static int rvin_digital_notify_bound(struct 
v4l2_async_notifier *notifier,
vin->digital->sink_pad = ret < 0 ? 0 : ret;
 
/* Find compatible subdevices mbus format */
-   vin->digital->code = 0;
+   vin->code = 0;
code.index = 0;
code.pad = vin->digital->source_pad;
-   while (!vin->digital->code &&
+   while (!vin->code &&
   !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
code.index++;
switch (code.code) {
@@ -111,16 +111,16 @@ static int rvin_digital_notify_bound(struct 
v4l2_async_notifier *notifier,
case MEDIA_BUS_FMT_UYVY8_2X8:
case MEDIA_BUS_FMT_UYVY10_2X10:
case MEDIA_BUS_FMT_RGB888_1X24:
-   vin->digital->code = code.code;
+   vin->code = code.code;
vin_dbg(vin, "Found media bus format for %s: %d\n",
-   subdev->name, vin->digital->code);
+   subdev->name, vin->code);
break;
default:
break;
}
}
 
-   if (!vin->digital->code) {
+   if (!vin->code) {
vin_err(vin, "Unsupported media bus format for %s\n",
subdev->name);
return -EINVAL;
@@ -186,16 +186,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 506d51a13b4f5f40..9362e7dba5e3ba95 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -633,7 +633,7 @@ static int rvin_setup(struct rvin_dev *vin)
/*
 * Input interface
 */
-   switch (vin->digital->code) {
+   switch (vin->code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
/* BT.601/BT.1358 16bit YCbCr422 */
vnmc |= VNMC_INF_YUV16;
@@ -641,7 +641,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;
@@ -650,7 +650,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;
@@ -662,11 +662,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 

[PATCH v7 23/25] rcar-vin: extend {start,stop}_streaming to work with media controller

2017-11-10 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 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 113 +++--
 1 file changed, 106 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index fe1319eb4c5df02d..b16b892a4de876bb 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -1087,15 +1087,116 @@ static void rvin_buffer_queue(struct vb2_buffer *vb)
spin_unlock_irqrestore(&vin->qlock, flags);
 }
 
+static int rvin_set_stream(struct rvin_dev *vin, int on)
+{
+   struct v4l2_subdev_format fmt = {
+   .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+   };
+   struct media_pipeline *pipe;
+   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(&vin->pad);
+   if (!pad)
+   return -EPIPE;
+
+   sd = media_entity_to_v4l2_subdev(pad->entity);
+   if (!sd)
+   return -EPIPE;
+
+   if (!on) {
+   media_pipeline_stop(&vin->vdev.entity);
+   ret = v4l2_subdev_call(sd, video, s_stream, 0);
+   return 0;
+   }
+
+   fmt.pad = pad->index;
+   if (v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt))
+   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->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 nativly */
+   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)
+   return -EPIPE;
+
+   pipe = sd->entity.pipe ? sd->entity.pipe : &vin->vdev.pipe;
+   if (media_pipeline_start(&vin->vdev.entity, pipe))
+   return -EPIPE;
+
+   ret = v4l2_subdev_call(sd, video, s_stream, 1);
+   if (ret == -ENOIOCTLCMD)
+   ret = 0;
+   if (ret)
+   media_pipeline_stop(&vin->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;
int ret;
 
-   sd = vin_to_source(vin);
-   v4l2_subdev_call(sd, video, s_stream, 1);
+   ret = rvin_set_stream(vin, 1);
+   if (ret) {
+   spin_lock_irqsave(&vin->qlock, flags);
+   return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
+   spin_unlock_irqrestore(&vin->qlock, flags);
+   return ret;
+   }
 
spin_lock_irqsave(&vin->qlock, flags);
 
@@ -1104,7 +1205,7 @@ static int rvin_start_streaming(struct vb2_queue *vq, 
unsigned int count)
ret = rvin_capture_start(vin);
if (ret) {
return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
-   v4l2_subdev_call(sd, video, s_stream, 0);
+   rvin_set_stream(vin, 0);
}
 
spin_unlock_irqrestore(&vin->qlock, flags);

[PATCH v7 24/25] rcar-vin: enable support for r8a7795

2017-11-10 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: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/Kconfig |   2 +-
 drivers/media/platform/rcar-vin/rcar-core.c | 150 
 2 files changed, 151 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 79b0334d8c563328..b22f6596700d2479 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 
@@ -955,6 +956,134 @@ static const struct rvin_info rcar_info_gen2 = {
.max_height = 2048,
 };
 
+static const struct rvin_info rcar_info_r8a7795 = {
+   .chip = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+
+   .num_chsels = 5,
+   .chsels = {
+   {
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 2 },
+   { .csi = RVIN_CSI20, .chan = 2 },
+   }, {
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 3 },
+   { .csi = RVIN_CSI20, .chan = 3 },
+   }, {
+   { .csi = RVIN_CSI41, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI41, .chan = 1 },
+   { .csi = RVIN_CSI41, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI41, .chan = 1 },
+   { .csi = RVIN_CSI41, .chan = 0 },
+   { .csi = RVIN_CSI41, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI41, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI41, .chan = 2 },
+   { .csi = RVIN_CSI20, .chan = 2 },
+   }, {
+   { .csi = RVIN_CSI41, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI41, .chan = 3 },
+   { .csi = RVIN_CSI20, .chan = 3 },
+   },
+   },
+};
+
+static const struct rvin_info rcar_info_r8a7795es1 = {
+   .chip = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+
+   .num_chsels = 6,
+   .chsels = {
+   {
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI21, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI21, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI21, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI21

[PATCH v7 19/25] rcar-vin: add group allocator functions

2017-11-10 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 to each VIN instance to know 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 creates a media device.

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

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 1b3572c8b6691a07..e204eb3db77c1d2b 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -20,12 +20,171 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 
 #include "rcar-vin.h"
 
+/* 
-
+ * Gen3 CSI2 Group Allocator
+ */
+
+static int rvin_group_read_id(struct rvin_dev *vin, struct device_node *np)
+{
+   u32 val;
+   int ret;
+
+   ret = of_property_read_u32(np, "renesas,id", &val);
+   if (ret) {
+   vin_err(vin, "%s: No renesas,id property found\n",
+   of_node_full_name(np));
+   return -EINVAL;
+   }
+
+   if (val >= RCAR_VIN_NUM) {
+   vin_err(vin, "%s: Invalid renesas,id '%u'\n",
+   of_node_full_name(np), val);
+   return -EINVAL;
+   }
+
+   return val;
+}
+
+static DEFINE_MUTEX(rvin_group_lock);
+static struct rvin_group *rvin_group_data;
+
+static void rvin_group_release(struct kref *kref)
+{
+   struct rvin_group *group =
+   container_of(kref, struct rvin_group, refcount);
+
+   mutex_lock(&rvin_group_lock);
+
+   media_device_unregister(&group->mdev);
+   media_device_cleanup(&group->mdev);
+
+   rvin_group_data = NULL;
+
+   mutex_unlock(&rvin_group_lock);
+
+   kfree(group);
+}
+
+static struct rvin_group *__rvin_group_allocate(struct rvin_dev *vin)
+{
+   struct rvin_group *group;
+
+   if (rvin_group_data) {
+   group = rvin_group_data;
+   kref_get(&group->refcount);
+   vin_dbg(vin, "%s: get group=%p\n", __func__, group);
+   return group;
+   }
+
+   group = kzalloc(sizeof(*group), GFP_KERNEL);
+   if (!group)
+   return NULL;
+
+   kref_init(&group->refcount);
+   rvin_group_data = group;
+
+   vin_dbg(vin, "%s: alloc group=%p\n", __func__, group);
+   return group;
+}
+
+static int rvin_group_add_vin(struct rvin_dev *vin)
+{
+   int ret;
+
+   ret = rvin_group_read_id(vin, vin->dev->of_node);
+   if (ret < 0)
+   return ret;
+
+   mutex_lock(&vin->group->lock);
+
+   if (vin->group->vin[ret]) {
+   mutex_unlock(&vin->group->lock);
+   vin_err(vin, "VIN number %d already occupied\n", ret);
+   return -EINVAL;
+   }
+
+   vin->group->vin[ret] = vin;
+
+   mutex_unlock(&vin->group->lock);
+
+   vin_dbg(vin, "I'm VIN number %d", ret);
+
+   return 0;
+}
+
+static int rvin_group_allocate(struct rvin_dev *vin)
+{
+   struct rvin_group *group;
+   struct media_device *mdev;
+   int ret;
+
+   mutex_lock(&rvin_group_lock);
+
+   group = __rvin_group_allocate(vin);
+   if (!group) {
+   mutex_unlock(&rvin_group_lock);
+   return -ENOMEM;
+   }
+
+   /* Init group data if it is not already initialized */
+   mdev = &group->mdev;
+   if (!mdev->dev) {
+   mutex_init(&group->lock);
+   mdev->dev = vin->dev;
+
+   strlcpy(mdev->driver_name, "Renesas VIN",
+   sizeof(mdev->driver_name));
+   strlcpy(mdev->model, vin->dev->of_node->name,
+   sizeof(mdev->model));
+   strlcpy(mdev->bus_info, of_node_full_name(vin->dev->of_node),
+   sizeof(mdev->bus_info));
+   media_device_init(mdev);
+
+   ret = media_device_register(mdev);
+   if (ret) {
+   vin_err(vin, "Failed to register media device\n");
+   kref_put(&group->refcount, rvin_group_release);
+   mutex_unlock(&rvin_group_lock);
+   return ret;
+   }
+   }
+
+   vin->group = group;
+   vin->v4l2_dev.mdev = mdev;
+
+   ret = rvin_group_add_vin(vin);
+   if (ret) {

[PATCH v7 11/25] rcar-vin: fix handling of single field frames (top, bottom and alternate fields)

2017-11-10 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. For sources using
this field format instead use the VIN hardware feature of combining the
fields to an interlaced format. This mode of operation was previously
the default behavior and ALTERNATING was only delivered to user-space if
explicitly requested. Allowing this to be explicitly requested was a
mistake and was never properly tested and never worked due to the
constraints put on the field format when it comes to sequence numbers and
timestamps etc.

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 
---
 drivers/media/platform/rcar-vin/rcar-dma.c  | 15 +
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 48 +++--
 2 files changed, 19 insertions(+), 44 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index b478eda84a27bf09..506d51a13b4f5f40 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:
if (vin->continuous) {
vnmc = VNMC_IM_ODD_EVEN;
@@ -757,18 +756,6 @@ static int rvin_get_active_slot(struct rvin_dev *vin, u32 
vnms)
return 0;
 }
 
-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;
@@ -941,7 +928,7 @@ static irqreturn_t rvin_irq(int irq, void *data)
goto done;
 
/* Capture frame */
-   vin->queue_buf[slot]->field = rvin_get_active_field(vin, vnms);
+   vin->queue_buf[slot]->field = vin->format.field;
vin->queue_buf[slot]->sequence = sequence;
vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns();
vb2_buffer_done(&vin->queue_buf[slot]->vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index ee5df05df2e9561f..b4e96e18ab845f8b 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -102,6 +102,24 @@ static int rvin_get_sd_format(struct rvin_dev *vin, struct 
v4l2_pix_format *pix)
if (ret)
return ret;
 
+   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:
+   break;
+   case V4L2_FIELD_ALTERNATE:
+   /* Use VIN hardware to combine the two fields */
+   fmt.format.field = V4L2_FIELD_INTERLACED;
+   fmt.format.height *= 2;
+   break;
+   default:
+   vin->format.field = V4L2_FIELD_NONE;
+   break;
+   }
+
v4l2_fill_pix_format(pix, &fmt.format);
 
return 0;
@@ -115,33 +133,6 @@ int rvin_reset_format(struct rvin_dev *vin)
if (ret)
return ret;
 
-   /*
-* 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_INTERLA

[PATCH v7 00/25] rcar-vin: Add Gen3 with media controller

2017-11-10 Thread Niklas Söderlund
 Add Sakaris Ack to patch 1/32.
- Rebase on top of v4.9-rc1 instead of v4.9-rc3 to ease integration 
  testing together with renesas-drivers tree.


Niklas Söderlund (25):
  rcar-vin: add Gen3 devicetree bindings documentation
  rcar-vin: register the video device at probe time
  rcar-vin: move chip information to own struct
  rcar-vin: move max width and height information to chip information
  rcar-vin: change name of video device
  rcar-vin: move functions regarding scaling
  rcar-vin: all Gen2 boards can scale simplify logic
  rcar-vin: do not reset crop and compose when setting format
  rcar-vin: do not allow changing scaling and composing while streaming
  rcar-vin: read subdevice format for crop only when needed
  rcar-vin: fix handling of single field frames (top, bottom and
alternate fields)
  rcar-vin: move media bus configuration to struct rvin_info
  rcar-vin: enable Gen3 hardware configuration
  rcar-vin: add function to manipulate Gen3 CHSEL value
  rcar-vin: add flag to switch to media controller mode
  rcar-vin: break out format alignment and checking
  rcar-vin: use different v4l2 operations in media controller mode
  rcar-vin: prepare for media controller mode initialization
  rcar-vin: add group allocator functions
  rcar-vin: add chsel information to rvin_info
  rcar-vin: parse Gen3 OF and setup media graph
  rcar-vin: add link notify for Gen3
  rcar-vin: extend {start,stop}_streaming to work with media controller
  rcar-vin: enable support for r8a7795
  rcar-vin: enable support for r8a7796

 .../devicetree/bindings/media/rcar_vin.txt |  117 ++-
 drivers/media/platform/rcar-vin/Kconfig|2 +-
 drivers/media/platform/rcar-vin/rcar-core.c| 1109 +++-
 drivers/media/platform/rcar-vin/rcar-dma.c |  985 +
 drivers/media/platform/rcar-vin/rcar-v4l2.c|  446 
 drivers/media/platform/rcar-vin/rcar-vin.h |  125 ++-
 6 files changed, 2090 insertions(+), 694 deletions(-)

-- 
2.15.0



[PATCH v7 10/25] rcar-vin: read subdevice format for crop only when needed

2017-11-10 Thread Niklas Söderlund
Instead of caching the subdevice format each time the video device
format is set read it directly when it's needed. As it turns out the
format is only needed when figuring out the max rectangle for cropping.

This simplifies the code and makes it clearer what the source format is
used for.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 88 ++---
 drivers/media/platform/rcar-vin/rcar-vin.h  | 12 
 2 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index b3c23634e9dbe095..ee5df05df2e9561f 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -90,24 +90,30 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format 
*pix)
  * V4L2
  */
 
-int rvin_reset_format(struct rvin_dev *vin)
+static int rvin_get_sd_format(struct rvin_dev *vin, struct v4l2_pix_format 
*pix)
 {
struct v4l2_subdev_format fmt = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+   .pad = vin->digital->source_pad,
};
-   struct v4l2_mbus_framefmt *mf = &fmt.format;
int ret;
 
-   fmt.pad = vin->digital->source_pad;
-
ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt);
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(pix, &fmt.format);
+
+   return 0;
+}
+
+int rvin_reset_format(struct rvin_dev *vin)
+{
+   int ret;
+
+   ret = rvin_get_sd_format(vin, &vin->format);
+   if (ret)
+   return ret;
 
/*
 * If the subdevice uses ALTERNATE field mode and G_STD is
@@ -137,12 +143,12 @@ int rvin_reset_format(struct rvin_dev *vin)
}
 
vin->crop.top = vin->crop.left = 0;
-   vin->crop.width = mf->width;
-   vin->crop.height = mf->height;
+   vin->crop.width = vin->format.width;
+   vin->crop.height = vin->format.height;
 
vin->compose.top = vin->compose.left = 0;
-   vin->compose.width = mf->width;
-   vin->compose.height = mf->height;
+   vin->compose.width = vin->format.width;
+   vin->compose.height = vin->format.height;
 
vin->format.bytesperline = rvin_format_bytesperline(&vin->format);
vin->format.sizeimage = rvin_format_sizeimage(&vin->format);
@@ -151,9 +157,7 @@ int rvin_reset_format(struct rvin_dev *vin)
 }
 
 static int __rvin_try_format_source(struct rvin_dev *vin,
-   u32 which,
-   struct v4l2_pix_format *pix,
-   struct rvin_source_fmt *source)
+   u32 which, struct v4l2_pix_format *pix)
 {
struct v4l2_subdev *sd;
struct v4l2_subdev_pad_config *pad_cfg;
@@ -186,25 +190,15 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
v4l2_fill_pix_format(pix, &format.format);
 
pix->field = field;
-
-   source->width = pix->width;
-   source->height = pix->height;
-
pix->width = width;
pix->height = height;
-
-   vin_dbg(vin, "Source resolution: %ux%u\n", source->width,
-   source->height);
-
 done:
v4l2_subdev_free_pad_config(pad_cfg);
return ret;
 }
 
 static int __rvin_try_format(struct rvin_dev *vin,
-u32 which,
-struct v4l2_pix_format *pix,
-struct rvin_source_fmt *source)
+u32 which, struct v4l2_pix_format *pix)
 {
u32 walign;
int ret;
@@ -225,7 +219,7 @@ static int __rvin_try_format(struct rvin_dev *vin,
pix->sizeimage = 0;
 
/* Limit to source capabilities */
-   ret = __rvin_try_format_source(vin, which, pix, source);
+   ret = __rvin_try_format_source(vin, which, pix);
if (ret)
return ret;
 
@@ -234,7 +228,6 @@ static int __rvin_try_format(struct rvin_dev *vin,
case V4L2_FIELD_BOTTOM:
case V4L2_FIELD_ALTERNATE:
pix->height /= 2;
-   source->height /= 2;
break;
case V4L2_FIELD_NONE:
case V4L2_FIELD_INTERLACED_TB:
@@ -286,30 +279,23 @@ static int rvin_try_fmt_vid_cap(struct file *file, void 
*priv,
struct v4l2_format *f)
 {
struct rvin_dev *vin = video_drvdata(file);
-   struct rvin_source_fmt source;
 
-   return __rvin_try_format(vin, V4L2_SUBDEV_FORMAT_TRY, &f-

[PATCH v7 18/25] rcar-vin: prepare for media controller mode initialization

2017-11-10 Thread Niklas Söderlund
When running in media controller mode a media pad is needed, register
one. Also set the media bus format to CSI-2.

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

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 071116eec284ba5f..1b3572c8b6691a07 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
+ */
+
 static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
 {
struct rvin_dev *vin = notifier_to_vin(notifier);
@@ -238,6 +242,20 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
return 0;
 }
 
+/* 
-
+ * Group async notifier
+ */
+
+static int rvin_group_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(&vin->vdev.entity, 1, &vin->pad);
+}
+
 /* 
-
  * Platform Device Driver
  */
@@ -326,8 +344,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_group_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 2789887efe2f3251..2d92b9dd0aed6cc9 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -103,6 +103,8 @@ struct rvin_info {
  * @notifier:  V4L2 asynchronous subdevs notifier
  * @digital:   entity in the DT for local digital subdevice
  *
+ * @pad:   pad for media controller
+ *
  * @lock:  protects @queue
  * @queue: vb2 buffers queue
  *
@@ -132,6 +134,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;
 
-- 
2.15.0



[PATCH v7 21/25] rcar-vin: parse Gen3 OF and setup media graph

2017-11-10 Thread Niklas Söderlund
Parse the VIN Gen3 OF graph and register all CSI-2 devices in the VIN
group common media device. Once all CSI-2 subdevices are added to the
common media device create links between them.

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. The first rcar-vin instance parses OF and
finds all other VIN and CSI-2 nodes which are part of the graph. It
stores a bit mask of all VIN instances found and handles to all CSI-2
nodes.

The bit mask is used to figure out when all VIN instances have been
probed. Once the last VIN instance is probed this is detected and this
instance registers all CSI-2 subdevices in its private async notifier.
Once the .complete() callback of this notifier is called it creates the
media controller links between all entities in the graph.

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

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index e204eb3db77c1d2b..78a9766eb7114959 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -405,10 +405,269 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
  * Group async notifier
  */
 
-static int rvin_group_init(struct rvin_dev *vin)
+/* group lock should be held when calling this function */
+static int rvin_group_add_link(struct rvin_dev *vin,
+  struct media_entity *source,
+  unsigned int source_idx,
+  struct media_entity *sink,
+  unsigned int sink_idx,
+  u32 flags)
+{
+   struct media_pad *source_pad, *sink_pad;
+   int ret = 0;
+
+   source_pad = &source->pads[source_idx];
+   sink_pad = &sink->pads[sink_idx];
+
+   if (!media_entity_find_link(source_pad, sink_pad))
+   ret = media_create_pad_link(source, source_idx,
+   sink, sink_idx, flags);
+
+   if (ret)
+   vin_err(vin, "Error adding link from %s to %s\n",
+   source->name, sink->name);
+
+   return ret;
+}
+
+static int rvin_group_update_links(struct rvin_dev *vin)
+{
+   struct media_entity *source, *sink;
+   struct rvin_dev *master;
+   unsigned int i, n, idx, csi;
+   int ret = 0;
+
+   mutex_lock(&vin->group->lock);
+
+   for (n = 0; n < RCAR_VIN_NUM; n++) {
+
+   /* Check that VIN is part of the group */
+   if (!vin->group->vin[n])
+   continue;
+
+   /* Check that subgroup master is part of the group */
+   master = vin->group->vin[n < 4 ? 0 : 4];
+   if (!master)
+   continue;
+
+   for (i = 0; i < vin->info->num_chsels; i++) {
+   csi = vin->info->chsels[n][i].csi;
+
+   /* If the CSI-2 is out of bounds it's a noop, skip */
+   if (csi >= RVIN_CSI_MAX)
+   continue;
+
+   /* Check that CSI-2 are part of the group */
+   if (!vin->group->csi[csi].subdev)
+   continue;
+
+   source = &vin->group->csi[csi].subdev->entity;
+   sink = &vin->group->vin[n]->vdev.entity;
+   idx = vin->info->chsels[n][i].chan + 1;
+
+   ret = rvin_group_add_link(vin, source, idx, sink, 0,
+ 0);
+   if (ret)
+   goto out;
+   }
+   }
+out:
+   mutex_unlock(&vin->group->lock);
+
+   return ret;
+}
+
+static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
 {
+   struct rvin_dev *vin = notifier_to_vin(notifier);
int ret;
 
+   ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
+   if (ret) {
+   vin_err(vin, "Failed to register subdev nodes\n");
+   return ret;
+   }
+
+   return rvin_group_update_links(vin);
+}
+
+static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
+struct v4l2_subdev *subdev,
+struct v4l2_async_subdev *asd)
+{
+   struct rvin_dev *vin = notifier_to_vin(notifier);
+   struct rvin_graph_entity *csi = to_rvin_graph_entity(asd);
+
+   mutex_lock(&vin->group-&

[PATCH v7 15/25] rcar-vin: add flag to switch to media controller mode

2017-11-10 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 
---
 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 fa76f494ec0c4bd2..071116eec284ba5f 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -244,18 +244,21 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 
 static const struct rvin_info rcar_info_h1 = {
.chip = RCAR_H1,
+   .use_mc = false,
.max_width = 2048,
.max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_m1 = {
.chip = RCAR_M1,
+   .use_mc = false,
.max_width = 2048,
.max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_gen2 = {
.chip = RCAR_GEN2,
+   .use_mc = false,
.max_width = 2048,
.max_height = 2048,
 };
@@ -349,7 +352,8 @@ static int rcar_vin_remove(struct platform_device *pdev)
v4l2_async_notifier_cleanup(&vin->notifier);
 
/* Checks internaly if handlers have been init or not */
-   v4l2_ctrl_handler_free(&vin->ctrl_handler);
+   if (!vin->info->use_mc)
+   v4l2_ctrl_handler_free(&vin->ctrl_handler);
 
rvin_v4l2_unregister(vin);
 
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 8a7c51724a90786c..de269764b00a2fa1 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -77,12 +77,14 @@ struct rvin_graph_entity {
 /**
  * struct rvin_info - Information about the particular VIN implementation
  * @chip:  type of VIN chip
+ * @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 chip_id chip;
+   bool use_mc;
 
unsigned int max_width;
unsigned int max_height;
-- 
2.15.0



[PATCH v7 13/25] rcar-vin: enable Gen3 hardware configuration

2017-11-10 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 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 94 --
 drivers/media/platform/rcar-vin/rcar-vin.h |  1 +
 2 files changed, 64 insertions(+), 31 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 9362e7dba5e3ba95..c4f8e81e88c99e28 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,13 @@
 #define VNDMR2_FTEV(1 << 17)
 #define VNDMR2_VLV(n)  ((n & 0xf) << 12)
 
+/* Video n CSI2 Interface Mode Register (Gen3) */
+#define VNCSI_IFMD_DES2(1 << 27)
+#define VNCSI_IFMD_DES1(1 << 26)
+#define VNCSI_IFMD_DES0(1 << 25)
+#define VNCSI_IFMD_CSI_CHSEL(n) ((n & 0xf) << 0)
+#define VNCSI_IFMD_CSI_CHSEL_MASK 0xf
+
 struct rvin_buffer {
struct vb2_v4l2_buffer vb;
struct list_head list;
@@ -514,28 +527,10 @@ static void rvin_set_coeff(struct rvin_dev *vin, unsigned 
short xs)
rvin_write(vin, p_set->coeff_set[23], VNC8C_REG);
 }
 
-static void rvin_crop_scale_comp(struct rvin_dev *vin)
+static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin)
 {
u32 xs, ys;
 
-   /* Set Start/End Pixel/Line Pre-Clip */
-   rvin_write(vin, vin->crop.left, VNSPPRC_REG);
-   rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
-   switch (vin->format.field) {
-   case V4L2_FIELD_INTERLACED:
-   case V4L2_FIELD_INTERLACED_TB:
-   case V4L2_FIELD_INTERLACED_BT:
-   rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG);
-   rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1,
-  VNELPRC_REG);
-   break;
-   default:
-   rvin_write(vin, vin->crop.top, VNSLPRC_REG);
-   rvin_write(vin, vin->crop.top + vin->crop.height - 1,
-  VNELPRC_REG);
-  

[PATCH v7 16/25] rcar-vin: break out format alignment and checking

2017-11-10 Thread Niklas Söderlund
Part of the format alignment and checking can be shared with the Gen3
format handling. Break that part out to its own function. While doing
this clean up the checking and add more checks.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 98 +++--
 1 file changed, 51 insertions(+), 47 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index f7e04601007edb64..c9a3fe21dea4ce5d 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -86,6 +86,56 @@ 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 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);
+   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;
+   default:
+   pix->field = V4L2_FIELD_NONE;
+   break;
+   }
+
+   /* Check that colorspace is reasonable, if not keep current */
+   if (!pix->colorspace || pix->colorspace >= 0xff)
+   pix->colorspace = vin->format.colorspace;
+
+   /* 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(&pix->width, 2, vin->info->max_width, walign,
+ &pix->height, 4, vin->info->max_height, 2, 0);
+
+   pix->bytesperline = rvin_format_bytesperline(pix);
+   pix->sizeimage = rvin_format_sizeimage(pix);
+
+   if (vin->info->chip == RCAR_M1 &&
+   pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
+   vin_err(vin, "pixel format XBGR32 not supported on M1\n");
+   return -EINVAL;
+   }
+
+   vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n",
+   pix->width, pix->height, pix->bytesperline, pix->sizeimage);
+
+   return 0;
+}
+
 /* 
-
  * V4L2
  */
@@ -191,64 +241,18 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
 static int __rvin_try_format(struct rvin_dev *vin,
 u32 which, struct v4l2_pix_format *pix)
 {
-   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",
-   pix->pixelformat, RVIN_DEFAULT_FORMAT);
-   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);
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;
-   default:
-   pix->field = V4L2_FIELD_NONE;
-   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(&pix->width, 2, vin->info->max_width, walign,
- &pix->height, 4, vin->info->max_height, 2, 0);
-
-   pix->bytesperline = max_t(u32, pix->bytesperline,
- rvin_format_bytesperline(pix));
-   pix->sizeimage = max_t(u32, pix->sizeimage,
-  rvin_format_sizeimage(pix));
-
-   if (vin->info->chip == RCAR_M1 &&
-   pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
-   vin_err(vin, "pixel format XBGR32 not

[PATCH v7 20/25] rcar-vin: add chsel information to rvin_info

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

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-vin.h | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index a9bd570d6635fd47..41c81b8d9fb8e851 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -35,6 +35,9 @@
 /* Max number on VIN instances that can be in a system */
 #define RCAR_VIN_NUM 8
 
+/* Max number of CHSEL values for any Gen3 SoC */
+#define RCAR_CHSEL_MAX 6
+
 enum chip_id {
RCAR_H1,
RCAR_M1,
@@ -91,6 +94,22 @@ struct rvin_graph_entity {
 
 struct rvin_group;
 
+/** struct rvin_group_chsel - Map a CSI-2 receiver and channel to a CHSEL value
+ * @csi:   VIN internal number for CSI-2 device
+ * @chan:  Output channel of the CSI-2 receiver. Each R-Car CSI-2
+ * receiver has four output channels facing the VIN
+ * devices, each channel can carry one CSI-2 Virtual
+ * Channel (VC) and there are no correlation between
+ * output channel number and CSI-2 VC. It's up to the
+ * CSI-2 receiver driver to configure which VC is
+ * outputted on which channel, the VIN devices only
+ * cares about output channels.
+ */
+struct rvin_group_chsel {
+   enum rvin_csi_id csi;
+   unsigned int chan;
+};
+
 /**
  * struct rvin_info - Information about the particular VIN implementation
  * @chip:  type of VIN chip
@@ -98,6 +117,9 @@ struct rvin_group;
  *
  * max_width:  max input width the VIN supports
  * max_height: max input height the VIN supports
+ *
+ * num_chsels: number of possible chsel values for this VIN
+ * chsels: routing table VIN <-> CSI-2 for the chsel values
  */
 struct rvin_info {
enum chip_id chip;
@@ -105,6 +127,9 @@ struct rvin_info {
 
unsigned int max_width;
unsigned int max_height;
+
+   unsigned int num_chsels;
+   struct rvin_group_chsel chsels[RCAR_VIN_NUM][RCAR_CHSEL_MAX];
 };
 
 /**
-- 
2.15.0



[PATCH v7 07/25] rcar-vin: all Gen2 boards can scale simplify logic

2017-11-10 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 
---
 drivers/media/platform/rcar-vin/rcar-dma.c  |  8 
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 22 ++
 drivers/media/platform/rcar-vin/rcar-vin.h  |  2 --
 3 files changed, 10 insertions(+), 22 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index b71259701d2da20f..daf01bb32b5fc3c2 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 f501da9df48c288b..02b081d2d8826e90 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, &format);
if (ret < 0 && ret != -ENOIOCTLCMD)
@@ -191,6 +195,9 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
source->width = pix->width;
source->height = pix->height;
 
+   pix->width = width;
+   pix->height = height;
+
vin_dbg(vin, "Source resolution: %ux%u\n", source->width,
source->height);
 
@@ -204,13 +211,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 +251,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 +269,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 e41dc3bff7fdc649..80f38b89ed8d9992 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -177,8 +177,6 @@ int rvin_reset_format(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.15.0



[PATCH v7 09/25] rcar-vin: do not allow changing scaling and composing while streaming

2017-11-10 Thread Niklas Söderlund
It is possible on Gen2 to change the registers controlling composing and
scaling while the stream is running. It is however not a good idea to do
so and could result in trouble. There are also no good reasons to allow
this, remove immediate reflection in hardware registers from
vidioc_s_selection and only configure scaling and composing when the
stream starts.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-dma.c  | 2 +-
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 ---
 drivers/media/platform/rcar-vin/rcar-vin.h  | 3 ---
 3 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index daf01bb32b5fc3c2..b478eda84a27bf09 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -514,7 +514,7 @@ 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(struct rvin_dev *vin)
 {
u32 xs, ys;
 
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 25f2386cb67447f2..b3c23634e9dbe095 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -436,9 +436,6 @@ static int rvin_s_selection(struct file *file, void *fh,
return -EINVAL;
}
 
-   /* HW supports modifying configuration while running */
-   rvin_crop_scale_comp(vin);
-
return 0;
 }
 
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 80f38b89ed8d9992..111dd8a1974253af 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -176,7 +176,4 @@ int rvin_reset_format(struct rvin_dev *vin);
 
 const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat);
 
-/* Cropping, composing and scaling */
-void rvin_crop_scale_comp(struct rvin_dev *vin);
-
 #endif
-- 
2.15.0



[PATCH v7 02/25] rcar-vin: register the video device at probe time

2017-11-10 Thread Niklas Söderlund
The driver registers the video device from the async complete callback
and unregistered in the async unbind callback. This creates problems if
if the subdevice is bound, unbound and later rebound. The second time
video_register_device() is called it fails:

   kobject (eb3be918): tried to init an initialized object, something is 
seriously wrong.

To prevent this register the video device at probe time and don't allow
user-space to open the video device if the subdevice is not bound yet.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 124 +++-
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  47 ++-
 drivers/media/platform/rcar-vin/rcar-vin.h  |   5 +-
 3 files changed, 95 insertions(+), 81 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 108d776f32651b27..856df3e407c05d97 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -46,54 +46,18 @@ static int rvin_find_pad(struct v4l2_subdev *sd, int 
direction)
return -EINVAL;
 }
 
-static bool rvin_mbus_supported(struct rvin_graph_entity *entity)
-{
-   struct v4l2_subdev *sd = entity->subdev;
-   struct v4l2_subdev_mbus_code_enum code = {
-   .which = V4L2_SUBDEV_FORMAT_ACTIVE,
-   };
-
-   code.index = 0;
-   code.pad = entity->source_pad;
-   while (!v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code)) {
-   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;
-   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)) {
-   vin_err(vin, "Unsupported media bus format for %s\n",
-   vin->digital->subdev->name);
-   return -EINVAL;
-   }
-
-   vin_dbg(vin, "Found media bus format for %s: %d\n",
-   vin->digital->subdev->name, vin->digital->code);
-
ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
if (ret < 0) {
vin_err(vin, "Failed to register subdev nodes\n");
return ret;
}
 
-   return rvin_v4l2_probe(vin);
+   return 0;
 }
 
 static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier,
@@ -103,8 +67,15 @@ 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);
+
+   mutex_lock(&vin->lock);
+
+   vin->vdev.ctrl_handler = NULL;
+   v4l2_ctrl_handler_free(&vin->ctrl_handler);
+
vin->digital->subdev = NULL;
+
+   mutex_unlock(&vin->lock);
 }
 
 static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier,
@@ -112,12 +83,14 @@ static int rvin_digital_notify_bound(struct 
v4l2_async_notifier *notifier,
 struct v4l2_async_subdev *asd)
 {
struct rvin_dev *vin = notifier_to_vin(notifier);
+   struct v4l2_subdev_mbus_code_enum code = {
+   .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+   };
int ret;
 
v4l2_set_subdev_hostdata(subdev, vin);
 
/* Find source and sink pad of remote subdevice */
-
ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);
if (ret < 0)
return ret;
@@ -126,21 +99,82 @@ static int rvin_digital_notify_bound(struct 
v4l2_async_notifier *notifier,
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 = vin->digital->source_pad;
+   while (!vin->digital->code &&
+  !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
+   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:
+   vin->digital->code = code.code;
+   vin_dbg(vin, "Found med

[PATCH v7 04/25] rcar-vin: move max width and height information to chip information

2017-11-10 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 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 6 ++
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 6 ++
 drivers/media/platform/rcar-vin/rcar-vin.h  | 6 ++
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index e90e5d014e074d64..cb761057459caa3f 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -244,14 +244,20 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 
 static const struct rvin_info rcar_info_h1 = {
.chip = RCAR_H1,
+   .max_width = 2048,
+   .max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_m1 = {
.chip = RCAR_M1,
+   .max_width = 2048,
+   .max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_gen2 = {
.chip = RCAR_GEN2,
+   .max_width = 2048,
+   .max_height = 2048,
 };
 
 static const struct of_device_id rvin_of_id_table[] = {
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index be00f4431493eb0a..76c0b8fa8602d08d 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(&pix->width, 2, RVIN_MAX_WIDTH, walign,
- &pix->height, 4, RVIN_MAX_HEIGHT, 2, 0);
+   v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign,
+ &pix->height, 4, vin->info->max_height, 2, 0);
 
pix->bytesperline = max_t(u32, pix->bytesperline,
  rvin_format_bytesperline(pix));
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index ab240eb4aad9176c..e41dc3bff7fdc649 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -91,9 +91,15 @@ struct rvin_graph_entity {
 /**
  * struct rvin_info - Information about the particular VIN implementation
  * @chip:  type of VIN chip
+ *
+ * max_width:  max input width the VIN supports
+ * max_height: max input height the VIN supports
  */
 struct rvin_info {
enum chip_id chip;
+
+   unsigned int max_width;
+   unsigned int max_height;
 };
 
 /**
-- 
2.15.0



[PATCH v7 08/25] rcar-vin: do not reset crop and compose when setting format

2017-11-10 Thread Niklas Söderlund
It was a bad idea to reset the crop and compose settings when a new
format is set. This would overwrite any crop/compose set by s_select and
cause unexpected behaviors, remove it. Also fold the reset helper in to
the only remaining caller.

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

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 02b081d2d8826e90..25f2386cb67447f2 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -90,17 +90,6 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix)
  * 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;
-}
-
 int rvin_reset_format(struct rvin_dev *vin)
 {
struct v4l2_subdev_format fmt = {
@@ -147,7 +136,13 @@ int rvin_reset_format(struct rvin_dev *vin)
break;
}
 
-   rvin_reset_crop_compose(vin);
+   vin->crop.top = vin->crop.left = 0;
+   vin->crop.width = mf->width;
+   vin->crop.height = mf->height;
+
+   vin->compose.top = vin->compose.left = 0;
+   vin->compose.width = mf->width;
+   vin->compose.height = mf->height;
 
vin->format.bytesperline = rvin_format_bytesperline(&vin->format);
vin->format.sizeimage = rvin_format_sizeimage(&vin->format);
@@ -317,8 +312,6 @@ static int rvin_s_fmt_vid_cap(struct file *file, void *priv,
 
vin->format = f->fmt.pix;
 
-   rvin_reset_crop_compose(vin);
-
return 0;
 }
 
-- 
2.15.0



[PATCH v7 06/25] rcar-vin: move functions regarding scaling

2017-11-10 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 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 806 +++--
 1 file changed, 405 insertions(+), 401 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 23fdff7a7370842e..b71259701d2da20f 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -138,305 +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, &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:
-   if (vin->continuous) {
-   vnmc = VNMC_IM_ODD_EVEN;
-   progressive = true;
-   } else {
-   vnmc = VNMC_IM_ODD;
-   }
-   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;
-
-   

[PATCH v7 03/25] rcar-vin: move chip information to own struct

2017-11-10 Thread Niklas Söderlund
When Gen3 support is added to the driver more than chip ID will be
different for the different SoCs. To avoid a lot of if statements in the
code create a struct chip_info to store this information.

And while we are at it 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 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 54 ++---
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  3 +-
 drivers/media/platform/rcar-vin/rcar-vin.h  | 12 +--
 3 files changed, 53 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 856df3e407c05d97..e90e5d014e074d64 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -242,21 +242,53 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
  * Platform Device Driver
  */
 
+static const struct rvin_info rcar_info_h1 = {
+   .chip = RCAR_H1,
+};
+
+static const struct rvin_info rcar_info_m1 = {
+   .chip = RCAR_M1,
+};
+
+static const struct rvin_info rcar_info_gen2 = {
+   .chip = RCAR_GEN2,
+};
+
 static const struct of_device_id rvin_of_id_table[] = {
-   { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
-   { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
-   { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
-   { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
-   { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
-   { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
-   { .compatible = "renesas,rcar-gen2-vin", .data = (void *)RCAR_GEN2 },
+   {
+   .compatible = "renesas,vin-r8a7778",
+   .data = &rcar_info_m1,
+   },
+   {
+   .compatible = "renesas,vin-r8a7779",
+   .data = &rcar_info_h1,
+   },
+   {
+   .compatible = "renesas,vin-r8a7790",
+   .data = &rcar_info_gen2,
+   },
+   {
+   .compatible = "renesas,vin-r8a7791",
+   .data = &rcar_info_gen2,
+   },
+   {
+   .compatible = "renesas,vin-r8a7793",
+   .data = &rcar_info_gen2,
+   },
+   {
+   .compatible = "renesas,vin-r8a7794",
+   .data = &rcar_info_gen2,
+   },
+   {
+   .compatible = "renesas,rcar-gen2-vin",
+   .data = &rcar_info_gen2,
+   },
{ },
 };
 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;
@@ -265,12 +297,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), &pdev->dev);
-   if (!match)
-   return -ENODEV;
-
vin->dev = &pdev->dev;
-   vin->chip = (enum chip_id)match->data;
+   vin->info = of_device_get_match_data(&pdev->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 33dd0ec0b82e57dc..be00f4431493eb0a 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->chip == RCAR_M1 &&
+   pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
vin_err(vin, "pixel format XBGR32 not supported on M1\n");
return -EINVAL;
}
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index ab48cdf09889982e..ab240eb4aad9176c 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -88,11 +88,19 @@ struct rvin_graph_entity {
unsigned int sink_pad;
 };
 
+/**
+ * struct rvin_info - Information about the particular VIN implementation
+ * @chip:  type of VIN chip
+ */
+struct rvin_info {
+   enum chip_id chip;
+};
+
 /**
  * struct rvin_dev - Renesas VIN device stru

[PATCH v7 01/25] rcar-vin: add Gen3 devicetree bindings documentation

2017-11-10 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 
---
 .../devicetree/bindings/media/rcar_vin.txt | 116 ++---
 1 file changed, 104 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt 
b/Documentation/devicetree/bindings/media/rcar_vin.txt
index 6e4ef8caf759e5d3..df1abd0fb20386f8 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 to a CSI-2 receiver.
 
  - compatible: Must be one or more of the following
- "renesas,vin-r8a7795" for the R8A7795 device
@@ -28,21 +32,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:
  - 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:
+
+Gen3 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.
 
+- renesas,id - ID number of the VIN, VINx in the documentation.
+- ports
+- port0 - sub-node describing a single endpoint connected to the VIN
+  from external SoC pins described in video-interfaces.txt[1]. Only
+  the first one will be considered as each VIN interface has at most
+  one set of SoC external input pins.
+- port1 - 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.
 
-Device node example

+- Endpoint 0 - sub-node describing the endpoint which is CSI20
+- Endpoint 1 - sub-node describing the endpoint which is CSI21
+- Endpoint 2 - sub-node describing the endpoint which is CSI40
+- Endpoint 3 - sub-node describing the endpoint which is CSI41
 
-   aliases {
-  vin0 = &vin0;
-   };
+Device node example Gen2
+
+
+aliases {
+vin0 = &vin0;
+};
 
 vin0: vin@0xe6ef {
 compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin";
@@ -52,8 +73,8 @@ Device node example
 status = "disabled";
 };
 
-Board setup example (vin1 composite video input)
-
+Board setup example Gen2 (vin1 composite video input)
+-
 
 &i2c2   {
 status = "ok";
@@ -92,6 +113,77 @@ Board setup example (vin1 composite video input)
 };
 };
 
+Device node example Gen3
+
+
+vin0: video@e6ef {
+compatible = "renesas,vin-r8a7795";
+reg = <0 0xe6ef 0 0x1000>;
+interrupts = ;
+clocks = <&cpg CPG_MOD 811>;
+power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+resets = <&cpg 811>;
+renesas,id = <0>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@1 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+reg = <1>;
+
+vin0csi20: endpoint@0 {
+reg = <0>;
+remote-endpoi

[PATCH v7 14/25] rcar-vin: add function to manipulate Gen3 CHSEL value

2017-11-10 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 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 25 +
 drivers/media/platform/rcar-vin/rcar-vin.h |  2 ++
 2 files changed, 27 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index c4f8e81e88c99e28..463c656b9878be52 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 
 
@@ -1228,3 +1229,27 @@ int rvin_dma_probe(struct rvin_dev *vin, int irq)
 
return ret;
 }
+
+/* 
-
+ * Gen3 CHSEL manipulation
+ */
+
+void rvin_set_chsel(struct rvin_dev *vin, u8 chsel)
+{
+   u32 ifmd, vnmc;
+
+   pm_runtime_get_sync(vin->dev);
+
+   /* Make register writes take effect immediately */
+   vnmc = rvin_read(vin, VNMC_REG) & ~VNMC_VUP;
+   rvin_write(vin, vnmc, VNMC_REG);
+
+   ifmd = VNCSI_IFMD_DES2 | VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0 |
+   VNCSI_IFMD_CSI_CHSEL(chsel);
+
+   rvin_write(vin, ifmd, VNCSI_IFMD_REG);
+
+   vin_dbg(vin, "Set IFMD 0x%x\n", ifmd);
+
+   pm_runtime_put(vin->dev);
+}
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 1f761518a6cc60b8..8a7c51724a90786c 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -164,4 +164,6 @@ int rvin_reset_format(struct rvin_dev *vin);
 
 const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat);
 
+void rvin_set_chsel(struct rvin_dev *vin, u8 chsel);
+
 #endif
-- 
2.15.0



[PATCH v7 05/25] rcar-vin: change name of video device

2017-11-10 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: Kieran Bingham 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

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



[PATCH v7 17/25] rcar-vin: use different v4l2 operations in media controller mode

2017-11-10 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 the running without directly
interacting with the source subdevice.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-dma.c  |   3 +-
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 153 +++-
 drivers/media/platform/rcar-vin/rcar-vin.h  |   1 +
 3 files changed, 154 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 463c656b9878be52..fe1319eb4c5df02d 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -628,7 +628,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, &std)) {
+   if (!vin->info->use_mc &&
+   !v4l2_subdev_call(vin_to_source(vin), video, g_std, &std)) {
if (std & V4L2_STD_525_60)
vnmc = VNMC_IM_FULL | VNMC_FOC;
}
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index c9a3fe21dea4ce5d..11064dd7dcbb53c7 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -23,6 +23,9 @@
 #include "rcar-vin.h"
 
 #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV
+#define RVIN_DEFAULT_WIDTH 800
+#define RVIN_DEFAULT_HEIGHT600
+#define RVIN_DEFAULT_COLORSPACEV4L2_COLORSPACE_SRGB
 
 /* 
-
  * Format Conversions
@@ -671,6 +674,84 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = {
.vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
 };
 
+/* 
-
+ * V4L2 Media Controller
+ */
+
+static int __rvin_mc_try_format(struct rvin_dev *vin,
+   struct v4l2_pix_format *pix)
+{
+   /* Keep current field if no specific one is asked for */
+   if (pix->field == V4L2_FIELD_ANY)
+   pix->field = vin->format.field;
+
+   return 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);
+
+   return __rvin_mc_try_format(vin, &f->fmt.pix);
+}
+
+static int rvin_mc_s_fmt_vid_cap(struct file *file, void *priv,
+struct v4l2_format *f)
+{
+   struct rvin_dev *vin = video_drvdata(file);
+   int ret;
+
+   if (vb2_is_busy(&vin->queue))
+   return -EBUSY;
+
+   ret = __rvin_mc_try_format(vin, &f->fmt.pix);
+   if (ret)
+   return ret;
+
+   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   

[PATCH] v4l: async: use the v4l2_dev from the root notifier when matching sub-devices

2017-11-15 Thread Niklas Söderlund
When matching and registering a sub-device from a sub-notifier use the
v4l2_device from the root parent notifier. Using the v4l2_dev stored in
the sub-notifier itself is incorrect as it might not be set.

This can be demonstrated by unbinding and rebinding the adv748x driver
and observing that it fails to probe due to the check !v4l2_dev in
v4l2_device_register_subdev().

# echo 4-0070 > /sys/bus/i2c/drivers/adv748x/unbind
# echo 4-0070 > /sys/bus/i2c/drivers/adv748x/bind
adv748x 4-0070: chip found @ 0xe0 revision 2143
adv748x 4-0070: Failed to probe TXA
adv748x: probe of 4-0070 failed with error -22

Looking at the commit which adds sub-notifiers to V4L2 it looks like
this is the intended behavior of the original commit. Whit this fix the
adv748x can be re-bound and still function properly.

Fixes: 2cab00bb076b9f0e ("media: v4l: async: Allow binding notifiers to 
sub-devices")
Signed-off-by: Niklas Söderlund 
---
 drivers/media/v4l2-core/v4l2-async.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-async.c 
b/drivers/media/v4l2-core/v4l2-async.c
index a7c3464976f24361..e5acfab470a5ee6b 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -558,8 +558,7 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
if (!asd)
continue;
 
-   ret = v4l2_async_match_notify(notifier, notifier->v4l2_dev, sd,
- asd);
+   ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
if (ret)
goto err_unbind;
 
-- 
2.15.0



Re: [PATCH v11 2/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver

2017-11-15 Thread Niklas Söderlund
Hi,

I just noticed I made a small mistake in this patch, see bellow. I will 
send out a new version in a few days with this fix included but I don't 
want to spam the list too much so I give it a few more days if there is 
any other feedback.

On 2017-11-11 01:25:26 +0100, Niklas Söderlund wrote:
> A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver
> supports the rcar-vin driver on R-Car Gen3 SoCs where separate CSI-2
> hardware blocks are connected between the video sources and the video
> grabbers (VIN).
> 
> Driver is based on a prototype by Koji Matsuoka in the Renesas BSP.
> 
> Signed-off-by: Niklas Söderlund 
> ---
>  drivers/media/platform/rcar-vin/Kconfig |  12 +
>  drivers/media/platform/rcar-vin/Makefile|   1 +
>  drivers/media/platform/rcar-vin/rcar-csi2.c | 896 
> 
>  3 files changed, 909 insertions(+)
>  create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c
> 
> diff --git a/drivers/media/platform/rcar-vin/Kconfig 
> b/drivers/media/platform/rcar-vin/Kconfig
> index af4c98b44d2e22cb..6875f30c1ae42631 100644
> --- a/drivers/media/platform/rcar-vin/Kconfig
> +++ b/drivers/media/platform/rcar-vin/Kconfig
> @@ -1,3 +1,15 @@
> +config VIDEO_RCAR_CSI2
> + tristate "R-Car MIPI CSI-2 Receiver"
> + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
> + depends on ARCH_RENESAS || COMPILE_TEST
> + select V4L2_FWNODE
> + ---help---
> +   Support for Renesas R-Car MIPI CSI-2 receiver.
> +   Supports R-Car Gen3 SoCs.
> +
> +   To compile this driver as a module, choose M here: the
> +   module will be called rcar-csi2.
> +
>  config VIDEO_RCAR_VIN
>   tristate "R-Car Video Input (VIN) Driver"
>   depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && 
> MEDIA_CONTROLLER
> diff --git a/drivers/media/platform/rcar-vin/Makefile 
> b/drivers/media/platform/rcar-vin/Makefile
> index 48c5632c21dc060b..5ab803d3e7c1aa57 100644
> --- a/drivers/media/platform/rcar-vin/Makefile
> +++ b/drivers/media/platform/rcar-vin/Makefile
> @@ -1,3 +1,4 @@
>  rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o
>  
> +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o
>  obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o
> diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
> b/drivers/media/platform/rcar-vin/rcar-csi2.c
> new file mode 100644
> index ..4202c60b4d0aa7f7
> --- /dev/null
> +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
> @@ -0,0 +1,896 @@
> +/*
> + * Driver for Renesas R-Car MIPI CSI-2 Receiver
> + *
> + * Copyright (C) 2017 Renesas Electronics Corp.
> + *
> + * This program is free software; you can redistribute  it and/or modify it
> + * under  the terms of  the GNU General  Public License as published by the
> + * Free Software Foundation;  either version 2 of the  License, or (at your
> + * option) any later version.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +/* Register offsets and bits */
> +
> +/* Control Timing Select */
> +#define TREF_REG 0x00
> +#define TREF_TREFBIT(0)
> +
> +/* Software Reset */
> +#define SRST_REG 0x04
> +#define SRST_SRSTBIT(0)
> +
> +/* PHY Operation Control */
> +#define PHYCNT_REG   0x08
> +#define PHYCNT_SHUTDOWNZ BIT(17)
> +#define PHYCNT_RSTZ  BIT(16)
> +#define PHYCNT_ENABLECLK BIT(4)
> +#define PHYCNT_ENABLE_3  BIT(3)
> +#define PHYCNT_ENABLE_2  BIT(2)
> +#define PHYCNT_ENABLE_1  BIT(1)
> +#define PHYCNT_ENABLE_0  BIT(0)
> +
> +/* Checksum Control */
> +#define CHKSUM_REG   0x0c
> +#define CHKSUM_ECC_ENBIT(1)
> +#define CHKSUM_CRC_ENBIT(0)
> +
> +/*
> + * Channel Data Type Select
> + * VCDT[0-15]:  Channel 1 VCDT[16-31]:  Channel 2
> + * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4
> + */
> +#define VCDT_REG 0x10
> +#define VCDT2_REG0x14
> +#define VCDT_VCDTN_ENBIT(15)
> +#define VCDT_SEL_VC(n)   (((n) & 0x3) << 8)
> +#define VCDT_SEL_DTN_ON  BIT(6)
> +#define VCDT_SEL_DT(n)   (((n) & 0x3f) << 0)
> +
> +/* Frame Data Type Selec

Re: [PATCH 1/3] tools: 8camera-status: Fix write failure mis-allocations

2017-11-15 Thread Niklas Söderlund
Hi Kieran,

Thanks for your patch, applied.

On 2017-11-15 14:38:29 +, Kieran Bingham wrote:
> From: Kieran Bingham 
> 
> Debug prints of the max9271_write call are appearing in the failure counts.
> 
> Fix the 'catcher' so that it is more specific to the failure
> 
> Signed-off-by: Kieran Bingham 
> ---
>  tools/8camera-status | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tools/8camera-status b/tools/8camera-status
> index 234b8a0cab2b..cdfe76ef286f 100755
> --- a/tools/8camera-status
> +++ b/tools/8camera-status
> @@ -21,7 +21,7 @@ BEGIN {
>   print
>  }
>  
> -/max9271_write/ {
> +/max9271_write.*write failed/ {
>   max9271_write_fail++
>   print
>  }
> -- 
> 2.7.4
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH 2/3] tools: 8camera-status: Expand to 9 cameras

2017-11-15 Thread Niklas Söderlund
Hi Kieran,

Thanks for your patch, applied.

On 2017-11-15 14:38:30 +, Kieran Bingham wrote:
> From: Kieran Bingham 
> 
> The 8th camera has an address conflict on the Salvator-X.
> As such it has been moved to the right by one address,
> Include this '9th' camera in the reporting status
> 
> Signed-off-by: Kieran Bingham 
> ---
>  tools/8camera-status | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/8camera-status b/tools/8camera-status
> index cdfe76ef286f..846673578f09 100755
> --- a/tools/8camera-status
> +++ b/tools/8camera-status
> @@ -1,7 +1,7 @@
>  #!/usr/bin/awk -f
>  
>  BEGIN {
> - for (x = 0; x <= 8; x++)
> + for (x = 0; x <= 9; x++)
>   cameras[x] = "-"
>  }
>  
> @@ -67,15 +67,15 @@ function ParseProbe ( line )
>  
>  function PrintCameras()
>  {
> - print ""
> - print "| 1 | 2 | 3 | 4 |  | 5 | 6 | 7 | 8 |"
> - for (x=1; x <= 8; x++) {
> + print ""
> + print "| 1 | 2 | 3 | 4 |  | 5 | 6 | 7 | 8 | 9 |"
> + for (x=1; x <= 9; x++) {
>   printf "| " cameras[x] " "
>   if (x == 4)
>   printf("|  ")
>   }
>   printf "|\n"
> - print ""
> + print "==="
>  }
>  
>  function Summarise() {
> -- 
> 2.7.4
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH 3/3] vin-tests: Refactor mc_get_dev

2017-11-15 Thread Niklas Söderlund
Hi Kieran,

Thanks for your patch.

Unfortunately I experience some problems with this patch.

On 2017-11-15 14:38:31 +, Kieran Bingham wrote:
> From: Kieran Bingham 
> 
> Rather that using shell parsing of each file when looking for a device
> node, use a combination of grep and sed to identify the device.
> 
> This is a remarkable speed optimisation for this code segment.
> 
> Signed-off-by: Kieran Bingham 
> ---
>  scripts/vin-tests.sh | 14 +++---
>  1 file changed, 3 insertions(+), 11 deletions(-)
> 
> diff --git a/scripts/vin-tests.sh b/scripts/vin-tests.sh
> index 7c81aa51c1c5..2e6214bc95e6 100644
> --- a/scripts/vin-tests.sh
> +++ b/scripts/vin-tests.sh
> @@ -99,17 +99,9 @@ mc_get_mdev() {
>  }
>  
>  mc_get_dev() {
> -name=$1
> -mdev=$(mc_get_mdev)
> -
> -for dev in  /sys/class/video4linux/*; do
> -if [[ "$(cat $dev/name)" == "$name" ]]; then
> -basename $dev
> -return 0
> -fi
> -done
> -
> -error "Can't find device"
> +name="$1"
> +grep -l "$name" /sys/class/video4linux/video*/name | \
> + sed 's#.*video4linux\(.*\)/name#/dev\1#g'

The only user of mc_get_dev() is the set-edid utility, which uses it to 
find the adv748x HDMI subdevice (adv748x 4-0070 hdmi) so it can program 
the EDID. I had to change search path above to 
/sys/class/video4linux/*/name to also searches in v4l-subdevX 
directories to find thatt device.

Also the return value changes from 'v4l-subdev42' to /dev/v4l-subdev42' 
so the set-edid tool needed a small update to handle that :-)

I have applied this patch as-is, and then a followup which takes care of 
the above. Out of curiosity, are you working on any new tests which uses 
mc_get_dev()?

>  }
>  
>  mc_log() {
> -- 
> 2.7.4
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH v7 01/25] rcar-vin: add Gen3 devicetree bindings documentation

2017-11-15 Thread Niklas Söderlund
Hi Rob,

Thanks for your feedback, much appreciated!

On 2017-11-15 14:02:26 -0600, Rob Herring wrote:
> On Sat, Nov 11, 2017 at 01:38:11AM +0100, Niklas Söderlund wrote:
> > 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 
> > ---
> >  .../devicetree/bindings/media/rcar_vin.txt | 116 
> > ++---
> >  1 file changed, 104 insertions(+), 12 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt 
> > b/Documentation/devicetree/bindings/media/rcar_vin.txt
> > index 6e4ef8caf759e5d3..df1abd0fb20386f8 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 to a CSI-2 receiver.
> >  
> >   - compatible: Must be one or more of the following
> > - "renesas,vin-r8a7795" for the R8A7795 device
> > @@ -28,21 +32,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:
> >   - 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:
> > +
> > +Gen3 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.
> >  
> > +- renesas,id - ID number of the VIN, VINx in the documentation.
> 
> Why is this needed? We try to avoid indexes unless that's the only way a 
> device is addressed (and then we use reg).

This is unfortunately needed (or something similar) as there is a 
register in one VIN instance which controls the routing of the incoming 
CSI-2 video streams, not only to itself, but also to other VIN instances 
inside the same SoC.

To be more specific I will try to clarify this using the R-Car H3 as an 
example. On the H3 there are 8 instances of the capture hardware (VIN0 - 
VIN7) and 3 instances off CSI-2 receivers (CSI20, CSI40 and CSI41) which 
receives CSI-2 streams, split the possible multiple virtual channels 
(VC) encoded in CSI-2 streams and forwards it to the VIN's.

The problem is that VIN0 and VIN4 are different from the other VIN's, 
they have one register (CHSEL) which controls the limited number of 
possible routes of video streams between a CSI-2 + VC to a specific VIN.  
The CHSEL register in VIN0 controls the routing for VIN0-3 and the one 
in VIN4 controls VIN4-7 (the two subgroups are similar so lets only 
consider VIN0-3).

There are only a handful of routes possible and the kicker is that 
changing the CHSEL value in VIN0, directly reflects all routes for 
VIN0-VIN3 per this table:

CHSEL reg in VIN0:  0 1 2 3 4
Video sent to VIN0: CSI40/VC0 CSI20/VC0 CSI40/VC1 CSI40/VC0 CSI20/VC0
Video sent to VIN1: CSI20/VC0 CSI40/VC1 CSI40/VC0 CSI40/VC1 CSI20/VC1
Video sent to VIN2: CSI20/VC1 CSI40/VC0 CSI20/VC0 CSI40/VC2 CSI20/VC2
Video sent to VIN3: CSI40/VC1 CSI20/VC1 CSI20/VC1 CSI40/VC3 CSI20/VC3

So if CHSEL in VIN0 is set to 2 the following routes are active: VIN0: 
CSI40/VC1, VIN1: CSI40/VC0, VIN2: CSI20/VC0, CSI20/VC1. These routing 
tables are different for most So

Re: [PATCH v11 1/2] media: rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver documentation

2017-11-15 Thread Niklas Söderlund
Hi Rob,

Thanks for your feedback.

On 2017-11-15 13:59:36 -0600, Rob Herring wrote:
> On Sat, Nov 11, 2017 at 01:25:25AM +0100, Niklas Söderlund wrote:
> > Documentation for Renesas R-Car MIPI CSI-2 receiver. The CSI-2 receivers
> > are located between the video sources (CSI-2 transmitters) and the video
> > grabbers (VIN) on Gen3 of Renesas R-Car SoC.
> > 
> > Each CSI-2 device is connected to more then one VIN device which
> > simultaneously can receive video from the same CSI-2 device. Each VIN
> > device can also be connected to more then one CSI-2 device. The routing
> > of which link are used are controlled by the VIN devices. There are only
> > a few possible routes which are set by hardware limitations, which are
> > different for each SoC in the Gen3 family.
> > 
> > To work with the limitations of routing possibilities it is necessary
> > for the DT bindings to describe which VIN device is connected to which
> > CSI-2 device. This is why port 1 needs to to assign reg numbers for each
> > VIN device that be connected to it. To setup and to know which links are
> > valid for each SoC is the responsibility of the VIN driver since the
> > register to configure it belongs to the VIN hardware.
> > 
> > Signed-off-by: Niklas Söderlund 
> > ---
> >  .../bindings/media/renesas,rcar-csi2.txt   | 104 
> > +
> >  MAINTAINERS|   1 +
> >  2 files changed, 105 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt 
> > b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
> > new file mode 100644
> > index ..24705d8997b14a10
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
> > @@ -0,0 +1,104 @@
> > +Renesas R-Car MIPI CSI-2
> > +
> > +
> > +The rcar-csi2 device provides MIPI CSI-2 capabilities for the Renesas R-Car
> > +family of devices. It is to be used in conjunction with the R-Car VIN 
> > module,
> > +which provides the video capture capabilities.
> > +
> > +Mandatory properties
> > +
> > + - compatible: Must be one or more of the following
> > +   - "renesas,r8a7795-csi2" for the R8A7795 device.
> > +   - "renesas,r8a7796-csi2" for the R8A7796 device.
> > +
> > + - reg: the register base and size for the device registers
> > + - interrupts: the interrupt for the device
> > + - clocks: Reference to the parent clock
> > +
> > +The device node shall contain two 'port' child nodes according to the
> > +bindings defined in Documentation/devicetree/bindings/media/
> > +video-interfaces.txt. Port 0 shall connect the node that is the video
> > +source for to the CSI-2. Port 1 shall connect all the R-Car VIN
> > +modules, which can make use of the CSI-2 module.
> > +
> > +- Port 0 - Video source (Mandatory)
> > +   - Endpoint 0 - sub-node describing the endpoint that is the video source
> > +
> > +- Port 1 - VIN instances (Mandatory for all VIN present in the SoC)
> > +   - Endpoint 0 - sub-node describing the endpoint that is VIN0
> > +   - Endpoint 1 - sub-node describing the endpoint that is VIN1
> > +   - Endpoint 2 - sub-node describing the endpoint that is VIN2
> > +   - Endpoint 3 - sub-node describing the endpoint that is VIN3
> > +   - Endpoint 4 - sub-node describing the endpoint that is VIN4
> > +   - Endpoint 5 - sub-node describing the endpoint that is VIN5
> > +   - Endpoint 6 - sub-node describing the endpoint that is VIN6
> > +   - Endpoint 7 - sub-node describing the endpoint that is VIN7
> > +
> > +Example:
> > +
> > +   csi20: csi2@fea8 {
> > +   compatible = "renesas,r8a7796-csi2", "renesas,rcar-gen3-csi2";
> > +   reg = <0 0xfea8 0 0x1>;
> > +   interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
> > +   clocks = <&cpg CPG_MOD 714>;
> > +   power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
> > +   resets = <&cpg 714>;
> > +
> > +   ports {
> > +   #address-cells = <1>;
> > +   #size-cells = <0>;
> > +
> > +   port@0 {
> > +   #address-cells = <1>;
> > +   #size-cells = <0>;
> > +
> > +   

Re: [PATCH] v4l: rcar-vin: Implement V4L2 video node release handler

2017-11-15 Thread Niklas Söderlund
Hi Laurent,

Thanks for your patch.

On 2017-11-16 00:49:07 +0200, Laurent Pinchart wrote:
> The rvin_dev data structure contains driver private data for an instance
> of the VIN. It is allocated dynamically at probe time, and must be freed
> once all users are gone.
> 
> The structure is currently allocated with devm_kzalloc(), which results
> in memory being freed when the device is unbound. If a userspace
> application is currently performing an ioctl call, or just keeps the
> device node open and closes it later, this will lead to accessing freed
> memory.
> 
> Fix the problem by implementing a V4L2 release handler for the video
> node associated with the VIN instance (called when the last user of the
> video node releases it), and freeing memory explicitly from the release
> handler.
> 
> Signed-off-by: Laurent Pinchart 

Acked-by: Niklas Söderlund 

This patch is based on-top of the VIN Gen3 enablement series not yet 
upstream. This is OK for me, just wanted to check that this was the 
intention as to minimize conflicts between the two.

> ---
>  drivers/media/platform/rcar-vin/rcar-core.c | 29 
> +++--
>  drivers/media/platform/rcar-vin/rcar-v4l2.c |  9 -
>  2 files changed, 27 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
> b/drivers/media/platform/rcar-vin/rcar-core.c
> index 495610949457..bd7976efa1fb 100644
> --- a/drivers/media/platform/rcar-vin/rcar-core.c
> +++ b/drivers/media/platform/rcar-vin/rcar-core.c
> @@ -1208,7 +1208,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
>   struct resource *mem;
>   int irq, ret;
>  
> - vin = devm_kzalloc(&pdev->dev, sizeof(*vin), GFP_KERNEL);
> + vin = kzalloc(sizeof(*vin), GFP_KERNEL);
>   if (!vin)
>   return -ENOMEM;
>  
> @@ -1224,20 +1224,26 @@ static int rcar_vin_probe(struct platform_device 
> *pdev)
>   vin->info = attr->data;
>  
>   mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - if (mem == NULL)
> - return -EINVAL;
> + if (mem == NULL) {
> + ret = -EINVAL;
> + goto error_free;
> + }
>  
>   vin->base = devm_ioremap_resource(vin->dev, mem);
> - if (IS_ERR(vin->base))
> - return PTR_ERR(vin->base);
> + if (IS_ERR(vin->base)) {
> + ret = PTR_ERR(vin->base);
> + goto error_free;
> + }
>  
>   irq = platform_get_irq(pdev, 0);
> - if (irq < 0)
> - return irq;
> + if (irq < 0) {
> + ret = irq;
> + goto error_free;
> + }
>  
>   ret = rvin_dma_probe(vin, irq);
>   if (ret)
> - return ret;
> + goto error_free;
>  
>   platform_set_drvdata(pdev, vin);
>   if (vin->info->use_mc)
> @@ -1245,15 +1251,18 @@ static int rcar_vin_probe(struct platform_device 
> *pdev)
>   else
>   ret = rvin_digital_graph_init(vin);
>   if (ret < 0)
> - goto error;
> + goto error_dma;
>  
>   pm_suspend_ignore_children(&pdev->dev, true);
>   pm_runtime_enable(&pdev->dev);
>  
>   return 0;
> -error:
> +
> +error_dma:
>   rvin_dma_remove(vin);
>   v4l2_async_notifier_cleanup(&vin->notifier);
> +error_free:
> + kfree(vin);
>  
>   return ret;
>  }
> diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
> b/drivers/media/platform/rcar-vin/rcar-v4l2.c
> index 2c14d44950b2..25f1d24c1d2d 100644
> --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
> +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
> @@ -1026,6 +1026,13 @@ static void rvin_notify(struct v4l2_subdev *sd,
>   }
>  }
>  
> +static void rvin_v4l2_release(struct video_device *vdev)
> +{
> + struct rvin_dev *vin = container_of(vdev, struct rvin_dev, vdev);
> +
> + kfree(vin);
> +}
> +
>  int rvin_v4l2_register(struct rvin_dev *vin)
>  {
>   struct video_device *vdev = &vin->vdev;
> @@ -1038,7 +1045,7 @@ int rvin_v4l2_register(struct rvin_dev *vin)
>   vdev->queue = &vin->queue;
>   snprintf(vdev->name, sizeof(vdev->name), "%s %s", KBUILD_MODNAME,
>dev_name(vin->dev));
> - vdev->release = video_device_release_empty;
> + vdev->release = rvin_v4l2_release;
>   vdev->lock = &vin->lock;
>   vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
>   V4L2_CAP_READWRITE;
> -- 
> Regards,
> 
> Laurent Pinchart
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH/RFC 2/2] v4l: rcar-vin: Wait for device access to complete before unplugging

2017-11-16 Thread Niklas Söderlund
Hi Sakari,

On 2017-11-16 14:36:24 +0200, Sakari Ailus wrote:
> On Thu, Nov 16, 2017 at 02:33:49AM +0200, Laurent Pinchart wrote:
> > To avoid races between device access and unplug, call the
> > video_device_unplug() function in the platform driver remove handler.
> > This will unsure that all device access completes before the remove
> > handler proceeds to free resources.
> > 
> > Signed-off-by: Laurent Pinchart 
> > ---
> >  drivers/media/platform/rcar-vin/rcar-core.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
> > b/drivers/media/platform/rcar-vin/rcar-core.c
> > index bd7976efa1fb..c5210f1d09ed 100644
> > --- a/drivers/media/platform/rcar-vin/rcar-core.c
> > +++ b/drivers/media/platform/rcar-vin/rcar-core.c
> > @@ -1273,6 +1273,7 @@ static int rcar_vin_remove(struct platform_device 
> > *pdev)
> >  
> > pm_runtime_disable(&pdev->dev);
> >  
> > +   video_device_unplug(&vin->vdev);
> 
> Does this depend on another patch?

I believe this patch is on top of the R-Car VIN Gen3 enablement series.

> 
> >  
> > if (!vin->info->use_mc) {
> >     v4l2_async_notifier_unregister(&vin->notifier);
> > -- 
> > Regards,
> > 
> > Laurent Pinchart
> > 
> 
> -- 
> Sakari Ailus
> e-mail: sakari.ai...@iki.fi

-- 
Regards,
Niklas Söderlund


[PATCH] rcar-vin: enable support for r8a77970

2017-11-25 Thread Niklas Söderlund
Add the SoC specific information for Renesas r8a77970.

Signed-off-by: Niklas Söderlund 
---
 .../devicetree/bindings/media/rcar_vin.txt |  1 +
 drivers/media/platform/rcar-vin/rcar-core.c| 40 ++
 2 files changed, 41 insertions(+)

Hi,

I plan to include this patch in the next version of the series for Gen3 
support. But to enable who wish to start working with VIN on V3M I
send it out now as a separate patch as the big Gen3 series is waiting 
for -rc1 to be available before being re-posted.

Regards,
Niklas

diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt 
b/Documentation/devicetree/bindings/media/rcar_vin.txt
index 17e0d642320fa90d..276af4b4b47703f6 100644
--- a/Documentation/devicetree/bindings/media/rcar_vin.txt
+++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
@@ -19,6 +19,7 @@ on Gen3 to a CSI-2 receiver.
- "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 compatible device.
 
When compatible with the generic version nodes must list the
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index e042cb12229d23d6..a13bc8325a1d1309 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -1149,6 +1149,42 @@ static const struct rvin_info rcar_info_r8a7796 = {
},
 };
 
+static const struct rvin_info rcar_info_r8a77970 = {
+   .chip = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+
+   .num_chsels = 5,
+   .chsels = {
+   {
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   }, {
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_NC, .chan = 0 },
+   }, {
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 2 },
+   { .csi = RVIN_NC, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 3 },
+   { .csi = RVIN_NC, .chan = 0 },
+   },
+   },
+};
+
 static const struct of_device_id rvin_of_id_table[] = {
{
.compatible = "renesas,vin-r8a7778",
@@ -1186,6 +1222,10 @@ static const struct of_device_id rvin_of_id_table[] = {
.compatible = "renesas,vin-r8a7796",
.data = &rcar_info_r8a7796,
},
+   {
+   .compatible = "renesas,vin-r8a77970",
+   .data = &rcar_info_r8a77970,
+   },
{ },
 };
 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
-- 
2.15.0



[PATCH 0/2] rcar-csi2: enable support for r8a77970

2017-11-25 Thread Niklas Söderlund
Hi,

This series adds Renesas r8a77970 (V3M) support to rcar-csi2. It is 
tested on V3M using the HDMI input connected to the adv748x on the V3M 
extension board. It depends on the series 'rcar-csi2: add Renesas R-Car 
MIPI CSI-2'.  

There are many different types of video sources and pipelines on the V3M 
and this is only tested with one of them as there are other none 
rcar-csi2 related issues in testing all of them. Therefor I do not wish 
to squash these changes into the series it depends on which adds the 
rcar-csi2 driver.

It's my firm belief that this is all that is needed to add CSI-2 support 
on V3M but it would be great if more pipelines where tested before this 
series is picked up. Therefor I post it here so other developers working 
on video capture on V3M can use this for CSI-2 support.

Niklas Söderlund (2):
  rcar-csi2: split Mbps calculation to separate function
  rcar-csi2: enable support for r8a77970

 .../bindings/media/renesas,rcar-csi2.txt   |   1 +
 drivers/media/platform/rcar-vin/rcar-csi2.c| 126 ++---
 2 files changed, 114 insertions(+), 13 deletions(-)

-- 
2.15.0



[PATCH 1/2] rcar-csi2: split Mbps calculation to separate function

2017-11-25 Thread Niklas Söderlund
The calculation of the Mbps to configured the link with needs to be
split out if other configuration procedures on new SoCs are to be able
to reuse the calculation procedure.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-csi2.c | 32 +
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
b/drivers/media/platform/rcar-vin/rcar-csi2.c
index f1363cc58eb74977..9afbd03d2dedf4cb 100644
--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
@@ -348,11 +348,8 @@ static int rcar_csi2_wait_phy_start(struct rcar_csi2 *priv)
return -ETIMEDOUT;
 }
 
-static int rcar_csi2_calc_phypll(struct rcar_csi2 *priv, unsigned int bpp,
-u32 *phypll)
+static int rcar_csi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp)
 {
-
-   const struct phypll_hsfreqrange *hsfreq;
struct media_pad *pad, *source_pad;
struct v4l2_subdev *source = NULL;
struct v4l2_ctrl *ctrl;
@@ -382,19 +379,26 @@ static int rcar_csi2_calc_phypll(struct rcar_csi2 *priv, 
unsigned int bpp,
mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * bpp;
do_div(mbps, priv->lanes * 100);
 
+   return mbps;
+}
+
+static int rcar_csi2_set_phypll(struct rcar_csi2 *priv, unsigned int mbps)
+{
+   const struct phypll_hsfreqrange *hsfreq;
+
for (hsfreq = priv->info->hsfreqrange; hsfreq->mbps != 0; hsfreq++)
if (hsfreq->mbps >= mbps)
break;
 
if (!hsfreq->mbps) {
-   dev_err(priv->dev, "Unsupported PHY speed (%llu Mbps)", mbps);
+   dev_err(priv->dev, "Unsupported PHY speed (%u Mbps)", mbps);
return -ERANGE;
}
 
-   dev_dbg(priv->dev, "PHY HSFREQRANGE requested %llu got %u Mbps\n", mbps,
+   dev_dbg(priv->dev, "PHY HSFREQRANGE requested %u got %u Mbps\n", mbps,
hsfreq->mbps);
 
-   *phypll = PHYPLL_HSFREQRANGE(hsfreq->reg);
+   rcar_csi2_write(priv, PHYPLL_REG, PHYPLL_HSFREQRANGE(hsfreq->reg));
 
return 0;
 }
@@ -402,10 +406,10 @@ static int rcar_csi2_calc_phypll(struct rcar_csi2 *priv, 
unsigned int bpp,
 static int rcar_csi2_start(struct rcar_csi2 *priv)
 {
const struct rcar_csi2_format *format;
-   u32 phycnt, phypll, tmp;
+   u32 phycnt, tmp;
u32 vcdt = 0, vcdt2 = 0;
unsigned int i;
-   int ret;
+   int mbps, ret;
 
dev_dbg(priv->dev, "Input size (%ux%u%c)\n",
priv->mf.width, priv->mf.height,
@@ -447,9 +451,9 @@ static int rcar_csi2_start(struct rcar_csi2 *priv)
return -EINVAL;
}
 
-   ret = rcar_csi2_calc_phypll(priv, format->bpp, &phypll);
-   if (ret)
-   return ret;
+   mbps = rcar_csi2_calc_mbps(priv, format->bpp);
+   if (mbps < 0)
+   return mbps;
 
/* Clear Ultra Low Power interrupt */
if (priv->info->clear_ulps)
@@ -490,7 +494,9 @@ static int rcar_csi2_start(struct rcar_csi2 *priv)
}
 
/* Start */
-   rcar_csi2_write(priv, PHYPLL_REG, phypll);
+   ret = rcar_csi2_set_phypll(priv, mbps);
+   if (ret)
+   return ret;
 
/* Set frequency range if we have it */
if (priv->info->csi0clkfreqrange)
-- 
2.15.0



[PATCH 2/2] rcar-csi2: enable support for r8a77970

2017-11-25 Thread Niklas Söderlund
Enable support for Renesas r8a77970 (V3M) by adding the new SoC specific
setup procedure and device tree binding.

Signed-off-by: Niklas Söderlund 
---
 .../bindings/media/renesas,rcar-csi2.txt   |   1 +
 drivers/media/platform/rcar-vin/rcar-csi2.c| 100 -
 2 files changed, 98 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt 
b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
index 688afd83bf66f8cf..2dd0a20e59d4c294 100644
--- a/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
+++ b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
@@ -10,6 +10,7 @@ Mandatory properties
  - compatible: Must be one or more of the following
- "renesas,r8a7795-csi2" for the R8A7795 device.
- "renesas,r8a7796-csi2" for the R8A7796 device.
+   - "renesas,r8a77970-csi2" for the R8A77970 device.
 
  - reg: the register base and size for the device registers
  - interrupts: the interrupt for the device
diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
b/drivers/media/platform/rcar-vin/rcar-csi2.c
index 9afbd03d2dedf4cb..5345f4b1e30226e9 100644
--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
@@ -118,6 +118,11 @@
 
 /* PHY Test Interface Write Register */
 #define PHTW_REG   0x50
+#define PHTW_DWEN  BIT(24)
+#define PHTW_TESTDIN_DATA(n)   (((n & 0xff)) << 16)
+#define PHTW_CWEN  BIT(8)
+#define PHTW_TESTDIN_CODE(n)   ((n & 0xff))
+
 
 /* PHY Test Interface Clear */
 #define PHTC_REG   0x58
@@ -228,6 +233,55 @@ static const struct phypll_hsfreqrange 
hsfreqrange_m3w_h3es1[] = {
{ .mbps =   0,  .reg = 0x00 },
 };
 
+struct phtw_testdin_data {
+   u16 mbps;
+   u16 reg;
+};
+
+static const struct phtw_testdin_data testdin_data_v3m_e3[] = {
+   { .mbps =   80, .reg = 0x00 },
+   { .mbps =   90, .reg = 0x20 },
+   { .mbps =  100, .reg = 0x40 },
+   { .mbps =  110, .reg = 0x02 },
+   { .mbps =  130, .reg = 0x22 },
+   { .mbps =  140, .reg = 0x42 },
+   { .mbps =  150, .reg = 0x04 },
+   { .mbps =  170, .reg = 0x24 },
+   { .mbps =  180, .reg = 0x44 },
+   { .mbps =  200, .reg = 0x06 },
+   { .mbps =  220, .reg = 0x26 },
+   { .mbps =  240, .reg = 0x46 },
+   { .mbps =  250, .reg = 0x08 },
+   { .mbps =  270, .reg = 0x28 },
+   { .mbps =  300, .reg = 0x0a },
+   { .mbps =  330, .reg = 0x2a },
+   { .mbps =  360, .reg = 0x4a },
+   { .mbps =  400, .reg = 0x0c },
+   { .mbps =  450, .reg = 0x2c },
+   { .mbps =  500, .reg = 0x0e },
+   { .mbps =  550, .reg = 0x2e },
+   { .mbps =  600, .reg = 0x10 },
+   { .mbps =  650, .reg = 0x30 },
+   { .mbps =  700, .reg = 0x12 },
+   { .mbps =  750, .reg = 0x32 },
+   { .mbps =  800, .reg = 0x52 },
+   { .mbps =  850, .reg = 0x72 },
+   { .mbps =  900, .reg = 0x14 },
+   { .mbps =  950, .reg = 0x34 },
+   { .mbps = 1000, .reg = 0x54 },
+   { .mbps = 1050, .reg = 0x74 },
+   { .mbps = 1100, .reg = 0x16 },
+   { .mbps = 1150, .reg = 0x36 },
+   { .mbps = 1200, .reg = 0x56 },
+   { .mbps = 1250, .reg = 0x76 },
+   { .mbps = 1300, .reg = 0x18 },
+   { .mbps = 1350, .reg = 0x38 },
+   { .mbps = 1400, .reg = 0x58 },
+   { .mbps = 1500, .reg = 0x78 },
+   /* guard */
+   { .mbps =   0,  .reg = 0x00 },
+};
+
 /* PHY ESC Error Monitor */
 #define PHEERM_REG 0x74
 
@@ -276,6 +330,7 @@ enum rcar_csi2_pads {
 
 struct rcar_csi2_info {
const struct phypll_hsfreqrange *hsfreqrange;
+   const struct phtw_testdin_data *testdin_data;
unsigned int csi0clkfreqrange;
bool clear_ulps;
bool init_phtw;
@@ -403,6 +458,29 @@ static int rcar_csi2_set_phypll(struct rcar_csi2 *priv, 
unsigned int mbps)
return 0;
 }
 
+static int rcar_csi2_set_phtw(struct rcar_csi2 *priv, unsigned int mbps)
+{
+   const struct phtw_testdin_data *testdin;
+
+   for (testdin = priv->info->testdin_data; testdin->mbps != 0; testdin++)
+   if (testdin->mbps >= mbps)
+   break;
+
+   if (!testdin->mbps) {
+   dev_err(priv->dev, "Unsupported PHY speed (%u Mbps)", mbps);
+   return -ERANGE;
+   }
+
+   dev_dbg(priv->dev, "PHY TESTDIN_DATA requested %u got %u Mbps\n", mbps,
+   testdin->mbps);
+
+   rcar_csi2_write(priv, PHTW_REG,
+   PHTW_DWEN | PHTW_TESTDIN_DATA(testdin->reg) |
+   PHTW_CWEN | PHTW_TESTDIN_CODE(0x44));
+
+   return 0;
+}
+
 static int rcar_csi2_start(struct rcar_csi2 *priv)
 {
const struct rcar_csi2_format *format;
@@ -494,9 +572,17 @@ static int rcar_csi2_start(struct 

[PATCH 3/3] arm64: dts: renesas: eagle: enable VIN

2017-11-25 Thread Niklas Söderlund
Signed-off-by: Niklas Söderlund 
---
 arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 16 
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts 
b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
index 41e3b4521a5aa39e..d3c6bcb82a5176c6 100644
--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
@@ -226,5 +226,21 @@
status = "okay";
 };
 
+&vin0 {
+   status = "okay";
+};
+
+&vin1 {
+   status = "okay";
+};
+
+&vin2 {
+   status = "okay";
+};
+
+&vin3 {
+   status = "okay";
+};
+
 /* FAKRA Overlay */
 #include "eagle-fakra.dtsi"
\ No newline at end of file
-- 
2.15.0



[PATCH 1/3] arm64: dts: renesas: r8a77970: add VIN and CSI-2

2017-11-25 Thread Niklas Söderlund
Define the nodes for CSI40 and VIN0-3.

Signed-off-by: Niklas Söderlund 
---
 arch/arm64/boot/dts/renesas/r8a77970.dtsi | 151 ++
 1 file changed, 151 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi 
b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
index b70649b7acd05c98..505a9a9c0c4f5a68 100644
--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
@@ -624,5 +624,156 @@
#size-cells = <0>;
status = "disabled";
};
+
+   csi40: csi2@feaa {
+   compatible = "renesas,r8a7795-csi2", 
"renesas,rcar-gen3-csi2";
+   reg = <0 0xfeaa 0 0x1>;
+   interrupts = ;
+   clocks = <&cpg CPG_MOD 716>;
+   power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+   resets = <&cpg 716>;
+   status = "disabled";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@1 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   reg = <1>;
+
+   csi40vin0: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <&vin0csi40>;
+   };
+   csi40vin1: endpoint@1 {
+   reg = <1>;
+   remote-endpoint = <&vin1csi40>;
+   };
+   csi40vin2: endpoint@2 {
+   reg = <2>;
+   remote-endpoint = <&vin2csi40>;
+   };
+   csi40vin3: endpoint@3 {
+   reg = <3>;
+   remote-endpoint = <&vin3csi40>;
+   };
+   };
+   };
+   };
+
+   vin0: video@e6ef {
+   compatible = "renesas,vin-r8a7795";
+   reg = <0 0xe6ef 0 0x1000>;
+   interrupts = ;
+   clocks = <&cpg CPG_MOD 811>;
+   power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+   resets = <&cpg 811>;
+   renesas,id = <0>;
+   status = "disabled";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@1 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   reg = <1>;
+
+   vin0csi40: endpoint@2 {
+   reg = <2>;
+   remote-endpoint= <&csi40vin0>;
+   };
+   };
+   };
+   };
+
+   vin1: video@e6ef1000 {
+   compatible = "renesas,vin-r8a7795";
+   reg = <0 0xe6ef1000 0 0x1000>;
+   interrupts = ;
+   clocks = <&cpg CPG_MOD 810>;
+   power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+   resets = <&cpg 810>;
+   renesas,id = <1>;
+   status = "disabled";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@1 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   reg = <1>;
+
+   vin1csi40: endpoint@2 {
+   reg = <2>;
+   remote-endpoint= <&csi40vin1>;
+ 

[PATCH 2/3] arm64: dts: renesas: eagle: expansion: enable and connect CSI40

2017-11-25 Thread Niklas Söderlund
On the extension board CSI40 is connected to the adv7482.

Signed-off-by: Niklas Söderlund 
---
 .../boot/dts/renesas/r8a77970-eagle-expansion.dtsi | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle-expansion.dtsi 
b/arch/arm64/boot/dts/renesas/r8a77970-eagle-expansion.dtsi
index e3dc5c32433014c9..565008595a6ce81b 100644
--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle-expansion.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle-expansion.dtsi
@@ -44,6 +44,22 @@
};
 };
 
+&csi40 {
+   status = "okay";
+
+   ports {
+   port@0 {
+   reg = <0>;
+
+   csi40_in: endpoint {
+   clock-lanes = <0>;
+   data-lanes = <1 2 3 4>;
+   remote-endpoint = <&adv7482_txa>;
+   };
+   };
+   };
+};
+
 &i2c0 {
/* GPIO Expander@27:
 *   IO.0: ROUTE_I2C_ENn
@@ -94,7 +110,7 @@
adv7482_txa: endpoint {
clock-lanes = <0>;
data-lanes = <1 2 3 4>;
-   // remote-endpoint = <&csi40_in>;
+   remote-endpoint = <&csi40_in>;
};
};
};
-- 
2.15.0



[PATCH 0/3] arm64: dts: renesas: r8a77970: connect VIN to CSI40

2017-11-25 Thread Niklas Söderlund
Hi,

This series describes how to connect VIN0-3 to CSI40 and the HDMI input 
of the adv7482 on the expansion board. It is tested on V3M together with 
V3M enablement for VIN and CSI-2 drivers on-top of Kieran's 
renesas-drivers-next-v3m branch [1].

It works and it's possible to program the EDID and capture frame frames.  
Remember to switch SW18 to the off position to route the CSI-2 bus to 
the expansion board instead of the MAX9286 for GMSL input.

1. git://git.kernel.org/pub/scm/linux/kernel/git/kbingham/rcar.git

Niklas Söderlund (3):
  arm64: dts: renesas: r8a77970: add VIN and CSI-2
  arm64: dts: renesas: eagle: expansion: enable and connect CSI40
  arm64: dts: renesas: eagle: enable VIN

 .../boot/dts/renesas/r8a77970-eagle-expansion.dtsi |  18 ++-
 arch/arm64/boot/dts/renesas/r8a77970-eagle.dts |  16 +++
 arch/arm64/boot/dts/renesas/r8a77970.dtsi  | 151 +
 3 files changed, 184 insertions(+), 1 deletion(-)

-- 
2.15.0



Re: [PATCH v2 1/4] dt-bindings: media: rcar_vin: Reverse SoC part number list

2017-11-28 Thread Niklas Söderlund
On 2017-11-16 18:22:48 +, Fabrizio Castro wrote:
> 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 

Acked-by: Niklas Söderlund 

> ---
> v1->v2:
> * new patch triggered by Geert's comment, see the below link for details:
>   https://www.mail-archive.com/linux-media@vger.kernel.org/msg121992.html
> 
>  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 6e4ef8c..98931f5 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.7.4
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH v2 2/4] dt-bindings: media: rcar_vin: add device tree support for r8a774[35]

2017-11-28 Thread Niklas Söderlund
On 2017-11-16 18:22:49 +, Fabrizio Castro wrote:
> 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 

Acked-by: Niklas Söderlund 

> ---
> v1->v2:
> * Fixed double "change" in changelog
> 
>  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 98931f5..ff9697e 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.7.4
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH] media: i2c: adv748x: Restore full DT paths in kernel messages

2017-11-28 Thread Niklas Söderlund
Hi Geert,

Thanks for your patch.

On 2017-11-28 14:01:24 +0100, Geert Uytterhoeven wrote:
> As of_node_full_name() now returns only the basename, the endpoint
> information printed became useless:
> 
> adv748x 4-0070: Endpoint endpoint on port 7
> adv748x 4-0070: Endpoint endpoint on port 8
> adv748x 4-0070: Endpoint endpoint on port 10
> adv748x 4-0070: Endpoint endpoint on port 11
> 
> Restore the old behavior by using "%pOF" instead:
> 
> adv748x 4-0070: Endpoint 
> /soc/i2c@e66d8000/video-receiver@70/port@7/endpoint on port 7
> adv748x 4-0070: Endpoint 
> /soc/i2c@e66d8000/video-receiver@70/port@8/endpoint on port 8
> adv748x 4-0070: Endpoint 
> /soc/i2c@e66d8000/video-receiver@70/port@10/endpoint on port 10
> adv748x 4-0070: Endpoint 
> /soc/i2c@e66d8000/video-receiver@70/port@11/endpoint on port 11
> 
> Fixes: a7e4cfb0a7ca4773 ("of/fdt: only store the device node basename in 
> full_name")
> Signed-off-by: Geert Uytterhoeven 

Reviewed-by: Niklas Söderlund 

> ---
>  drivers/media/i2c/adv748x/adv748x-core.c | 10 --
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/i2c/adv748x/adv748x-core.c 
> b/drivers/media/i2c/adv748x/adv748x-core.c
> index 5ee14f2c27478e3a..c1001db6a172e256 100644
> --- a/drivers/media/i2c/adv748x/adv748x-core.c
> +++ b/drivers/media/i2c/adv748x/adv748x-core.c
> @@ -646,14 +646,12 @@ static int adv748x_parse_dt(struct adv748x_state *state)
>  
>   for_each_endpoint_of_node(state->dev->of_node, ep_np) {
>   of_graph_parse_endpoint(ep_np, &ep);
> - adv_info(state, "Endpoint %s on port %d",
> - of_node_full_name(ep.local_node),
> - ep.port);
> + adv_info(state, "Endpoint %pOF on port %d", ep.local_node,
> +  ep.port);
>  
>   if (ep.port >= ADV748X_PORT_MAX) {
> - adv_err(state, "Invalid endpoint %s on port %d",
> - of_node_full_name(ep.local_node),
> - ep.port);
> +     adv_err(state, "Invalid endpoint %pOF on port %d",
> + ep.local_node, ep.port);
>  
>   continue;
>   }
> -- 
> 2.7.4
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH 0/3] arm64: dts: renesas: r8a77970: connect VIN to CSI40

2017-11-29 Thread Niklas Söderlund
Hi Simon,

On 2017-11-29 10:53:17 +0100, Simon Horman wrote:
> On Sun, Nov 26, 2017 at 01:50:09AM +0100, Niklas Söderlund wrote:
> > Hi,
> > 
> > This series describes how to connect VIN0-3 to CSI40 and the HDMI input 
> > of the adv7482 on the expansion board. It is tested on V3M together with 
> > V3M enablement for VIN and CSI-2 drivers on-top of Kieran's 
> > renesas-drivers-next-v3m branch [1].
> > 
> > It works and it's possible to program the EDID and capture frame frames.  
> > Remember to switch SW18 to the off position to route the CSI-2 bus to 
> > the expansion board instead of the MAX9286 for GMSL input.
> > 
> > 1. git://git.kernel.org/pub/scm/linux/kernel/git/kbingham/rcar.git
> 
> Hi Niklas,
> 
> how do you view the path to upstream of this patch-set?

I think there are a few things that needs to go upstream before this 
set.

- The VIN and CSI-2 Gen3 driver support.
- All or some of the V3M DT patches from renesas-drivers-next-v3m.

I would mark this as deferred as I expect some of the patches in 
renesas-drivers-next-v3m needs more work and therefor this set also 
needs to be updated before it's ready to go upstream.

-- 
Regards,
Niklas Söderlund


[PATCH v12 0/2] rcar-csi2: add Renesas R-Car MIPI CSI-2

2017-11-29 Thread Niklas Söderlund
_HAS_DEVNODE it should never have been set.
- Switched from MEDIA_ENT_F_ATV_DECODER to
  MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER as entity function. I can't
  find a more suitable function, and what the hardware do is to fetch
  video from an external chip and passes it on to a another SoC internal
  IP it's sort of a formatter.
- Break out DT documentation and code in two patches.

Changes since v3:
- Update DT binding documentation with input from Geert Uytterhoeven,
  thanks!

Changes since v2:
- Added media control pads as this is needed by the new rcar-vin driver.
- Update DT bindings after review comments and to add r8a7796 support.
- Add get_fmt handler.
- Fix media bus format error s/YUYV8/UYVY8/

Changes since v1:
- Drop dependency on a pad aware s_stream operation.
- Use the DT bindings format "renesas,-", thanks Geert
  for pointing this out.

Niklas Söderlund (2):
  rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver documentation
  rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver

 .../bindings/media/renesas,rcar-csi2.txt   | 105 +++
 MAINTAINERS|   1 +
 drivers/media/platform/rcar-vin/Kconfig|  12 +
 drivers/media/platform/rcar-vin/Makefile   |   1 +
 drivers/media/platform/rcar-vin/rcar-csi2.c| 898 +
 5 files changed, 1017 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
 create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c

-- 
2.15.0



[PATCH v12 2/2] rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver

2017-11-29 Thread Niklas Söderlund
A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver
supports the rcar-vin driver on R-Car Gen3 SoCs where separate CSI-2
hardware blocks are connected between the video sources and the video
grabbers (VIN).

Driver is based on a prototype by Koji Matsuoka in the Renesas BSP.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/Kconfig |  12 +
 drivers/media/platform/rcar-vin/Makefile|   1 +
 drivers/media/platform/rcar-vin/rcar-csi2.c | 898 
 3 files changed, 911 insertions(+)
 create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c

diff --git a/drivers/media/platform/rcar-vin/Kconfig 
b/drivers/media/platform/rcar-vin/Kconfig
index af4c98b44d2e22cb..6875f30c1ae42631 100644
--- a/drivers/media/platform/rcar-vin/Kconfig
+++ b/drivers/media/platform/rcar-vin/Kconfig
@@ -1,3 +1,15 @@
+config VIDEO_RCAR_CSI2
+   tristate "R-Car MIPI CSI-2 Receiver"
+   depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
+   depends on ARCH_RENESAS || COMPILE_TEST
+   select V4L2_FWNODE
+   ---help---
+ Support for Renesas R-Car MIPI CSI-2 receiver.
+ Supports R-Car Gen3 SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rcar-csi2.
+
 config VIDEO_RCAR_VIN
tristate "R-Car Video Input (VIN) Driver"
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && 
MEDIA_CONTROLLER
diff --git a/drivers/media/platform/rcar-vin/Makefile 
b/drivers/media/platform/rcar-vin/Makefile
index 48c5632c21dc060b..5ab803d3e7c1aa57 100644
--- a/drivers/media/platform/rcar-vin/Makefile
+++ b/drivers/media/platform/rcar-vin/Makefile
@@ -1,3 +1,4 @@
 rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o
 
+obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o
 obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o
diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
b/drivers/media/platform/rcar-vin/rcar-csi2.c
new file mode 100644
index ..30aafcbb7a3642c6
--- /dev/null
+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
@@ -0,0 +1,898 @@
+/*
+ * Driver for Renesas R-Car MIPI CSI-2 Receiver
+ *
+ * Copyright (C) 2017 Renesas Electronics Corp.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Register offsets and bits */
+
+/* Control Timing Select */
+#define TREF_REG   0x00
+#define TREF_TREF  BIT(0)
+
+/* Software Reset */
+#define SRST_REG   0x04
+#define SRST_SRST  BIT(0)
+
+/* PHY Operation Control */
+#define PHYCNT_REG 0x08
+#define PHYCNT_SHUTDOWNZ   BIT(17)
+#define PHYCNT_RSTZBIT(16)
+#define PHYCNT_ENABLECLK   BIT(4)
+#define PHYCNT_ENABLE_3BIT(3)
+#define PHYCNT_ENABLE_2BIT(2)
+#define PHYCNT_ENABLE_1BIT(1)
+#define PHYCNT_ENABLE_0BIT(0)
+
+/* Checksum Control */
+#define CHKSUM_REG 0x0c
+#define CHKSUM_ECC_EN  BIT(1)
+#define CHKSUM_CRC_EN  BIT(0)
+
+/*
+ * Channel Data Type Select
+ * VCDT[0-15]:  Channel 1 VCDT[16-31]:  Channel 2
+ * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4
+ */
+#define VCDT_REG   0x10
+#define VCDT2_REG  0x14
+#define VCDT_VCDTN_EN  BIT(15)
+#define VCDT_SEL_VC(n) (((n) & 0x3) << 8)
+#define VCDT_SEL_DTN_ONBIT(6)
+#define VCDT_SEL_DT(n) (((n) & 0x3f) << 0)
+
+/* Frame Data Type Select */
+#define FRDT_REG   0x18
+
+/* Field Detection Control */
+#define FLD_REG0x1c
+#define FLD_FLD_NUM(n) (((n) & 0xff) << 16)
+#define FLD_FLD_EN4BIT(3)
+#define FLD_FLD_EN3BIT(2)
+#define FLD_FLD_EN2BIT(1)
+#define FLD_FLD_EN BIT(0)
+
+/* Automatic Standby Control */
+#define ASTBY_REG  0x20
+
+/* Long Data Type Setting 0 */
+#define LNGDT0_REG 0x28
+
+/* Long Data Type Setting 1 */
+#define LNGDT1_REG 0x2c
+
+/* Interrupt Enable */
+#define INTEN_REG  0x30
+
+/* Interrupt Source Mask */
+#define INTCLOSE_REG   0x34
+
+/* Interrupt Status Monitor */
+#define INTSTATE_REG   0x38
+#

[PATCH v12 1/2] rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver documentation

2017-11-29 Thread Niklas Söderlund
Documentation for Renesas R-Car MIPI CSI-2 receiver. The CSI-2 receivers
are located between the video sources (CSI-2 transmitters) and the video
grabbers (VIN) on Gen3 of Renesas R-Car SoC.

Each CSI-2 device is connected to more then one VIN device which
simultaneously can receive video from the same CSI-2 device. Each VIN
device can also be connected to more then one CSI-2 device. The routing
of which link are used are controlled by the VIN devices. There are only
a few possible routes which are set by hardware limitations, which are
different for each SoC in the Gen3 family.

To work with the limitations of routing possibilities it is necessary
for the DT bindings to describe which VIN device is connected to which
CSI-2 device. This is why port 1 needs to to assign reg numbers for each
VIN device that be connected to it. To setup and to know which links are
valid for each SoC is the responsibility of the VIN driver since the
register to configure it belongs to the VIN hardware.

Signed-off-by: Niklas Söderlund 
Acked-by: Rob Herring 
---
 .../bindings/media/renesas,rcar-csi2.txt   | 105 +
 MAINTAINERS|   1 +
 2 files changed, 106 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt

diff --git a/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt 
b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
new file mode 100644
index ..688afd83bf66f8cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
@@ -0,0 +1,105 @@
+Renesas R-Car MIPI CSI-2
+
+
+The rcar-csi2 device provides MIPI CSI-2 capabilities for the Renesas R-Car
+family of devices. It is to be used in conjunction with the R-Car VIN module,
+which provides the video capture capabilities.
+
+Mandatory properties
+
+ - compatible: Must be one or more of the following
+   - "renesas,r8a7795-csi2" for the R8A7795 device.
+   - "renesas,r8a7796-csi2" for the R8A7796 device.
+
+ - reg: the register base and size for the device registers
+ - interrupts: the interrupt for the device
+ - clocks: Reference to the parent clock
+
+The device node shall contain two 'port' child nodes according to the
+bindings defined in Documentation/devicetree/bindings/media/
+video-interfaces.txt. Port 0 shall connect the node that is the video
+source for to the CSI-2. Port 1 shall connect all the R-Car VIN
+modules, which can make use of the CSI-2 module.
+
+- Port 0 - Video source (Mandatory)
+   - Endpoint 0 - sub-node describing the endpoint that is the video source
+
+- Port 1 - VIN instances (Mandatory for all VIN present in the SoC)
+   - Endpoint 0 - sub-node describing the endpoint that is VIN0
+   - Endpoint 1 - sub-node describing the endpoint that is VIN1
+   - Endpoint 2 - sub-node describing the endpoint that is VIN2
+   - Endpoint 3 - sub-node describing the endpoint that is VIN3
+   - Endpoint 4 - sub-node describing the endpoint that is VIN4
+   - Endpoint 5 - sub-node describing the endpoint that is VIN5
+   - Endpoint 6 - sub-node describing the endpoint that is VIN6
+   - Endpoint 7 - sub-node describing the endpoint that is VIN7
+
+Example:
+
+   csi20: csi2@fea8 {
+   compatible = "renesas,r8a7796-csi2";
+   reg = <0 0xfea8 0 0x1>;
+   interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+   clocks = <&cpg CPG_MOD 714>;
+   power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+   resets = <&cpg 714>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   reg = <0>;
+
+   csi20_in: endpoint@0 {
+   reg = <0>;
+   clock-lanes = <0>;
+   data-lanes = <1>;
+   remote-endpoint = <&adv7482_txb>;
+   };
+   };
+
+   port@1 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   reg = <1>;
+
+   csi20vin0: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <&vin0csi20>;
+   };
+   csi20vin1: endpoint@1 {
+

[PATCH v8 01/28] rcar-vin: add Gen3 devicetree bindings documentation

2017-11-29 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 
---
 .../devicetree/bindings/media/rcar_vin.txt | 116 ++---
 1 file changed, 104 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt 
b/Documentation/devicetree/bindings/media/rcar_vin.txt
index ff9697ed81396e64..5a95d9668d2c7dfd 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 to a CSI-2 receiver.
 
  - compatible: Must be one or more of the following
- "renesas,vin-r8a7743" for the R8A7743 device
@@ -31,21 +35,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:
  - 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:
+
+Gen3 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.
 
+- renesas,id - ID number of the VIN, VINx in the documentation.
+- ports
+- port0 - sub-node describing a single endpoint connected to the VIN
+  from external SoC pins described in video-interfaces.txt[1]. Only
+  the first one will be considered as each VIN interface has at most
+  one set of SoC external input pins.
+- port1 - 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.
 
-Device node example

+- Endpoint 0 - sub-node describing the endpoint which is CSI20
+- Endpoint 1 - sub-node describing the endpoint which is CSI21
+- Endpoint 2 - sub-node describing the endpoint which is CSI40
+- Endpoint 3 - sub-node describing the endpoint which is CSI41
 
-   aliases {
-  vin0 = &vin0;
-   };
+Device node example Gen2
+
+
+aliases {
+vin0 = &vin0;
+};
 
 vin0: vin@0xe6ef {
 compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin";
@@ -55,8 +76,8 @@ Device node example
 status = "disabled";
 };
 
-Board setup example (vin1 composite video input)
-
+Board setup example Gen2 (vin1 composite video input)
+-
 
 &i2c2   {
 status = "ok";
@@ -95,6 +116,77 @@ Board setup example (vin1 composite video input)
 };
 };
 
+Device node example Gen3
+
+
+vin0: video@e6ef {
+compatible = "renesas,vin-r8a7795";
+reg = <0 0xe6ef 0 0x1000>;
+interrupts = ;
+clocks = <&cpg CPG_MOD 811>;
+power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+resets = <&cpg 811>;
+renesas,id = <0>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@1 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+reg = <1>;
+
+vin0csi20: endpoint@0 {
+reg = <0>;
+remote-endpoi

[PATCH v8 28/28] rcar-vin: enable support for r8a77970

2017-11-29 Thread Niklas Söderlund
Add the SoC specific information for Renesas r8a77970.

Signed-off-by: Niklas Söderlund 
---
 .../devicetree/bindings/media/rcar_vin.txt |  1 +
 drivers/media/platform/rcar-vin/rcar-core.c| 40 ++
 2 files changed, 41 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt 
b/Documentation/devicetree/bindings/media/rcar_vin.txt
index 314743532bbb4523..6b98f8a3398fa493 100644
--- a/Documentation/devicetree/bindings/media/rcar_vin.txt
+++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
@@ -21,6 +21,7 @@ on Gen3 to a CSI-2 receiver.
- "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.
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 62eb89b36fbb2ee1..bbdf36b5c3c8178d 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -1145,6 +1145,42 @@ static const struct rvin_info rcar_info_r8a7796 = {
},
 };
 
+static const struct rvin_info rcar_info_r8a77970 = {
+   .chip = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+
+   .num_chsels = 5,
+   .chsels = {
+   {
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   }, {
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_NC, .chan = 0 },
+   }, {
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 2 },
+   { .csi = RVIN_NC, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 3 },
+   { .csi = RVIN_NC, .chan = 0 },
+   },
+   },
+};
+
 static const struct of_device_id rvin_of_id_table[] = {
{
.compatible = "renesas,vin-r8a7778",
@@ -1182,6 +1218,10 @@ static const struct of_device_id rvin_of_id_table[] = {
.compatible = "renesas,vin-r8a7796",
.data = &rcar_info_r8a7796,
},
+   {
+   .compatible = "renesas,vin-r8a77970",
+   .data = &rcar_info_r8a77970,
+   },
{ },
 };
 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
-- 
2.15.0



[PATCH v8 06/28] rcar-vin: move max width and height information to chip information

2017-11-29 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 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 6 ++
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 6 ++
 drivers/media/platform/rcar-vin/rcar-vin.h  | 6 ++
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 73c1700a409bfd35..03d3cd63e38bee11 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -232,14 +232,20 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 
 static const struct rvin_info rcar_info_h1 = {
.chip = RCAR_H1,
+   .max_width = 2048,
+   .max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_m1 = {
.chip = RCAR_M1,
+   .max_width = 2048,
+   .max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_gen2 = {
.chip = RCAR_GEN2,
+   .max_width = 2048,
+   .max_height = 2048,
 };
 
 static const struct of_device_id rvin_of_id_table[] = {
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index b1caa04921aa23bb..59ec6d3d119590aa 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(&pix->width, 2, RVIN_MAX_WIDTH, walign,
- &pix->height, 4, RVIN_MAX_HEIGHT, 2, 0);
+   v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign,
+ &pix->height, 4, vin->info->max_height, 2, 0);
 
pix->bytesperline = max_t(u32, pix->bytesperline,
  rvin_format_bytesperline(pix));
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 0d3949c8c08c8f63..646f897f5c05ec4e 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -91,9 +91,15 @@ struct rvin_graph_entity {
 /**
  * struct rvin_info - Information about the particular VIN implementation
  * @chip:  type of VIN chip
+ *
+ * max_width:  max input width the VIN supports
+ * max_height: max input height the VIN supports
  */
 struct rvin_info {
enum chip_id chip;
+
+   unsigned int max_width;
+   unsigned int max_height;
 };
 
 /**
-- 
2.15.0



[PATCH v8 24/28] rcar-vin: add link notify for Gen3

2017-11-29 Thread Niklas Söderlund
Add the ability to process media device link change request. 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 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 205 
 1 file changed, 205 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 2081637e493e1941..456f93d60b40fb80 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -27,6 +27,209 @@
 
 #include "rcar-vin.h"
 
+/* 
-
+ * Media Controller link notification
+ */
+
+static unsigned int rvin_group_csi_pad_to_chan(unsigned int pad)
+{
+   /*
+* The companion CSI-2 receiver driver (rcar-csi2) is known
+* and we know it have one source pad (pad 0) and four sink
+* pads (pad 1-4). So to translate a pad on the remote
+* CSI-2 receiver to the VIN internal channel number simply
+* subtract one from the pad number.
+*/
+   return pad - 1;
+}
+
+/* group lock should be held when calling this function */
+static int rvin_group_entity_to_vin_num(struct rvin_group *group,
+   struct media_entity *entity)
+{
+   struct video_device *vdev;
+   int i;
+
+   if (!is_media_entity_v4l2_video_device(entity))
+   return -ENODEV;
+
+   vdev = media_entity_to_video_device(entity);
+
+   for (i = 0; i < RCAR_VIN_NUM; i++) {
+   if (!group->vin[i])
+   continue;
+
+   if (&group->vin[i]->vdev == vdev)
+   return i;
+   }
+
+   return -ENODEV;
+}
+
+/* group lock should be held when calling this function */
+static int rvin_group_entity_to_csi_num(struct rvin_group *group,
+   struct media_entity *entity)
+{
+   struct v4l2_subdev *sd;
+   int i;
+
+   if (!is_media_entity_v4l2_subdev(entity))
+   return -ENODEV;
+
+   sd = media_entity_to_v4l2_subdev(entity);
+
+   for (i = 0; i < RVIN_CSI_MAX; i++)
+   if (group->csi[i].subdev == sd)
+   return i;
+
+   return -ENODEV;
+}
+
+/* group lock should be held when calling this function */
+static void __rvin_group_build_link_list(struct rvin_group *group,
+struct rvin_group_chsel *map,
+int start, int len)
+{
+   struct media_pad *vin_pad, *remote_pad;
+   unsigned int n;
+
+   for (n = 0; n < len; n++) {
+   map[n].csi = -1;
+   map[n].chan = -1;
+
+   if (!group->vin[start + n])
+   continue;
+
+   vin_pad = &group->vin[start + n]->vdev.entity.pads[0];
+
+   remote_pad = media_entity_remote_pad(vin_pad);
+   if (!remote_pad)
+   continue;
+
+   map[n].csi =
+   rvin_group_entity_to_csi_num(group, remote_pad->entity);
+   map[n].chan = rvin_group_csi_pad_to_chan(remote_pad->index);
+   }
+}
+
+/* group lock should be held when calling this function */
+static int __rvin_group_try_get_chsel(struct rvin_group *group,
+ struct rvin_group_chsel *map,
+ int start, int len)
+{
+   const struct rvin_group_chsel *sel;
+   unsigned int i, n;
+   int chsel;
+
+   for (i = 0; i < group->vin[start]->info->num_chsels; i++) {
+   chsel = i;
+   for (n = 0; n < len; n++) {
+
+   /* If the link is not active it's OK */
+   if (map[n].csi == -1)
+   continue;
+
+   /* Check if chsel matches requested link */
+   sel = &group->vin[start]->info->chsels[s

[PATCH v8 25/28] rcar-vin: extend {start,stop}_streaming to work with media controller

2017-11-29 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: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 112 +++--
 1 file changed, 105 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 6c5df13b30d6dd14..8a6674a891aab357 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -1087,15 +1087,115 @@ static void rvin_buffer_queue(struct vb2_buffer *vb)
spin_unlock_irqrestore(&vin->qlock, flags);
 }
 
+static int rvin_set_stream(struct rvin_dev *vin, int on)
+{
+   struct v4l2_subdev_format fmt = {
+   .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+   };
+   struct media_pipeline *pipe;
+   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(&vin->pad);
+   if (!pad)
+   return -EPIPE;
+
+   sd = media_entity_to_v4l2_subdev(pad->entity);
+   if (!sd)
+   return -EPIPE;
+
+   if (!on) {
+   media_pipeline_stop(&vin->vdev.entity);
+   return v4l2_subdev_call(sd, video, s_stream, 0);
+   }
+
+   fmt.pad = pad->index;
+   if (v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt))
+   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->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)
+   return -EPIPE;
+
+   pipe = sd->entity.pipe ? sd->entity.pipe : &vin->vdev.pipe;
+   if (media_pipeline_start(&vin->vdev.entity, pipe))
+   return -EPIPE;
+
+   ret = v4l2_subdev_call(sd, video, s_stream, 1);
+   if (ret == -ENOIOCTLCMD)
+   ret = 0;
+   if (ret)
+   media_pipeline_stop(&vin->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;
int ret;
 
-   sd = vin_to_source(vin);
-   v4l2_subdev_call(sd, video, s_stream, 1);
+   ret = rvin_set_stream(vin, 1);
+   if (ret) {
+   spin_lock_irqsave(&vin->qlock, flags);
+   return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
+   spin_unlock_irqrestore(&vin->qlock, flags);
+   return ret;
+   }
 
spin_lock_irqsave(&vin->qlock, flags);
 
@@ -1104,7 +1204,7 @@ static int rvin_start_streaming(struct vb2_queue *vq, 
unsigned int count)
ret = rvin_capture_start(vin);
if (ret) {
return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
-   v4l2_subdev_call(sd, video, s_stream, 0);
+   rvin_set_stream(vin, 0);
}
 
spin_unlock_irqrestore(&vin->qlock, flags);

[PATCH v8 20/28] rcar-vin: prepare for media controller mode initialization

2017-11-29 Thread Niklas Söderlund
When running in media controller mode a media pad is needed, register
one. Also set the media bus format to CSI-2.

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

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 61f48ecc1ab815ec..45de4079fd835759 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
+ */
+
 static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
 {
struct rvin_dev *vin = notifier_to_vin(notifier);
@@ -226,6 +230,20 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
return 0;
 }
 
+/* 
-
+ * Group async notifier
+ */
+
+static int rvin_group_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(&vin->vdev.entity, 1, &vin->pad);
+}
+
 /* 
-
  * Platform Device Driver
  */
@@ -314,8 +332,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_group_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 fd3cd781be0ab1cf..07d270a976893cdb 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -103,6 +103,8 @@ struct rvin_info {
  * @notifier:  V4L2 asynchronous subdevs notifier
  * @digital:   entity in the DT for local digital subdevice
  *
+ * @pad:   pad for media controller
+ *
  * @lock:  protects @queue
  * @queue: vb2 buffers queue
  *
@@ -132,6 +134,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;
 
-- 
2.15.0



[PATCH v8 19/28] rcar-vin: use different v4l2 operations in media controller mode

2017-11-29 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 the running without directly
interacting with the source subdevice.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-dma.c  |   3 +-
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 155 +++-
 drivers/media/platform/rcar-vin/rcar-vin.h  |   1 +
 3 files changed, 155 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index d2788d8bb9565aaa..6c5df13b30d6dd14 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -628,7 +628,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, &std)) {
+   if (!vin->info->use_mc &&
+   !v4l2_subdev_call(vin_to_source(vin), video, g_std, &std)) {
if (std & V4L2_STD_525_60)
vnmc = VNMC_IM_FULL | VNMC_FOC;
}
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 0ffbf0c16fb7b00e..5fea2856fd61030f 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -23,6 +23,9 @@
 #include "rcar-vin.h"
 
 #define RVIN_DEFAULT_FORMATV4L2_PIX_FMT_YUYV
+#define RVIN_DEFAULT_WIDTH 800
+#define RVIN_DEFAULT_HEIGHT600
+#define RVIN_DEFAULT_COLORSPACEV4L2_COLORSPACE_SRGB
 
 /* 
-
  * Format Conversions
@@ -671,6 +674,84 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = {
.vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
 };
 
+/* 
-
+ * V4L2 Media Controller
+ */
+
+static int __rvin_mc_try_format(struct rvin_dev *vin,
+   struct v4l2_pix_format *pix)
+{
+   /* Keep current field if no specific one is asked for */
+   if (pix->field == V4L2_FIELD_ANY)
+   pix->field = vin->format.field;
+
+   return 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);
+
+   return __rvin_mc_try_format(vin, &f->fmt.pix);
+}
+
+static int rvin_mc_s_fmt_vid_cap(struct file *file, void *priv,
+struct v4l2_format *f)
+{
+   struct rvin_dev *vin = video_drvdata(file);
+   int ret;
+
+   if (vb2_is_busy(&vin->queue))
+   return -EBUSY;
+
+   ret = __rvin_mc_try_format(vin, &f->fmt.pix);
+   if (ret)
+   return ret;
+
+   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   

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

2017-11-29 Thread Niklas Söderlund
Parse the VIN Gen3 OF graph and register all CSI-2 devices in the VIN
group common media device. Once all CSI-2 subdevices are added to the
common media device create links between them.

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. The first rcar-vin instance parses OF and
finds all other VIN and CSI-2 nodes which are part of the graph. It
stores a bit mask of all VIN instances found and handles to all CSI-2
nodes.

The bit mask is used to figure out when all VIN instances have been
probed. Once the last VIN instance is probed this is detected and this
instance registers all CSI-2 subdevices in its private async notifier.
Once the .complete() callback of this notifier is called it register all
video devices and creates the media controller links between all
entities.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 322 +++-
 drivers/media/platform/rcar-vin/rcar-vin.h  |  10 +-
 2 files changed, 327 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index a6713fd61dd87a88..2081637e493e1941 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -86,6 +86,7 @@ static struct rvin_group *__rvin_group_allocate(struct 
rvin_dev *vin)
return NULL;
 
kref_init(&group->refcount);
+   group->notifier = NULL;
rvin_group_data = group;
 
vin_dbg(vin, "%s: alloc group=%p\n", __func__, group);
@@ -392,10 +393,281 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
  * Group async notifier
  */
 
-static int rvin_group_init(struct rvin_dev *vin)
+/* group lock should be held when calling this function */
+static int rvin_group_add_link(struct rvin_dev *vin,
+  struct media_entity *source,
+  unsigned int source_idx,
+  struct media_entity *sink,
+  unsigned int sink_idx,
+  u32 flags)
+{
+   struct media_pad *source_pad, *sink_pad;
+   int ret = 0;
+
+   source_pad = &source->pads[source_idx];
+   sink_pad = &sink->pads[sink_idx];
+
+   if (!media_entity_find_link(source_pad, sink_pad))
+   ret = media_create_pad_link(source, source_idx,
+   sink, sink_idx, flags);
+
+   if (ret)
+   vin_err(vin, "Error adding link from %s to %s\n",
+   source->name, sink->name);
+
+   return ret;
+}
+
+static int rvin_group_update_links(struct rvin_dev *vin)
+{
+   struct media_entity *source, *sink;
+   struct rvin_dev *master;
+   unsigned int i, n, idx, csi;
+   int ret = 0;
+
+   mutex_lock(&vin->group->lock);
+
+   for (n = 0; n < RCAR_VIN_NUM; n++) {
+
+   /* Check that VIN is part of the group */
+   if (!vin->group->vin[n])
+   continue;
+
+   /* Check that subgroup master is part of the group */
+   master = vin->group->vin[n < 4 ? 0 : 4];
+   if (!master)
+   continue;
+
+   for (i = 0; i < vin->info->num_chsels; i++) {
+   csi = vin->info->chsels[n][i].csi;
+
+   /* If the CSI-2 is out of bounds it's a noop, skip */
+   if (csi >= RVIN_CSI_MAX)
+   continue;
+
+   /* Check that CSI-2 are part of the group */
+   if (!vin->group->csi[csi].subdev)
+   continue;
+
+   source = &vin->group->csi[csi].subdev->entity;
+   sink = &vin->group->vin[n]->vdev.entity;
+   idx = vin->info->chsels[n][i].chan + 1;
+
+   ret = rvin_group_add_link(vin, source, idx, sink, 0,
+ 0);
+   if (ret)
+   goto out;
+   }
+   }
+out:
+   mutex_unlock(&vin->group->lock);
+
+   return ret;
+}
+
+static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
 {
+   struct rvin_dev *vin = notifier_to_vin(notifier);
+   unsigned int i;
int ret;
 
+   ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
+   if (ret) {
+   vin_err(vin, "Failed to register subdev nodes\n");
+   return ret;
+   }
+
+   for (i = 0; i < RCAR_VIN_NUM; i++) {
+   if (vin->group->vin[i]) {
+   ret = rvin_v4l2_regi

[PATCH v8 08/28] rcar-vin: move functions regarding scaling

2017-11-29 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 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 806 +++--
 1 file changed, 405 insertions(+), 401 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index d701b52d198243b5..a7cda3922cb74baa 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -138,305 +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, &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:
-   if (vin->continuous) {
-   vnmc = VNMC_IM_ODD_EVEN;
-   progressive = true;
-   } else {
-   vnmc = VNMC_IM_ODD;
-   }
-   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;
-
-   

[PATCH v8 21/28] rcar-vin: add group allocator functions

2017-11-29 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 to each VIN instance to know 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 creates a media device.

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

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 45de4079fd835759..a6713fd61dd87a88 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -20,12 +20,170 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 
 #include "rcar-vin.h"
 
+/* 
-
+ * Gen3 CSI2 Group Allocator
+ */
+
+static int rvin_group_read_id(struct rvin_dev *vin, struct device_node *np)
+{
+   u32 val;
+   int ret;
+
+   ret = of_property_read_u32(np, "renesas,id", &val);
+   if (ret) {
+   vin_err(vin, "%pOF: No renesas,id property found\n", np);
+   return -EINVAL;
+   }
+
+   if (val >= RCAR_VIN_NUM) {
+   vin_err(vin, "%pOF: Invalid renesas,id '%u'\n", np, val);
+   return -EINVAL;
+   }
+
+   return val;
+}
+
+static DEFINE_MUTEX(rvin_group_lock);
+static struct rvin_group *rvin_group_data;
+
+static void rvin_group_release(struct kref *kref)
+{
+   struct rvin_group *group =
+   container_of(kref, struct rvin_group, refcount);
+
+   mutex_lock(&rvin_group_lock);
+
+   media_device_unregister(&group->mdev);
+   media_device_cleanup(&group->mdev);
+
+   rvin_group_data = NULL;
+
+   mutex_unlock(&rvin_group_lock);
+
+   kfree(group);
+}
+
+static struct rvin_group *__rvin_group_allocate(struct rvin_dev *vin)
+{
+   struct rvin_group *group;
+
+   if (rvin_group_data) {
+   group = rvin_group_data;
+   kref_get(&group->refcount);
+   vin_dbg(vin, "%s: get group=%p\n", __func__, group);
+   return group;
+   }
+
+   group = kzalloc(sizeof(*group), GFP_KERNEL);
+   if (!group)
+   return NULL;
+
+   kref_init(&group->refcount);
+   rvin_group_data = group;
+
+   vin_dbg(vin, "%s: alloc group=%p\n", __func__, group);
+   return group;
+}
+
+static int rvin_group_add_vin(struct rvin_dev *vin)
+{
+   int ret;
+
+   ret = rvin_group_read_id(vin, vin->dev->of_node);
+   if (ret < 0)
+   return ret;
+
+   mutex_lock(&vin->group->lock);
+
+   if (vin->group->vin[ret]) {
+   mutex_unlock(&vin->group->lock);
+   vin_err(vin, "VIN number %d already occupied\n", ret);
+   return -EINVAL;
+   }
+
+   vin->group->vin[ret] = vin;
+
+   mutex_unlock(&vin->group->lock);
+
+   vin_dbg(vin, "I'm VIN number %d", ret);
+
+   return 0;
+}
+
+static int rvin_group_allocate(struct rvin_dev *vin)
+{
+   struct rvin_group *group;
+   struct media_device *mdev;
+   int ret;
+
+   mutex_lock(&rvin_group_lock);
+
+   group = __rvin_group_allocate(vin);
+   if (!group) {
+   mutex_unlock(&rvin_group_lock);
+   return -ENOMEM;
+   }
+
+   /* Init group data if it is not already initialized */
+   mdev = &group->mdev;
+   if (!mdev->dev) {
+   mutex_init(&group->lock);
+   mdev->dev = vin->dev;
+
+   strlcpy(mdev->driver_name, "Renesas VIN",
+   sizeof(mdev->driver_name));
+   strlcpy(mdev->model, vin->dev->of_node->name,
+   sizeof(mdev->model));
+
+   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) {
+   vin_err(vin, "Failed to register media device\n");
+   kref_put(&group->refcount, rvin_group_release);
+   mutex_unlock(&rvin_group_lock);
+   return ret;
+   }
+   }
+
+   vin->group = group;
+   vin->v4l2_dev.mdev = mdev;
+
+   ret = rvin_group_add_vin(vin);
+   if (ret) {
+   kref_put(&group->refcount, rvin_group_r

[PATCH v8 17/28] rcar-vin: add flag to switch to media controller mode

2017-11-29 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 
---
 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 7d49904cab9cb2d9..61f48ecc1ab815ec 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -232,18 +232,21 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 
 static const struct rvin_info rcar_info_h1 = {
.chip = RCAR_H1,
+   .use_mc = false,
.max_width = 2048,
.max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_m1 = {
.chip = RCAR_M1,
+   .use_mc = false,
.max_width = 2048,
.max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_gen2 = {
.chip = RCAR_GEN2,
+   .use_mc = false,
.max_width = 2048,
.max_height = 2048,
 };
@@ -338,7 +341,8 @@ static int rcar_vin_remove(struct platform_device *pdev)
v4l2_async_notifier_unregister(&vin->notifier);
v4l2_async_notifier_cleanup(&vin->notifier);
 
-   v4l2_ctrl_handler_free(&vin->ctrl_handler);
+   if (!vin->info->use_mc)
+   v4l2_ctrl_handler_free(&vin->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 7819c760c2c13422..0747873c2b9cb74c 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -77,12 +77,14 @@ struct rvin_graph_entity {
 /**
  * struct rvin_info - Information about the particular VIN implementation
  * @chip:  type of VIN chip
+ * @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 chip_id chip;
+   bool use_mc;
 
unsigned int max_width;
unsigned int max_height;
-- 
2.15.0



[PATCH v8 09/28] rcar-vin: all Gen2 boards can scale simplify logic

2017-11-29 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 
---
 drivers/media/platform/rcar-vin/rcar-dma.c  |  8 
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 22 ++
 drivers/media/platform/rcar-vin/rcar-vin.h  |  2 --
 3 files changed, 10 insertions(+), 22 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index a7cda3922cb74baa..fd14be20a6604d7a 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 19de99133f048960..1c5e7f6d5b963740 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, &format);
if (ret < 0 && ret != -ENOIOCTLCMD)
@@ -191,6 +195,9 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
source->width = pix->width;
source->height = pix->height;
 
+   pix->width = width;
+   pix->height = height;
+
vin_dbg(vin, "Source resolution: %ux%u\n", source->width,
source->height);
 
@@ -204,13 +211,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 +251,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 +269,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 646f897f5c05ec4e..36d0f0cc4ce01a6e 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -176,8 +176,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.15.0



[PATCH v8 27/28] rcar-vin: enable support for r8a7796

2017-11-29 Thread Niklas Söderlund
Add the SoC specific information for Renesas r8a7796.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
---
 .../devicetree/bindings/media/rcar_vin.txt |  1 +
 drivers/media/platform/rcar-vin/rcar-core.c| 64 ++
 2 files changed, 65 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt 
b/Documentation/devicetree/bindings/media/rcar_vin.txt
index 5a95d9668d2c7dfd..314743532bbb4523 100644
--- a/Documentation/devicetree/bindings/media/rcar_vin.txt
+++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
@@ -20,6 +20,7 @@ on Gen3 to a CSI-2 receiver.
- "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,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.
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 9da5aff33fd224f2..62eb89b36fbb2ee1 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -1085,6 +1085,66 @@ static const struct rvin_info rcar_info_r8a7795es1 = {
},
 };
 
+static const struct rvin_info rcar_info_r8a7796 = {
+   .chip = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+
+   .num_chsels = 5,
+   .chsels = {
+   {
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   }, {
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 2 },
+   { .csi = RVIN_CSI20, .chan = 2 },
+   }, {
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_NC, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 3 },
+   { .csi = RVIN_CSI20, .chan = 3 },
+   }, {
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   }, {
+   { .csi = RVIN_NC, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 2 },
+   { .csi = RVIN_CSI20, .chan = 2 },
+   }, {
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_NC, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 3 },
+   { .csi = RVIN_CSI20, .chan = 3 },
+   },
+   },
+};
+
 static const struct of_device_id rvin_of_id_table[] = {
{
.compatible = "renesas,vin-r8a7778",
@@ -1118,6 +1178,10 @@ static const struct of_device_id rvin_of_id_table[] = {
.compatible = "renesas,vin-r8a7795",
.data = &rcar_info_r8a7795,
},
+   {
+   .compatible = "renesas,vin-r8a7796",
+   .data = &rcar_info_r8a7796,
+   },
{ },
 };
 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
-- 
2.15.0



[PATCH v8 22/28] rcar-vin: add chsel information to rvin_info

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

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

diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 5f736a3500b6e10f..41bf24aa8a1a0aed 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -35,6 +35,9 @@
 /* Max number on VIN instances that can be in a system */
 #define RCAR_VIN_NUM 8
 
+/* Max number of CHSEL values for any Gen3 SoC */
+#define RCAR_CHSEL_MAX 6
+
 enum chip_id {
RCAR_H1,
RCAR_M1,
@@ -91,6 +94,22 @@ struct rvin_graph_entity {
 
 struct rvin_group;
 
+/** struct rvin_group_chsel - Map a CSI-2 receiver and channel to a CHSEL value
+ * @csi:   VIN internal number for CSI-2 device
+ * @chan:  Output channel of the CSI-2 receiver. Each R-Car CSI-2
+ * receiver has four output channels facing the VIN
+ * devices, each channel can carry one CSI-2 Virtual
+ * Channel (VC) and there are no correlation between
+ * output channel number and CSI-2 VC. It's up to the
+ * CSI-2 receiver driver to configure which VC is
+ * outputted on which channel, the VIN devices only
+ * cares about output channels.
+ */
+struct rvin_group_chsel {
+   enum rvin_csi_id csi;
+   unsigned int chan;
+};
+
 /**
  * struct rvin_info - Information about the particular VIN implementation
  * @chip:  type of VIN chip
@@ -98,6 +117,9 @@ struct rvin_group;
  *
  * max_width:  max input width the VIN supports
  * max_height: max input height the VIN supports
+ *
+ * num_chsels: number of possible chsel values for this VIN
+ * chsels: routing table VIN <-> CSI-2 for the chsel values
  */
 struct rvin_info {
enum chip_id chip;
@@ -105,6 +127,9 @@ struct rvin_info {
 
unsigned int max_width;
unsigned int max_height;
+
+   unsigned int num_chsels;
+   struct rvin_group_chsel chsels[RCAR_VIN_NUM][RCAR_CHSEL_MAX];
 };
 
 /**
-- 
2.15.0



[PATCH v8 18/28] rcar-vin: break out format alignment and checking

2017-11-29 Thread Niklas Söderlund
Part of the format alignment and checking can be shared with the Gen3
format handling. Break that part out to its own function. While doing
this clean up the checking and add more checks.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 98 +++--
 1 file changed, 51 insertions(+), 47 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 56c5183f55922e1d..0ffbf0c16fb7b00e 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -86,6 +86,56 @@ 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 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);
+   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;
+   default:
+   pix->field = V4L2_FIELD_NONE;
+   break;
+   }
+
+   /* Check that colorspace is reasonable, if not keep current */
+   if (!pix->colorspace || pix->colorspace >= 0xff)
+   pix->colorspace = vin->format.colorspace;
+
+   /* 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(&pix->width, 2, vin->info->max_width, walign,
+ &pix->height, 4, vin->info->max_height, 2, 0);
+
+   pix->bytesperline = rvin_format_bytesperline(pix);
+   pix->sizeimage = rvin_format_sizeimage(pix);
+
+   if (vin->info->chip == RCAR_M1 &&
+   pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
+   vin_err(vin, "pixel format XBGR32 not supported on M1\n");
+   return -EINVAL;
+   }
+
+   vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n",
+   pix->width, pix->height, pix->bytesperline, pix->sizeimage);
+
+   return 0;
+}
+
 /* 
-
  * V4L2
  */
@@ -191,64 +241,18 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
 static int __rvin_try_format(struct rvin_dev *vin,
 u32 which, struct v4l2_pix_format *pix)
 {
-   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",
-   pix->pixelformat, RVIN_DEFAULT_FORMAT);
-   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);
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;
-   default:
-   pix->field = V4L2_FIELD_NONE;
-   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(&pix->width, 2, vin->info->max_width, walign,
- &pix->height, 4, vin->info->max_height, 2, 0);
-
-   pix->bytesperline = max_t(u32, pix->bytesperline,
- rvin_format_bytesperline(pix));
-   pix->sizeimage = max_t(u32, pix->sizeimage,
-  rvin_format_sizeimage(pix));
-
-   if (vin->info->chip == RCAR_M1 &&
-   pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
-   vin_err(vin, "pixel format XBGR32 not

[PATCH v8 26/28] rcar-vin: enable support for r8a7795

2017-11-29 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: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/Kconfig |   2 +-
 drivers/media/platform/rcar-vin/rcar-core.c | 150 
 2 files changed, 151 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 456f93d60b40fb80..9da5aff33fd224f2 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 
@@ -956,6 +957,134 @@ static const struct rvin_info rcar_info_gen2 = {
.max_height = 2048,
 };
 
+static const struct rvin_info rcar_info_r8a7795 = {
+   .chip = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+
+   .num_chsels = 5,
+   .chsels = {
+   {
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 2 },
+   { .csi = RVIN_CSI20, .chan = 2 },
+   }, {
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 3 },
+   { .csi = RVIN_CSI20, .chan = 3 },
+   }, {
+   { .csi = RVIN_CSI41, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI41, .chan = 1 },
+   { .csi = RVIN_CSI41, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI41, .chan = 1 },
+   { .csi = RVIN_CSI41, .chan = 0 },
+   { .csi = RVIN_CSI41, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI41, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI41, .chan = 2 },
+   { .csi = RVIN_CSI20, .chan = 2 },
+   }, {
+   { .csi = RVIN_CSI41, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI41, .chan = 3 },
+   { .csi = RVIN_CSI20, .chan = 3 },
+   },
+   },
+};
+
+static const struct rvin_info rcar_info_r8a7795es1 = {
+   .chip = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+
+   .num_chsels = 6,
+   .chsels = {
+   {
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI21, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI21, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI21, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI21

[PATCH v8 15/28] rcar-vin: enable Gen3 hardware configuration

2017-11-29 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 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 94 --
 drivers/media/platform/rcar-vin/rcar-vin.h |  1 +
 2 files changed, 64 insertions(+), 31 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index d7660f485a2df9e4..ace95d5b543a17e3 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,13 @@
 #define VNDMR2_FTEV(1 << 17)
 #define VNDMR2_VLV(n)  ((n & 0xf) << 12)
 
+/* Video n CSI2 Interface Mode Register (Gen3) */
+#define VNCSI_IFMD_DES2(1 << 27)
+#define VNCSI_IFMD_DES1(1 << 26)
+#define VNCSI_IFMD_DES0(1 << 25)
+#define VNCSI_IFMD_CSI_CHSEL(n) ((n & 0xf) << 0)
+#define VNCSI_IFMD_CSI_CHSEL_MASK 0xf
+
 struct rvin_buffer {
struct vb2_v4l2_buffer vb;
struct list_head list;
@@ -514,28 +527,10 @@ static void rvin_set_coeff(struct rvin_dev *vin, unsigned 
short xs)
rvin_write(vin, p_set->coeff_set[23], VNC8C_REG);
 }
 
-static void rvin_crop_scale_comp(struct rvin_dev *vin)
+static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin)
 {
u32 xs, ys;
 
-   /* Set Start/End Pixel/Line Pre-Clip */
-   rvin_write(vin, vin->crop.left, VNSPPRC_REG);
-   rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
-   switch (vin->format.field) {
-   case V4L2_FIELD_INTERLACED:
-   case V4L2_FIELD_INTERLACED_TB:
-   case V4L2_FIELD_INTERLACED_BT:
-   rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG);
-   rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1,
-  VNELPRC_REG);
-   break;
-   default:
-   rvin_write(vin, vin->crop.top, VNSLPRC_REG);
-   rvin_write(vin, vin->crop.top + vin->crop.height - 1,
-  VNELPRC_REG);
-  

[PATCH v8 05/28] rcar-vin: move chip information to own struct

2017-11-29 Thread Niklas Söderlund
When Gen3 support is added to the driver more than chip ID will be
different for the different SoCs. To avoid a lot of if statements in the
code create a struct chip_info to store this information.

And while we are at it 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 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 54 ++---
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  3 +-
 drivers/media/platform/rcar-vin/rcar-vin.h  | 12 +--
 3 files changed, 53 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 6ab51acd676641ec..73c1700a409bfd35 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -230,21 +230,53 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
  * Platform Device Driver
  */
 
+static const struct rvin_info rcar_info_h1 = {
+   .chip = RCAR_H1,
+};
+
+static const struct rvin_info rcar_info_m1 = {
+   .chip = RCAR_M1,
+};
+
+static const struct rvin_info rcar_info_gen2 = {
+   .chip = RCAR_GEN2,
+};
+
 static const struct of_device_id rvin_of_id_table[] = {
-   { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
-   { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
-   { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
-   { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
-   { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
-   { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
-   { .compatible = "renesas,rcar-gen2-vin", .data = (void *)RCAR_GEN2 },
+   {
+   .compatible = "renesas,vin-r8a7778",
+   .data = &rcar_info_m1,
+   },
+   {
+   .compatible = "renesas,vin-r8a7779",
+   .data = &rcar_info_h1,
+   },
+   {
+   .compatible = "renesas,vin-r8a7790",
+   .data = &rcar_info_gen2,
+   },
+   {
+   .compatible = "renesas,vin-r8a7791",
+   .data = &rcar_info_gen2,
+   },
+   {
+   .compatible = "renesas,vin-r8a7793",
+   .data = &rcar_info_gen2,
+   },
+   {
+   .compatible = "renesas,vin-r8a7794",
+   .data = &rcar_info_gen2,
+   },
+   {
+   .compatible = "renesas,rcar-gen2-vin",
+   .data = &rcar_info_gen2,
+   },
{ },
 };
 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;
@@ -253,12 +285,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), &pdev->dev);
-   if (!match)
-   return -ENODEV;
-
vin->dev = &pdev->dev;
-   vin->chip = (enum chip_id)match->data;
+   vin->info = of_device_get_match_data(&pdev->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..b1caa04921aa23bb 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->chip == RCAR_M1 &&
+   pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
vin_err(vin, "pixel format XBGR32 not supported on M1\n");
return -EINVAL;
}
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 85cb7ec53d2b08b5..0d3949c8c08c8f63 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -88,11 +88,19 @@ struct rvin_graph_entity {
unsigned int sink_pad;
 };
 
+/**
+ * struct rvin_info - Information about the particular VIN implementation
+ * @chip:  type of VIN chip
+ */
+struct rvin_info {
+   enum chip_id chip;
+};
+
 /**
  * struct rvin_dev - Renesas VIN device stru

[PATCH v8 16/28] rcar-vin: add function to manipulate Gen3 chsel value

2017-11-29 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: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 25 +
 drivers/media/platform/rcar-vin/rcar-vin.h |  2 ++
 2 files changed, 27 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index ace95d5b543a17e3..d2788d8bb9565aaa 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 
 
@@ -1228,3 +1229,27 @@ int rvin_dma_register(struct rvin_dev *vin, int irq)
 
return ret;
 }
+
+/* 
-
+ * Gen3 CHSEL manipulation
+ */
+
+void rvin_set_chsel(struct rvin_dev *vin, u8 chsel)
+{
+   u32 ifmd, vnmc;
+
+   pm_runtime_get_sync(vin->dev);
+
+   /* Make register writes take effect immediately */
+   vnmc = rvin_read(vin, VNMC_REG) & ~VNMC_VUP;
+   rvin_write(vin, vnmc, VNMC_REG);
+
+   ifmd = VNCSI_IFMD_DES2 | VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0 |
+   VNCSI_IFMD_CSI_CHSEL(chsel);
+
+   rvin_write(vin, ifmd, VNCSI_IFMD_REG);
+
+   vin_dbg(vin, "Set IFMD 0x%x\n", ifmd);
+
+   pm_runtime_put(vin->dev);
+}
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index a440effe4b86af31..7819c760c2c13422 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -163,4 +163,6 @@ void rvin_v4l2_unregister(struct rvin_dev *vin);
 
 const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat);
 
+void rvin_set_chsel(struct rvin_dev *vin, u8 chsel);
+
 #endif
-- 
2.15.0



[PATCH v8 07/28] rcar-vin: change name of video device

2017-11-29 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: Kieran Bingham 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

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



[PATCH v8 10/28] rcar-vin: do not reset crop and compose when setting format

2017-11-29 Thread Niklas Söderlund
It was a bad idea to reset the crop and compose settings when a new
format is set. This would overwrite any crop/compose set by s_select and
cause unexpected behaviors, remove it. Also fold the reset helper in to
the only remaining caller.

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

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 1c5e7f6d5b963740..254fa1c8770275a5 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -90,17 +90,6 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix)
  * 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 = {
@@ -147,7 +136,13 @@ static int rvin_reset_format(struct rvin_dev *vin)
break;
}
 
-   rvin_reset_crop_compose(vin);
+   vin->crop.top = vin->crop.left = 0;
+   vin->crop.width = mf->width;
+   vin->crop.height = mf->height;
+
+   vin->compose.top = vin->compose.left = 0;
+   vin->compose.width = mf->width;
+   vin->compose.height = mf->height;
 
vin->format.bytesperline = rvin_format_bytesperline(&vin->format);
vin->format.sizeimage = rvin_format_sizeimage(&vin->format);
@@ -317,8 +312,6 @@ static int rvin_s_fmt_vid_cap(struct file *file, void *priv,
 
vin->format = f->fmt.pix;
 
-   rvin_reset_crop_compose(vin);
-
return 0;
 }
 
-- 
2.15.0



[PATCH v8 12/28] rcar-vin: read subdevice format for crop only when needed

2017-11-29 Thread Niklas Söderlund
Instead of caching the subdevice format each time the video device
format is set read it directly when it's needed. As it turns out the
format is only needed when figuring out the max rectangle for cropping.

This simplifies the code and makes it clearer what the source format is
used for.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 88 ++---
 drivers/media/platform/rcar-vin/rcar-vin.h  | 12 
 2 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index d6298c684ab2d731..9cf9ff48ac1e2f4f 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -90,24 +90,30 @@ static u32 rvin_format_sizeimage(struct v4l2_pix_format 
*pix)
  * V4L2
  */
 
-static int rvin_reset_format(struct rvin_dev *vin)
+static int rvin_get_sd_format(struct rvin_dev *vin, struct v4l2_pix_format 
*pix)
 {
struct v4l2_subdev_format fmt = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+   .pad = vin->digital->source_pad,
};
-   struct v4l2_mbus_framefmt *mf = &fmt.format;
int ret;
 
-   fmt.pad = vin->digital->source_pad;
-
ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt);
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(pix, &fmt.format);
+
+   return 0;
+}
+
+static int rvin_reset_format(struct rvin_dev *vin)
+{
+   int ret;
+
+   ret = rvin_get_sd_format(vin, &vin->format);
+   if (ret)
+   return ret;
 
/*
 * If the subdevice uses ALTERNATE field mode and G_STD is
@@ -137,12 +143,12 @@ static int rvin_reset_format(struct rvin_dev *vin)
}
 
vin->crop.top = vin->crop.left = 0;
-   vin->crop.width = mf->width;
-   vin->crop.height = mf->height;
+   vin->crop.width = vin->format.width;
+   vin->crop.height = vin->format.height;
 
vin->compose.top = vin->compose.left = 0;
-   vin->compose.width = mf->width;
-   vin->compose.height = mf->height;
+   vin->compose.width = vin->format.width;
+   vin->compose.height = vin->format.height;
 
vin->format.bytesperline = rvin_format_bytesperline(&vin->format);
vin->format.sizeimage = rvin_format_sizeimage(&vin->format);
@@ -151,9 +157,7 @@ static int rvin_reset_format(struct rvin_dev *vin)
 }
 
 static int __rvin_try_format_source(struct rvin_dev *vin,
-   u32 which,
-   struct v4l2_pix_format *pix,
-   struct rvin_source_fmt *source)
+   u32 which, struct v4l2_pix_format *pix)
 {
struct v4l2_subdev *sd;
struct v4l2_subdev_pad_config *pad_cfg;
@@ -186,25 +190,15 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
v4l2_fill_pix_format(pix, &format.format);
 
pix->field = field;
-
-   source->width = pix->width;
-   source->height = pix->height;
-
pix->width = width;
pix->height = height;
-
-   vin_dbg(vin, "Source resolution: %ux%u\n", source->width,
-   source->height);
-
 done:
v4l2_subdev_free_pad_config(pad_cfg);
return ret;
 }
 
 static int __rvin_try_format(struct rvin_dev *vin,
-u32 which,
-struct v4l2_pix_format *pix,
-struct rvin_source_fmt *source)
+u32 which, struct v4l2_pix_format *pix)
 {
u32 walign;
int ret;
@@ -225,7 +219,7 @@ static int __rvin_try_format(struct rvin_dev *vin,
pix->sizeimage = 0;
 
/* Limit to source capabilities */
-   ret = __rvin_try_format_source(vin, which, pix, source);
+   ret = __rvin_try_format_source(vin, which, pix);
if (ret)
return ret;
 
@@ -234,7 +228,6 @@ static int __rvin_try_format(struct rvin_dev *vin,
case V4L2_FIELD_BOTTOM:
case V4L2_FIELD_ALTERNATE:
pix->height /= 2;
-   source->height /= 2;
break;
case V4L2_FIELD_NONE:
case V4L2_FIELD_INTERLACED_TB:
@@ -286,30 +279,23 @@ static int rvin_try_fmt_vid_cap(struct file *file, void 
*priv,
struct v4l2_format *f)
 {
struct rvin_dev *vin = video_drvdata(file);
-   struct rvin_source_fmt source;
 
-   return __rvin_try_format(vin, V4L2_SUBDEV_FORMAT_TRY, &f-

[PATCH v8 04/28] rcar-vin: move subdevice handling to async callbacks

2017-11-29 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.

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 105 ++--
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  35 --
 2 files changed, 67 insertions(+), 73 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 6d99542ec74b49a7..6ab51acd676641ec 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -46,47 +46,11 @@ static int rvin_find_pad(struct v4l2_subdev *sd, int 
direction)
return -EINVAL;
 }
 
-static bool rvin_mbus_supported(struct rvin_graph_entity *entity)
-{
-   struct v4l2_subdev *sd = entity->subdev;
-   struct v4l2_subdev_mbus_code_enum code = {
-   .which = V4L2_SUBDEV_FORMAT_ACTIVE,
-   };
-
-   code.index = 0;
-   code.pad = entity->source_pad;
-   while (!v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code)) {
-   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;
-   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)) {
-   vin_err(vin, "Unsupported media bus format for %s\n",
-   vin->digital->subdev->name);
-   return -EINVAL;
-   }
-
-   vin_dbg(vin, "Found media bus format for %s: %d\n",
-   vin->digital->subdev->name, vin->digital->code);
-
ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
if (ret < 0) {
vin_err(vin, "Failed to register subdev nodes\n");
@@ -103,8 +67,16 @@ 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);
+
+   mutex_lock(&vin->lock);
+
rvin_v4l2_unregister(vin);
+   v4l2_ctrl_handler_free(&vin->ctrl_handler);
+
+   vin->vdev.ctrl_handler = NULL;
vin->digital->subdev = NULL;
+
+   mutex_unlock(&vin->lock);
 }
 
 static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier,
@@ -112,12 +84,14 @@ static int rvin_digital_notify_bound(struct 
v4l2_async_notifier *notifier,
 struct v4l2_async_subdev *asd)
 {
struct rvin_dev *vin = notifier_to_vin(notifier);
+   struct v4l2_subdev_mbus_code_enum code = {
+   .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+   };
int ret;
 
v4l2_set_subdev_hostdata(subdev, vin);
 
/* Find source and sink pad of remote subdevice */
-
ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);
if (ret < 0)
return ret;
@@ -126,21 +100,74 @@ static int rvin_digital_notify_bound(struct 
v4l2_async_notifier *notifier,
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 = vin->digital->source_pad;
+   while (!vin->digital->code &&
+  !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
+   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:
+   vin->digital->code = code.code;
+   vin_dbg(vin, "Found media bus format for %s: %d\n",
+   subdev->name, vin->digital->code);
+   break;
+   default:
+   break;
+   }
+   }
+
+   if (!vin->digital->cod

[PATCH v8 03/28] rcar-vin: unregister video device on driver removal

2017-11-29 Thread Niklas Söderlund
If the video device was registered by the complete() callback it should
be unregistered when the driver is removed. Protect from printing a
uninitialized video device node name by adding a checking in
rvin_v4l2_unregister() by checking that the video device is registered.

Signed-off-by: Niklas Söderlund 
---
 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 f7a4c21909da6923..6d99542ec74b49a7 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(&pdev->dev);
 
+   rvin_v4l2_unregister(vin);
+
v4l2_async_notifier_unregister(&vin->notifier);
v4l2_async_notifier_cleanup(&vin->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(&vin->vdev))
+   return;
+
v4l2_info(&vin->v4l2_dev, "Removing %s\n",
  video_device_node_name(&vin->vdev));
 
-- 
2.15.0



[PATCH v8 11/28] rcar-vin: do not allow changing scaling and composing while streaming

2017-11-29 Thread Niklas Söderlund
It is possible on Gen2 to change the registers controlling composing and
scaling while the stream is running. It is however not a good idea to do
so and could result in trouble. There are also no good reasons to allow
this, remove immediate reflection in hardware registers from
vidioc_s_selection and only configure scaling and composing when the
stream starts.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-dma.c  | 2 +-
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 3 ---
 drivers/media/platform/rcar-vin/rcar-vin.h  | 3 ---
 3 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index fd14be20a6604d7a..7be5080f742825fb 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -514,7 +514,7 @@ 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(struct rvin_dev *vin)
 {
u32 xs, ys;
 
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 254fa1c8770275a5..d6298c684ab2d731 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -436,9 +436,6 @@ static int rvin_s_selection(struct file *file, void *fh,
return -EINVAL;
}
 
-   /* HW supports modifying configuration while running */
-   rvin_crop_scale_comp(vin);
-
return 0;
 }
 
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 36d0f0cc4ce01a6e..67541b483ee43c52 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -175,7 +175,4 @@ 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_crop_scale_comp(struct rvin_dev *vin);
-
 #endif
-- 
2.15.0



[PATCH v8 00/28] rcar-vin: Add Gen3 with media controller

2017-11-29 Thread Niklas Söderlund
ince v4 (Not posted to ML)
- Updated to the new fwnode functions.
- Moved the registration of the video devices to the async notification
  callback.

* Changes since v3
- Only add neighboring subdevices to the async notifier. Instead of
  parsing the whole OF graph depend on incremental async subnotifier to
  discover the whole pipeline. This is needed to support arbitrarily
  long graphs and support the new ADV7482 prototype driver which Kieran
  is working on.
- Fix warning from lockdep, reported by Kieran.
- Fix commit messages from feedback from Sergei, thanks.
- Fix chip info an OF device ids sorting order, thanks Geert.
- Use subdev->of_node instead of subdev->dev->of_node, thanks Kieran.

* Changes since v2
- Do not try to control the subdevices in the media graph from the rcar-vin
  driver. Have user-space configure to format in the pipeline instead.
- Add link validation before starting the stream.
- Rework on how the subdevices are and the video node behave by defining
  specific V4L2 operations for the MC mode of operation, this simplified
  the driver quit a bit, thanks Laurent!
- Add a new 'renesas,id' DT property which is needed to to be able to
  keep the VIN to CSI-2 routing table inside the driver. Previously this
  information was taken from the CSI-2 DT node which is obviously the
  wrong way to do things. Thanks Laurent for pointing this out.
- Fixed a memory leek in the group allocator function.
- Return -EMLINK instead of -EBUSY if a MC link is not possible given
  the current routing setup.
- Add comments to clarify that the 4 channels from the CSI-2 node is not
  directly related to CSI-2 virtual channels, the CSI-2 node can output
  any VC on any of its output channels.

* Changes since v1
- Remove unneeded casts as pointed out by Geert.
- Fix spelling and DT documentation as pointed out by Geert and Sergei,
  thanks!
- Refresh patch 2/32 with an updated version, thanks Sakari for pointing
  this out.
- Add Sakaris Ack to patch 1/32.
- Rebase on top of v4.9-rc1 instead of v4.9-rc3 to ease integration
  testing together with renesas-drivers tree.


Niklas Söderlund (28):
  rcar-vin: add Gen3 devicetree bindings documentation
  rcar-vin: rename poorly named initialize and cleanup functions
  rcar-vin: unregister video device on driver removal
  rcar-vin: move subdevice handling to async callbacks
  rcar-vin: move chip information to own struct
  rcar-vin: move max width and height information to chip information
  rcar-vin: change name of video device
  rcar-vin: move functions regarding scaling
  rcar-vin: all Gen2 boards can scale simplify logic
  rcar-vin: do not reset crop and compose when setting format
  rcar-vin: do not allow changing scaling and composing while streaming
  rcar-vin: read subdevice format for crop only when needed
  rcar-vin: fix handling of single field frames (top, bottom and
alternate fields)
  rcar-vin: move media bus configuration to struct rvin_info
  rcar-vin: enable Gen3 hardware configuration
  rcar-vin: add function to manipulate Gen3 chsel value
  rcar-vin: add flag to switch to media controller mode
  rcar-vin: break out format alignment and checking
  rcar-vin: use different v4l2 operations in media controller mode
  rcar-vin: prepare for media controller mode initialization
  rcar-vin: add group allocator functions
  rcar-vin: add chsel information to rvin_info
  rcar-vin: parse Gen3 OF and setup media graph
  rcar-vin: add link notify for Gen3
  rcar-vin: extend {start,stop}_streaming to work with media controller
  rcar-vin: enable support for r8a7795
  rcar-vin: enable support for r8a7796
  rcar-vin: enable support for r8a77970

 .../devicetree/bindings/media/rcar_vin.txt |  118 +-
 drivers/media/platform/rcar-vin/Kconfig|2 +-
 drivers/media/platform/rcar-vin/rcar-core.c| 1159 ++--
 drivers/media/platform/rcar-vin/rcar-dma.c |  990 ++---
 drivers/media/platform/rcar-vin/rcar-v4l2.c|  445 +---
 drivers/media/platform/rcar-vin/rcar-vin.h |  131 ++-
 6 files changed, 2143 insertions(+), 702 deletions(-)

-- 
2.15.0



[PATCH v8 13/28] rcar-vin: fix handling of single field frames (top, bottom and alternate fields)

2017-11-29 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. For sources using
this field format instead use the VIN hardware feature of combining the
fields to an interlaced format. This mode of operation was previously
the default behavior and ALTERNATING was only delivered to user-space if
explicitly requested. Allowing this to be explicitly requested was a
mistake and was never properly tested and never worked due to the
constraints put on the field format when it comes to sequence numbers and
timestamps etc.

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 
---
 drivers/media/platform/rcar-vin/rcar-dma.c  | 15 +
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 48 +++--
 2 files changed, 19 insertions(+), 44 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 7be5080f742825fb..e6478088d9464221 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:
if (vin->continuous) {
vnmc = VNMC_IM_ODD_EVEN;
@@ -757,18 +756,6 @@ static int rvin_get_active_slot(struct rvin_dev *vin, u32 
vnms)
return 0;
 }
 
-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;
@@ -941,7 +928,7 @@ static irqreturn_t rvin_irq(int irq, void *data)
goto done;
 
/* Capture frame */
-   vin->queue_buf[slot]->field = rvin_get_active_field(vin, vnms);
+   vin->queue_buf[slot]->field = vin->format.field;
vin->queue_buf[slot]->sequence = sequence;
vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns();
vb2_buffer_done(&vin->queue_buf[slot]->vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 9cf9ff48ac1e2f4f..37fe1f6c646b0ea3 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -102,6 +102,24 @@ static int rvin_get_sd_format(struct rvin_dev *vin, struct 
v4l2_pix_format *pix)
if (ret)
return ret;
 
+   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:
+   break;
+   case V4L2_FIELD_ALTERNATE:
+   /* Use VIN hardware to combine the two fields */
+   fmt.format.field = V4L2_FIELD_INTERLACED;
+   fmt.format.height *= 2;
+   break;
+   default:
+   vin->format.field = V4L2_FIELD_NONE;
+   break;
+   }
+
v4l2_fill_pix_format(pix, &fmt.format);
 
return 0;
@@ -115,33 +133,6 @@ static int rvin_reset_format(struct rvin_dev *vin)
if (ret)
return ret;
 
-   /*
-* 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_INTERLA

[PATCH v8 02/28] rcar-vin: rename poorly named initialize and cleanup functions

2017-11-29 Thread Niklas Söderlund
The functions to initialize and cleanup the hardware and video device
where poorly named from the start. Rename them to better describe there
intended function.

Signed-off-by: Niklas Söderlund 
---
 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 108d776f32651b27..f7a4c21909da6923 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(&vin->notifier);
 
return ret;
@@ -275,7 +275,7 @@ static int rcar_vin_remove(struct platform_device *pdev)
v4l2_async_notifier_unregister(&vin->notifier);
v4l2_async_notifier_cleanup(&vin->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 23fdff7a7370842e..d701b52d198243b5 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -1153,14 +1153,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(&vin->lock);
 
v4l2_device_unregister(&vin->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 = &vin->queue;
int i, ret;
@@ -1208,7 +1208,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(&vin->v4l2_dev, "Removing %s\n",
  video_device_node_name(&vin->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 = &vin->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 5382078143fb3869..85cb7ec53d2b08b5 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);
 
-- 
2.15.0



[PATCH v8 14/28] rcar-vin: move media bus configuration to struct rvin_info

2017-11-29 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_info to show it's not always coupled
to the parallel subdevice.

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

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 03d3cd63e38bee11..7d49904cab9cb2d9 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -101,10 +101,10 @@ static int rvin_digital_notify_bound(struct 
v4l2_async_notifier *notifier,
vin->digital->sink_pad = ret < 0 ? 0 : ret;
 
/* Find compatible subdevices mbus format */
-   vin->digital->code = 0;
+   vin->code = 0;
code.index = 0;
code.pad = vin->digital->source_pad;
-   while (!vin->digital->code &&
+   while (!vin->code &&
   !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
code.index++;
switch (code.code) {
@@ -112,16 +112,16 @@ static int rvin_digital_notify_bound(struct 
v4l2_async_notifier *notifier,
case MEDIA_BUS_FMT_UYVY8_2X8:
case MEDIA_BUS_FMT_UYVY10_2X10:
case MEDIA_BUS_FMT_RGB888_1X24:
-   vin->digital->code = code.code;
+   vin->code = code.code;
vin_dbg(vin, "Found media bus format for %s: %d\n",
-   subdev->name, vin->digital->code);
+   subdev->name, vin->code);
break;
default:
break;
}
}
 
-   if (!vin->digital->code) {
+   if (!vin->code) {
vin_err(vin, "Unsupported media bus format for %s\n",
subdev->name);
return -EINVAL;
@@ -179,16 +179,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 e6478088d9464221..d7660f485a2df9e4 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -633,7 +633,7 @@ static int rvin_setup(struct rvin_dev *vin)
/*
 * Input interface
 */
-   switch (vin->digital->code) {
+   switch (vin->code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
/* BT.601/BT.1358 16bit YCbCr422 */
vnmc |= VNMC_INF_YUV16;
@@ -641,7 +641,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;
@@ -650,7 +650,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;
@@ -662,11 +662,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 

Re: [PATCH/RFT renesas-devel] arm64: dts: ulcb: Enable NFS root

2017-11-30 Thread Niklas Söderlund
Hi Simon,

On 2017-11-30 10:43:55 +0100, Simon Horman wrote:
> On Tue, May 02, 2017 at 11:27:58AM +0200, Geert Uytterhoeven wrote:
> > Hi Simon,
> > 
> > On Tue, May 2, 2017 at 11:24 AM, Simon Horman
> >  wrote:
> > > Enable NFS root on the r8a7795/h3ulcb and r8a7796/m3ulcb
> > > as per:
> > > * commit b2407c566ba29215 ("arm64: dts: r8a7795: enable nfs root on 
> > > Salvator-X board").
> > > * commit 742a9dfb90f0 ("arm64: dts: r8a7796: salvator-x: Enable NFS root")
> > >
> > > Also set ignore_loglevel rw as boot args as is the case for the boards
> > > for the boards for other Renesas ARM/ARM64 based SoCs.
> > 
> > s/for the boards//
> > 
> > > Signed-off-by: Simon Horman 
> > 
> > Reviewed-by: Geert Uytterhoeven 
> > 
> > Gr{oetje,eeting}s,
> 
> Sergei has pointed out that bootargs has seems to have effect on ARM64
> kernels. So I think this patch should be withdrawn and we should consider
> removing bootargs from those ARM64 boards where it is present.
> 

I don't think this is true.

I just added a argument to bootargs to salvator-common.dtsi for some 
hack testing and it took effect. Tested on-top of latest renesas-drivers 
and H3 ES2.0.

>>> DIFF <<<
diff --git a/arch/arm64/boot/dts/renesas/salvator-common.dtsi 
b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
index 7b30044a55367d35..4cb4b44f8be42cb4 100644
--- a/arch/arm64/boot/dts/renesas/salvator-common.dtsi
+++ b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
@@ -42,7 +42,7 @@
};
 
chosen {
-   bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+   bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp 
adv748x.txbvc=1";
stdout-path = "serial0:115200n8";
};
>>> END DIFF <<<

# cat /sys/firmware/devicetree/base/chosen/bootargs
ignore_loglevel rw root=/dev/nfs ip=dhcp adv748x.txbvc=1

And the module parameter had the expected effect on the adv7482x driver.  
Is there another issue here which I'm missing?

-- 
Regards,
Niklas Söderlund


Re: [PATCH v8 23/28] rcar-vin: parse Gen3 OF and setup media graph

2017-11-30 Thread Niklas Söderlund
Hi,

There is one error in this patch. A left over from moving the video 
device registration from probe() to the async callbacks, see bellow. I 
will await further feedback before resending but will include this fix 
in the next version.

On 2017-11-29 20:43:37 +0100, Niklas Söderlund wrote:
> Parse the VIN Gen3 OF graph and register all CSI-2 devices in the VIN
> group common media device. Once all CSI-2 subdevices are added to the
> common media device create links between them.
> 
> 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. The first rcar-vin instance parses OF and
> finds all other VIN and CSI-2 nodes which are part of the graph. It
> stores a bit mask of all VIN instances found and handles to all CSI-2
> nodes.
> 
> The bit mask is used to figure out when all VIN instances have been
> probed. Once the last VIN instance is probed this is detected and this
> instance registers all CSI-2 subdevices in its private async notifier.
> Once the .complete() callback of this notifier is called it register all
> video devices and creates the media controller links between all
> entities.
> 
> Signed-off-by: Niklas Söderlund 
> ---
>  drivers/media/platform/rcar-vin/rcar-core.c | 322 
> +++-
>  drivers/media/platform/rcar-vin/rcar-vin.h  |  10 +-
>  2 files changed, 327 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
> b/drivers/media/platform/rcar-vin/rcar-core.c
> index a6713fd61dd87a88..2081637e493e1941 100644
> --- a/drivers/media/platform/rcar-vin/rcar-core.c
> +++ b/drivers/media/platform/rcar-vin/rcar-core.c
> @@ -86,6 +86,7 @@ static struct rvin_group *__rvin_group_allocate(struct 
> rvin_dev *vin)
>   return NULL;
>  
>   kref_init(&group->refcount);
> + group->notifier = NULL;
>   rvin_group_data = group;
>  
>   vin_dbg(vin, "%s: alloc group=%p\n", __func__, group);
> @@ -392,10 +393,281 @@ static int rvin_digital_graph_init(struct rvin_dev 
> *vin)
>   * Group async notifier
>   */
>  
> -static int rvin_group_init(struct rvin_dev *vin)
> +/* group lock should be held when calling this function */
> +static int rvin_group_add_link(struct rvin_dev *vin,
> +struct media_entity *source,
> +unsigned int source_idx,
> +struct media_entity *sink,
> +unsigned int sink_idx,
> +u32 flags)
> +{
> + struct media_pad *source_pad, *sink_pad;
> + int ret = 0;
> +
> + source_pad = &source->pads[source_idx];
> + sink_pad = &sink->pads[sink_idx];
> +
> + if (!media_entity_find_link(source_pad, sink_pad))
> + ret = media_create_pad_link(source, source_idx,
> + sink, sink_idx, flags);
> +
> + if (ret)
> + vin_err(vin, "Error adding link from %s to %s\n",
> + source->name, sink->name);
> +
> + return ret;
> +}
> +
> +static int rvin_group_update_links(struct rvin_dev *vin)
> +{
> + struct media_entity *source, *sink;
> + struct rvin_dev *master;
> + unsigned int i, n, idx, csi;
> + int ret = 0;
> +
> + mutex_lock(&vin->group->lock);
> +
> + for (n = 0; n < RCAR_VIN_NUM; n++) {
> +
> + /* Check that VIN is part of the group */
> + if (!vin->group->vin[n])
> + continue;
> +
> + /* Check that subgroup master is part of the group */
> + master = vin->group->vin[n < 4 ? 0 : 4];
> + if (!master)
> + continue;
> +
> + for (i = 0; i < vin->info->num_chsels; i++) {
> + csi = vin->info->chsels[n][i].csi;
> +
> + /* If the CSI-2 is out of bounds it's a noop, skip */
> + if (csi >= RVIN_CSI_MAX)
> + continue;
> +
> + /* Check that CSI-2 are part of the group */
> + if (!vin->group->csi[csi].subdev)
> + continue;
> +
> + source = &vin->group->csi[csi].subdev->entity;
> + sink = &vin->group->vin[n]->vdev.entity;
> + idx = vin->info->chsels[n][i].chan + 1;
> +
> + ret = rvin_group_add_link(vin, source, idx, sink, 0,
> + 

Re: [PATCH] rcar-vin: Fix rvin_group_init

2017-11-30 Thread Niklas Söderlund
Hi Kieran,

Thanks for your patch. I will squash this in with the original patch.

This was a left over from moving the video device registration from 
probe() to the async callbacks.

On 2017-11-30 14:59:04 +, Kieran Bingham wrote:
> From: Kieran Bingham 
> 
> rvin_group_init incorrectly calls rvin_group_update_links.
> 
> Repair by removing the call, and simply returning 0;
> 
> Fixes: 3135326aae2c ("rcar-vin: parse Gen3 OF and setup media graph")
> Signed-off-by: Kieran Bingham 
> ---
> Hi Niklas,
> 
> A small fixup for your RCar VIN branch
> 
>  drivers/media/platform/rcar-vin/rcar-core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
> b/drivers/media/platform/rcar-vin/rcar-core.c
> index be2dfe2908e0..924722a0fdfa 100644
> --- a/drivers/media/platform/rcar-vin/rcar-core.c
> +++ b/drivers/media/platform/rcar-vin/rcar-core.c
> @@ -926,7 +926,7 @@ static int rvin_group_init(struct rvin_dev *vin)
>   goto error_vdev;
>   }
>  
> - return rvin_group_update_links(vin);
> + return 0;
>  
>  error_vdev:
>   rvin_v4l2_unregister(vin);
> -- 
> 2.7.4
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH v12 2/2] rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver

2017-12-02 Thread Niklas Söderlund
Hej Sakari,

On 2017-12-01 15:01:36 +0200, Sakari Ailus wrote:
> Hej Niklas,
> 
> Tack för dina nya lappar!

Tack för dina kommentarer.

> 
> On Wed, Nov 29, 2017 at 08:32:35PM +0100, Niklas Söderlund wrote:
> > A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver
> > supports the rcar-vin driver on R-Car Gen3 SoCs where separate CSI-2
> > hardware blocks are connected between the video sources and the video
> > grabbers (VIN).
> > 
> > Driver is based on a prototype by Koji Matsuoka in the Renesas BSP.
> > 
> > Signed-off-by: Niklas Söderlund 
> > Reviewed-by: Hans Verkuil 
> > ---
> >  drivers/media/platform/rcar-vin/Kconfig |  12 +
> >  drivers/media/platform/rcar-vin/Makefile|   1 +
> >  drivers/media/platform/rcar-vin/rcar-csi2.c | 898 
> > 
> >  3 files changed, 911 insertions(+)
> >  create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c
> > 
> > diff --git a/drivers/media/platform/rcar-vin/Kconfig 
> > b/drivers/media/platform/rcar-vin/Kconfig
> > index af4c98b44d2e22cb..6875f30c1ae42631 100644
> > --- a/drivers/media/platform/rcar-vin/Kconfig
> > +++ b/drivers/media/platform/rcar-vin/Kconfig
> > @@ -1,3 +1,15 @@
> > +config VIDEO_RCAR_CSI2
> > +   tristate "R-Car MIPI CSI-2 Receiver"
> > +   depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
> > +   depends on ARCH_RENESAS || COMPILE_TEST
> > +   select V4L2_FWNODE
> > +   ---help---
> > + Support for Renesas R-Car MIPI CSI-2 receiver.
> > + Supports R-Car Gen3 SoCs.
> > +
> > + To compile this driver as a module, choose M here: the
> > + module will be called rcar-csi2.
> > +
> >  config VIDEO_RCAR_VIN
> > tristate "R-Car Video Input (VIN) Driver"
> > depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && 
> > MEDIA_CONTROLLER
> > diff --git a/drivers/media/platform/rcar-vin/Makefile 
> > b/drivers/media/platform/rcar-vin/Makefile
> > index 48c5632c21dc060b..5ab803d3e7c1aa57 100644
> > --- a/drivers/media/platform/rcar-vin/Makefile
> > +++ b/drivers/media/platform/rcar-vin/Makefile
> > @@ -1,3 +1,4 @@
> >  rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o
> >  
> > +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o
> >  obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o
> > diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
> > b/drivers/media/platform/rcar-vin/rcar-csi2.c
> > new file mode 100644
> > index ..30aafcbb7a3642c6
> > --- /dev/null
> > +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
> > @@ -0,0 +1,898 @@
> > +/*
> > + * Driver for Renesas R-Car MIPI CSI-2 Receiver
> > + *
> > + * Copyright (C) 2017 Renesas Electronics Corp.
> > + *
> > + * This program is free software; you can redistribute  it and/or modify it
> > + * under  the terms of  the GNU General  Public License as published by the
> > + * Free Software Foundation;  either version 2 of the  License, or (at your
> > + * option) any later version.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +/* Register offsets and bits */
> > +
> > +/* Control Timing Select */
> > +#define TREF_REG   0x00
> > +#define TREF_TREF  BIT(0)
> > +
> > +/* Software Reset */
> > +#define SRST_REG   0x04
> > +#define SRST_SRST  BIT(0)
> > +
> > +/* PHY Operation Control */
> > +#define PHYCNT_REG 0x08
> > +#define PHYCNT_SHUTDOWNZ   BIT(17)
> > +#define PHYCNT_RSTZBIT(16)
> > +#define PHYCNT_ENABLECLK   BIT(4)
> > +#define PHYCNT_ENABLE_3BIT(3)
> > +#define PHYCNT_ENABLE_2BIT(2)
> > +#define PHYCNT_ENABLE_1BIT(1)
> > +#define PHYCNT_ENABLE_0BIT(0)
> > +
> > +/* Checksum Control */
> > +#define CHKSUM_REG 0x0c
> > +#define CHKSUM_ECC_EN  BIT(1)
> > +#define CHKSUM_CRC_EN  BIT(0)
> > +
> > +/*
> > + * Channel Data Type Select
> > + * VCDT[0-15]:  Channel 1 VCDT[16-31]:  Channel 2
> > + * V

Re: [PATCH v12 2/2] rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver

2017-12-02 Thread Niklas Söderlund
Hej Sakari,

Thanks for your feedback.

On 2017-12-02 16:05:08 +0200, Sakari Ailus wrote:
> Hejssan,
> 
> On Sat, Dec 02, 2017 at 12:08:21PM +0100, Niklas Söderlund wrote:
> ...
> > > > +static int rcar_csi2_parse_dt(struct rcar_csi2 *priv)
> > > > +{
> > > > +   struct device_node *ep;
> > > > +   struct v4l2_fwnode_endpoint v4l2_ep;
> > > > +   int ret;
> > > > +
> > > > +   ep = of_graph_get_endpoint_by_regs(priv->dev->of_node, 0, 0);
> > > > +   if (!ep) {
> > > > +   dev_err(priv->dev, "Not connected to subdevice\n");
> > > > +   return -EINVAL;
> > > > +   }
> > > > +
> > > > +   ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), 
> > > > &v4l2_ep);
> > > > +   if (ret) {
> > > > +   dev_err(priv->dev, "Could not parse v4l2 endpoint\n");
> > > > +   of_node_put(ep);
> > > > +   return -EINVAL;
> > > > +   }
> > > > +
> > > > +   ret = rcar_csi2_parse_v4l2(priv, &v4l2_ep);
> > > > +   if (ret)
> > > > +   return ret;
> > > > +
> > > > +   priv->remote.match.fwnode.fwnode =
> > > > +   fwnode_graph_get_remote_endpoint(of_fwnode_handle(ep));
> > > 
> > > To continue the discussion from v10 --- how does this work? The V4L2 async
> > > framework does still matching for the node of the device, not the 
> > > endpoint.
> > > 
> > > My suggestion is to handle this in match_fwnode until all drivers have 
> > > been
> > > converted. The V4L2 fwnode helper should be changed as well, then you 
> > > could
> > > use it here, too.
> > 
> > I agree that the V4L2 async framework should be changed to work with 
> > endpoints and not the node of the device. I also agree on how this 
> > change should be introduced.
> > 
> > But I don't feel that this change of the framework needs to block this 
> > patch-set. Once the framework is updated to work with endpoints it 
> > should be a trivial patch to change rcar-csi2 to use the new helper. Do 
> > you agree whit this or do you feel that this patch-set should depend on 
> > such change of the framework?
> 
> Without changes to the framework, I don't think this would work since the
> async framework (or individual drivers) will assign the device's fwnode,
> not that of the endpoint, to the fwnode against which to match the async
> sub-device.
> 
> Therefore you'll need these changes for this driver to work. Or if you
> introduce a sub-device driver that uses endpoints as well, then we have two
> non-interoperable sets of ISP (or bridge) and sub-device drivers. That'd be
> quite undesirable.

Such a driver is already upstream, the adv748x driver register its 
subdevices using endpoints rather then the node of the device itself.


int adv748x_csi2_init(...)
{

...

/* Ensure that matching is based upon the endpoint fwnodes */
tx->sd.fwnode = of_fwnode_handle(ep);

...
}


A related patch to when the adv748x driver was unstreamed where 
'v4l2-async: Match parent devices' by Kieran to make this change in
behavior not to cause the non-interoperable sets your mention. It seems 
however that that change have fallen thru the cracks.

> 
> Or, if you don't care whether it'd work with your use case right now, you
> could use the helper function without changes. :-)

The adv748x is the primary use-case for the rcar-csi2 driver at the 
moment. So I must either keep this workaround in the driver or make this 
patch-set depend on future framework fixes. I would prefer to be able to 
use the helper as it makes the driver less complex. At the same time I 
don't want yet another framework change as a blocker for this patch-set 
:-)

Once I'm back from my short vacation I will give the framework update a 
try and if it turns out OK I will make this patch-set dependent on those 
changes and squash in my patch which converts rcar-csi2 to use the 
helper which is already done in preparation of future framework updates.

If it turns out the changes needed are complex or get stuck in review I 
would prefer if it was possible to move forward with the workaround in 
the driver for now and move it to the helper once it's available. Do 
this sound like a agreeable plan to you?

> 
> > > > +{
> > > > +   const struct soc_device_attribute *attr;
> > > > +   struct rcar_csi2 *priv;

Re: [PATCH] v4l: rcar-vin: Implement V4L2 video node release handler

2017-12-04 Thread Niklas Söderlund
Hi Hans,

On 2017-12-04 10:05:35 +0100, Hans Verkuil wrote:
> Hi Niklas,
> 
> On 11/16/2017 01:27 AM, Laurent Pinchart wrote:
> > Hi Niklas,
> > 
> > On Thursday, 16 November 2017 01:34:33 EET Niklas Söderlund wrote:
> >> On 2017-11-16 00:49:07 +0200, Laurent Pinchart wrote:
> >>> The rvin_dev data structure contains driver private data for an instance
> >>> of the VIN. It is allocated dynamically at probe time, and must be freed
> >>> once all users are gone.
> >>>
> >>> The structure is currently allocated with devm_kzalloc(), which results
> >>> in memory being freed when the device is unbound. If a userspace
> >>> application is currently performing an ioctl call, or just keeps the
> >>> device node open and closes it later, this will lead to accessing freed
> >>> memory.
> >>>
> >>> Fix the problem by implementing a V4L2 release handler for the video
> >>> node associated with the VIN instance (called when the last user of the
> >>> video node releases it), and freeing memory explicitly from the release
> >>> handler.
> >>>
> >>> Signed-off-by: Laurent Pinchart
> >>> 
> >>
> >> Acked-by: Niklas Söderlund 
> >>
> >> This patch is based on-top of the VIN Gen3 enablement series not yet
> >> upstream. This is OK for me, just wanted to check that this was the
> >> intention as to minimize conflicts between the two.
> > 
> > Yes, that's my intention. The patch should be included, or possibly 
> > squashed 
> > in, your development branch.
> > 
> 
> Has this patch been added in your v8 series? If not, can you add it when you
> post a v9?

This patch needs more work, with the video device now registered at 
complete() time and unregistered at unbind() time. Applying this would 
free the rcar-vin private data structure at unbind() which probably not 
what we want.

I think this issue should be addressed but maybe together with a 
patch-set targeting the generic problem with video device lifetimes in 
v4l2 framework? For now I would be happy to focus on getting Gen3 
support picked-up and observe what Laurent's work on lifetime issues 
brings and adept the rcar-vin driver to take advantage of that once it's 
ready.

> 
> Thanks,
> 
>   Hans

-- 
Regards,
Niklas Söderlund


[PATCH v9 02/28] rcar-vin: rename poorly named initialize and cleanup functions

2017-12-07 Thread Niklas Söderlund
The functions to initialize and cleanup 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 
---
 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 108d776f32651b27..f7a4c21909da6923 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(&vin->notifier);
 
return ret;
@@ -275,7 +275,7 @@ static int rcar_vin_remove(struct platform_device *pdev)
v4l2_async_notifier_unregister(&vin->notifier);
v4l2_async_notifier_cleanup(&vin->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 23fdff7a7370842e..d701b52d198243b5 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -1153,14 +1153,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(&vin->lock);
 
v4l2_device_unregister(&vin->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 = &vin->queue;
int i, ret;
@@ -1208,7 +1208,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(&vin->v4l2_dev, "Removing %s\n",
  video_device_node_name(&vin->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 = &vin->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 5382078143fb3869..85cb7ec53d2b08b5 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);
 
-- 
2.15.0



[PATCH v9 01/28] rcar-vin: add Gen3 devicetree bindings documentation

2017-12-07 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 
---
 .../devicetree/bindings/media/rcar_vin.txt | 116 ++---
 1 file changed, 104 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt 
b/Documentation/devicetree/bindings/media/rcar_vin.txt
index ff9697ed81396e64..5a95d9668d2c7dfd 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 to a CSI-2 receiver.
 
  - compatible: Must be one or more of the following
- "renesas,vin-r8a7743" for the R8A7743 device
@@ -31,21 +35,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:
  - 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:
+
+Gen3 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.
 
+- renesas,id - ID number of the VIN, VINx in the documentation.
+- ports
+- port0 - sub-node describing a single endpoint connected to the VIN
+  from external SoC pins described in video-interfaces.txt[1]. Only
+  the first one will be considered as each VIN interface has at most
+  one set of SoC external input pins.
+- port1 - 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.
 
-Device node example

+- Endpoint 0 - sub-node describing the endpoint which is CSI20
+- Endpoint 1 - sub-node describing the endpoint which is CSI21
+- Endpoint 2 - sub-node describing the endpoint which is CSI40
+- Endpoint 3 - sub-node describing the endpoint which is CSI41
 
-   aliases {
-  vin0 = &vin0;
-   };
+Device node example Gen2
+
+
+aliases {
+vin0 = &vin0;
+};
 
 vin0: vin@0xe6ef {
 compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin";
@@ -55,8 +76,8 @@ Device node example
 status = "disabled";
 };
 
-Board setup example (vin1 composite video input)
-
+Board setup example Gen2 (vin1 composite video input)
+-
 
 &i2c2   {
 status = "ok";
@@ -95,6 +116,77 @@ Board setup example (vin1 composite video input)
 };
 };
 
+Device node example Gen3
+
+
+vin0: video@e6ef {
+compatible = "renesas,vin-r8a7795";
+reg = <0 0xe6ef 0 0x1000>;
+interrupts = ;
+clocks = <&cpg CPG_MOD 811>;
+power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+resets = <&cpg 811>;
+renesas,id = <0>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@1 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+reg = <1>;
+
+vin0csi20: endpoint@0 {
+reg = <0>;
+remote-endpoi

[PATCH v9 17/28] rcar-vin: add flag to switch to media controller mode

2017-12-07 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 
---
 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 7d49904cab9cb2d9..61f48ecc1ab815ec 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -232,18 +232,21 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 
 static const struct rvin_info rcar_info_h1 = {
.chip = RCAR_H1,
+   .use_mc = false,
.max_width = 2048,
.max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_m1 = {
.chip = RCAR_M1,
+   .use_mc = false,
.max_width = 2048,
.max_height = 2048,
 };
 
 static const struct rvin_info rcar_info_gen2 = {
.chip = RCAR_GEN2,
+   .use_mc = false,
.max_width = 2048,
.max_height = 2048,
 };
@@ -338,7 +341,8 @@ static int rcar_vin_remove(struct platform_device *pdev)
v4l2_async_notifier_unregister(&vin->notifier);
v4l2_async_notifier_cleanup(&vin->notifier);
 
-   v4l2_ctrl_handler_free(&vin->ctrl_handler);
+   if (!vin->info->use_mc)
+   v4l2_ctrl_handler_free(&vin->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 7819c760c2c13422..0747873c2b9cb74c 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -77,12 +77,14 @@ struct rvin_graph_entity {
 /**
  * struct rvin_info - Information about the particular VIN implementation
  * @chip:  type of VIN chip
+ * @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 chip_id chip;
+   bool use_mc;
 
unsigned int max_width;
unsigned int max_height;
-- 
2.15.0



[PATCH v9 16/28] rcar-vin: add function to manipulate Gen3 chsel value

2017-12-07 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: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 25 +
 drivers/media/platform/rcar-vin/rcar-vin.h |  2 ++
 2 files changed, 27 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index ace95d5b543a17e3..d2788d8bb9565aaa 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 
 
@@ -1228,3 +1229,27 @@ int rvin_dma_register(struct rvin_dev *vin, int irq)
 
return ret;
 }
+
+/* 
-
+ * Gen3 CHSEL manipulation
+ */
+
+void rvin_set_chsel(struct rvin_dev *vin, u8 chsel)
+{
+   u32 ifmd, vnmc;
+
+   pm_runtime_get_sync(vin->dev);
+
+   /* Make register writes take effect immediately */
+   vnmc = rvin_read(vin, VNMC_REG) & ~VNMC_VUP;
+   rvin_write(vin, vnmc, VNMC_REG);
+
+   ifmd = VNCSI_IFMD_DES2 | VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0 |
+   VNCSI_IFMD_CSI_CHSEL(chsel);
+
+   rvin_write(vin, ifmd, VNCSI_IFMD_REG);
+
+   vin_dbg(vin, "Set IFMD 0x%x\n", ifmd);
+
+   pm_runtime_put(vin->dev);
+}
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index a440effe4b86af31..7819c760c2c13422 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -163,4 +163,6 @@ void rvin_v4l2_unregister(struct rvin_dev *vin);
 
 const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat);
 
+void rvin_set_chsel(struct rvin_dev *vin, u8 chsel);
+
 #endif
-- 
2.15.0



[PATCH v9 14/28] rcar-vin: move media bus configuration to struct rvin_info

2017-12-07 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_info to show it's not always coupled
to the parallel subdevice.

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

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 03d3cd63e38bee11..7d49904cab9cb2d9 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -101,10 +101,10 @@ static int rvin_digital_notify_bound(struct 
v4l2_async_notifier *notifier,
vin->digital->sink_pad = ret < 0 ? 0 : ret;
 
/* Find compatible subdevices mbus format */
-   vin->digital->code = 0;
+   vin->code = 0;
code.index = 0;
code.pad = vin->digital->source_pad;
-   while (!vin->digital->code &&
+   while (!vin->code &&
   !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
code.index++;
switch (code.code) {
@@ -112,16 +112,16 @@ static int rvin_digital_notify_bound(struct 
v4l2_async_notifier *notifier,
case MEDIA_BUS_FMT_UYVY8_2X8:
case MEDIA_BUS_FMT_UYVY10_2X10:
case MEDIA_BUS_FMT_RGB888_1X24:
-   vin->digital->code = code.code;
+   vin->code = code.code;
vin_dbg(vin, "Found media bus format for %s: %d\n",
-   subdev->name, vin->digital->code);
+   subdev->name, vin->code);
break;
default:
break;
}
}
 
-   if (!vin->digital->code) {
+   if (!vin->code) {
vin_err(vin, "Unsupported media bus format for %s\n",
subdev->name);
return -EINVAL;
@@ -179,16 +179,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 e6478088d9464221..d7660f485a2df9e4 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -633,7 +633,7 @@ static int rvin_setup(struct rvin_dev *vin)
/*
 * Input interface
 */
-   switch (vin->digital->code) {
+   switch (vin->code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
/* BT.601/BT.1358 16bit YCbCr422 */
vnmc |= VNMC_INF_YUV16;
@@ -641,7 +641,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;
@@ -650,7 +650,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;
@@ -662,11 +662,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 

[PATCH v9 26/28] rcar-vin: enable support for r8a7795

2017-12-07 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: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/Kconfig |   2 +-
 drivers/media/platform/rcar-vin/rcar-core.c | 150 
 2 files changed, 151 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 09ebeff1580556dc..66a8144fbba437d3 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 
@@ -956,6 +957,134 @@ static const struct rvin_info rcar_info_gen2 = {
.max_height = 2048,
 };
 
+static const struct rvin_info rcar_info_r8a7795 = {
+   .chip = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+
+   .num_chsels = 5,
+   .chsels = {
+   {
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 2 },
+   { .csi = RVIN_CSI20, .chan = 2 },
+   }, {
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI40, .chan = 3 },
+   { .csi = RVIN_CSI20, .chan = 3 },
+   }, {
+   { .csi = RVIN_CSI41, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI41, .chan = 1 },
+   { .csi = RVIN_CSI41, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI41, .chan = 1 },
+   { .csi = RVIN_CSI41, .chan = 0 },
+   { .csi = RVIN_CSI41, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI41, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI41, .chan = 2 },
+   { .csi = RVIN_CSI20, .chan = 2 },
+   }, {
+   { .csi = RVIN_CSI41, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI41, .chan = 3 },
+   { .csi = RVIN_CSI20, .chan = 3 },
+   },
+   },
+};
+
+static const struct rvin_info rcar_info_r8a7795es1 = {
+   .chip = RCAR_GEN3,
+   .use_mc = true,
+   .max_width = 4096,
+   .max_height = 4096,
+
+   .num_chsels = 6,
+   .chsels = {
+   {
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI21, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI21, .chan = 0 },
+   }, {
+   { .csi = RVIN_CSI20, .chan = 0 },
+   { .csi = RVIN_CSI21, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 0 },
+   { .csi = RVIN_CSI40, .chan = 1 },
+   { .csi = RVIN_CSI20, .chan = 1 },
+   { .csi = RVIN_CSI21

[PATCH v9 15/28] rcar-vin: enable Gen3 hardware configuration

2017-12-07 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 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 94 --
 drivers/media/platform/rcar-vin/rcar-vin.h |  1 +
 2 files changed, 64 insertions(+), 31 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index d7660f485a2df9e4..ace95d5b543a17e3 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,13 @@
 #define VNDMR2_FTEV(1 << 17)
 #define VNDMR2_VLV(n)  ((n & 0xf) << 12)
 
+/* Video n CSI2 Interface Mode Register (Gen3) */
+#define VNCSI_IFMD_DES2(1 << 27)
+#define VNCSI_IFMD_DES1(1 << 26)
+#define VNCSI_IFMD_DES0(1 << 25)
+#define VNCSI_IFMD_CSI_CHSEL(n) ((n & 0xf) << 0)
+#define VNCSI_IFMD_CSI_CHSEL_MASK 0xf
+
 struct rvin_buffer {
struct vb2_v4l2_buffer vb;
struct list_head list;
@@ -514,28 +527,10 @@ static void rvin_set_coeff(struct rvin_dev *vin, unsigned 
short xs)
rvin_write(vin, p_set->coeff_set[23], VNC8C_REG);
 }
 
-static void rvin_crop_scale_comp(struct rvin_dev *vin)
+static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin)
 {
u32 xs, ys;
 
-   /* Set Start/End Pixel/Line Pre-Clip */
-   rvin_write(vin, vin->crop.left, VNSPPRC_REG);
-   rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
-   switch (vin->format.field) {
-   case V4L2_FIELD_INTERLACED:
-   case V4L2_FIELD_INTERLACED_TB:
-   case V4L2_FIELD_INTERLACED_BT:
-   rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG);
-   rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1,
-  VNELPRC_REG);
-   break;
-   default:
-   rvin_write(vin, vin->crop.top, VNSLPRC_REG);
-   rvin_write(vin, vin->crop.top + vin->crop.height - 1,
-  VNELPRC_REG);
-  

[PATCH v9 18/28] rcar-vin: break out format alignment and checking

2017-12-07 Thread Niklas Söderlund
Part of the format alignment and checking can be shared with the Gen3
format handling. Break that part out to its own function. While doing
this clean up the checking and add more checks.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Hans Verkuil 
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 98 +++--
 1 file changed, 51 insertions(+), 47 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 56c5183f55922e1d..0ffbf0c16fb7b00e 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -86,6 +86,56 @@ 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 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);
+   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;
+   default:
+   pix->field = V4L2_FIELD_NONE;
+   break;
+   }
+
+   /* Check that colorspace is reasonable, if not keep current */
+   if (!pix->colorspace || pix->colorspace >= 0xff)
+   pix->colorspace = vin->format.colorspace;
+
+   /* 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(&pix->width, 2, vin->info->max_width, walign,
+ &pix->height, 4, vin->info->max_height, 2, 0);
+
+   pix->bytesperline = rvin_format_bytesperline(pix);
+   pix->sizeimage = rvin_format_sizeimage(pix);
+
+   if (vin->info->chip == RCAR_M1 &&
+   pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
+   vin_err(vin, "pixel format XBGR32 not supported on M1\n");
+   return -EINVAL;
+   }
+
+   vin_dbg(vin, "Format %ux%u bpl: %d size: %d\n",
+   pix->width, pix->height, pix->bytesperline, pix->sizeimage);
+
+   return 0;
+}
+
 /* 
-
  * V4L2
  */
@@ -191,64 +241,18 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
 static int __rvin_try_format(struct rvin_dev *vin,
 u32 which, struct v4l2_pix_format *pix)
 {
-   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",
-   pix->pixelformat, RVIN_DEFAULT_FORMAT);
-   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);
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;
-   default:
-   pix->field = V4L2_FIELD_NONE;
-   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(&pix->width, 2, vin->info->max_width, walign,
- &pix->height, 4, vin->info->max_height, 2, 0);
-
-   pix->bytesperline = max_t(u32, pix->bytesperline,
- rvin_format_bytesperline(pix));
-   pix->sizeimage = max_t(u32, pix->sizeimage,
-  rvin_format_sizeimage(pix));
-
-   if (vin->info->chip == RCAR_M1 &&
-   pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
-   vin_err(vin, "pixel format XBGR32 not

[PATCH v9 20/28] rcar-vin: prepare for media controller mode initialization

2017-12-07 Thread Niklas Söderlund
When running in media controller mode a media pad is needed, register
one. Also set the media bus format to CSI-2.

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

diff --git a/drivers/media/platform/rcar-vin/rcar-core.c 
b/drivers/media/platform/rcar-vin/rcar-core.c
index 61f48ecc1ab815ec..45de4079fd835759 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
+ */
+
 static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
 {
struct rvin_dev *vin = notifier_to_vin(notifier);
@@ -226,6 +230,20 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
return 0;
 }
 
+/* 
-
+ * Group async notifier
+ */
+
+static int rvin_group_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(&vin->vdev.entity, 1, &vin->pad);
+}
+
 /* 
-
  * Platform Device Driver
  */
@@ -314,8 +332,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_group_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 fd3cd781be0ab1cf..07d270a976893cdb 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -103,6 +103,8 @@ struct rvin_info {
  * @notifier:  V4L2 asynchronous subdevs notifier
  * @digital:   entity in the DT for local digital subdevice
  *
+ * @pad:   pad for media controller
+ *
  * @lock:  protects @queue
  * @queue: vb2 buffers queue
  *
@@ -132,6 +134,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;
 
-- 
2.15.0



[PATCH v9 22/28] rcar-vin: add chsel information to rvin_info

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

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

diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 5f736a3500b6e10f..41bf24aa8a1a0aed 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -35,6 +35,9 @@
 /* Max number on VIN instances that can be in a system */
 #define RCAR_VIN_NUM 8
 
+/* Max number of CHSEL values for any Gen3 SoC */
+#define RCAR_CHSEL_MAX 6
+
 enum chip_id {
RCAR_H1,
RCAR_M1,
@@ -91,6 +94,22 @@ struct rvin_graph_entity {
 
 struct rvin_group;
 
+/** struct rvin_group_chsel - Map a CSI-2 receiver and channel to a CHSEL value
+ * @csi:   VIN internal number for CSI-2 device
+ * @chan:  Output channel of the CSI-2 receiver. Each R-Car CSI-2
+ * receiver has four output channels facing the VIN
+ * devices, each channel can carry one CSI-2 Virtual
+ * Channel (VC) and there are no correlation between
+ * output channel number and CSI-2 VC. It's up to the
+ * CSI-2 receiver driver to configure which VC is
+ * outputted on which channel, the VIN devices only
+ * cares about output channels.
+ */
+struct rvin_group_chsel {
+   enum rvin_csi_id csi;
+   unsigned int chan;
+};
+
 /**
  * struct rvin_info - Information about the particular VIN implementation
  * @chip:  type of VIN chip
@@ -98,6 +117,9 @@ struct rvin_group;
  *
  * max_width:  max input width the VIN supports
  * max_height: max input height the VIN supports
+ *
+ * num_chsels: number of possible chsel values for this VIN
+ * chsels: routing table VIN <-> CSI-2 for the chsel values
  */
 struct rvin_info {
enum chip_id chip;
@@ -105,6 +127,9 @@ struct rvin_info {
 
unsigned int max_width;
unsigned int max_height;
+
+   unsigned int num_chsels;
+   struct rvin_group_chsel chsels[RCAR_VIN_NUM][RCAR_CHSEL_MAX];
 };
 
 /**
-- 
2.15.0



  1   2   3   4   5   6   7   8   9   10   >