All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/10] Xilinx Video IP Core support
@ 2014-12-01 20:13 Laurent Pinchart
  2014-12-01 20:13 ` [PATCH v4 01/10] media: entity: Document the media_entity_ops structure Laurent Pinchart
                   ` (9 more replies)
  0 siblings, 10 replies; 20+ messages in thread
From: Laurent Pinchart @ 2014-12-01 20:13 UTC (permalink / raw)
  To: linux-media; +Cc: Michal Simek, Chris Kohn, Hyun Kwon, devicetree

Hello,

Here's the fourth version of the Xilinx FPGA Video IP Cores kernel drivers.

I won't detail in great lengths the Xilinx Video IP architecture here, as that
would result in dozens of pages of documentation. The interested reader can
refer to the Zynq ZC702 Base TRD (Targeted Reference Design) User Guide
(http://www.xilinx.com/support/documentation/boards_and_kits/zc702_zvik/2014_2/ug925-zynq-zc702-base-trd.pdf).

In a nutshell, the Xilinx Video IP Cores architecture specifies how
video-related IP cores need to be designed to interoperate and how to assemble
them in pipelines of various complexities. The concepts map neatly to the
media controller architecture, which this patch set uses extensively.

The series starts with various new V4L2 core features, bug fixes or cleanups,
with a small documentation enhancement (01/10), the addition of new media bus
formats needed by the new drivers (02/10 to 04/10) and a new V4L2 OF link
parsing function (05/10).

The next two patches (06/10 and 07/10) fix two race conditions in videobuf2.
I'd like to get them in v3.19, either as part of this series or independently.

The last three patches are the core of this series.

Patch 08/10 adds support for the Xilinx Video IP architecture core in the form
of a base object to model video IP cores (xilinx-vip.c - Video IP), a
framework that parses a DT representation of a video pipeline and connects the
corresponding V4L2 subdevices together (xilinx-vipp.c - Video IP Pipeline) and
a glue between the Video DMA engine driver and the V4L2 API (xilinx-dma.c).

Patch à9/10 adds a driver for the Video Timing Controller (VTC) IP core. While
not strictly a video processing IP core, the VTC is required by other video IP
core drivers.

Finally, patch 10/10 adds a first video IP core driver for the Test Pattern
Generator (TPG). Drivers for other IP cores will be added in the future.

Changes since v3:

- Drop the three Xilinx Video DMA patches since they have been merged in the
  dmaengine tree
- Manage the subdevs clocks explicitly
- Add and use resource init and cleanup helpers
- Rename V4L2_MBUS_FMT_* to MEDIA_BUS_FMT_*
- Cleanup unused vdma configuration.
- Return buffers to vb2 when media pipeline start fails

Cc: devicetree@vger.kernel.org

Hyun Kwon (2):
  v4l: Sort YUV formats of v4l2_mbus_pixelcode
  v4l: Add VUY8 24 bits bus format

Laurent Pinchart (8):
  media: entity: Document the media_entity_ops structure
  v4l: Add RBG and RGB 8:8:8 media bus formats on 24 and 32 bit busses
  v4l: of: Add v4l2_of_parse_link() function
  v4l: vb2: Fix race condition in vb2_fop_poll
  v4l: vb2: Fix race condition in _vb2_fop_release
  v4l: xilinx: Add Xilinx Video IP core
  v4l: xilinx: Add Video Timing Controller driver
  v4l: xilinx: Add Test Pattern Generator driver

 Documentation/DocBook/media/v4l/subdev-formats.xml | 719 +++++++++-------
 .../devicetree/bindings/media/xilinx/video.txt     |  52 ++
 .../devicetree/bindings/media/xilinx/xlnx,v-tc.txt |  33 +
 .../bindings/media/xilinx/xlnx,v-tpg.txt           |  71 ++
 .../bindings/media/xilinx/xlnx,video.txt           |  55 ++
 MAINTAINERS                                        |  10 +
 drivers/media/platform/Kconfig                     |   1 +
 drivers/media/platform/Makefile                    |   2 +
 drivers/media/platform/xilinx/Kconfig              |  23 +
 drivers/media/platform/xilinx/Makefile             |   5 +
 drivers/media/platform/xilinx/xilinx-dma.c         | 753 +++++++++++++++++
 drivers/media/platform/xilinx/xilinx-dma.h         | 109 +++
 drivers/media/platform/xilinx/xilinx-tpg.c         | 925 +++++++++++++++++++++
 drivers/media/platform/xilinx/xilinx-vip.c         | 296 +++++++
 drivers/media/platform/xilinx/xilinx-vip.h         | 233 ++++++
 drivers/media/platform/xilinx/xilinx-vipp.c        | 669 +++++++++++++++
 drivers/media/platform/xilinx/xilinx-vipp.h        |  49 ++
 drivers/media/platform/xilinx/xilinx-vtc.c         | 380 +++++++++
 drivers/media/platform/xilinx/xilinx-vtc.h         |  42 +
 drivers/media/v4l2-core/v4l2-of.c                  |  61 ++
 drivers/media/v4l2-core/videobuf2-core.c           |  35 +-
 include/media/media-entity.h                       |   9 +
 include/media/v4l2-of.h                            |  27 +
 include/uapi/linux/Kbuild                          |   1 +
 include/uapi/linux/media-bus-format.h              |  19 +-
 include/uapi/linux/xilinx-v4l2-controls.h          |  73 ++
 26 files changed, 4310 insertions(+), 342 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/xilinx/video.txt
 create mode 100644 Documentation/devicetree/bindings/media/xilinx/xlnx,v-tc.txt
 create mode 100644 Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt
 create mode 100644 Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
 create mode 100644 drivers/media/platform/xilinx/Kconfig
 create mode 100644 drivers/media/platform/xilinx/Makefile
 create mode 100644 drivers/media/platform/xilinx/xilinx-dma.c
 create mode 100644 drivers/media/platform/xilinx/xilinx-dma.h
 create mode 100644 drivers/media/platform/xilinx/xilinx-tpg.c
 create mode 100644 drivers/media/platform/xilinx/xilinx-vip.c
 create mode 100644 drivers/media/platform/xilinx/xilinx-vip.h
 create mode 100644 drivers/media/platform/xilinx/xilinx-vipp.c
 create mode 100644 drivers/media/platform/xilinx/xilinx-vipp.h
 create mode 100644 drivers/media/platform/xilinx/xilinx-vtc.c
 create mode 100644 drivers/media/platform/xilinx/xilinx-vtc.h
 create mode 100644 include/uapi/linux/xilinx-v4l2-controls.h

-- 
Regards,

Laurent Pinchart

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

* [PATCH v4 01/10] media: entity: Document the media_entity_ops structure
  2014-12-01 20:13 [PATCH v4 00/10] Xilinx Video IP Core support Laurent Pinchart
@ 2014-12-01 20:13 ` Laurent Pinchart
  2014-12-01 20:13 ` [PATCH v4 02/10] v4l: Add RBG and RGB 8:8:8 media bus formats on 24 and 32 bit busses Laurent Pinchart
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2014-12-01 20:13 UTC (permalink / raw)
  To: linux-media; +Cc: Michal Simek, Chris Kohn, Hyun Kwon

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 include/media/media-entity.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index e004591..786906b 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -44,6 +44,15 @@ struct media_pad {
 	unsigned long flags;		/* Pad flags (MEDIA_PAD_FL_*) */
 };
 
+/**
+ * struct media_entity_operations - Media entity operations
+ * @link_setup:		Notify the entity of link changes. The operation can
+ *			return an error, in which case link setup will be
+ *			cancelled. Optional.
+ * @link_validate:	Return whether a link is valid from the entity point of
+ *			view. The media_entity_pipeline_start() function
+ *			validates all links by calling this operation. Optional.
+ */
 struct media_entity_operations {
 	int (*link_setup)(struct media_entity *entity,
 			  const struct media_pad *local,
-- 
2.0.4


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

* [PATCH v4 02/10] v4l: Add RBG and RGB 8:8:8 media bus formats on 24 and 32 bit busses
  2014-12-01 20:13 [PATCH v4 00/10] Xilinx Video IP Core support Laurent Pinchart
  2014-12-01 20:13 ` [PATCH v4 01/10] media: entity: Document the media_entity_ops structure Laurent Pinchart
@ 2014-12-01 20:13 ` Laurent Pinchart
  2014-12-01 20:13 ` [PATCH v4 03/10] v4l: Sort YUV formats of v4l2_mbus_pixelcode Laurent Pinchart
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2014-12-01 20:13 UTC (permalink / raw)
  To: linux-media; +Cc: Michal Simek, Chris Kohn, Hyun Kwon

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 Documentation/DocBook/media/v4l/subdev-formats.xml | 67 ++++++++++++++++++++++
 include/uapi/linux/media-bus-format.h              |  4 +-
 2 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/Documentation/DocBook/media/v4l/subdev-formats.xml b/Documentation/DocBook/media/v4l/subdev-formats.xml
index 18730b9..0cc3ca5 100644
--- a/Documentation/DocBook/media/v4l/subdev-formats.xml
+++ b/Documentation/DocBook/media/v4l/subdev-formats.xml
@@ -424,6 +424,36 @@
 	      <entry>b<subscript>1</subscript></entry>
 	      <entry>b<subscript>0</subscript></entry>
 	    </row>
+	    <row id="MEDIA-BUS-FMT-RBG888-1X24">
+	      <entry>MEDIA_BUS_FMT_RBG888_1X24</entry>
+	      <entry>0x100e</entry>
+	      <entry></entry>
+	      &dash-ent-8;
+	      <entry>r<subscript>7</subscript></entry>
+	      <entry>r<subscript>6</subscript></entry>
+	      <entry>r<subscript>5</subscript></entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	      <entry>b<subscript>7</subscript></entry>
+	      <entry>b<subscript>6</subscript></entry>
+	      <entry>b<subscript>5</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	      <entry>g<subscript>7</subscript></entry>
+	      <entry>g<subscript>6</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	    </row>
 	    <row id="MEDIA-BUS-FMT-RGB888-1X24">
 	      <entry>MEDIA_BUS_FMT_RGB888_1X24</entry>
 	      <entry>0x100a</entry>
@@ -563,6 +593,43 @@
 	      <entry>b<subscript>1</subscript></entry>
 	      <entry>b<subscript>0</subscript></entry>
 	    </row>
+	    <row id="MEDIA-BUS-FMT-RGB888-1X32-PADHI">
+	      <entry>MEDIA_BUS_FMT_RGB888_1X32_PADHI</entry>
+	      <entry>0x100f</entry>
+	      <entry></entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>r<subscript>7</subscript></entry>
+	      <entry>r<subscript>6</subscript></entry>
+	      <entry>r<subscript>5</subscript></entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	      <entry>g<subscript>7</subscript></entry>
+	      <entry>g<subscript>6</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	      <entry>b<subscript>7</subscript></entry>
+	      <entry>b<subscript>6</subscript></entry>
+	      <entry>b<subscript>5</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
 	  </tbody>
 	</tgroup>
       </table>
diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h
index 23b4090..b585bb3 100644
--- a/include/uapi/linux/media-bus-format.h
+++ b/include/uapi/linux/media-bus-format.h
@@ -33,7 +33,7 @@
 
 #define MEDIA_BUS_FMT_FIXED			0x0001
 
-/* RGB - next is	0x100e */
+/* RGB - next is	0x1010 */
 #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE	0x1001
 #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE	0x1002
 #define MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE	0x1003
@@ -43,10 +43,12 @@
 #define MEDIA_BUS_FMT_RGB565_2X8_BE		0x1007
 #define MEDIA_BUS_FMT_RGB565_2X8_LE		0x1008
 #define MEDIA_BUS_FMT_RGB666_1X18		0x1009
+#define MEDIA_BUS_FMT_RBG888_1X24		0x100e
 #define MEDIA_BUS_FMT_RGB888_1X24		0x100a
 #define MEDIA_BUS_FMT_RGB888_2X12_BE		0x100b
 #define MEDIA_BUS_FMT_RGB888_2X12_LE		0x100c
 #define MEDIA_BUS_FMT_ARGB8888_1X32		0x100d
+#define MEDIA_BUS_FMT_RGB888_1X32_PADHI		0x100f
 
 /* YUV (including grey) - next is	0x2024 */
 #define MEDIA_BUS_FMT_Y8_1X8			0x2001
-- 
2.0.4


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

* [PATCH v4 03/10] v4l: Sort YUV formats of v4l2_mbus_pixelcode
  2014-12-01 20:13 [PATCH v4 00/10] Xilinx Video IP Core support Laurent Pinchart
  2014-12-01 20:13 ` [PATCH v4 01/10] media: entity: Document the media_entity_ops structure Laurent Pinchart
  2014-12-01 20:13 ` [PATCH v4 02/10] v4l: Add RBG and RGB 8:8:8 media bus formats on 24 and 32 bit busses Laurent Pinchart
@ 2014-12-01 20:13 ` Laurent Pinchart
  2014-12-01 20:13 ` [PATCH v4 04/10] v4l: Add VUY8 24 bits bus format Laurent Pinchart
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2014-12-01 20:13 UTC (permalink / raw)
  To: linux-media; +Cc: Michal Simek, Chris Kohn, Hyun Kwon

From: Hyun Kwon <hyun.kwon@xilinx.com>

Keep the formats sorted by type, bus_width, bits per component, samples
per pixel and order of subsamples, in that order.

Signed-off-by: Hyun Kwon <hyun.kwon@xilinx.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 Documentation/DocBook/media/v4l/subdev-formats.xml | 600 ++++++++++-----------
 include/uapi/linux/media-bus-format.h              |  12 +-
 2 files changed, 306 insertions(+), 306 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/subdev-formats.xml b/Documentation/DocBook/media/v4l/subdev-formats.xml
index 0cc3ca5..872ff89 100644
--- a/Documentation/DocBook/media/v4l/subdev-formats.xml
+++ b/Documentation/DocBook/media/v4l/subdev-formats.xml
@@ -2239,11 +2239,15 @@
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-UYVY8-1X16">
-	      <entry>MEDIA_BUS_FMT_UYVY8_1X16</entry>
-	      <entry>0x200f</entry>
+	    <row id="MEDIA-BUS-FMT-UYVY12-2X12">
+	      <entry>MEDIA_BUS_FMT_UYVY12_2X12</entry>
+	      <entry>0x201c</entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &dash-ent-20;
+	      <entry>u<subscript>11</subscript></entry>
+	      <entry>u<subscript>10</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2252,6 +2256,16 @@
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2265,7 +2279,11 @@
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &dash-ent-20;
+	      <entry>v<subscript>11</subscript></entry>
+	      <entry>v<subscript>10</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2274,6 +2292,16 @@
 	      <entry>v<subscript>2</subscript></entry>
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2283,11 +2311,15 @@
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-VYUY8-1X16">
-	      <entry>MEDIA_BUS_FMT_VYUY8_1X16</entry>
-	      <entry>0x2010</entry>
+	    <row id="MEDIA-BUS-FMT-VYUY12-2X12">
+	      <entry>MEDIA_BUS_FMT_VYUY12_2X12</entry>
+	      <entry>0x201d</entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &dash-ent-20;
+	      <entry>v<subscript>11</subscript></entry>
+	      <entry>v<subscript>10</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2296,6 +2328,16 @@
 	      <entry>v<subscript>2</subscript></entry>
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2309,7 +2351,11 @@
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &dash-ent-20;
+	      <entry>u<subscript>11</subscript></entry>
+	      <entry>u<subscript>10</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2318,6 +2364,16 @@
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2327,11 +2383,15 @@
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-YUYV8-1X16">
-	      <entry>MEDIA_BUS_FMT_YUYV8_1X16</entry>
-	      <entry>0x2011</entry>
+	    <row id="MEDIA-BUS-FMT-YUYV12-2X12">
+	      <entry>MEDIA_BUS_FMT_YUYV12_2X12</entry>
+	      <entry>0x201e</entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2340,6 +2400,16 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>u<subscript>11</subscript></entry>
+	      <entry>u<subscript>10</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2353,7 +2423,11 @@
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2362,6 +2436,16 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>v<subscript>11</subscript></entry>
+	      <entry>v<subscript>10</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2371,11 +2455,15 @@
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-YVYU8-1X16">
-	      <entry>MEDIA_BUS_FMT_YVYU8_1X16</entry>
-	      <entry>0x2012</entry>
+	    <row id="MEDIA-BUS-FMT-YVYU12-2X12">
+	      <entry>MEDIA_BUS_FMT_YVYU12_2X12</entry>
+	      <entry>0x201f</entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2384,6 +2472,16 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>v<subscript>11</subscript></entry>
+	      <entry>v<subscript>10</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2397,29 +2495,11 @@
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
-	      <entry>y<subscript>7</subscript></entry>
-	      <entry>y<subscript>6</subscript></entry>
-	      <entry>y<subscript>5</subscript></entry>
-	      <entry>y<subscript>4</subscript></entry>
-	      <entry>y<subscript>3</subscript></entry>
-	      <entry>y<subscript>2</subscript></entry>
-	      <entry>y<subscript>1</subscript></entry>
-	      <entry>y<subscript>0</subscript></entry>
-	      <entry>u<subscript>7</subscript></entry>
-	      <entry>u<subscript>6</subscript></entry>
-	      <entry>u<subscript>5</subscript></entry>
-	      <entry>u<subscript>4</subscript></entry>
-	      <entry>u<subscript>3</subscript></entry>
-	      <entry>u<subscript>2</subscript></entry>
-	      <entry>u<subscript>1</subscript></entry>
-	      <entry>u<subscript>0</subscript></entry>
-	    </row>
-	    <row id="MEDIA-BUS-FMT-YDYUYDYV8-1X16">
-	      <entry>MEDIA_BUS_FMT_YDYUYDYV8_1X16</entry>
-	      <entry>0x2014</entry>
-	      <entry></entry>
-	      &dash-ent-16;
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2428,28 +2508,16 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
 	    </row>
 	    <row>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
-	      <entry>y<subscript>7</subscript></entry>
-	      <entry>y<subscript>6</subscript></entry>
-	      <entry>y<subscript>5</subscript></entry>
-	      <entry>y<subscript>4</subscript></entry>
-	      <entry>y<subscript>3</subscript></entry>
-	      <entry>y<subscript>2</subscript></entry>
-	      <entry>y<subscript>1</subscript></entry>
-	      <entry>y<subscript>0</subscript></entry>
+	      &dash-ent-20;
+	      <entry>u<subscript>11</subscript></entry>
+	      <entry>u<subscript>10</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2459,57 +2527,11 @@
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
 	    </row>
-	    <row>
-	      <entry></entry>
-	      <entry></entry>
-	      <entry></entry>
-	      &dash-ent-16;
-	      <entry>y<subscript>7</subscript></entry>
-	      <entry>y<subscript>6</subscript></entry>
-	      <entry>y<subscript>5</subscript></entry>
-	      <entry>y<subscript>4</subscript></entry>
-	      <entry>y<subscript>3</subscript></entry>
-	      <entry>y<subscript>2</subscript></entry>
-	      <entry>y<subscript>1</subscript></entry>
-	      <entry>y<subscript>0</subscript></entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	    </row>
-	    <row>
-	      <entry></entry>
-	      <entry></entry>
+	    <row id="MEDIA-BUS-FMT-UYVY8-1X16">
+	      <entry>MEDIA_BUS_FMT_UYVY8_1X16</entry>
+	      <entry>0x200f</entry>
 	      <entry></entry>
 	      &dash-ent-16;
-	      <entry>y<subscript>7</subscript></entry>
-	      <entry>y<subscript>6</subscript></entry>
-	      <entry>y<subscript>5</subscript></entry>
-	      <entry>y<subscript>4</subscript></entry>
-	      <entry>y<subscript>3</subscript></entry>
-	      <entry>y<subscript>2</subscript></entry>
-	      <entry>y<subscript>1</subscript></entry>
-	      <entry>y<subscript>0</subscript></entry>
-	      <entry>v<subscript>7</subscript></entry>
-	      <entry>v<subscript>6</subscript></entry>
-	      <entry>v<subscript>5</subscript></entry>
-	      <entry>v<subscript>4</subscript></entry>
-	      <entry>v<subscript>3</subscript></entry>
-	      <entry>v<subscript>2</subscript></entry>
-	      <entry>v<subscript>1</subscript></entry>
-	      <entry>v<subscript>0</subscript></entry>
-	    </row>
-	    <row id="MEDIA-BUS-FMT-UYVY10-1X20">
-	      <entry>MEDIA_BUS_FMT_UYVY10_1X20</entry>
-	      <entry>0x201a</entry>
-	      <entry></entry>
-	      &dash-ent-12;
-	      <entry>u<subscript>9</subscript></entry>
-	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2518,8 +2540,6 @@
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2533,9 +2553,7 @@
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-12;
-	      <entry>v<subscript>9</subscript></entry>
-	      <entry>v<subscript>8</subscript></entry>
+	      &dash-ent-16;
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2544,8 +2562,6 @@
 	      <entry>v<subscript>2</subscript></entry>
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2555,13 +2571,11 @@
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-VYUY10-1X20">
-	      <entry>MEDIA_BUS_FMT_VYUY10_1X20</entry>
-	      <entry>0x201b</entry>
+	    <row id="MEDIA-BUS-FMT-VYUY8-1X16">
+	      <entry>MEDIA_BUS_FMT_VYUY8_1X16</entry>
+	      <entry>0x2010</entry>
 	      <entry></entry>
-	      &dash-ent-12;
-	      <entry>v<subscript>9</subscript></entry>
-	      <entry>v<subscript>8</subscript></entry>
+	      &dash-ent-16;
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2570,8 +2584,6 @@
 	      <entry>v<subscript>2</subscript></entry>
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2585,9 +2597,7 @@
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-12;
-	      <entry>u<subscript>9</subscript></entry>
-	      <entry>u<subscript>8</subscript></entry>
+	      &dash-ent-16;
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2596,8 +2606,6 @@
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2607,13 +2615,11 @@
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-YUYV10-1X20">
-	      <entry>MEDIA_BUS_FMT_YUYV10_1X20</entry>
-	      <entry>0x200d</entry>
+	    <row id="MEDIA-BUS-FMT-YUYV8-1X16">
+	      <entry>MEDIA_BUS_FMT_YUYV8_1X16</entry>
+	      <entry>0x2011</entry>
 	      <entry></entry>
-	      &dash-ent-12;
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2622,8 +2628,6 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>u<subscript>9</subscript></entry>
-	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2637,9 +2641,7 @@
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-12;
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2648,8 +2650,6 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>v<subscript>9</subscript></entry>
-	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2659,13 +2659,11 @@
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-YVYU10-1X20">
-	      <entry>MEDIA_BUS_FMT_YVYU10_1X20</entry>
-	      <entry>0x200e</entry>
+	    <row id="MEDIA-BUS-FMT-YVYU8-1X16">
+	      <entry>MEDIA_BUS_FMT_YVYU8_1X16</entry>
+	      <entry>0x2012</entry>
 	      <entry></entry>
-	      &dash-ent-12;
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2674,8 +2672,6 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>v<subscript>9</subscript></entry>
-	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2689,9 +2685,51 @@
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-12;
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
+	      &dash-ent-16;
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row id="MEDIA-BUS-FMT-YDYUYDYV8-1X16">
+	      <entry>MEDIA_BUS_FMT_YDYUYDYV8_1X16</entry>
+	      <entry>0x2014</entry>
+	      <entry></entry>
+	      &dash-ent-16;
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2700,8 +2738,6 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>u<subscript>9</subscript></entry>
-	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2711,14 +2747,11 @@
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-YUV10-1X30">
-	      <entry>MEDIA_BUS_FMT_YUV10_1X30</entry>
-	      <entry>0x2016</entry>
+	    <row>
 	      <entry></entry>
-	      <entry>-</entry>
-	      <entry>-</entry>
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2727,39 +2760,20 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>u<subscript>9</subscript></entry>
-	      <entry>u<subscript>8</subscript></entry>
-	      <entry>u<subscript>7</subscript></entry>
-	      <entry>u<subscript>6</subscript></entry>
-	      <entry>u<subscript>5</subscript></entry>
-	      <entry>u<subscript>4</subscript></entry>
-	      <entry>u<subscript>3</subscript></entry>
-	      <entry>u<subscript>2</subscript></entry>
-	      <entry>u<subscript>1</subscript></entry>
-	      <entry>u<subscript>0</subscript></entry>
-	      <entry>v<subscript>9</subscript></entry>
-	      <entry>v<subscript>8</subscript></entry>
-	      <entry>v<subscript>7</subscript></entry>
-	      <entry>v<subscript>6</subscript></entry>
-	      <entry>v<subscript>5</subscript></entry>
-	      <entry>v<subscript>4</subscript></entry>
-	      <entry>v<subscript>3</subscript></entry>
-	      <entry>v<subscript>2</subscript></entry>
-	      <entry>v<subscript>1</subscript></entry>
-	      <entry>v<subscript>0</subscript></entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-AYUV8-1X32">
-	      <entry>MEDIA_BUS_FMT_AYUV8_1X32</entry>
-	      <entry>0x2017</entry>
+	    <row>
 	      <entry></entry>
-	      <entry>a<subscript>7</subscript></entry>
-	      <entry>a<subscript>6</subscript></entry>
-	      <entry>a<subscript>5</subscript></entry>
-	      <entry>a<subscript>4</subscript></entry>
-	      <entry>a<subscript>3</subscript></entry>
-	      <entry>a<subscript>2</subscript></entry>
-	      <entry>a<subscript>1</subscript></entry>
-	      <entry>a<subscript>0</subscript></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2768,14 +2782,6 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>u<subscript>7</subscript></entry>
-	      <entry>u<subscript>6</subscript></entry>
-	      <entry>u<subscript>5</subscript></entry>
-	      <entry>u<subscript>4</subscript></entry>
-	      <entry>u<subscript>3</subscript></entry>
-	      <entry>u<subscript>2</subscript></entry>
-	      <entry>u<subscript>1</subscript></entry>
-	      <entry>u<subscript>0</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2785,13 +2791,11 @@
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-UYVY12-2X12">
-	      <entry>MEDIA_BUS_FMT_UYVY12_2X12</entry>
-	      <entry>0x201c</entry>
+	    <row id="MEDIA-BUS-FMT-UYVY10-1X20">
+	      <entry>MEDIA_BUS_FMT_UYVY10_1X20</entry>
+	      <entry>0x201a</entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>u<subscript>11</subscript></entry>
-	      <entry>u<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>u<subscript>9</subscript></entry>
 	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
@@ -2802,14 +2806,6 @@
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
-	    </row>
-	    <row>
-	      <entry></entry>
-	      <entry></entry>
-	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>y<subscript>11</subscript></entry>
-	      <entry>y<subscript>10</subscript></entry>
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -2825,9 +2821,7 @@
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>v<subscript>11</subscript></entry>
-	      <entry>v<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>v<subscript>9</subscript></entry>
 	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
@@ -2838,14 +2832,6 @@
 	      <entry>v<subscript>2</subscript></entry>
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
-	    </row>
-	    <row>
-	      <entry></entry>
-	      <entry></entry>
-	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>y<subscript>11</subscript></entry>
-	      <entry>y<subscript>10</subscript></entry>
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -2857,13 +2843,11 @@
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-VYUY12-2X12">
-	      <entry>MEDIA_BUS_FMT_VYUY12_2X12</entry>
-	      <entry>0x201d</entry>
+	    <row id="MEDIA-BUS-FMT-VYUY10-1X20">
+	      <entry>MEDIA_BUS_FMT_VYUY10_1X20</entry>
+	      <entry>0x201b</entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>v<subscript>11</subscript></entry>
-	      <entry>v<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>v<subscript>9</subscript></entry>
 	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
@@ -2874,14 +2858,6 @@
 	      <entry>v<subscript>2</subscript></entry>
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
-	    </row>
-	    <row>
-	      <entry></entry>
-	      <entry></entry>
-	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>y<subscript>11</subscript></entry>
-	      <entry>y<subscript>10</subscript></entry>
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -2897,9 +2873,7 @@
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>u<subscript>11</subscript></entry>
-	      <entry>u<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>u<subscript>9</subscript></entry>
 	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
@@ -2910,14 +2884,6 @@
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
-	    </row>
-	    <row>
-	      <entry></entry>
-	      <entry></entry>
-	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>y<subscript>11</subscript></entry>
-	      <entry>y<subscript>10</subscript></entry>
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -2929,13 +2895,11 @@
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-YUYV12-2X12">
-	      <entry>MEDIA_BUS_FMT_YUYV12_2X12</entry>
-	      <entry>0x201e</entry>
+	    <row id="MEDIA-BUS-FMT-YUYV10-1X20">
+	      <entry>MEDIA_BUS_FMT_YUYV10_1X20</entry>
+	      <entry>0x200d</entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>y<subscript>11</subscript></entry>
-	      <entry>y<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -2946,14 +2910,6 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	    </row>
-	    <row>
-	      <entry></entry>
-	      <entry></entry>
-	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>u<subscript>11</subscript></entry>
-	      <entry>u<subscript>10</subscript></entry>
 	      <entry>u<subscript>9</subscript></entry>
 	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
@@ -2969,9 +2925,7 @@
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>y<subscript>11</subscript></entry>
-	      <entry>y<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -2982,14 +2936,6 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	    </row>
-	    <row>
-	      <entry></entry>
-	      <entry></entry>
-	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>v<subscript>11</subscript></entry>
-	      <entry>v<subscript>10</subscript></entry>
 	      <entry>v<subscript>9</subscript></entry>
 	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
@@ -3001,13 +2947,11 @@
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-YVYU12-2X12">
-	      <entry>MEDIA_BUS_FMT_YVYU12_2X12</entry>
-	      <entry>0x201f</entry>
+	    <row id="MEDIA-BUS-FMT-YVYU10-1X20">
+	      <entry>MEDIA_BUS_FMT_YVYU10_1X20</entry>
+	      <entry>0x200e</entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>y<subscript>11</subscript></entry>
-	      <entry>y<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -3018,14 +2962,6 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	    </row>
-	    <row>
-	      <entry></entry>
-	      <entry></entry>
-	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>v<subscript>11</subscript></entry>
-	      <entry>v<subscript>10</subscript></entry>
 	      <entry>v<subscript>9</subscript></entry>
 	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
@@ -3041,9 +2977,7 @@
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>y<subscript>11</subscript></entry>
-	      <entry>y<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -3054,14 +2988,6 @@
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	    </row>
-	    <row>
-	      <entry></entry>
-	      <entry></entry>
-	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>u<subscript>11</subscript></entry>
-	      <entry>u<subscript>10</subscript></entry>
 	      <entry>u<subscript>9</subscript></entry>
 	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
@@ -3313,6 +3239,80 @@
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
 	    </row>
+	    <row id="MEDIA-BUS-FMT-YUV10-1X30">
+	      <entry>MEDIA_BUS_FMT_YUV10_1X30</entry>
+	      <entry>0x2016</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row id="MEDIA-BUS-FMT-AYUV8-1X32">
+	      <entry>MEDIA_BUS_FMT_AYUV8_1X32</entry>
+	      <entry>0x2017</entry>
+	      <entry></entry>
+	      <entry>a<subscript>7</subscript></entry>
+	      <entry>a<subscript>6</subscript></entry>
+	      <entry>a<subscript>5</subscript></entry>
+	      <entry>a<subscript>4</subscript></entry>
+	      <entry>a<subscript>3</subscript></entry>
+	      <entry>a<subscript>2</subscript></entry>
+	      <entry>a<subscript>1</subscript></entry>
+	      <entry>a<subscript>0</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
 	  </tbody>
 	</tgroup>
       </table>
diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h
index b585bb3..363a30f 100644
--- a/include/uapi/linux/media-bus-format.h
+++ b/include/uapi/linux/media-bus-format.h
@@ -67,6 +67,10 @@
 #define MEDIA_BUS_FMT_YUYV10_2X10		0x200b
 #define MEDIA_BUS_FMT_YVYU10_2X10		0x200c
 #define MEDIA_BUS_FMT_Y12_1X12			0x2013
+#define MEDIA_BUS_FMT_UYVY12_2X12		0x201c
+#define MEDIA_BUS_FMT_VYUY12_2X12		0x201d
+#define MEDIA_BUS_FMT_YUYV12_2X12		0x201e
+#define MEDIA_BUS_FMT_YVYU12_2X12		0x201f
 #define MEDIA_BUS_FMT_UYVY8_1X16		0x200f
 #define MEDIA_BUS_FMT_VYUY8_1X16		0x2010
 #define MEDIA_BUS_FMT_YUYV8_1X16		0x2011
@@ -76,16 +80,12 @@
 #define MEDIA_BUS_FMT_VYUY10_1X20		0x201b
 #define MEDIA_BUS_FMT_YUYV10_1X20		0x200d
 #define MEDIA_BUS_FMT_YVYU10_1X20		0x200e
-#define MEDIA_BUS_FMT_YUV10_1X30		0x2016
-#define MEDIA_BUS_FMT_AYUV8_1X32		0x2017
-#define MEDIA_BUS_FMT_UYVY12_2X12		0x201c
-#define MEDIA_BUS_FMT_VYUY12_2X12		0x201d
-#define MEDIA_BUS_FMT_YUYV12_2X12		0x201e
-#define MEDIA_BUS_FMT_YVYU12_2X12		0x201f
 #define MEDIA_BUS_FMT_UYVY12_1X24		0x2020
 #define MEDIA_BUS_FMT_VYUY12_1X24		0x2021
 #define MEDIA_BUS_FMT_YUYV12_1X24		0x2022
 #define MEDIA_BUS_FMT_YVYU12_1X24		0x2023
+#define MEDIA_BUS_FMT_YUV10_1X30		0x2016
+#define MEDIA_BUS_FMT_AYUV8_1X32		0x2017
 
 /* Bayer - next is	0x3019 */
 #define MEDIA_BUS_FMT_SBGGR8_1X8		0x3001
-- 
2.0.4


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

* [PATCH v4 04/10] v4l: Add VUY8 24 bits bus format
  2014-12-01 20:13 [PATCH v4 00/10] Xilinx Video IP Core support Laurent Pinchart
                   ` (2 preceding siblings ...)
  2014-12-01 20:13 ` [PATCH v4 03/10] v4l: Sort YUV formats of v4l2_mbus_pixelcode Laurent Pinchart
@ 2014-12-01 20:13 ` Laurent Pinchart
  2014-12-01 20:13 ` [PATCH v4 05/10] v4l: of: Add v4l2_of_parse_link() function Laurent Pinchart
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2014-12-01 20:13 UTC (permalink / raw)
  To: linux-media; +Cc: Michal Simek, Chris Kohn, Hyun Kwon

From: Hyun Kwon <hyun.kwon@xilinx.com>

Add VUY8 24 bits bus format, V4L2_MBUS_FMT_VUY8_1X24.

Signed-off-by: Hyun Kwon <hyun.kwon@xilinx.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 Documentation/DocBook/media/v4l/subdev-formats.xml | 30 ++++++++++++++++++++++
 include/uapi/linux/media-bus-format.h              |  3 ++-
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/Documentation/DocBook/media/v4l/subdev-formats.xml b/Documentation/DocBook/media/v4l/subdev-formats.xml
index 872ff89..a41e70c 100644
--- a/Documentation/DocBook/media/v4l/subdev-formats.xml
+++ b/Documentation/DocBook/media/v4l/subdev-formats.xml
@@ -2999,6 +2999,36 @@
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
 	    </row>
+	    <row id="MEDIA-BUS-FMT-VUY8-1X24">
+	      <entry>MEDIA_BUS_FMT_VUY8_1X24</entry>
+	      <entry>0x201a</entry>
+	      <entry></entry>
+	      &dash-ent-8;
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
 	    <row id="MEDIA-BUS-FMT-UYVY12-1X24">
 	      <entry>MEDIA_BUS_FMT_UYVY12_1X24</entry>
 	      <entry>0x2020</entry>
diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h
index 363a30f..d391893 100644
--- a/include/uapi/linux/media-bus-format.h
+++ b/include/uapi/linux/media-bus-format.h
@@ -50,7 +50,7 @@
 #define MEDIA_BUS_FMT_ARGB8888_1X32		0x100d
 #define MEDIA_BUS_FMT_RGB888_1X32_PADHI		0x100f
 
-/* YUV (including grey) - next is	0x2024 */
+/* YUV (including grey) - next is	0x2025 */
 #define MEDIA_BUS_FMT_Y8_1X8			0x2001
 #define MEDIA_BUS_FMT_UV8_1X8			0x2015
 #define MEDIA_BUS_FMT_UYVY8_1_5X8		0x2002
@@ -80,6 +80,7 @@
 #define MEDIA_BUS_FMT_VYUY10_1X20		0x201b
 #define MEDIA_BUS_FMT_YUYV10_1X20		0x200d
 #define MEDIA_BUS_FMT_YVYU10_1X20		0x200e
+#define MEDIA_BUS_FMT_VUY8_1X24			0x2024
 #define MEDIA_BUS_FMT_UYVY12_1X24		0x2020
 #define MEDIA_BUS_FMT_VYUY12_1X24		0x2021
 #define MEDIA_BUS_FMT_YUYV12_1X24		0x2022
-- 
2.0.4


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

* [PATCH v4 05/10] v4l: of: Add v4l2_of_parse_link() function
  2014-12-01 20:13 [PATCH v4 00/10] Xilinx Video IP Core support Laurent Pinchart
                   ` (3 preceding siblings ...)
  2014-12-01 20:13 ` [PATCH v4 04/10] v4l: Add VUY8 24 bits bus format Laurent Pinchart
@ 2014-12-01 20:13 ` Laurent Pinchart
  2014-12-03 12:30   ` Sakari Ailus
  2014-12-03 15:02   ` Sylwester Nawrocki
  2014-12-01 20:13 ` [PATCH v4 06/10] v4l: vb2: Fix race condition in vb2_fop_poll Laurent Pinchart
                   ` (4 subsequent siblings)
  9 siblings, 2 replies; 20+ messages in thread
From: Laurent Pinchart @ 2014-12-01 20:13 UTC (permalink / raw)
  To: linux-media; +Cc: Michal Simek, Chris Kohn, Hyun Kwon, Sylwester Nawrocki

The function fills a link data structure with the device node and port
number at both the local and remote ends of a link defined by one of its
endpoint nodes.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/v4l2-core/v4l2-of.c | 61 +++++++++++++++++++++++++++++++++++++++
 include/media/v4l2-of.h           | 27 +++++++++++++++++
 2 files changed, 88 insertions(+)

Cc: Sylwester Nawrocki <s.nawrocki@samsung.com>

diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c
index b4ed9a9..c473479 100644
--- a/drivers/media/v4l2-core/v4l2-of.c
+++ b/drivers/media/v4l2-core/v4l2-of.c
@@ -142,3 +142,64 @@ int v4l2_of_parse_endpoint(const struct device_node *node,
 	return 0;
 }
 EXPORT_SYMBOL(v4l2_of_parse_endpoint);
+
+/**
+ * v4l2_of_parse_link() - parse a link between two endpoints
+ * @node: pointer to the endpoint at the local end of the link
+ * @link: pointer to the V4L2 OF link data structure
+ *
+ * Fill the link structure with the local and remote nodes and port numbers.
+ * The local_node and remote_node fields are set to point to the local and
+ * remote port parent nodes respectively (the port parent node being the parent
+ * node of the port node if that node isn't a 'ports' node, or the grand-parent
+ * node of the port node otherwise).
+ *
+ * A reference is taken to both the local and remote nodes, the caller must use
+ * v4l2_of_put_link() to drop the references when done with the link.
+ *
+ * Return: 0 on success, or -ENOLINK if the remote endpoint can't be found.
+ */
+int v4l2_of_parse_link(const struct device_node *node,
+		       struct v4l2_of_link *link)
+{
+	struct device_node *np;
+
+	memset(link, 0, sizeof(*link));
+
+	np = of_get_parent(node);
+	of_property_read_u32(np, "reg", &link->local_port);
+	np = of_get_next_parent(np);
+	if (of_node_cmp(np->name, "ports") == 0)
+		np = of_get_next_parent(np);
+	link->local_node = np;
+
+	np = of_parse_phandle(node, "remote-endpoint", 0);
+	if (!np) {
+		of_node_put(link->local_node);
+		return -ENOLINK;
+	}
+
+	np = of_get_parent(np);
+	of_property_read_u32(np, "reg", &link->remote_port);
+	np = of_get_next_parent(np);
+	if (of_node_cmp(np->name, "ports") == 0)
+		np = of_get_next_parent(np);
+	link->remote_node = np;
+
+	return 0;
+}
+EXPORT_SYMBOL(v4l2_of_parse_link);
+
+/**
+ * v4l2_of_put_link() - drop references to nodes in a link
+ * @link: pointer to the V4L2 OF link data structure
+ *
+ * Drop references to the local and remote nodes in the link. This function must
+ * be called on every link parsed with v4l2_of_parse_link().
+ */
+void v4l2_of_put_link(struct v4l2_of_link *link)
+{
+	of_node_put(link->local_node);
+	of_node_put(link->remote_node);
+}
+EXPORT_SYMBOL(v4l2_of_put_link);
diff --git a/include/media/v4l2-of.h b/include/media/v4l2-of.h
index 70fa7b7..078846d 100644
--- a/include/media/v4l2-of.h
+++ b/include/media/v4l2-of.h
@@ -66,9 +66,26 @@ struct v4l2_of_endpoint {
 	struct list_head head;
 };
 
+/**
+ * struct v4l2_of_link - a link between two endpoints
+ * @local_node: pointer to device_node of this endpoint
+ * @local_port: identifier of the port this endpoint belongs to
+ * @remote_node: pointer to device_node of the remote endpoint
+ * @remote_port: identifier of the port the remote endpoint belongs to
+ */
+struct v4l2_of_link {
+	struct device_node *local_node;
+	unsigned int local_port;
+	struct device_node *remote_node;
+	unsigned int remote_port;
+};
+
 #ifdef CONFIG_OF
 int v4l2_of_parse_endpoint(const struct device_node *node,
 			   struct v4l2_of_endpoint *endpoint);
+int v4l2_of_parse_link(const struct device_node *node,
+		       struct v4l2_of_link *link);
+void v4l2_of_put_link(struct v4l2_of_link *link);
 #else /* CONFIG_OF */
 
 static inline int v4l2_of_parse_endpoint(const struct device_node *node,
@@ -77,6 +94,16 @@ static inline int v4l2_of_parse_endpoint(const struct device_node *node,
 	return -ENOSYS;
 }
 
+static inline int v4l2_of_parse_link(const struct device_node *node,
+				     struct v4l2_of_link *link)
+{
+	return -ENOSYS;
+}
+
+static inline void v4l2_of_put_link(struct v4l2_of_link *link)
+{
+}
+
 #endif /* CONFIG_OF */
 
 #endif /* _V4L2_OF_H */
-- 
2.0.4


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

* [PATCH v4 06/10] v4l: vb2: Fix race condition in vb2_fop_poll
  2014-12-01 20:13 [PATCH v4 00/10] Xilinx Video IP Core support Laurent Pinchart
                   ` (4 preceding siblings ...)
  2014-12-01 20:13 ` [PATCH v4 05/10] v4l: of: Add v4l2_of_parse_link() function Laurent Pinchart
@ 2014-12-01 20:13 ` Laurent Pinchart
  2014-12-01 20:13 ` [PATCH v4 07/10] v4l: vb2: Fix race condition in _vb2_fop_release Laurent Pinchart
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2014-12-01 20:13 UTC (permalink / raw)
  To: linux-media; +Cc: Michal Simek, Chris Kohn, Hyun Kwon

The vb2_fop_poll() implementation tries to be clever on whether it needs
to lock the queue mutex by checking whether polling might start fileio.
The test requires reading the q->num_buffer field, which is racy if we
don't hold the queue mutex in the first place.

Remove the extra cleverness and just lock the mutex.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/v4l2-core/videobuf2-core.c | 27 ++++++++-------------------
 1 file changed, 8 insertions(+), 19 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 7aed8f2..2685670 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -3459,27 +3459,16 @@ unsigned int vb2_fop_poll(struct file *file, poll_table *wait)
 	struct video_device *vdev = video_devdata(file);
 	struct vb2_queue *q = vdev->queue;
 	struct mutex *lock = q->lock ? q->lock : vdev->lock;
-	unsigned long req_events = poll_requested_events(wait);
 	unsigned res;
 	void *fileio;
-	bool must_lock = false;
-
-	/* Try to be smart: only lock if polling might start fileio,
-	   otherwise locking will only introduce unwanted delays. */
-	if (q->num_buffers == 0 && !vb2_fileio_is_active(q)) {
-		if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) &&
-				(req_events & (POLLIN | POLLRDNORM)))
-			must_lock = true;
-		else if (V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_WRITE) &&
-				(req_events & (POLLOUT | POLLWRNORM)))
-			must_lock = true;
-	}
 
-	/* If locking is needed, but this helper doesn't know how, then you
-	   shouldn't be using this helper but you should write your own. */
-	WARN_ON(must_lock && !lock);
+	/*
+	 * If this helper doesn't know how to lock, then you shouldn't be using
+	 * it but you should write your own.
+	 */
+	WARN_ON(!lock);
 
-	if (must_lock && lock && mutex_lock_interruptible(lock))
+	if (lock && mutex_lock_interruptible(lock))
 		return POLLERR;
 
 	fileio = q->fileio;
@@ -3487,9 +3476,9 @@ unsigned int vb2_fop_poll(struct file *file, poll_table *wait)
 	res = vb2_poll(vdev->queue, file, wait);
 
 	/* If fileio was started, then we have a new queue owner. */
-	if (must_lock && !fileio && q->fileio)
+	if (!fileio && q->fileio)
 		q->owner = file->private_data;
-	if (must_lock && lock)
+	if (lock)
 		mutex_unlock(lock);
 	return res;
 }
-- 
2.0.4


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

* [PATCH v4 07/10] v4l: vb2: Fix race condition in _vb2_fop_release
  2014-12-01 20:13 [PATCH v4 00/10] Xilinx Video IP Core support Laurent Pinchart
                   ` (5 preceding siblings ...)
  2014-12-01 20:13 ` [PATCH v4 06/10] v4l: vb2: Fix race condition in vb2_fop_poll Laurent Pinchart
@ 2014-12-01 20:13 ` Laurent Pinchart
  2014-12-03 15:07   ` Sylwester Nawrocki
  2014-12-01 20:13 ` [PATCH v4 08/10] v4l: xilinx: Add Xilinx Video IP core Laurent Pinchart
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Laurent Pinchart @ 2014-12-01 20:13 UTC (permalink / raw)
  To: linux-media; +Cc: Michal Simek, Chris Kohn, Hyun Kwon

The function releases the queue if the file being released is the queue
owner. The check reads the queue->owner field without taking the queue
lock, creating a race condition with functions that set the queue owner,
such as vb2_ioctl_reqbufs() for instance.

Fix this by moving the queue->owner check within the mutex protected
section.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/v4l2-core/videobuf2-core.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 2685670..d09a891 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -3389,14 +3389,14 @@ int _vb2_fop_release(struct file *file, struct mutex *lock)
 {
 	struct video_device *vdev = video_devdata(file);
 
+	if (lock)
+		mutex_lock(lock);
 	if (file->private_data == vdev->queue->owner) {
-		if (lock)
-			mutex_lock(lock);
 		vb2_queue_release(vdev->queue);
 		vdev->queue->owner = NULL;
-		if (lock)
-			mutex_unlock(lock);
 	}
+	if (lock)
+		mutex_unlock(lock);
 	return v4l2_fh_release(file);
 }
 EXPORT_SYMBOL_GPL(_vb2_fop_release);
-- 
2.0.4


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

* [PATCH v4 08/10] v4l: xilinx: Add Xilinx Video IP core
  2014-12-01 20:13 [PATCH v4 00/10] Xilinx Video IP Core support Laurent Pinchart
                   ` (6 preceding siblings ...)
  2014-12-01 20:13 ` [PATCH v4 07/10] v4l: vb2: Fix race condition in _vb2_fop_release Laurent Pinchart
@ 2014-12-01 20:13 ` Laurent Pinchart
       [not found]   ` <1417464820-6718-9-git-send-email-laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
  2014-12-01 20:13 ` [PATCH v4 09/10] v4l: xilinx: Add Video Timing Controller driver Laurent Pinchart
  2014-12-01 20:13 ` [PATCH v4 10/10] v4l: xilinx: Add Test Pattern Generator driver Laurent Pinchart
  9 siblings, 1 reply; 20+ messages in thread
From: Laurent Pinchart @ 2014-12-01 20:13 UTC (permalink / raw)
  To: linux-media; +Cc: Michal Simek, Chris Kohn, Hyun Kwon, devicetree

Xilinx platforms have no hardwired video capture or video processing
interface. Users create capture and memory to memory processing
pipelines in the FPGA fabric to suit their particular needs, by
instantiating video IP cores from a large library.

The Xilinx Video IP core is a framework that models a video pipeline
described in the device tree and expose the pipeline to userspace
through the media controller and V4L2 APIs.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hyun Kwon <hyun.kwon@xilinx.com>
Signed-off-by: Radhey Shyam Pandey <radheys@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>

---

Cc: devicetree@vger.kernel.org

Changes since v3:

- Rename V4L2_MBUS_FMT_* to MEDIA_BUS_FMT_*
- Cleanup unused vdma configuration.
- Add resource init and cleanup helpers
- Return buffers to vb2 when media pipeline start fails

Changes since v2:

- Remove explicit trailing \0 after snprintf
- Don't hardcode colorspace

Changes since v1:

- Remove unnecessary fields from struct xvip_dma_buffer
- Fix querycap capabilities and bus_info reporting
- Refuse to set format when the queue is busy
- Return buffers to vb2 when start_streaming fails
- Use vb2 fops and ioctl ops

v1 was made of the following individual patches.

media: xilinx: vip: Add yuv444 and bayer formats
media: xilinx: vip: Remove _TIMING_ from register definition
media: xilinx: dma: Add vidioc_enum_fmt_vid_cap callback
media: xilinx: dma: Fix alignments of xvip_dma_fops definition
media: xilinx: dma: Workaround for bytesperline
media: xilinx: vip: Add default min/max height/width definitions
media: xilinx: vip: Add common sink/source pad IDs
media: xilinx: vip: Add xvip_set_format_size()
media: xilinx: vip: Add xvip_enum_mbus_code()
media: xilinx: vip: Add xvip_enum_frame_size()
media: xilinx: vip: Add register clear and set functions
media: xilinx: vip: Add xvip_start()
media: xilinx: vip: Add xvip_stop()
media: xilinx: vip: Add xvip_set_frame_size()
media: xilinx: vip: Add enable/disable reg update functions
media: xilinx: vip: Add xvip_print_version()
media: xilinx: vip: Add xvip_reset()
media: xilinx: vip: Add xvip_get_frame_size()
media: xilinx: vip: Add suspend/resume helper functions
media: xilinx: vip: Change the return value of xvip_get_format_by_code()
media: xilinx: vip: Change the return value of xvip_of_get_format()
media: xilinx: vip: Change the return value of xvip_get_format_by_fourcc()
media: xilinx: vipp: Remove of_match_ptr()
media: xilinx: vipp: Add control to inherit subdevice controls
media: xilinx: Make disconnected video nodes return -EPIPE at stream on
media: xilinx: Make links configurable
media: xilinx: Rename xvip_pipeline_entity to xvip_graph_entity
media: xilinx: Rename xvip_pipeline to xvip_composite_device
media: xilinx: Rename xvipp_pipeline_* functions to xvip_graph_*
media: xilinx: Rename xvipp_v4l2_* functions to xvip_composite_v4l2_*
media: xilinx: Rename xvipp_* functions to xvip_composite_*
media: xilinx: Move pipeline management code to xilinx-dma.c
media: xilinx: Add missing mutex_destroy call
media: xilinx: Create xvip_pipeline structure
media: xilinx: Support more than two VDMAs in DT
media: xilinx: dma: Change vdma configuration to cyclic-mode
Revert "media: xilinx: dma: Workaround for bytesperline"
media: xilinx: Added DMA error handling
media: xilinx: Fix error handling
media: xilinx: Reordered mutexes initialization
media: xilinx: vipp: Add devicetree bindings documentation
media: xilinx: Reordered mutexes initialization
media: xilinx: Set format description in enum_fmt
media: xilinx: Remove global control handler
media: xilinx: dma: Use the interleaved dmaengine API
xilinx: Remove .owner field for drivers
v4l: xilinx: video: Rename compatible string to xlnx,video
v4l: xilinx: Remove axi- prefix from DT properties
v4l: xilinx: dma: Give back queued buffers at streamoff time
---
 .../devicetree/bindings/media/xilinx/video.txt     |  52 ++
 .../bindings/media/xilinx/xlnx,video.txt           |  55 ++
 MAINTAINERS                                        |   9 +
 drivers/media/platform/Kconfig                     |   1 +
 drivers/media/platform/Makefile                    |   2 +
 drivers/media/platform/xilinx/Kconfig              |  10 +
 drivers/media/platform/xilinx/Makefile             |   3 +
 drivers/media/platform/xilinx/xilinx-dma.c         | 753 +++++++++++++++++++++
 drivers/media/platform/xilinx/xilinx-dma.h         | 109 +++
 drivers/media/platform/xilinx/xilinx-vip.c         | 296 ++++++++
 drivers/media/platform/xilinx/xilinx-vip.h         | 233 +++++++
 drivers/media/platform/xilinx/xilinx-vipp.c        | 669 ++++++++++++++++++
 drivers/media/platform/xilinx/xilinx-vipp.h        |  49 ++
 13 files changed, 2241 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/xilinx/video.txt
 create mode 100644 Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
 create mode 100644 drivers/media/platform/xilinx/Kconfig
 create mode 100644 drivers/media/platform/xilinx/Makefile
 create mode 100644 drivers/media/platform/xilinx/xilinx-dma.c
 create mode 100644 drivers/media/platform/xilinx/xilinx-dma.h
 create mode 100644 drivers/media/platform/xilinx/xilinx-vip.c
 create mode 100644 drivers/media/platform/xilinx/xilinx-vip.h
 create mode 100644 drivers/media/platform/xilinx/xilinx-vipp.c
 create mode 100644 drivers/media/platform/xilinx/xilinx-vipp.h

diff --git a/Documentation/devicetree/bindings/media/xilinx/video.txt b/Documentation/devicetree/bindings/media/xilinx/video.txt
new file mode 100644
index 0000000..15720e4
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/xilinx/video.txt
@@ -0,0 +1,52 @@
+DT bindings for Xilinx video IP cores
+-------------------------------------
+
+Xilinx video IP cores process video streams by acting as video sinks and/or
+sources. They are connected by links through their input and output ports,
+creating a video pipeline.
+
+Each video IP core is represented by an AMBA bus child node in the device
+tree using bindings documented in this directory. Connections between the IP
+cores are represented as defined in ../video-interfaces.txt.
+
+The whole  pipeline is represented by an AMBA bus child node in the device
+tree using bindings documented in ./xlnx,video.txt.
+
+Common properties
+-----------------
+
+The following properties are common to all Xilinx video IP cores.
+
+- xlnx,video-format: This property represents a video format transmitted on an
+  AXI bus between video IP cores. How the format relates to the IP core is
+  decribed in the IP core bindings documentation. The following formats are
+  supported.
+
+	rbg
+	xrgb
+	yuv422
+	yuv444
+	rggb
+	grbg
+	gbrg
+	bggr
+
+- xlnx,video-width: This property qualifies the video format with the sample
+  width expressed as a number of bits per pixel component. All components must
+  use the same width.
+
+The following table lists the supported formats and widths combinations, along
+with the corresponding media bus pixel code.
+
+----------------+-------+-------------------------------------------------------
+Format		| Width	| Media bus code
+----------------+-------+-------------------------------------------------------
+rbg		| 8	| V4L2_MBUS_FMT_RBG888_1X24
+xrgb		| 8	| V4L2_MBUS_FMT_RGB888_1X32_PADHI
+yuv422		| 8	| V4L2_MBUS_FMT_UYVY8_1X16
+yuv444		| 8	| V4L2_MBUS_FMT_VUY888_1X24
+rggb		| 8	| V4L2_MBUS_FMT_SRGGB8_1X8
+grbg		| 8	| V4L2_MBUS_FMT_SGRBG8_1X8
+gbrg		| 8	| V4L2_MBUS_FMT_SGBRG8_1X8
+bggr		| 8	| V4L2_MBUS_FMT_SBGGR8_1X8
+----------------+-------+-------------------------------------------------------
diff --git a/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt b/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
new file mode 100644
index 0000000..5a02270
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
@@ -0,0 +1,55 @@
+Xilinx Video IP Pipeline (VIPP)
+-------------------------------
+
+General concept
+---------------
+
+Xilinx video IP pipeline processes video streams through one or more Xilinx
+video IP cores. Each video IP core is represented as documented in video.txt
+and IP core specific documentation, xlnx,v-*.txt, in this directory. The DT
+node of the VIPP represents as a top level node of the pipeline and defines
+mappings between DMAs and the video IP cores.
+
+Required properties:
+
+- compatible: Must be "xlnx,video".
+
+- dmas, dma-names: List of one DMA specifier and identifier string (as defined
+  in Documentation/devicetree/bindings/dma/dma.txt) per port. Each port
+  requires a DMA channel with the identifier string set to "port" followed by
+  the port index.
+
+- ports: Video port, using the DT bindings defined in ../video-interfaces.txt.
+
+Required port properties:
+
+- direction: should be either "input" or "output" depending on the direction
+  of stream.
+
+Example:
+
+	video_cap {
+		compatible = "xlnx,video";
+		dmas = <&vdma_1 1>, <&vdma_3 1>;
+		dma-names = "port0", "port1";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				direction = "input";
+				vcap0_in0: endpoint {
+					remote-endpoint = <&scaler0_out>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				direction = "input";
+				vcap0_in1: endpoint {
+					remote-endpoint = <&switch_out1>;
+				};
+			};
+		};
+	};
diff --git a/MAINTAINERS b/MAINTAINERS
index a6288ca..789e36f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10392,6 +10392,15 @@ L:	linux-serial@vger.kernel.org
 S:	Maintained
 F:	drivers/tty/serial/uartlite.c
 
+XILINX VIDEO IP CORES
+M:	Hyun Kwon <hyun.kwon@xilinx.com>
+M:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+L:	linux-media@vger.kernel.org
+T:	git git://linuxtv.org/media_tree.git
+S:	Supported
+F:	Documentation/devicetree/bindings/media/xilinx/
+F:	drivers/media/platform/xilinx/
+
 XILLYBUS DRIVER
 M:	Eli Billauer <eli.billauer@gmail.com>
 L:	linux-kernel@vger.kernel.org
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 0c61155..67c24c2 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -126,6 +126,7 @@ config VIDEO_S3C_CAMIF
 source "drivers/media/platform/soc_camera/Kconfig"
 source "drivers/media/platform/exynos4-is/Kconfig"
 source "drivers/media/platform/s5p-tv/Kconfig"
+source "drivers/media/platform/xilinx/Kconfig"
 
 endif # V4L_PLATFORM_DRIVERS
 
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index b818afb..dd72939 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -49,4 +49,6 @@ obj-$(CONFIG_VIDEO_RENESAS_VSP1)	+= vsp1/
 
 obj-y	+= omap/
 
+obj-$(CONFIG_VIDEO_XILINX)		+= xilinx/
+
 ccflags-y += -I$(srctree)/drivers/media/i2c
diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig
new file mode 100644
index 0000000..f4347e9
--- /dev/null
+++ b/drivers/media/platform/xilinx/Kconfig
@@ -0,0 +1,10 @@
+config VIDEO_XILINX
+	tristate "Xilinx Video IP (EXPERIMENTAL)"
+	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
+	select VIDEOBUF2_DMA_CONTIG
+	---help---
+	  Driver for Xilinx Video IP Pipelines
+
+if VIDEO_XILINX
+
+endif #VIDEO_XILINX
diff --git a/drivers/media/platform/xilinx/Makefile b/drivers/media/platform/xilinx/Makefile
new file mode 100644
index 0000000..3ef9c8e
--- /dev/null
+++ b/drivers/media/platform/xilinx/Makefile
@@ -0,0 +1,3 @@
+xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o
+
+obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
new file mode 100644
index 0000000..53a44f8
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -0,0 +1,753 @@
+/*
+ * Xilinx Video DMA
+ *
+ * Copyright (C) 2013-2014 Ideas on Board
+ * Copyright (C) 2013-2014 Xilinx, Inc.
+ *
+ * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
+ *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/amba/xilinx_dma.h>
+#include <linux/lcm.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "xilinx-dma.h"
+#include "xilinx-vip.h"
+#include "xilinx-vipp.h"
+
+#define XVIP_DMA_DEF_FORMAT		V4L2_PIX_FMT_YUYV
+#define XVIP_DMA_DEF_WIDTH		1920
+#define XVIP_DMA_DEF_HEIGHT		1080
+
+/* Minimum and maximum widths are expressed in bytes */
+#define XVIP_DMA_MIN_WIDTH		1U
+#define XVIP_DMA_MAX_WIDTH		65535U
+#define XVIP_DMA_MIN_HEIGHT		1U
+#define XVIP_DMA_MAX_HEIGHT		8191U
+
+/* -----------------------------------------------------------------------------
+ * Helper functions
+ */
+
+static struct v4l2_subdev *
+xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)
+{
+	struct media_pad *remote;
+
+	remote = media_entity_remote_pad(local);
+	if (remote == NULL ||
+	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		return NULL;
+
+	if (pad)
+		*pad = remote->index;
+
+	return media_entity_to_v4l2_subdev(remote->entity);
+}
+
+static int xvip_dma_verify_format(struct xvip_dma *dma)
+{
+	struct v4l2_subdev_format fmt;
+	struct v4l2_subdev *subdev;
+	int ret;
+
+	subdev = xvip_dma_remote_subdev(&dma->pad, &fmt.pad);
+	if (subdev == NULL)
+		return -EPIPE;
+
+	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
+	if (ret < 0)
+		return ret == -ENOIOCTLCMD ? -EINVAL : ret;
+
+	if (dma->fmtinfo->code != fmt.format.code ||
+	    dma->format.height != fmt.format.height ||
+	    dma->format.width != fmt.format.width ||
+	    dma->format.colorspace != fmt.format.colorspace)
+		return -EINVAL;
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Pipeline Stream Management
+ */
+
+/**
+ * xvip_pipeline_start_stop - Start ot stop streaming on a pipeline
+ * @pipe: The pipeline
+ * @start: Start (when true) or stop (when false) the pipeline
+ *
+ * Walk the entities chain starting at the pipeline output video node and start
+ * or stop all of them.
+ *
+ * Return: 0 if successful, or the return value of the failed video::s_stream
+ * operation otherwise.
+ */
+static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)
+{
+	struct xvip_dma *dma = pipe->output;
+	struct media_entity *entity;
+	struct media_pad *pad;
+	struct v4l2_subdev *subdev;
+	int ret;
+
+	entity = &dma->video.entity;
+	while (1) {
+		pad = &entity->pads[0];
+		if (!(pad->flags & MEDIA_PAD_FL_SINK))
+			break;
+
+		pad = media_entity_remote_pad(pad);
+		if (pad == NULL ||
+		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+			break;
+
+		entity = pad->entity;
+		subdev = media_entity_to_v4l2_subdev(entity);
+
+		ret = v4l2_subdev_call(subdev, video, s_stream, start);
+		if (start && ret < 0 && ret != -ENOIOCTLCMD)
+			return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * xvip_pipeline_set_stream - Enable/disable streaming on a pipeline
+ * @pipe: The pipeline
+ * @on: Turn the stream on when true or off when false
+ *
+ * The pipeline is shared between all DMA engines connect at its input and
+ * output. While the stream state of DMA engines can be controlled
+ * independently, pipelines have a shared stream state that enable or disable
+ * all entities in the pipeline. For this reason the pipeline uses a streaming
+ * counter that tracks the number of DMA engines that have requested the stream
+ * to be enabled.
+ *
+ * When called with the @on argument set to true, this function will increment
+ * the pipeline streaming count. If the streaming count reaches the number of
+ * DMA engines in the pipeline it will enable all entities that belong to the
+ * pipeline.
+ *
+ * Similarly, when called with the @on argument set to false, this function will
+ * decrement the pipeline streaming count and disable all entities in the
+ * pipeline when the streaming count reaches zero.
+ *
+ * Return: 0 if successful, or the return value of the failed video::s_stream
+ * operation otherwise. Stopping the pipeline never fails. The pipeline state is
+ * not updated when the operation fails.
+ */
+static int xvip_pipeline_set_stream(struct xvip_pipeline *pipe, bool on)
+{
+	int ret = 0;
+
+	mutex_lock(&pipe->lock);
+
+	if (on) {
+		if (pipe->stream_count == pipe->num_dmas - 1) {
+			ret = xvip_pipeline_start_stop(pipe, true);
+			if (ret < 0)
+				goto done;
+		}
+		pipe->stream_count++;
+	} else {
+		if (--pipe->stream_count == 0)
+			xvip_pipeline_start_stop(pipe, false);
+	}
+
+done:
+	mutex_unlock(&pipe->lock);
+	return ret;
+}
+
+static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
+				  struct xvip_dma *start)
+{
+	struct media_entity_graph graph;
+	struct media_entity *entity = &start->video.entity;
+	struct media_device *mdev = entity->parent;
+	unsigned int num_inputs = 0;
+	unsigned int num_outputs = 0;
+
+	mutex_lock(&mdev->graph_mutex);
+
+	/* Walk the graph to locate the video nodes. */
+	media_entity_graph_walk_start(&graph, entity);
+
+	while ((entity = media_entity_graph_walk_next(&graph))) {
+		struct xvip_dma *dma;
+
+		if (entity->type != MEDIA_ENT_T_DEVNODE_V4L)
+			continue;
+
+		dma = to_xvip_dma(media_entity_to_video_device(entity));
+
+		if (dma->pad.flags & MEDIA_PAD_FL_SINK) {
+			pipe->output = dma;
+			num_outputs++;
+		} else {
+			num_inputs++;
+		}
+	}
+
+	mutex_unlock(&mdev->graph_mutex);
+
+	/* We need exactly one output and zero or one input. */
+	if (num_outputs != 1 || num_inputs > 1)
+		return -EPIPE;
+
+	pipe->num_dmas = num_inputs + num_outputs;
+
+	return 0;
+}
+
+static void __xvip_pipeline_cleanup(struct xvip_pipeline *pipe)
+{
+	pipe->num_dmas = 0;
+	pipe->output = NULL;
+}
+
+/**
+ * xvip_pipeline_cleanup - Cleanup the pipeline after streaming
+ * @pipe: the pipeline
+ *
+ * Decrease the pipeline use count and clean it up if we were the last user.
+ */
+static void xvip_pipeline_cleanup(struct xvip_pipeline *pipe)
+{
+	mutex_lock(&pipe->lock);
+
+	/* If we're the last user clean up the pipeline. */
+	if (--pipe->use_count == 0)
+		__xvip_pipeline_cleanup(pipe);
+
+	mutex_unlock(&pipe->lock);
+}
+
+/**
+ * xvip_pipeline_prepare - Prepare the pipeline for streaming
+ * @pipe: the pipeline
+ * @dma: DMA engine at one end of the pipeline
+ *
+ * Validate the pipeline if no user exists yet, otherwise just increase the use
+ * count.
+ *
+ * Return: 0 if successful or -EPIPE if the pipeline is not valid.
+ */
+static int xvip_pipeline_prepare(struct xvip_pipeline *pipe,
+				 struct xvip_dma *dma)
+{
+	int ret;
+
+	mutex_lock(&pipe->lock);
+
+	/* If we're the first user validate and initialize the pipeline. */
+	if (pipe->use_count == 0) {
+		ret = xvip_pipeline_validate(pipe, dma);
+		if (ret < 0) {
+			__xvip_pipeline_cleanup(pipe);
+			goto done;
+		}
+	}
+
+	pipe->use_count++;
+	ret = 0;
+
+done:
+	mutex_unlock(&pipe->lock);
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * videobuf2 queue operations
+ */
+
+/**
+ * struct xvip_dma_buffer - Video DMA buffer
+ * @buf: vb2 buffer base object
+ * @queue: buffer list entry in the DMA engine queued buffers list
+ * @dma: DMA channel that uses the buffer
+ */
+struct xvip_dma_buffer {
+	struct vb2_buffer buf;
+	struct list_head queue;
+	struct xvip_dma *dma;
+};
+
+#define to_xvip_dma_buffer(vb)	container_of(vb, struct xvip_dma_buffer, buf)
+
+static void xvip_dma_complete(void *param)
+{
+	struct xvip_dma_buffer *buf = param;
+	struct xvip_dma *dma = buf->dma;
+
+	spin_lock(&dma->queued_lock);
+	list_del(&buf->queue);
+	spin_unlock(&dma->queued_lock);
+
+	buf->buf.v4l2_buf.sequence = dma->sequence++;
+	v4l2_get_timestamp(&buf->buf.v4l2_buf.timestamp);
+	vb2_set_plane_payload(&buf->buf, 0, dma->format.sizeimage);
+	vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE);
+}
+
+static int
+xvip_dma_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+		     unsigned int *nbuffers, unsigned int *nplanes,
+		     unsigned int sizes[], void *alloc_ctxs[])
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vq);
+
+	*nplanes = 1;
+
+	sizes[0] = dma->format.sizeimage;
+	alloc_ctxs[0] = dma->alloc_ctx;
+
+	return 0;
+}
+
+static int xvip_dma_buffer_prepare(struct vb2_buffer *vb)
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
+	struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vb);
+
+	buf->dma = dma;
+
+	return 0;
+}
+
+static void xvip_dma_buffer_queue(struct vb2_buffer *vb)
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
+	struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vb);
+	struct dma_async_tx_descriptor *desc;
+	dma_addr_t addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+	u32 flags;
+
+	if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
+		dma->xt.dir = DMA_DEV_TO_MEM;
+		dma->xt.src_sgl = false;
+		dma->xt.dst_sgl = true;
+		dma->xt.dst_start = addr;
+	} else {
+		flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
+		dma->xt.dir = DMA_MEM_TO_DEV;
+		dma->xt.src_sgl = true;
+		dma->xt.dst_sgl = false;
+		dma->xt.src_start = addr;
+	}
+
+	dma->xt.frame_size = 1;
+	dma->sgl[0].size = dma->format.width * dma->fmtinfo->bpp;
+	dma->sgl[0].icg = dma->format.bytesperline - dma->sgl[0].size;
+	dma->xt.numf = dma->format.height;
+
+	desc = dmaengine_prep_interleaved_dma(dma->dma, &dma->xt, flags);
+	if (!desc) {
+		dev_err(dma->xdev->dev, "Failed to prepare DMA transfer\n");
+		vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR);
+		return;
+	}
+	desc->callback = xvip_dma_complete;
+	desc->callback_param = buf;
+
+	spin_lock_irq(&dma->queued_lock);
+	list_add_tail(&buf->queue, &dma->queued_bufs);
+	spin_unlock_irq(&dma->queued_lock);
+
+	dmaengine_submit(desc);
+
+	if (vb2_is_streaming(&dma->queue))
+		dma_async_issue_pending(dma->dma);
+}
+
+static int xvip_dma_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vq);
+	struct xvip_dma_buffer *buf, *nbuf;
+	struct xvip_pipeline *pipe;
+	int ret;
+
+	dma->sequence = 0;
+
+	/*
+	 * Start streaming on the pipeline. No link touching an entity in the
+	 * pipeline can be activated or deactivated once streaming is started.
+	 *
+	 * Use the pipeline object embedded in the first DMA object that starts
+	 * streaming.
+	 */
+	pipe = dma->video.entity.pipe
+	     ? to_xvip_pipeline(&dma->video.entity) : &dma->pipe;
+
+	ret = media_entity_pipeline_start(&dma->video.entity, &pipe->pipe);
+	if (ret < 0)
+		goto error;
+
+	/* Verify that the configured format matches the output of the
+	 * connected subdev.
+	 */
+	ret = xvip_dma_verify_format(dma);
+	if (ret < 0)
+		goto error_stop;
+
+	ret = xvip_pipeline_prepare(pipe, dma);
+	if (ret < 0)
+		goto error_stop;
+
+	/* Start the DMA engine. This must be done before starting the blocks
+	 * in the pipeline to avoid DMA synchronization issues.
+	 */
+	dma_async_issue_pending(dma->dma);
+
+	/* Start the pipeline. */
+	xvip_pipeline_set_stream(pipe, true);
+
+	return 0;
+
+error_stop:
+	media_entity_pipeline_stop(&dma->video.entity);
+
+error:
+	/* Give back all queued buffers to videobuf2. */
+	spin_lock_irq(&dma->queued_lock);
+	list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) {
+		vb2_buffer_done(&buf->buf, VB2_BUF_STATE_QUEUED);
+		list_del(&buf->queue);
+	}
+	spin_unlock_irq(&dma->queued_lock);
+
+	return ret;
+}
+
+static void xvip_dma_stop_streaming(struct vb2_queue *vq)
+{
+	struct xvip_dma *dma = vb2_get_drv_priv(vq);
+	struct xvip_pipeline *pipe = to_xvip_pipeline(&dma->video.entity);
+	struct xvip_dma_buffer *buf, *nbuf;
+
+	/* Stop the pipeline. */
+	xvip_pipeline_set_stream(pipe, false);
+
+	/* Stop and reset the DMA engine. */
+	dmaengine_device_control(dma->dma, DMA_TERMINATE_ALL, 0);
+
+	/* Cleanup the pipeline and mark it as being stopped. */
+	xvip_pipeline_cleanup(pipe);
+	media_entity_pipeline_stop(&dma->video.entity);
+
+	/* Give back all queued buffers to videobuf2. */
+	spin_lock_irq(&dma->queued_lock);
+	list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) {
+		vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR);
+		list_del(&buf->queue);
+	}
+	spin_unlock_irq(&dma->queued_lock);
+}
+
+static struct vb2_ops xvip_dma_queue_qops = {
+	.queue_setup = xvip_dma_queue_setup,
+	.buf_prepare = xvip_dma_buffer_prepare,
+	.buf_queue = xvip_dma_buffer_queue,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+	.start_streaming = xvip_dma_start_streaming,
+	.stop_streaming = xvip_dma_stop_streaming,
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 ioctls
+ */
+
+static int
+xvip_dma_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+
+	cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
+			  | dma->xdev->v4l2_caps;
+
+	if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+	else
+		cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+
+	strlcpy(cap->driver, "xilinx-vipp", sizeof(cap->driver));
+	strlcpy(cap->card, dma->video.name, sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s:%u",
+		 dma->xdev->dev->of_node->name, dma->port);
+
+	return 0;
+}
+
+/* FIXME: without this callback function, some applications are not configured
+ * with correct formats, and it results in frames in wrong format. Whether this
+ * callback needs to be required is not clearly defined, so it should be
+ * clarified through the mailing list.
+ */
+static int
+xvip_dma_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+
+	if (f->index > 0)
+		return -EINVAL;
+
+	f->pixelformat = dma->format.pixelformat;
+	strlcpy(f->description, dma->fmtinfo->description,
+		sizeof(f->description));
+
+	return 0;
+}
+
+static int
+xvip_dma_get_format(struct file *file, void *fh, struct v4l2_format *format)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+
+	format->fmt.pix = dma->format;
+
+	return 0;
+}
+
+static void
+__xvip_dma_try_format(struct xvip_dma *dma, struct v4l2_pix_format *pix,
+		      const struct xvip_video_format **fmtinfo)
+{
+	const struct xvip_video_format *info;
+	unsigned int min_width;
+	unsigned int max_width;
+	unsigned int min_bpl;
+	unsigned int max_bpl;
+	unsigned int width;
+	unsigned int align;
+	unsigned int bpl;
+
+	/* Retrieve format information and select the default format if the
+	 * requested format isn't supported.
+	 */
+	info = xvip_get_format_by_fourcc(pix->pixelformat);
+	if (IS_ERR(info))
+		info = xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT);
+
+	pix->pixelformat = info->fourcc;
+	pix->field = V4L2_FIELD_NONE;
+
+	/* The transfer alignment requirements are expressed in bytes. Compute
+	 * the minimum and maximum values, clamp the requested width and convert
+	 * it back to pixels.
+	 */
+	align = lcm(dma->align, info->bpp);
+	min_width = roundup(XVIP_DMA_MIN_WIDTH, align);
+	max_width = rounddown(XVIP_DMA_MAX_WIDTH, align);
+	width = rounddown(pix->width * info->bpp, align);
+
+	pix->width = clamp(width, min_width, max_width) / info->bpp;
+	pix->height = clamp(pix->height, XVIP_DMA_MIN_HEIGHT,
+			    XVIP_DMA_MAX_HEIGHT);
+
+	/* Clamp the requested bytes per line value. If the maximum bytes per
+	 * line value is zero, the module doesn't support user configurable line
+	 * sizes. Override the requested value with the minimum in that case.
+	 */
+	min_bpl = pix->width * info->bpp;
+	max_bpl = rounddown(XVIP_DMA_MAX_WIDTH, dma->align);
+	bpl = rounddown(pix->bytesperline, dma->align);
+
+	pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
+	pix->sizeimage = pix->bytesperline * pix->height;
+
+	if (fmtinfo)
+		*fmtinfo = info;
+}
+
+static int
+xvip_dma_try_format(struct file *file, void *fh, struct v4l2_format *format)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+
+	__xvip_dma_try_format(dma, &format->fmt.pix, NULL);
+	return 0;
+}
+
+static int
+xvip_dma_set_format(struct file *file, void *fh, struct v4l2_format *format)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
+	const struct xvip_video_format *info;
+
+	__xvip_dma_try_format(dma, &format->fmt.pix, &info);
+
+	if (vb2_is_busy(&dma->queue))
+		return -EBUSY;
+
+	dma->format = format->fmt.pix;
+	dma->fmtinfo = info;
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops xvip_dma_ioctl_ops = {
+	.vidioc_querycap		= xvip_dma_querycap,
+	.vidioc_enum_fmt_vid_cap	= xvip_dma_enum_format,
+	.vidioc_g_fmt_vid_cap		= xvip_dma_get_format,
+	.vidioc_g_fmt_vid_out		= xvip_dma_get_format,
+	.vidioc_s_fmt_vid_cap		= xvip_dma_set_format,
+	.vidioc_s_fmt_vid_out		= xvip_dma_set_format,
+	.vidioc_try_fmt_vid_cap		= xvip_dma_try_format,
+	.vidioc_try_fmt_vid_out		= xvip_dma_try_format,
+	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
+	.vidioc_querybuf		= vb2_ioctl_querybuf,
+	.vidioc_qbuf			= vb2_ioctl_qbuf,
+	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
+	.vidioc_expbuf			= vb2_ioctl_expbuf,
+	.vidioc_streamon		= vb2_ioctl_streamon,
+	.vidioc_streamoff		= vb2_ioctl_streamoff,
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 file operations
+ */
+
+static const struct v4l2_file_operations xvip_dma_fops = {
+	.owner		= THIS_MODULE,
+	.unlocked_ioctl	= video_ioctl2,
+	.open		= v4l2_fh_open,
+	.release	= vb2_fop_release,
+	.poll		= vb2_fop_poll,
+	.mmap		= vb2_fop_mmap,
+};
+
+/* -----------------------------------------------------------------------------
+ * Xilinx Video DMA Core
+ */
+
+int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
+		  enum v4l2_buf_type type, unsigned int port)
+{
+	char name[14];
+	int ret;
+
+	dma->xdev = xdev;
+	dma->port = port;
+	mutex_init(&dma->lock);
+	mutex_init(&dma->pipe.lock);
+	INIT_LIST_HEAD(&dma->queued_bufs);
+	spin_lock_init(&dma->queued_lock);
+
+	dma->fmtinfo = xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT);
+	dma->format.pixelformat = dma->fmtinfo->fourcc;
+	dma->format.colorspace = V4L2_COLORSPACE_SRGB;
+	dma->format.field = V4L2_FIELD_NONE;
+	dma->format.width = XVIP_DMA_DEF_WIDTH;
+	dma->format.height = XVIP_DMA_DEF_HEIGHT;
+	dma->format.bytesperline = dma->format.width * dma->fmtinfo->bpp;
+	dma->format.sizeimage = dma->format.bytesperline * dma->format.height;
+
+	/* Initialize the media entity... */
+	dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+		       ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+
+	ret = media_entity_init(&dma->video.entity, 1, &dma->pad, 0);
+	if (ret < 0)
+		goto error;
+
+	/* ... and the video node... */
+	dma->video.fops = &xvip_dma_fops;
+	dma->video.v4l2_dev = &xdev->v4l2_dev;
+	dma->video.queue = &dma->queue;
+	snprintf(dma->video.name, sizeof(dma->video.name), "%s %s %u",
+		 xdev->dev->of_node->name,
+		 type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "output" : "input",
+		 port);
+	dma->video.vfl_type = VFL_TYPE_GRABBER;
+	dma->video.vfl_dir = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+			   ? VFL_DIR_RX : VFL_DIR_TX;
+	dma->video.release = video_device_release_empty;
+	dma->video.ioctl_ops = &xvip_dma_ioctl_ops;
+	dma->video.lock = &dma->lock;
+
+	video_set_drvdata(&dma->video, dma);
+
+	/* ... and the buffers queue... */
+	dma->alloc_ctx = vb2_dma_contig_init_ctx(dma->xdev->dev);
+	if (IS_ERR(dma->alloc_ctx))
+		goto error;
+
+	dma->queue.type = type;
+	dma->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+	dma->queue.lock = &dma->lock;
+	dma->queue.drv_priv = dma;
+	dma->queue.buf_struct_size = sizeof(struct xvip_dma_buffer);
+	dma->queue.ops = &xvip_dma_queue_qops;
+	dma->queue.mem_ops = &vb2_dma_contig_memops;
+	dma->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
+				   | V4L2_BUF_FLAG_TSTAMP_SRC_EOF;
+	ret = vb2_queue_init(&dma->queue);
+	if (ret < 0) {
+		dev_err(dma->xdev->dev, "failed to initialize VB2 queue\n");
+		goto error;
+	}
+
+	/* ... and the DMA channel. */
+	sprintf(name, "port%u", port);
+	dma->dma = dma_request_slave_channel(dma->xdev->dev, name);
+	if (dma->dma == NULL) {
+		dev_err(dma->xdev->dev, "no VDMA channel found\n");
+		ret = -ENODEV;
+		goto error;
+	}
+
+	dma->align = 1 << dma->dma->device->copy_align;
+
+	ret = video_register_device(&dma->video, VFL_TYPE_GRABBER, -1);
+	if (ret < 0) {
+		dev_err(dma->xdev->dev, "failed to register video device\n");
+		goto error;
+	}
+
+	return 0;
+
+error:
+	xvip_dma_cleanup(dma);
+	return ret;
+}
+
+void xvip_dma_cleanup(struct xvip_dma *dma)
+{
+	if (video_is_registered(&dma->video))
+		video_unregister_device(&dma->video);
+
+	if (dma->dma)
+		dma_release_channel(dma->dma);
+
+	if (!IS_ERR_OR_NULL(dma->alloc_ctx))
+		vb2_dma_contig_cleanup_ctx(dma->alloc_ctx);
+
+	media_entity_cleanup(&dma->video.entity);
+
+	mutex_destroy(&dma->lock);
+	mutex_destroy(&dma->pipe.lock);
+}
diff --git a/drivers/media/platform/xilinx/xilinx-dma.h b/drivers/media/platform/xilinx/xilinx-dma.h
new file mode 100644
index 0000000..95bf6b2
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-dma.h
@@ -0,0 +1,109 @@
+/*
+ * Xilinx Video DMA
+ *
+ * Copyright (C) 2013-2014 Ideas on Board
+ * Copyright (C) 2013-2014 Xilinx, Inc.
+ *
+ * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
+ *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __XILINX_VIP_DMA_H__
+#define __XILINX_VIP_DMA_H__
+
+#include <linux/dmaengine.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+
+#include <media/media-entity.h>
+#include <media/v4l2-dev.h>
+#include <media/videobuf2-core.h>
+
+struct dma_chan;
+struct xvip_composite_device;
+struct xvip_video_format;
+
+/**
+ * struct xvip_pipeline - Xilinx Video IP pipeline structure
+ * @pipe: media pipeline
+ * @lock: protects the pipeline @stream_count
+ * @use_count: number of DMA engines using the pipeline
+ * @stream_count: number of DMA engines currently streaming
+ * @num_dmas: number of DMA engines in the pipeline
+ * @output: DMA engine at the output of the pipeline
+ */
+struct xvip_pipeline {
+	struct media_pipeline pipe;
+
+	struct mutex lock;
+	unsigned int use_count;
+	unsigned int stream_count;
+
+	unsigned int num_dmas;
+	struct xvip_dma *output;
+};
+
+static inline struct xvip_pipeline *to_xvip_pipeline(struct media_entity *e)
+{
+	return container_of(e->pipe, struct xvip_pipeline, pipe);
+}
+
+/**
+ * struct xvip_dma - Video DMA channel
+ * @list: list entry in a composite device dmas list
+ * @video: V4L2 video device associated with the DMA channel
+ * @pad: media pad for the video device entity
+ * @xdev: composite device the DMA channel belongs to
+ * @pipe: pipeline belonging to the DMA channel
+ * @port: composite device DT node port number for the DMA channel
+ * @lock: protects the @format, @fmtinfo and @queue fields
+ * @format: active V4L2 pixel format
+ * @fmtinfo: format information corresponding to the active @format
+ * @queue: vb2 buffers queue
+ * @alloc_ctx: allocation context for the vb2 @queue
+ * @sequence: V4L2 buffers sequence number
+ * @queued_bufs: list of queued buffers
+ * @queued_lock: protects the buf_queued list
+ * @dma: DMA engine channel
+ * @align: transfer alignment required by the DMA channel (in bytes)
+ * @xt: dma interleaved template for dma configuration
+ * @sgl: data chunk structure for dma_interleaved_template
+ */
+struct xvip_dma {
+	struct list_head list;
+	struct video_device video;
+	struct media_pad pad;
+
+	struct xvip_composite_device *xdev;
+	struct xvip_pipeline pipe;
+	unsigned int port;
+
+	struct mutex lock;
+	struct v4l2_pix_format format;
+	const struct xvip_video_format *fmtinfo;
+
+	struct vb2_queue queue;
+	void *alloc_ctx;
+	unsigned int sequence;
+
+	struct list_head queued_bufs;
+	spinlock_t queued_lock;
+
+	struct dma_chan *dma;
+	unsigned int align;
+	struct dma_interleaved_template xt;
+	struct data_chunk sgl[1];
+};
+
+#define to_xvip_dma(vdev)	container_of(vdev, struct xvip_dma, video)
+
+int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
+		  enum v4l2_buf_type type, unsigned int port);
+void xvip_dma_cleanup(struct xvip_dma *dma);
+
+#endif /* __XILINX_VIP_DMA_H__ */
diff --git a/drivers/media/platform/xilinx/xilinx-vip.c b/drivers/media/platform/xilinx/xilinx-vip.c
new file mode 100644
index 0000000..3f064df
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-vip.c
@@ -0,0 +1,296 @@
+/*
+ * Xilinx Video IP Core
+ *
+ * Copyright (C) 2013-2014 Ideas on Board
+ * Copyright (C) 2013-2014 Xilinx, Inc.
+ *
+ * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
+ *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "xilinx-vip.h"
+
+/* -----------------------------------------------------------------------------
+ * Helper functions
+ */
+
+static const struct xvip_video_format xvip_video_formats[] = {
+	{ "rbg", 8, 3, MEDIA_BUS_FMT_RBG888_1X24, 0, NULL },
+	{ "xrgb", 8, 4, MEDIA_BUS_FMT_RGB888_1X32_PADHI, V4L2_PIX_FMT_BGR32,
+	  "RGB32 (BE)" },
+	{ "yuv422", 8, 2, MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_YUYV,
+	  "4:2:2, packed, YUYV" },
+	{ "yuv444", 8, 3, MEDIA_BUS_FMT_VUY8_1X24, V4L2_PIX_FMT_YUV444,
+	  "4:4:4, packed, YUYV" },
+	{ "rggb", 8, 1, MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SGRBG8,
+	  "Bayer 8-bit RGGB" },
+	{ "grbg", 8, 1, MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8,
+	  "Bayer 8-bit GRBG" },
+	{ "gbrg", 8, 1, MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8,
+	  "Bayer 8-bit GBRG" },
+	{ "bggr", 8, 1, MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8,
+	  "Bayer 8-bit BGGR" },
+};
+
+/**
+ * xvip_get_format_by_code - Retrieve format information for a media bus code
+ * @code: the format media bus code
+ *
+ * Return: a pointer to the format information structure corresponding to the
+ * given V4L2 media bus format @code, or ERR_PTR if no corresponding format can
+ * be found.
+ */
+const struct xvip_video_format *xvip_get_format_by_code(unsigned int code)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) {
+		const struct xvip_video_format *format = &xvip_video_formats[i];
+
+		if (format->code == code)
+			return format;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(xvip_get_format_by_code);
+
+/**
+ * xvip_get_format_by_fourcc - Retrieve format information for a 4CC
+ * @fourcc: the format 4CC
+ *
+ * Return: a pointer to the format information structure corresponding to the
+ * given V4L2 format @fourcc, or ERR_PTR if no corresponding format can be
+ * found.
+ */
+const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) {
+		const struct xvip_video_format *format = &xvip_video_formats[i];
+
+		if (format->fourcc == fourcc)
+			return format;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(xvip_get_format_by_fourcc);
+
+/**
+ * xvip_of_get_format - Parse a device tree node and return format information
+ * @node: the device tree node
+ *
+ * Read the xlnx,video-format and xlnx,video-width properties from the device
+ * tree @node passed as an argument and return the corresponding format
+ * information.
+ *
+ * Return: a pointer to the format information structure corresponding to the
+ * format name and width, or ERR_PTR if no corresponding format can be found.
+ */
+const struct xvip_video_format *xvip_of_get_format(struct device_node *node)
+{
+	const char *name;
+	unsigned int i;
+	u32 width;
+	int ret;
+
+	ret = of_property_read_string(node, "xlnx,video-format", &name);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	ret = of_property_read_u32(node, "xlnx,video-width", &width);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) {
+		const struct xvip_video_format *format = &xvip_video_formats[i];
+
+		if (strcmp(format->name, name) == 0 && format->width == width)
+			return format;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(xvip_of_get_format);
+
+/**
+ * xvip_set_format_size - Set the media bus frame format size
+ * @format: V4L2 frame format on media bus
+ * @fmt: media bus format
+ *
+ * Set the media bus frame format size. The width / height from the subdevice
+ * format are set to the given media bus format. The new format size is stored
+ * in @format. The width and height are clamped using default min / max values.
+ */
+void xvip_set_format_size(struct v4l2_mbus_framefmt *format,
+			  const struct v4l2_subdev_format *fmt)
+{
+	format->width = clamp_t(unsigned int, fmt->format.width,
+				XVIP_MIN_WIDTH, XVIP_MAX_WIDTH);
+	format->height = clamp_t(unsigned int, fmt->format.height,
+			 XVIP_MIN_HEIGHT, XVIP_MAX_HEIGHT);
+}
+EXPORT_SYMBOL_GPL(xvip_set_format_size);
+
+/**
+ * xvip_clr_or_set - Clear or set the register with a bitmask
+ * @xvip: Xilinx Video IP device
+ * @addr: address of register
+ * @mask: bitmask to be set or cleared
+ * @set: boolean flag indicating whether to set or clear
+ *
+ * Clear or set the register at address @addr with a bitmask @mask depending on
+ * the boolean flag @set. When the flag @set is true, the bitmask is set in
+ * the register, otherwise the bitmask is cleared from the register
+ * when the flag @set is false.
+ *
+ * Fox eample, this function can be used to set a control with a boolean value
+ * requested by users. If the caller knows whether to set or clear in the first
+ * place, the caller should call xvip_clr() or xvip_set() directly instead of
+ * using this function.
+ */
+void xvip_clr_or_set(struct xvip_device *xvip, u32 addr, u32 mask, bool set)
+{
+	u32 reg;
+
+	reg = xvip_read(xvip, addr);
+	reg = set ? reg | mask : reg & ~mask;
+	xvip_write(xvip, addr, reg);
+}
+EXPORT_SYMBOL_GPL(xvip_clr_or_set);
+
+/**
+ * xvip_clr_and_set - Clear and set the register with a bitmask
+ * @xvip: Xilinx Video IP device
+ * @addr: address of register
+ * @clr: bitmask to be cleared
+ * @set: bitmask to be set
+ *
+ * Clear a bit(s) of mask @clr in the register at address @addr, then set
+ * a bit(s) of mask @set in the register after.
+ */
+void xvip_clr_and_set(struct xvip_device *xvip, u32 addr, u32 clr, u32 set)
+{
+	u32 reg;
+
+	reg = xvip_read(xvip, addr);
+	reg &= ~clr;
+	reg |= set;
+	xvip_write(xvip, addr, reg);
+}
+EXPORT_SYMBOL_GPL(xvip_clr_and_set);
+
+int xvip_init_resources(struct xvip_device *xvip)
+{
+	struct platform_device *pdev = to_platform_device(xvip->dev);
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xvip->iomem = devm_ioremap_resource(xvip->dev, res);
+	if (IS_ERR(xvip->iomem))
+		return PTR_ERR(xvip->iomem);
+
+	xvip->clk = devm_clk_get(xvip->dev, NULL);
+	if (IS_ERR(xvip->clk))
+		return PTR_ERR(xvip->clk);
+
+	clk_prepare_enable(xvip->clk);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xvip_init_resources);
+
+void xvip_cleanup_resources(struct xvip_device *xvip)
+{
+	clk_disable_unprepare(xvip->clk);
+}
+EXPORT_SYMBOL_GPL(xvip_cleanup_resources);
+
+/* -----------------------------------------------------------------------------
+ * Subdev operation helpers
+ */
+
+/**
+ * xvip_enum_mbus_code - Enumerate the media format code
+ * @subdev: V4L2 subdevice
+ * @fh: V4L2 subdevice file handle
+ * @code: returning media bus code
+ *
+ * Enumerate the media bus code of the subdevice. Return the corresponding
+ * pad format code. This function only works for subdevices with fixed format
+ * on all pads. Subdevices with multiple format should have their own
+ * function to enumerate mbus codes.
+ *
+ * Return: 0 if the media bus code is found, or -EINVAL if the format index
+ * is not valid.
+ */
+int xvip_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
+			struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct v4l2_mbus_framefmt *format;
+
+	if (code->index)
+		return -EINVAL;
+
+	format = v4l2_subdev_get_try_format(fh, code->pad);
+
+	code->code = format->code;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xvip_enum_mbus_code);
+
+/**
+ * xvip_enum_frame_size - Enumerate the media bus frame size
+ * @subdev: V4L2 subdevice
+ * @fh: V4L2 subdevice file handle
+ * @fse: returning media bus frame size
+ *
+ * This function is a drop-in implementation of the subdev enum_frame_size pad
+ * operation. It assumes that the subdevice has one sink pad and one source
+ * pad, and that the format on the source pad is always identical to the
+ * format on the sink pad. Entities with different requirements need to
+ * implement their own enum_frame_size handlers.
+ *
+ * Return: 0 if the media bus frame size is found, or -EINVAL
+ * if the index or the code is not valid.
+ */
+int xvip_enum_frame_size(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
+			 struct v4l2_subdev_frame_size_enum *fse)
+{
+	struct v4l2_mbus_framefmt *format;
+
+	format = v4l2_subdev_get_try_format(fh, fse->pad);
+
+	if (fse->index || fse->code != format->code)
+		return -EINVAL;
+
+	if (fse->pad == XVIP_PAD_SINK) {
+		fse->min_width = XVIP_MIN_WIDTH;
+		fse->max_width = XVIP_MAX_WIDTH;
+		fse->min_height = XVIP_MIN_HEIGHT;
+		fse->max_height = XVIP_MAX_HEIGHT;
+	} else {
+		/* The size on the source pad is fixed and always identical to
+		 * the size on the sink pad.
+		 */
+		fse->min_width = format->width;
+		fse->max_width = format->width;
+		fse->min_height = format->height;
+		fse->max_height = format->height;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xvip_enum_frame_size);
diff --git a/drivers/media/platform/xilinx/xilinx-vip.h b/drivers/media/platform/xilinx/xilinx-vip.h
new file mode 100644
index 0000000..780071f
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-vip.h
@@ -0,0 +1,233 @@
+/*
+ * Xilinx Video IP Core
+ *
+ * Copyright (C) 2013-2014 Ideas on Board
+ * Copyright (C) 2013-2014 Xilinx, Inc.
+ *
+ * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
+ *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __XILINX_VIP_H__
+#define __XILINX_VIP_H__
+
+#include <linux/io.h>
+#include <media/v4l2-subdev.h>
+
+struct clk;
+
+/*
+ * Minimum and maximum width and height common to most video IP cores. IP
+ * cores with different requirements must define their own values.
+ */
+#define XVIP_MIN_WIDTH			32
+#define XVIP_MAX_WIDTH			7680
+#define XVIP_MIN_HEIGHT			32
+#define XVIP_MAX_HEIGHT			7680
+
+/*
+ * Pad IDs. IP cores with with multiple inputs or outputs should define
+ * their own values.
+ */
+#define XVIP_PAD_SINK			0
+#define XVIP_PAD_SOURCE			1
+
+/* Xilinx Video IP Control Registers */
+#define XVIP_CTRL_CONTROL			0x0000
+#define XVIP_CTRL_CONTROL_SW_ENABLE		(1 << 0)
+#define XVIP_CTRL_CONTROL_REG_UPDATE		(1 << 1)
+#define XVIP_CTRL_CONTROL_BYPASS		(1 << 4)
+#define XVIP_CTRL_CONTROL_TEST_PATTERN		(1 << 5)
+#define XVIP_CTRL_CONTROL_FRAME_SYNC_RESET	(1 << 30)
+#define XVIP_CTRL_CONTROL_SW_RESET		(1 << 31)
+#define XVIP_CTRL_STATUS			0x0004
+#define XVIP_CTRL_STATUS_PROC_STARTED		(1 << 0)
+#define XVIP_CTRL_STATUS_EOF			(1 << 1)
+#define XVIP_CTRL_ERROR				0x0008
+#define XVIP_CTRL_ERROR_SLAVE_EOL_EARLY		(1 << 0)
+#define XVIP_CTRL_ERROR_SLAVE_EOL_LATE		(1 << 1)
+#define XVIP_CTRL_ERROR_SLAVE_SOF_EARLY		(1 << 2)
+#define XVIP_CTRL_ERROR_SLAVE_SOF_LATE		(1 << 3)
+#define XVIP_CTRL_IRQ_ENABLE			0x000c
+#define XVIP_CTRL_IRQ_ENABLE_PROC_STARTED	(1 << 0)
+#define XVIP_CTRL_IRQ_EOF			(1 << 1)
+#define XVIP_CTRL_VERSION			0x0010
+#define XVIP_CTRL_VERSION_MAJOR_MASK		(0xff << 24)
+#define XVIP_CTRL_VERSION_MAJOR_SHIFT		24
+#define XVIP_CTRL_VERSION_MINOR_MASK		(0xff << 16)
+#define XVIP_CTRL_VERSION_MINOR_SHIFT		16
+#define XVIP_CTRL_VERSION_REVISION_MASK		(0xf << 12)
+#define XVIP_CTRL_VERSION_REVISION_SHIFT	12
+#define XVIP_CTRL_VERSION_PATCH_MASK		(0xf << 8)
+#define XVIP_CTRL_VERSION_PATCH_SHIFT		8
+#define XVIP_CTRL_VERSION_INTERNAL_MASK		(0xff << 0)
+#define XVIP_CTRL_VERSION_INTERNAL_SHIFT	0
+
+/* Xilinx Video IP Timing Registers */
+#define XVIP_ACTIVE_SIZE			0x0020
+#define XVIP_ACTIVE_VSIZE_MASK			(0x7ff << 16)
+#define XVIP_ACTIVE_VSIZE_SHIFT			16
+#define XVIP_ACTIVE_HSIZE_MASK			(0x7ff << 0)
+#define XVIP_ACTIVE_HSIZE_SHIFT			0
+#define XVIP_ENCODING				0x0028
+#define XVIP_ENCODING_NBITS_8			(0 << 4)
+#define XVIP_ENCODING_NBITS_10			(1 << 4)
+#define XVIP_ENCODING_NBITS_12			(2 << 4)
+#define XVIP_ENCODING_NBITS_16			(3 << 4)
+#define XVIP_ENCODING_NBITS_MASK		(3 << 4)
+#define XVIP_ENCODING_NBITS_SHIFT		4
+#define XVIP_ENCODING_VIDEO_FORMAT_YUV422	(0 << 0)
+#define XVIP_ENCODING_VIDEO_FORMAT_YUV444	(1 << 0)
+#define XVIP_ENCODING_VIDEO_FORMAT_RGB		(2 << 0)
+#define XVIP_ENCODING_VIDEO_FORMAT_YUV420	(3 << 0)
+#define XVIP_ENCODING_VIDEO_FORMAT_MASK		(3 << 0)
+#define XVIP_ENCODING_VIDEO_FORMAT_SHIFT	0
+
+/**
+ * struct xvip_device - Xilinx Video IP device structure
+ * @subdev: V4L2 subdevice
+ * @dev: (OF) device
+ * @iomem: device I/O register space remapped to kernel virtual memory
+ * @saved_ctrl: saved control register for resume / suspend
+ */
+struct xvip_device {
+	struct v4l2_subdev subdev;
+	struct device *dev;
+	void __iomem *iomem;
+	struct clk *clk;
+	u32 saved_ctrl;
+};
+
+/**
+ * struct xvip_video_format - Xilinx Video IP video format description
+ * @name: AXI4 format name
+ * @width: AXI4 format width in bits per component
+ * @bpp: bytes per pixel (when stored in memory)
+ * @code: media bus format code
+ * @fourcc: V4L2 pixel format FCC identifier
+ * @description: format description, suitable for userspace
+ */
+struct xvip_video_format {
+	const char *name;
+	unsigned int width;
+	unsigned int bpp;
+	unsigned int code;
+	u32 fourcc;
+	const char *description;
+};
+
+const struct xvip_video_format *xvip_get_format_by_code(unsigned int code);
+const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc);
+const struct xvip_video_format *xvip_of_get_format(struct device_node *node);
+void xvip_set_format_size(struct v4l2_mbus_framefmt *format,
+			  const struct v4l2_subdev_format *fmt);
+int xvip_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
+			struct v4l2_subdev_mbus_code_enum *code);
+int xvip_enum_frame_size(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
+			 struct v4l2_subdev_frame_size_enum *fse);
+
+static inline u32 xvip_read(struct xvip_device *xvip, u32 addr)
+{
+	return ioread32(xvip->iomem + addr);
+}
+
+static inline void xvip_write(struct xvip_device *xvip, u32 addr, u32 value)
+{
+	iowrite32(value, xvip->iomem + addr);
+}
+
+static inline void xvip_clr(struct xvip_device *xvip, u32 addr, u32 clr)
+{
+	xvip_write(xvip, addr, xvip_read(xvip, addr) & ~clr);
+}
+
+static inline void xvip_set(struct xvip_device *xvip, u32 addr, u32 set)
+{
+	xvip_write(xvip, addr, xvip_read(xvip, addr) | set);
+}
+
+void xvip_clr_or_set(struct xvip_device *xvip, u32 addr, u32 mask, bool set);
+void xvip_clr_and_set(struct xvip_device *xvip, u32 addr, u32 clr, u32 set);
+
+int xvip_init_resources(struct xvip_device *xvip);
+void xvip_cleanup_resources(struct xvip_device *xvip);
+
+static inline void xvip_reset(struct xvip_device *xvip)
+{
+	xvip_write(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_RESET);
+}
+
+static inline void xvip_start(struct xvip_device *xvip)
+{
+	xvip_set(xvip, XVIP_CTRL_CONTROL,
+		 XVIP_CTRL_CONTROL_SW_ENABLE | XVIP_CTRL_CONTROL_REG_UPDATE);
+}
+
+static inline void xvip_stop(struct xvip_device *xvip)
+{
+	xvip_clr(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_ENABLE);
+}
+
+static inline void xvip_resume(struct xvip_device *xvip)
+{
+	xvip_write(xvip, XVIP_CTRL_CONTROL,
+		   xvip->saved_ctrl | XVIP_CTRL_CONTROL_SW_ENABLE);
+}
+
+static inline void xvip_suspend(struct xvip_device *xvip)
+{
+	xvip->saved_ctrl = xvip_read(xvip, XVIP_CTRL_CONTROL);
+	xvip_write(xvip, XVIP_CTRL_CONTROL,
+		   xvip->saved_ctrl & ~XVIP_CTRL_CONTROL_SW_ENABLE);
+}
+
+static inline void xvip_set_frame_size(struct xvip_device *xvip,
+				       const struct v4l2_mbus_framefmt *format)
+{
+	xvip_write(xvip, XVIP_ACTIVE_SIZE,
+		   (format->height << XVIP_ACTIVE_VSIZE_SHIFT) |
+		   (format->width << XVIP_ACTIVE_HSIZE_SHIFT));
+}
+
+static inline void xvip_get_frame_size(struct xvip_device *xvip,
+				       struct v4l2_mbus_framefmt *format)
+{
+	u32 reg;
+
+	reg = xvip_read(xvip, XVIP_ACTIVE_SIZE);
+	format->width = (reg & XVIP_ACTIVE_HSIZE_MASK) >>
+			XVIP_ACTIVE_HSIZE_SHIFT;
+	format->height = (reg & XVIP_ACTIVE_VSIZE_MASK) >>
+			 XVIP_ACTIVE_VSIZE_SHIFT;
+}
+
+static inline void xvip_enable_reg_update(struct xvip_device *xvip)
+{
+	xvip_set(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_REG_UPDATE);
+}
+
+static inline void xvip_disable_reg_update(struct xvip_device *xvip)
+{
+	xvip_clr(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_REG_UPDATE);
+}
+
+static inline void xvip_print_version(struct xvip_device *xvip)
+{
+	u32 version;
+
+	version = xvip_read(xvip, XVIP_CTRL_VERSION);
+
+	dev_info(xvip->dev, "device found, version %u.%02x%x\n",
+		 ((version & XVIP_CTRL_VERSION_MAJOR_MASK) >>
+		  XVIP_CTRL_VERSION_MAJOR_SHIFT),
+		 ((version & XVIP_CTRL_VERSION_MINOR_MASK) >>
+		  XVIP_CTRL_VERSION_MINOR_SHIFT),
+		 ((version & XVIP_CTRL_VERSION_REVISION_MASK) >>
+		  XVIP_CTRL_VERSION_REVISION_SHIFT));
+}
+
+#endif /* __XILINX_VIP_H__ */
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
new file mode 100644
index 0000000..76039c2
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -0,0 +1,669 @@
+/*
+ * Xilinx Video IP Composite Device
+ *
+ * Copyright (C) 2013-2014 Ideas on Board
+ * Copyright (C) 2013-2014 Xilinx, Inc.
+ *
+ * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
+ *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-async.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-of.h>
+
+#include "xilinx-dma.h"
+#include "xilinx-vipp.h"
+
+#define XVIPP_DMA_S2MM				0
+#define XVIPP_DMA_MM2S				1
+
+/**
+ * struct xvip_graph_entity - Entity in the video graph
+ * @list: list entry in a graph entities list
+ * @node: the entity's DT node
+ * @entity: media entity, from the corresponding V4L2 subdev
+ * @asd: subdev asynchronous registration information
+ * @subdev: V4L2 subdev
+ */
+struct xvip_graph_entity {
+	struct list_head list;
+	struct device_node *node;
+	struct media_entity *entity;
+
+	struct v4l2_async_subdev asd;
+	struct v4l2_subdev *subdev;
+};
+
+/* -----------------------------------------------------------------------------
+ * Graph Management
+ */
+
+static struct xvip_graph_entity *
+xvip_graph_find_entity(struct xvip_composite_device *xdev,
+		       const struct device_node *node)
+{
+	struct xvip_graph_entity *entity;
+
+	list_for_each_entry(entity, &xdev->entities, list) {
+		if (entity->node == node)
+			return entity;
+	}
+
+	return NULL;
+}
+
+static int xvip_graph_build_one(struct xvip_composite_device *xdev,
+				struct xvip_graph_entity *entity)
+{
+	u32 link_flags = MEDIA_LNK_FL_ENABLED;
+	struct media_entity *local = entity->entity;
+	struct media_entity *remote;
+	struct media_pad *local_pad;
+	struct media_pad *remote_pad;
+	struct xvip_graph_entity *ent;
+	struct v4l2_of_link link;
+	struct device_node *ep = NULL;
+	struct device_node *next;
+	int ret = 0;
+
+	dev_dbg(xdev->dev, "creating links for entity %s\n", local->name);
+
+	while (1) {
+		/* Get the next endpoint and parse its link. */
+		next = of_graph_get_next_endpoint(entity->node, ep);
+		if (next == NULL)
+			break;
+
+		of_node_put(ep);
+		ep = next;
+
+		dev_dbg(xdev->dev, "processing endpoint %s\n", ep->full_name);
+
+		ret = v4l2_of_parse_link(ep, &link);
+		if (ret < 0) {
+			dev_err(xdev->dev, "failed to parse link for %s\n",
+				ep->full_name);
+			continue;
+		}
+
+		/* Skip sink ports, they will be processed from the other end of
+		 * the link.
+		 */
+		if (link.local_port >= local->num_pads) {
+			dev_err(xdev->dev, "invalid port number %u on %s\n",
+				link.local_port, link.local_node->full_name);
+			v4l2_of_put_link(&link);
+			ret = -EINVAL;
+			break;
+		}
+
+		local_pad = &local->pads[link.local_port];
+
+		if (local_pad->flags & MEDIA_PAD_FL_SINK) {
+			dev_dbg(xdev->dev, "skipping sink port %s:%u\n",
+				link.local_node->full_name, link.local_port);
+			v4l2_of_put_link(&link);
+			continue;
+		}
+
+		/* Skip DMA engines, they will be processed separately. */
+		if (link.remote_node == xdev->dev->of_node) {
+			dev_dbg(xdev->dev, "skipping DMA port %s:%u\n",
+				link.local_node->full_name, link.local_port);
+			v4l2_of_put_link(&link);
+			continue;
+		}
+
+		/* Find the remote entity. */
+		ent = xvip_graph_find_entity(xdev, link.remote_node);
+		if (ent == NULL) {
+			dev_err(xdev->dev, "no entity found for %s\n",
+				link.remote_node->full_name);
+			v4l2_of_put_link(&link);
+			ret = -ENODEV;
+			break;
+		}
+
+		remote = ent->entity;
+
+		if (link.remote_port >= remote->num_pads) {
+			dev_err(xdev->dev, "invalid port number %u on %s\n",
+				link.remote_port, link.remote_node->full_name);
+			v4l2_of_put_link(&link);
+			ret = -EINVAL;
+			break;
+		}
+
+		remote_pad = &remote->pads[link.remote_port];
+
+		v4l2_of_put_link(&link);
+
+		/* Create the media link. */
+		dev_dbg(xdev->dev, "creating %s:%u -> %s:%u link\n",
+			local->name, local_pad->index,
+			remote->name, remote_pad->index);
+
+		ret = media_entity_create_link(local, local_pad->index,
+					       remote, remote_pad->index,
+					       link_flags);
+		if (ret < 0) {
+			dev_err(xdev->dev,
+				"failed to create %s:%u -> %s:%u link\n",
+				local->name, local_pad->index,
+				remote->name, remote_pad->index);
+			break;
+		}
+	}
+
+	of_node_put(ep);
+	return ret;
+}
+
+static struct xvip_dma *
+xvip_graph_find_dma(struct xvip_composite_device *xdev, unsigned int port)
+{
+	struct xvip_dma *dma;
+
+	list_for_each_entry(dma, &xdev->dmas, list) {
+		if (dma->port == port)
+			return dma;
+	}
+
+	return NULL;
+}
+
+static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
+{
+	u32 link_flags = MEDIA_LNK_FL_ENABLED;
+	struct device_node *node = xdev->dev->of_node;
+	struct media_entity *source;
+	struct media_entity *sink;
+	struct media_pad *source_pad;
+	struct media_pad *sink_pad;
+	struct xvip_graph_entity *ent;
+	struct v4l2_of_link link;
+	struct device_node *ep = NULL;
+	struct device_node *next;
+	struct xvip_dma *dma;
+	int ret = 0;
+
+	dev_dbg(xdev->dev, "creating links for DMA engines\n");
+
+	while (1) {
+		/* Get the next endpoint and parse its link. */
+		next = of_graph_get_next_endpoint(node, ep);
+		if (next == NULL)
+			break;
+
+		of_node_put(ep);
+		ep = next;
+
+		dev_dbg(xdev->dev, "processing endpoint %s\n", ep->full_name);
+
+		ret = v4l2_of_parse_link(ep, &link);
+		if (ret < 0) {
+			dev_err(xdev->dev, "failed to parse link for %s\n",
+				ep->full_name);
+			continue;
+		}
+
+		/* Find the DMA engine. */
+		dma = xvip_graph_find_dma(xdev, link.local_port);
+		if (dma == NULL) {
+			dev_err(xdev->dev, "no DMA engine found for port %u\n",
+				link.local_port);
+			v4l2_of_put_link(&link);
+			ret = -EINVAL;
+			break;
+		}
+
+		dev_dbg(xdev->dev, "creating link for DMA engine %s\n",
+			dma->video.name);
+
+		/* Find the remote entity. */
+		ent = xvip_graph_find_entity(xdev, link.remote_node);
+		if (ent == NULL) {
+			dev_err(xdev->dev, "no entity found for %s\n",
+				link.remote_node->full_name);
+			v4l2_of_put_link(&link);
+			ret = -ENODEV;
+			break;
+		}
+
+		if (link.remote_port >= ent->entity->num_pads) {
+			dev_err(xdev->dev, "invalid port number %u on %s\n",
+				link.remote_port, link.remote_node->full_name);
+			v4l2_of_put_link(&link);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (dma->pad.flags & MEDIA_PAD_FL_SOURCE) {
+			source = &dma->video.entity;
+			source_pad = &dma->pad;
+			sink = ent->entity;
+			sink_pad = &sink->pads[link.remote_port];
+		} else {
+			source = ent->entity;
+			source_pad = &source->pads[link.remote_port];
+			sink = &dma->video.entity;
+			sink_pad = &dma->pad;
+		}
+
+		v4l2_of_put_link(&link);
+
+		/* Create the media link. */
+		dev_dbg(xdev->dev, "creating %s:%u -> %s:%u link\n",
+			source->name, source_pad->index,
+			sink->name, sink_pad->index);
+
+		ret = media_entity_create_link(source, source_pad->index,
+					       sink, sink_pad->index,
+					       link_flags);
+		if (ret < 0) {
+			dev_err(xdev->dev,
+				"failed to create %s:%u -> %s:%u link\n",
+				source->name, source_pad->index,
+				sink->name, sink_pad->index);
+			break;
+		}
+	}
+
+	of_node_put(ep);
+	return ret;
+}
+
+static int xvip_graph_notify_complete(struct v4l2_async_notifier *notifier)
+{
+	struct xvip_composite_device *xdev =
+		container_of(notifier, struct xvip_composite_device, notifier);
+	struct xvip_graph_entity *entity;
+	int ret;
+
+	dev_dbg(xdev->dev, "notify complete, all subdevs registered\n");
+
+	/* Create links for every entity. */
+	list_for_each_entry(entity, &xdev->entities, list) {
+		ret = xvip_graph_build_one(xdev, entity);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* Create links for DMA channels. */
+	ret = xvip_graph_build_dma(xdev);
+	if (ret < 0)
+		return ret;
+
+	ret = v4l2_device_register_subdev_nodes(&xdev->v4l2_dev);
+	if (ret < 0)
+		dev_err(xdev->dev, "failed to register subdev nodes\n");
+
+	return ret;
+}
+
+static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier,
+				   struct v4l2_subdev *subdev,
+				   struct v4l2_async_subdev *asd)
+{
+	struct xvip_composite_device *xdev =
+		container_of(notifier, struct xvip_composite_device, notifier);
+	struct xvip_graph_entity *entity;
+
+	/* Locate the entity corresponding to the bound subdev and store the
+	 * subdev pointer.
+	 */
+	list_for_each_entry(entity, &xdev->entities, list) {
+		if (entity->node != subdev->dev->of_node)
+			continue;
+
+		if (entity->subdev) {
+			dev_err(xdev->dev, "duplicate subdev for node %s\n",
+				entity->node->full_name);
+			return -EINVAL;
+		}
+
+		dev_dbg(xdev->dev, "subdev %s bound\n", subdev->name);
+		entity->entity = &subdev->entity;
+		entity->subdev = subdev;
+		return 0;
+	}
+
+	dev_err(xdev->dev, "no entity for subdev %s\n", subdev->name);
+	return -EINVAL;
+}
+
+static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
+				struct device_node *node)
+{
+	struct xvip_graph_entity *entity;
+	struct device_node *remote;
+	struct device_node *ep = NULL;
+	struct device_node *next;
+	int ret = 0;
+
+	dev_dbg(xdev->dev, "parsing node %s\n", node->full_name);
+
+	while (1) {
+		next = of_graph_get_next_endpoint(node, ep);
+		if (next == NULL)
+			break;
+
+		of_node_put(ep);
+		ep = next;
+
+		dev_dbg(xdev->dev, "handling endpoint %s\n", ep->full_name);
+
+		remote = of_graph_get_remote_port_parent(ep);
+		if (remote == NULL) {
+			ret = -EINVAL;
+			break;
+		}
+
+		/* Skip entities that we have already processed. */
+		if (remote == xdev->dev->of_node ||
+		    xvip_graph_find_entity(xdev, remote)) {
+			of_node_put(remote);
+			continue;
+		}
+
+		entity = devm_kzalloc(xdev->dev, sizeof(*entity), GFP_KERNEL);
+		if (entity == NULL) {
+			of_node_put(remote);
+			ret = -ENOMEM;
+			break;
+		}
+
+		entity->node = remote;
+		entity->asd.match_type = V4L2_ASYNC_MATCH_OF;
+		entity->asd.match.of.node = remote;
+		list_add_tail(&entity->list, &xdev->entities);
+		xdev->num_subdevs++;
+	}
+
+	of_node_put(ep);
+	return ret;
+}
+
+static int xvip_graph_parse(struct xvip_composite_device *xdev)
+{
+	struct xvip_graph_entity *entity;
+	int ret;
+
+	/*
+	 * Walk the links to parse the full graph. Start by parsing the
+	 * composite node and then parse entities in turn. The list_for_each
+	 * loop will handle entities added at the end of the list while walking
+	 * the links.
+	 */
+	ret = xvip_graph_parse_one(xdev, xdev->dev->of_node);
+	if (ret < 0)
+		return 0;
+
+	list_for_each_entry(entity, &xdev->entities, list) {
+		ret = xvip_graph_parse_one(xdev, entity->node);
+		if (ret < 0)
+			break;
+	}
+
+	return ret;
+}
+
+static int xvip_graph_dma_init_one(struct xvip_composite_device *xdev,
+				   struct device_node *node)
+{
+	struct xvip_dma *dma;
+	enum v4l2_buf_type type;
+	const char *direction;
+	unsigned int index;
+	int ret;
+
+	ret = of_property_read_string(node, "direction", &direction);
+	if (ret < 0)
+		return ret;
+
+	if (strcmp(direction, "input") == 0)
+		type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	else if (strcmp(direction, "output") == 0)
+		type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+	else
+		return -EINVAL;
+
+	of_property_read_u32(node, "reg", &index);
+
+	dma = devm_kzalloc(xdev->dev, sizeof(*dma), GFP_KERNEL);
+	if (dma == NULL)
+		return -ENOMEM;
+
+	ret = xvip_dma_init(xdev, dma, type, index);
+	if (ret < 0) {
+		dev_err(xdev->dev, "%s initialization failed\n",
+			node->full_name);
+		return ret;
+	}
+
+	list_add_tail(&dma->list, &xdev->dmas);
+
+	xdev->v4l2_caps |= type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+			 ? V4L2_CAP_VIDEO_CAPTURE : V4L2_CAP_VIDEO_OUTPUT;
+
+	return 0;
+}
+
+static int xvip_graph_dma_init(struct xvip_composite_device *xdev)
+{
+	struct device_node *ports;
+	struct device_node *port;
+	int ret;
+
+	ports = of_get_child_by_name(xdev->dev->of_node, "ports");
+	if (ports == NULL) {
+		dev_err(xdev->dev, "ports node not present\n");
+		return -EINVAL;
+	}
+
+	for_each_child_of_node(ports, port) {
+		ret = xvip_graph_dma_init_one(xdev, port);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void xvip_graph_cleanup(struct xvip_composite_device *xdev)
+{
+	struct xvip_graph_entity *entityp;
+	struct xvip_graph_entity *entity;
+	struct xvip_dma *dmap;
+	struct xvip_dma *dma;
+
+	v4l2_async_notifier_unregister(&xdev->notifier);
+
+	list_for_each_entry_safe(entity, entityp, &xdev->entities, list) {
+		of_node_put(entity->node);
+		list_del(&entity->list);
+	}
+
+	list_for_each_entry_safe(dma, dmap, &xdev->dmas, list) {
+		xvip_dma_cleanup(dma);
+		list_del(&dma->list);
+	}
+}
+
+static int xvip_graph_init(struct xvip_composite_device *xdev)
+{
+	struct xvip_graph_entity *entity;
+	struct v4l2_async_subdev **subdevs = NULL;
+	unsigned int num_subdevs;
+	unsigned int i;
+	int ret;
+
+	/* Init the DMA channels. */
+	ret = xvip_graph_dma_init(xdev);
+	if (ret < 0) {
+		dev_err(xdev->dev, "DMA initialization failed\n");
+		goto done;
+	}
+
+	/* Parse the graph to extract a list of subdevice DT nodes. */
+	ret = xvip_graph_parse(xdev);
+	if (ret < 0) {
+		dev_err(xdev->dev, "graph parsing failed\n");
+		goto done;
+	}
+
+	if (!xdev->num_subdevs) {
+		dev_err(xdev->dev, "no subdev found in graph\n");
+		goto done;
+	}
+
+	/* Register the subdevices notifier. */
+	num_subdevs = xdev->num_subdevs;
+	subdevs = devm_kzalloc(xdev->dev, sizeof(*subdevs) * num_subdevs,
+			       GFP_KERNEL);
+	if (subdevs == NULL) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	i = 0;
+	list_for_each_entry(entity, &xdev->entities, list)
+		subdevs[i++] = &entity->asd;
+
+	xdev->notifier.subdevs = subdevs;
+	xdev->notifier.num_subdevs = num_subdevs;
+	xdev->notifier.bound = xvip_graph_notify_bound;
+	xdev->notifier.complete = xvip_graph_notify_complete;
+
+	ret = v4l2_async_notifier_register(&xdev->v4l2_dev, &xdev->notifier);
+	if (ret < 0) {
+		dev_err(xdev->dev, "notifier registration failed\n");
+		goto done;
+	}
+
+	ret = 0;
+
+done:
+	if (ret < 0)
+		xvip_graph_cleanup(xdev);
+
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * Media Controller and V4L2
+ */
+
+static void xvip_composite_v4l2_cleanup(struct xvip_composite_device *xdev)
+{
+	v4l2_device_unregister(&xdev->v4l2_dev);
+	media_device_unregister(&xdev->media_dev);
+}
+
+static int xvip_composite_v4l2_init(struct xvip_composite_device *xdev)
+{
+	int ret;
+
+	xdev->media_dev.dev = xdev->dev;
+	strlcpy(xdev->media_dev.model, "Xilinx Video Composite Device",
+		sizeof(xdev->media_dev.model));
+	xdev->media_dev.hw_revision = 0;
+
+	ret = media_device_register(&xdev->media_dev);
+	if (ret < 0) {
+		dev_err(xdev->dev, "media device registration failed (%d)\n",
+			ret);
+		return ret;
+	}
+
+	xdev->v4l2_dev.mdev = &xdev->media_dev;
+	ret = v4l2_device_register(xdev->dev, &xdev->v4l2_dev);
+	if (ret < 0) {
+		dev_err(xdev->dev, "V4L2 device registration failed (%d)\n",
+			ret);
+		media_device_unregister(&xdev->media_dev);
+		return ret;
+	}
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Platform Device Driver
+ */
+
+static int xvip_composite_probe(struct platform_device *pdev)
+{
+	struct xvip_composite_device *xdev;
+	int ret;
+
+	xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
+	if (!xdev)
+		return -ENOMEM;
+
+	xdev->dev = &pdev->dev;
+	INIT_LIST_HEAD(&xdev->entities);
+	INIT_LIST_HEAD(&xdev->dmas);
+
+	ret = xvip_composite_v4l2_init(xdev);
+	if (ret < 0)
+		return ret;
+
+	ret = xvip_graph_init(xdev);
+	if (ret < 0)
+		goto error;
+
+	platform_set_drvdata(pdev, xdev);
+
+	dev_info(xdev->dev, "device registered\n");
+
+	return 0;
+
+error:
+	xvip_composite_v4l2_cleanup(xdev);
+	return ret;
+}
+
+static int xvip_composite_remove(struct platform_device *pdev)
+{
+	struct xvip_composite_device *xdev = platform_get_drvdata(pdev);
+
+	xvip_graph_cleanup(xdev);
+	xvip_composite_v4l2_cleanup(xdev);
+
+	return 0;
+}
+
+static const struct of_device_id xvip_composite_of_id_table[] = {
+	{ .compatible = "xlnx,video" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, xvip_composite_of_id_table);
+
+static struct platform_driver xvip_composite_driver = {
+	.driver = {
+		.name = "xilinx-video",
+		.of_match_table = xvip_composite_of_id_table,
+	},
+	.probe = xvip_composite_probe,
+	.remove = xvip_composite_remove,
+};
+
+module_platform_driver(xvip_composite_driver);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("Xilinx Video IP Composite Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.h b/drivers/media/platform/xilinx/xilinx-vipp.h
new file mode 100644
index 0000000..e9c7f73
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-vipp.h
@@ -0,0 +1,49 @@
+/*
+ * Xilinx Video IP Composite Device
+ *
+ * Copyright (C) 2013-2014 Ideas on Board
+ * Copyright (C) 2013-2014 Xilinx, Inc.
+ *
+ * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
+ *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __XILINX_VIPP_H__
+#define __XILINX_VIPP_H__
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <media/media-device.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+
+/**
+ * struct xvip_composite_device - Xilinx Video IP device structure
+ * @v4l2_dev: V4L2 device
+ * @media_dev: media device
+ * @dev: (OF) device
+ * @notifier: V4L2 asynchronous subdevs notifier
+ * @entities: entities in the graph as a list of xvip_graph_entity
+ * @num_subdevs: number of subdevs in the pipeline
+ * @dmas: list of DMA channels at the pipeline output and input
+ * @v4l2_caps: V4L2 capabilities of the whole device (see VIDIOC_QUERYCAP)
+ */
+struct xvip_composite_device {
+	struct v4l2_device v4l2_dev;
+	struct media_device media_dev;
+	struct device *dev;
+
+	struct v4l2_async_notifier notifier;
+	struct list_head entities;
+	unsigned int num_subdevs;
+
+	struct list_head dmas;
+	u32 v4l2_caps;
+};
+
+#endif /* __XILINX_VIPP_H__ */
-- 
2.0.4

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

* [PATCH v4 09/10] v4l: xilinx: Add Video Timing Controller driver
  2014-12-01 20:13 [PATCH v4 00/10] Xilinx Video IP Core support Laurent Pinchart
                   ` (7 preceding siblings ...)
  2014-12-01 20:13 ` [PATCH v4 08/10] v4l: xilinx: Add Xilinx Video IP core Laurent Pinchart
@ 2014-12-01 20:13 ` Laurent Pinchart
  2014-12-01 20:13 ` [PATCH v4 10/10] v4l: xilinx: Add Test Pattern Generator driver Laurent Pinchart
  9 siblings, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2014-12-01 20:13 UTC (permalink / raw)
  To: linux-media; +Cc: Michal Simek, Chris Kohn, Hyun Kwon, devicetree

The Video Timing Controller (VTC) includes a timing detector and/or a
timing generator. Only the generator is currently supported.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>

---

Cc: devicetree@vger.kernel.org

Changes since v3:

- Use xvip_init_resources()

v1 was made of the following individual patches.

xilinx: Remove .owner field for drivers
v4l: xilinx: vtc: Rename compatible string to xlnx,v-tc
---
 .../devicetree/bindings/media/xilinx/xlnx,v-tc.txt |  33 ++
 drivers/media/platform/xilinx/Kconfig              |   6 +
 drivers/media/platform/xilinx/Makefile             |   1 +
 drivers/media/platform/xilinx/xilinx-vtc.c         | 380 +++++++++++++++++++++
 drivers/media/platform/xilinx/xilinx-vtc.h         |  42 +++
 5 files changed, 462 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/xilinx/xlnx,v-tc.txt
 create mode 100644 drivers/media/platform/xilinx/xilinx-vtc.c
 create mode 100644 drivers/media/platform/xilinx/xilinx-vtc.h

diff --git a/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tc.txt b/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tc.txt
new file mode 100644
index 0000000..2aed3b4
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tc.txt
@@ -0,0 +1,33 @@
+Xilinx Video Timing Controller (VTC)
+------------------------------------
+
+The Video Timing Controller is a general purpose video timing generator and
+detector.
+
+Required properties:
+
+  - compatible: Must be "xlnx,v-tc-6.1".
+
+  - reg: Physical base address and length of the registers set for the device.
+
+  - clocks: Must contain a clock specifier for the VTC core and timing
+    interfaces clock.
+
+Optional properties:
+
+  - xlnx,detector: The VTC has a timing detector
+  - xlnx,generator: The VTC has a timing generator
+
+  At least one of the xlnx,detector and xlnx,generator properties must be
+  specified.
+
+
+Example:
+
+	vtc: vtc@43c40000 {
+		compatible = "xlnx,v-tc-6.1";
+		reg = <0x43c40000 0x10000>;
+
+		clocks = <&clkc 15>;
+		xlnx,generator;
+	};
diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig
index f4347e9..19db823 100644
--- a/drivers/media/platform/xilinx/Kconfig
+++ b/drivers/media/platform/xilinx/Kconfig
@@ -7,4 +7,10 @@ config VIDEO_XILINX
 
 if VIDEO_XILINX
 
+config VIDEO_XILINX_VTC
+	tristate "Xilinx Video Timing Controller"
+	depends on VIDEO_XILINX
+	---help---
+	   Driver for the Xilinx Video Timing Controller
+
 endif #VIDEO_XILINX
diff --git a/drivers/media/platform/xilinx/Makefile b/drivers/media/platform/xilinx/Makefile
index 3ef9c8e..6611e32 100644
--- a/drivers/media/platform/xilinx/Makefile
+++ b/drivers/media/platform/xilinx/Makefile
@@ -1,3 +1,4 @@
 xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o
 
 obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o
+obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o
diff --git a/drivers/media/platform/xilinx/xilinx-vtc.c b/drivers/media/platform/xilinx/xilinx-vtc.c
new file mode 100644
index 0000000..194bdf2
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-vtc.c
@@ -0,0 +1,380 @@
+/*
+ * Xilinx Video Timing Controller
+ *
+ * Copyright (C) 2013-2014 Ideas on Board
+ * Copyright (C) 2013-2014 Xilinx, Inc.
+ *
+ * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
+ *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "xilinx-vip.h"
+#include "xilinx-vtc.h"
+
+#define XVTC_CONTROL_FIELD_ID_POL_SRC		(1 << 26)
+#define XVTC_CONTROL_ACTIVE_CHROMA_POL_SRC	(1 << 25)
+#define XVTC_CONTROL_ACTIVE_VIDEO_POL_SRC	(1 << 24)
+#define XVTC_CONTROL_HSYNC_POL_SRC		(1 << 23)
+#define XVTC_CONTROL_VSYNC_POL_SRC		(1 << 22)
+#define XVTC_CONTROL_HBLANK_POL_SRC		(1 << 21)
+#define XVTC_CONTROL_VBLANK_POL_SRC		(1 << 20)
+#define XVTC_CONTROL_CHROMA_SRC			(1 << 18)
+#define XVTC_CONTROL_VBLANK_HOFF_SRC		(1 << 17)
+#define XVTC_CONTROL_VSYNC_END_SRC		(1 << 16)
+#define XVTC_CONTROL_VSYNC_START_SRC		(1 << 15)
+#define XVTC_CONTROL_ACTIVE_VSIZE_SRC		(1 << 14)
+#define XVTC_CONTROL_FRAME_VSIZE_SRC		(1 << 13)
+#define XVTC_CONTROL_HSYNC_END_SRC		(1 << 11)
+#define XVTC_CONTROL_HSYNC_START_SRC		(1 << 10)
+#define XVTC_CONTROL_ACTIVE_HSIZE_SRC		(1 << 9)
+#define XVTC_CONTROL_FRAME_HSIZE_SRC		(1 << 8)
+#define XVTC_CONTROL_SYNC_ENABLE		(1 << 5)
+#define XVTC_CONTROL_DET_ENABLE			(1 << 3)
+#define XVTC_CONTROL_GEN_ENABLE			(1 << 2)
+
+#define XVTC_STATUS_FSYNC(n)			((n) << 16)
+#define XVTC_STATUS_GEN_ACTIVE_VIDEO		(1 << 13)
+#define XVTC_STATUS_GEN_VBLANK			(1 << 12)
+#define XVTC_STATUS_DET_ACTIVE_VIDEO		(1 << 11)
+#define XVTC_STATUS_DET_VBLANK			(1 << 10)
+#define XVTC_STATUS_LOCK_LOSS			(1 << 9)
+#define XVTC_STATUS_LOCK			(1 << 8)
+
+#define XVTC_ERROR_ACTIVE_CHROMA_LOCK		(1 << 21)
+#define XVTC_ERROR_ACTIVE_VIDEO_LOCK		(1 << 20)
+#define XVTC_ERROR_HSYNC_LOCK			(1 << 19)
+#define XVTC_ERROR_VSYNC_LOCK			(1 << 18)
+#define XVTC_ERROR_HBLANK_LOCK			(1 << 17)
+#define XVTC_ERROR_VBLANK_LOCK			(1 << 16)
+
+#define XVTC_IRQ_ENABLE_FSYNC(n)		((n) << 16)
+#define XVTC_IRQ_ENABLE_GEN_ACTIVE_VIDEO	(1 << 13)
+#define XVTC_IRQ_ENABLE_GEN_VBLANK		(1 << 12)
+#define XVTC_IRQ_ENABLE_DET_ACTIVE_VIDEO	(1 << 11)
+#define XVTC_IRQ_ENABLE_DET_VBLANK		(1 << 10)
+#define XVTC_IRQ_ENABLE_LOCK_LOSS		(1 << 9)
+#define XVTC_IRQ_ENABLE_LOCK			(1 << 8)
+
+/*
+ * The following registers exist in two blocks, one at 0x0020 for the detector
+ * and one at 0x0060 for the generator.
+ */
+
+#define XVTC_DETECTOR_OFFSET			0x0020
+#define XVTC_GENERATOR_OFFSET			0x0060
+
+#define XVTC_ACTIVE_SIZE			0x0000
+#define XVTC_ACTIVE_VSIZE_SHIFT			16
+#define XVTC_ACTIVE_VSIZE_MASK			(0x1fff << 16)
+#define XVTC_ACTIVE_HSIZE_SHIFT			0
+#define XVTC_ACTIVE_HSIZE_MASK			(0x1fff << 0)
+
+#define XVTC_TIMING_STATUS			0x0004
+#define XVTC_TIMING_STATUS_ACTIVE_VIDEO		(1 << 2)
+#define XVTC_TIMING_STATUS_VBLANK		(1 << 1)
+#define XVTC_TIMING_STATUS_LOCKED		(1 << 0)
+
+#define XVTC_ENCODING				0x0008
+#define XVTC_ENCODING_CHROMA_PARITY_SHIFT	8
+#define XVTC_ENCODING_CHROMA_PARITY_MASK	(3 << 8)
+#define XVTC_ENCODING_CHROMA_PARITY_EVEN_ALL	(0 << 8)
+#define XVTC_ENCODING_CHROMA_PARITY_ODD_ALL	(1 << 8)
+#define XVTC_ENCODING_CHROMA_PARITY_EVEN_EVEN	(2 << 8)
+#define XVTC_ENCODING_CHROMA_PARITY_ODD_EVEN	(3 << 8)
+#define XVTC_ENCODING_VIDEO_FORMAT_SHIFT	0
+#define XVTC_ENCODING_VIDEO_FORMAT_MASK		(0xf << 0)
+#define XVTC_ENCODING_VIDEO_FORMAT_YUV422	(0 << 0)
+#define XVTC_ENCODING_VIDEO_FORMAT_YUV444	(1 << 0)
+#define XVTC_ENCODING_VIDEO_FORMAT_RGB		(2 << 0)
+#define XVTC_ENCODING_VIDEO_FORMAT_YUV420	(3 << 0)
+
+#define XVTC_POLARITY				0x000c
+#define XVTC_POLARITY_ACTIVE_CHROMA_POL		(1 << 5)
+#define XVTC_POLARITY_ACTIVE_VIDEO_POL		(1 << 4)
+#define XVTC_POLARITY_HSYNC_POL			(1 << 3)
+#define XVTC_POLARITY_VSYNC_POL			(1 << 2)
+#define XVTC_POLARITY_HBLANK_POL		(1 << 1)
+#define XVTC_POLARITY_VBLANK_POL		(1 << 0)
+
+#define XVTC_HSIZE				0x0010
+#define XVTC_HSIZE_MASK				(0x1fff << 0)
+
+#define XVTC_VSIZE				0x0014
+#define XVTC_VSIZE_MASK				(0x1fff << 0)
+
+#define XVTC_HSYNC				0x0018
+#define XVTC_HSYNC_END_SHIFT			16
+#define XVTC_HSYNC_END_MASK			(0x1fff << 16)
+#define XVTC_HSYNC_START_SHIFT			0
+#define XVTC_HSYNC_START_MASK			(0x1fff << 0)
+
+#define XVTC_F0_VBLANK_H			0x001c
+#define XVTC_F0_VBLANK_HEND_SHIFT		16
+#define XVTC_F0_VBLANK_HEND_MASK		(0x1fff << 16)
+#define XVTC_F0_VBLANK_HSTART_SHIFT		0
+#define XVTC_F0_VBLANK_HSTART_MASK		(0x1fff << 0)
+
+#define XVTC_F0_VSYNC_V				0x0020
+#define XVTC_F0_VSYNC_VEND_SHIFT		16
+#define XVTC_F0_VSYNC_VEND_MASK			(0x1fff << 16)
+#define XVTC_F0_VSYNC_VSTART_SHIFT		0
+#define XVTC_F0_VSYNC_VSTART_MASK		(0x1fff << 0)
+
+#define XVTC_F0_VSYNC_H				0x0024
+#define XVTC_F0_VSYNC_HEND_SHIFT		16
+#define XVTC_F0_VSYNC_HEND_MASK			(0x1fff << 16)
+#define XVTC_F0_VSYNC_HSTART_SHIFT		0
+#define XVTC_F0_VSYNC_HSTART_MASK		(0x1fff << 0)
+
+#define XVTC_FRAME_SYNC_CONFIG(n)		(0x0100 + 4 * (n))
+#define XVTC_FRAME_SYNC_V_START_SHIFT		16
+#define XVTC_FRAME_SYNC_V_START_MASK		(0x1fff << 16)
+#define XVTC_FRAME_SYNC_H_START_SHIFT		0
+#define XVTC_FRAME_SYNC_H_START_MASK		(0x1fff << 0)
+
+#define XVTC_GENERATOR_GLOBAL_DELAY		0x0104
+
+/**
+ * struct xvtc_device - Xilinx Video Timing Controller device structure
+ * @xvip: Xilinx Video IP device
+ * @list: entry in the global VTC list
+ * @has_detector: the VTC has a timing detector
+ * @has_generator: the VTC has a timing generator
+ * @config: generator timings configuration
+ */
+struct xvtc_device {
+	struct xvip_device xvip;
+	struct list_head list;
+
+	bool has_detector;
+	bool has_generator;
+
+	struct xvtc_config config;
+};
+
+static LIST_HEAD(xvtc_list);
+static DEFINE_MUTEX(xvtc_lock);
+
+static inline void xvtc_gen_write(struct xvtc_device *xvtc, u32 addr, u32 value)
+{
+	xvip_write(&xvtc->xvip, XVTC_GENERATOR_OFFSET + addr, value);
+}
+
+/* -----------------------------------------------------------------------------
+ * Generator Operations
+ */
+
+int xvtc_generator_start(struct xvtc_device *xvtc,
+			 const struct xvtc_config *config)
+{
+	int ret;
+
+	if (!xvtc->has_generator)
+		return -ENXIO;
+
+	ret = clk_prepare_enable(xvtc->xvip.clk);
+	if (ret < 0)
+		return ret;
+
+	/* We don't care about the chroma active signal, encoding parameters are
+	 * not important for now.
+	 */
+	xvtc_gen_write(xvtc, XVTC_POLARITY,
+		       XVTC_POLARITY_ACTIVE_CHROMA_POL |
+		       XVTC_POLARITY_ACTIVE_VIDEO_POL |
+		       XVTC_POLARITY_HSYNC_POL | XVTC_POLARITY_VSYNC_POL |
+		       XVTC_POLARITY_HBLANK_POL | XVTC_POLARITY_VBLANK_POL);
+
+	/* Hardcode the polarity to active high, as required by the video in to
+	 * AXI4-stream core.
+	 */
+	xvtc_gen_write(xvtc, XVTC_ENCODING, 0);
+
+	/* Configure the timings. The VBLANK and VSYNC signals assertion and
+	 * deassertion are hardcoded to the first pixel of the line.
+	 */
+	xvtc_gen_write(xvtc, XVTC_ACTIVE_SIZE,
+		       (config->vblank_start << XVTC_ACTIVE_VSIZE_SHIFT) |
+		       (config->hblank_start << XVTC_ACTIVE_HSIZE_SHIFT));
+	xvtc_gen_write(xvtc, XVTC_HSIZE, config->hsize);
+	xvtc_gen_write(xvtc, XVTC_VSIZE, config->vsize);
+	xvtc_gen_write(xvtc, XVTC_HSYNC,
+		       (config->hsync_end << XVTC_HSYNC_END_SHIFT) |
+		       (config->hsync_start << XVTC_HSYNC_START_SHIFT));
+	xvtc_gen_write(xvtc, XVTC_F0_VBLANK_H, 0);
+	xvtc_gen_write(xvtc, XVTC_F0_VSYNC_V,
+		       (config->vsync_end << XVTC_F0_VSYNC_VEND_SHIFT) |
+		       (config->vsync_start << XVTC_F0_VSYNC_VSTART_SHIFT));
+	xvtc_gen_write(xvtc, XVTC_F0_VSYNC_H, 0);
+
+	/* Enable the generator. Set the source of all generator parameters to
+	 * generator registers.
+	 */
+	xvip_write(&xvtc->xvip, XVIP_CTRL_CONTROL,
+		   XVTC_CONTROL_ACTIVE_CHROMA_POL_SRC |
+		   XVTC_CONTROL_ACTIVE_VIDEO_POL_SRC |
+		   XVTC_CONTROL_HSYNC_POL_SRC | XVTC_CONTROL_VSYNC_POL_SRC |
+		   XVTC_CONTROL_HBLANK_POL_SRC | XVTC_CONTROL_VBLANK_POL_SRC |
+		   XVTC_CONTROL_CHROMA_SRC | XVTC_CONTROL_VBLANK_HOFF_SRC |
+		   XVTC_CONTROL_VSYNC_END_SRC | XVTC_CONTROL_VSYNC_START_SRC |
+		   XVTC_CONTROL_ACTIVE_VSIZE_SRC |
+		   XVTC_CONTROL_FRAME_VSIZE_SRC | XVTC_CONTROL_HSYNC_END_SRC |
+		   XVTC_CONTROL_HSYNC_START_SRC |
+		   XVTC_CONTROL_ACTIVE_HSIZE_SRC |
+		   XVTC_CONTROL_FRAME_HSIZE_SRC | XVTC_CONTROL_GEN_ENABLE |
+		   XVIP_CTRL_CONTROL_REG_UPDATE);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xvtc_generator_start);
+
+int xvtc_generator_stop(struct xvtc_device *xvtc)
+{
+	if (!xvtc->has_generator)
+		return -ENXIO;
+
+	xvip_write(&xvtc->xvip, XVIP_CTRL_CONTROL, 0);
+
+	clk_disable_unprepare(xvtc->xvip.clk);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xvtc_generator_stop);
+
+struct xvtc_device *xvtc_of_get(struct device_node *np)
+{
+	struct device_node *xvtc_node;
+	struct xvtc_device *found = NULL;
+	struct xvtc_device *xvtc;
+
+	if (!of_find_property(np, "xlnx,vtc", NULL))
+		return NULL;
+
+	xvtc_node = of_parse_phandle(np, "xlnx,vtc", 0);
+	if (xvtc_node == NULL)
+		return ERR_PTR(-EINVAL);
+
+	mutex_lock(&xvtc_lock);
+	list_for_each_entry(xvtc, &xvtc_list, list) {
+		if (xvtc->xvip.dev->of_node == xvtc_node) {
+			found = xvtc;
+			break;
+		}
+	}
+	mutex_unlock(&xvtc_lock);
+
+	of_node_put(xvtc_node);
+
+	if (!found)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	return found;
+}
+EXPORT_SYMBOL_GPL(xvtc_of_get);
+
+void xvtc_put(struct xvtc_device *xvtc)
+{
+}
+EXPORT_SYMBOL_GPL(xvtc_put);
+
+/* -----------------------------------------------------------------------------
+ * Registration and Unregistration
+ */
+
+static void xvtc_register_device(struct xvtc_device *xvtc)
+{
+	mutex_lock(&xvtc_lock);
+	list_add_tail(&xvtc->list, &xvtc_list);
+	mutex_unlock(&xvtc_lock);
+}
+
+static void xvtc_unregister_device(struct xvtc_device *xvtc)
+{
+	mutex_lock(&xvtc_lock);
+	list_del(&xvtc->list);
+	mutex_unlock(&xvtc_lock);
+}
+
+/* -----------------------------------------------------------------------------
+ * Platform Device Driver
+ */
+
+static int xvtc_parse_of(struct xvtc_device *xvtc)
+{
+	struct device_node *node = xvtc->xvip.dev->of_node;
+
+	xvtc->has_detector = of_property_read_bool(node, "xlnx,detector");
+	xvtc->has_generator = of_property_read_bool(node, "xlnx,generator");
+
+	return 0;
+}
+
+static int xvtc_probe(struct platform_device *pdev)
+{
+	struct xvtc_device *xvtc;
+	int ret;
+
+	xvtc = devm_kzalloc(&pdev->dev, sizeof(*xvtc), GFP_KERNEL);
+	if (!xvtc)
+		return -ENOMEM;
+
+	xvtc->xvip.dev = &pdev->dev;
+
+	ret = xvtc_parse_of(xvtc);
+	if (ret < 0)
+		return ret;
+
+	ret = xvip_init_resources(&xvtc->xvip);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, xvtc);
+
+	xvip_print_version(&xvtc->xvip);
+
+	xvtc_register_device(xvtc);
+
+	return 0;
+}
+
+static int xvtc_remove(struct platform_device *pdev)
+{
+	struct xvtc_device *xvtc = platform_get_drvdata(pdev);
+
+	xvtc_unregister_device(xvtc);
+
+	xvip_cleanup_resources(&xvtc->xvip);
+
+	return 0;
+}
+
+static const struct of_device_id xvtc_of_id_table[] = {
+	{ .compatible = "xlnx,v-tc-6.1" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, xvtc_of_id_table);
+
+static struct platform_driver xvtc_driver = {
+	.driver = {
+		.name = "xilinx-vtc",
+		.of_match_table = xvtc_of_id_table,
+	},
+	.probe = xvtc_probe,
+	.remove = xvtc_remove,
+};
+
+module_platform_driver(xvtc_driver);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("Xilinx Video Timing Controller Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/xilinx/xilinx-vtc.h b/drivers/media/platform/xilinx/xilinx-vtc.h
new file mode 100644
index 0000000..da632fe
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-vtc.h
@@ -0,0 +1,42 @@
+/*
+ * Xilinx Video Timing Controller
+ *
+ * Copyright (C) 2013-2014 Ideas on Board
+ * Copyright (C) 2013-2014 Xilinx, Inc.
+ *
+ * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
+ *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __XILINX_VTC_H__
+#define __XILINX_VTC_H__
+
+struct device_node;
+struct xvtc_device;
+
+#define XVTC_MAX_HSIZE			8191
+#define XVTC_MAX_VSIZE			8191
+
+struct xvtc_config {
+	unsigned int hblank_start;
+	unsigned int hsync_start;
+	unsigned int hsync_end;
+	unsigned int hsize;
+	unsigned int vblank_start;
+	unsigned int vsync_start;
+	unsigned int vsync_end;
+	unsigned int vsize;
+};
+
+struct xvtc_device *xvtc_of_get(struct device_node *np);
+void xvtc_put(struct xvtc_device *xvtc);
+
+int xvtc_generator_start(struct xvtc_device *xvtc,
+			 const struct xvtc_config *config);
+int xvtc_generator_stop(struct xvtc_device *xvtc);
+
+#endif /* __XILINX_VTC_H__ */
-- 
2.0.4

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

* [PATCH v4 10/10] v4l: xilinx: Add Test Pattern Generator driver
  2014-12-01 20:13 [PATCH v4 00/10] Xilinx Video IP Core support Laurent Pinchart
                   ` (8 preceding siblings ...)
  2014-12-01 20:13 ` [PATCH v4 09/10] v4l: xilinx: Add Video Timing Controller driver Laurent Pinchart
@ 2014-12-01 20:13 ` Laurent Pinchart
  9 siblings, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2014-12-01 20:13 UTC (permalink / raw)
  To: linux-media; +Cc: Michal Simek, Chris Kohn, Hyun Kwon, devicetree

The TPG generates multiple static or dynamic test patterns. The driver
currently hardcodes the pattern to the moving box pattern.

Signed-off-by: Christian Kohn <christian.kohn@xilinx.com>
Signed-off-by: Hyun Kwon <hyun.kwon@xilinx.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>

---

Cc: devicetree@vger.kernel.org

I'd appreciate if DT reviewers could have a look at the xlnx,video-format and
xlnx,video-width properties if nothing else.

Changes since v3:

- Rename V4L2_MBUS_FMT_* to MEDIA_BUS_FMT_*
- Use xvip_init_resources()

Changes since v1:

v4l: xilinx: tpg: Fix typo

v1 was made of the following individual patches.

media: xilinx: tpg: Add the version number in DT compatible string
media: xilinx: tpg: Use <linux/device.h> instead of <linux/slab.h>
media: xilinx: tpg: Reset in probe()
media: xilinx: tpg: Add controls for TPG
media: xilinx: tpg: Add the default format
media: xilinx: tpg: Fix alignments around __xtpg_get_pad_format()
media: xilinx: tpg: Change 'format' to 'fmt'
media: xilinx: tpg: Fix alignments
media: xilinx: tpg: Fix the structure comment
media: xilinx: tpg: Use xvip_enum_mbus_code()
media: xilinx: tpg: Use xvip_enum_frame_size()
media: xilinx: tpg: Use xvip_set_format_size()
media: xilinx: tpg: Use xvip_start()
media: xilinx: tpg: Use xvip_stop()
media: xilinx: tpg: Use xvip_set_frame_size()
media: xilinx: tpg: Use xvip_print_version()
media: xilinx: tpg: Add power management functions
media: xilinx: tpg: Remove of_match_ptr()
media: xilinx: tpg: Fix devm_ioremap_resource() return value check
media: xilinx: tpg: Make number of pads dynamic
media: xilinx: tpg: Configure the bayer phase
media: xilinx: tpg: Allocate active formats for each pad
media: xilinx: tpg: Include the format infomation in 'port' node
media: xilinx: tpg: Add VTC support
media: xilinx: tpg: Add video timing mux support
media: xilinx: tpg: Default to the color bars test pattern
media: xilinx: tpg: Disallow switching passthrough mode during streaming
media: xilinx: tpg: Move control IDs to xilinx-controls.h
media: xilinx: tpg: Make horizontal and vertical blanking configurable
media: xilinx: tpg: Ignore unconnected input ports
xilinx: Remove .owner field for drivers
v4l: xilinx: tpg: Rename compatible string to xlnx,v-tpg
v4l: xilinx: tpg: Lock the control handler when modifying control range
v4l: xilinx: tpg: Use devm_gpiod_get_optional
v4l: xilinx: tpg: Remove axi- prefix from DT properties
---
 .../bindings/media/xilinx/xlnx,v-tpg.txt           |  71 ++
 MAINTAINERS                                        |   1 +
 drivers/media/platform/xilinx/Kconfig              |   7 +
 drivers/media/platform/xilinx/Makefile             |   1 +
 drivers/media/platform/xilinx/xilinx-tpg.c         | 925 +++++++++++++++++++++
 include/uapi/linux/Kbuild                          |   1 +
 include/uapi/linux/xilinx-v4l2-controls.h          |  73 ++
 7 files changed, 1079 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt
 create mode 100644 drivers/media/platform/xilinx/xilinx-tpg.c
 create mode 100644 include/uapi/linux/xilinx-v4l2-controls.h

diff --git a/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt b/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt
new file mode 100644
index 0000000..ffc47a9
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt
@@ -0,0 +1,71 @@
+Xilinx Video Test Pattern Generator (TPG)
+-----------------------------------------
+
+Required properties:
+
+- compatible: Must contain at least one of
+
+    "xlnx,v-tpg-5.0" (TPG version 5.0)
+    "xlnx,v-tpg-6.0" (TPG version 6.0)
+
+  TPG versions backward-compatible with previous versions should list all
+  compatible versions in the newer to older order.
+
+- reg: Physical base address and length of the registers set for the device.
+
+- clocks: Reference to the video core clock.
+
+- xlnx,video-format, xlnx,video-width: Video format and width, as defined in
+  video.txt.
+
+- port: Video port, using the DT bindings defined in ../video-interfaces.txt.
+  The TPG has a single output port numbered 0.
+
+Optional properties:
+
+- xlnx,vtc: A phandle referencing the Video Timing Controller that generates
+  video timings for the TPG test patterns.
+
+- timing-gpios: Specifier for a GPIO that controls the timing mux at the TPG
+  input. The GPIO active level corresponds to the selection of VTC-generated
+  video timings.
+
+The xlnx,vtc and timing-gpios properties are mandatory when the TPG is
+synthesized with two ports and forbidden when synthesized with one port.
+
+Example:
+
+	tpg_0: tpg@40050000 {
+		compatible = "xlnx,v-tpg-6.0", "xlnx,v-tpg-5.0";
+		reg = <0x40050000 0x10000>;
+		clocks = <&clkc 15>;
+
+		xlnx,vtc = <&vtc_3>;
+		timing-gpios = <&ps7_gpio_0 55 GPIO_ACTIVE_LOW>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				xlnx,video-format = "yuv422";
+				xlnx,video-width = <8>;
+
+				tpg_in: endpoint {
+					remote-endpoint = <&adv7611_out>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+
+				xlnx,video-format = "yuv422";
+				xlnx,video-width = <8>;
+
+				tpg1_out: endpoint {
+					remote-endpoint = <&switch_in0>;
+				};
+			}:
+		};
+	};
diff --git a/MAINTAINERS b/MAINTAINERS
index 789e36f..2b5cf2b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10400,6 +10400,7 @@ T:	git git://linuxtv.org/media_tree.git
 S:	Supported
 F:	Documentation/devicetree/bindings/media/xilinx/
 F:	drivers/media/platform/xilinx/
+F:	include/uapi/linux/xilinx-v4l2-controls.h
 
 XILLYBUS DRIVER
 M:	Eli Billauer <eli.billauer@gmail.com>
diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig
index 19db823..d7324c7 100644
--- a/drivers/media/platform/xilinx/Kconfig
+++ b/drivers/media/platform/xilinx/Kconfig
@@ -7,6 +7,13 @@ config VIDEO_XILINX
 
 if VIDEO_XILINX
 
+config VIDEO_XILINX_TPG
+	tristate "Xilinx Video Test Pattern Generator"
+	depends on VIDEO_XILINX
+	select VIDEO_XILINX_VTC
+	---help---
+	   Driver for the Xilinx Video Test Pattern Generator
+
 config VIDEO_XILINX_VTC
 	tristate "Xilinx Video Timing Controller"
 	depends on VIDEO_XILINX
diff --git a/drivers/media/platform/xilinx/Makefile b/drivers/media/platform/xilinx/Makefile
index 6611e32..e8a0f2a 100644
--- a/drivers/media/platform/xilinx/Makefile
+++ b/drivers/media/platform/xilinx/Makefile
@@ -1,4 +1,5 @@
 xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o
 
 obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o
+obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o
 obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o
diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c b/drivers/media/platform/xilinx/xilinx-tpg.c
new file mode 100644
index 0000000..520d069
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-tpg.c
@@ -0,0 +1,925 @@
+/*
+ * Xilinx Test Pattern Generator
+ *
+ * Copyright (C) 2013-2014 Ideas on Board
+ * Copyright (C) 2013-2014 Xilinx, Inc.
+ *
+ * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
+ *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/xilinx-v4l2-controls.h>
+
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+
+#include "xilinx-vip.h"
+#include "xilinx-vtc.h"
+
+#define XTPG_CTRL_STATUS_SLAVE_ERROR		(1 << 16)
+#define XTPG_CTRL_IRQ_SLAVE_ERROR		(1 << 16)
+
+#define XTPG_PATTERN_CONTROL			0x0100
+#define XTPG_PATTERN_MASK			(0xf << 0)
+#define XTPG_PATTERN_CONTROL_CROSS_HAIRS	(1 << 4)
+#define XTPG_PATTERN_CONTROL_MOVING_BOX		(1 << 5)
+#define XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT	6
+#define XTPG_PATTERN_CONTROL_COLOR_MASK_MASK	(0xf << 6)
+#define XTPG_PATTERN_CONTROL_STUCK_PIXEL	(1 << 9)
+#define XTPG_PATTERN_CONTROL_NOISE		(1 << 10)
+#define XTPG_PATTERN_CONTROL_MOTION		(1 << 12)
+#define XTPG_MOTION_SPEED			0x0104
+#define XTPG_CROSS_HAIRS			0x0108
+#define XTPG_CROSS_HAIRS_ROW_SHIFT		0
+#define XTPG_CROSS_HAIRS_ROW_MASK		(0xfff << 0)
+#define XTPG_CROSS_HAIRS_COLUMN_SHIFT		16
+#define XTPG_CROSS_HAIRS_COLUMN_MASK		(0xfff << 16)
+#define XTPG_ZPLATE_HOR_CONTROL			0x010c
+#define XTPG_ZPLATE_VER_CONTROL			0x0110
+#define XTPG_ZPLATE_START_SHIFT			0
+#define XTPG_ZPLATE_START_MASK			(0xffff << 0)
+#define XTPG_ZPLATE_SPEED_SHIFT			16
+#define XTPG_ZPLATE_SPEED_MASK			(0xffff << 16)
+#define XTPG_BOX_SIZE				0x0114
+#define XTPG_BOX_COLOR				0x0118
+#define XTPG_STUCK_PIXEL_THRESH			0x011c
+#define XTPG_NOISE_GAIN				0x0120
+#define XTPG_BAYER_PHASE			0x0124
+#define XTPG_BAYER_PHASE_RGGB			0
+#define XTPG_BAYER_PHASE_GRBG			1
+#define XTPG_BAYER_PHASE_GBRG			2
+#define XTPG_BAYER_PHASE_BGGR			3
+#define XTPG_BAYER_PHASE_OFF			4
+
+/*
+ * The minimum blanking value is one clock cycle for the front porch, one clock
+ * cycle for the sync pulse and one clock cycle for the back porch.
+ */
+#define XTPG_MIN_HBLANK			3
+#define XTPG_MAX_HBLANK			(XVTC_MAX_HSIZE - XVIP_MIN_WIDTH)
+#define XTPG_MIN_VBLANK			3
+#define XTPG_MAX_VBLANK			(XVTC_MAX_VSIZE - XVIP_MIN_HEIGHT)
+
+/**
+ * struct xtpg_device - Xilinx Test Pattern Generator device structure
+ * @xvip: Xilinx Video IP device
+ * @pads: media pads
+ * @npads: number of pads (1 or 2)
+ * @has_input: whether an input is connected to the sink pad
+ * @formats: active V4L2 media bus format for each pad
+ * @default_format: default V4L2 media bus format
+ * @vip_format: format information corresponding to the active format
+ * @bayer: boolean flag if TPG is set to any bayer format
+ * @ctrl_handler: control handler
+ * @hblank: horizontal blanking control
+ * @vblank: vertical blanking control
+ * @pattern: test pattern control
+ * @streaming: is the video stream active
+ * @vtc: video timing controller
+ * @vtmux_gpio: video timing mux GPIO
+ */
+struct xtpg_device {
+	struct xvip_device xvip;
+
+	struct media_pad pads[2];
+	unsigned int npads;
+	bool has_input;
+
+	struct v4l2_mbus_framefmt formats[2];
+	struct v4l2_mbus_framefmt default_format;
+	const struct xvip_video_format *vip_format;
+	bool bayer;
+
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct v4l2_ctrl *hblank;
+	struct v4l2_ctrl *vblank;
+	struct v4l2_ctrl *pattern;
+	bool streaming;
+
+	struct xvtc_device *vtc;
+	struct gpio_desc *vtmux_gpio;
+};
+
+static inline struct xtpg_device *to_tpg(struct v4l2_subdev *subdev)
+{
+	return container_of(subdev, struct xtpg_device, xvip.subdev);
+}
+
+static u32 xtpg_get_bayer_phase(unsigned int code)
+{
+	switch (code) {
+	case MEDIA_BUS_FMT_SRGGB8_1X8:
+		return XTPG_BAYER_PHASE_RGGB;
+	case MEDIA_BUS_FMT_SGRBG8_1X8:
+		return XTPG_BAYER_PHASE_GRBG;
+	case MEDIA_BUS_FMT_SGBRG8_1X8:
+		return XTPG_BAYER_PHASE_GBRG;
+	case MEDIA_BUS_FMT_SBGGR8_1X8:
+		return XTPG_BAYER_PHASE_BGGR;
+	default:
+		return XTPG_BAYER_PHASE_OFF;
+	}
+}
+
+static void __xtpg_update_pattern_control(struct xtpg_device *xtpg,
+					  bool passthrough, bool pattern)
+{
+	u32 pattern_mask = (1 << (xtpg->pattern->maximum + 1)) - 1;
+
+	/*
+	 * If the TPG has no sink pad or no input connected to its sink pad
+	 * passthrough mode can't be enabled.
+	 */
+	if (xtpg->npads == 1 || !xtpg->has_input)
+		passthrough = false;
+
+	/* If passthrough mode is allowed unmask bit 0. */
+	if (passthrough)
+		pattern_mask &= ~1;
+
+	/* If test pattern mode is allowed unmask all other bits. */
+	if (pattern)
+		pattern_mask &= 1;
+
+	__v4l2_ctrl_modify_range(xtpg->pattern, 0, xtpg->pattern->maximum,
+				 pattern_mask, pattern ? 9 : 0);
+}
+
+static void xtpg_update_pattern_control(struct xtpg_device *xtpg,
+					bool passthrough, bool pattern)
+{
+	mutex_lock(xtpg->ctrl_handler.lock);
+	__xtpg_update_pattern_control(xtpg, passthrough, pattern);
+	mutex_unlock(xtpg->ctrl_handler.lock);
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Video Operations
+ */
+
+static int xtpg_s_stream(struct v4l2_subdev *subdev, int enable)
+{
+	struct xtpg_device *xtpg = to_tpg(subdev);
+	unsigned int width = xtpg->formats[0].width;
+	unsigned int height = xtpg->formats[0].height;
+	bool passthrough;
+	u32 bayer_phase;
+
+	if (!enable) {
+		xvip_stop(&xtpg->xvip);
+		if (xtpg->vtc)
+			xvtc_generator_stop(xtpg->vtc);
+
+		xtpg_update_pattern_control(xtpg, true, true);
+		xtpg->streaming = false;
+		return 0;
+	}
+
+	xvip_set_frame_size(&xtpg->xvip, &xtpg->formats[0]);
+
+	if (xtpg->vtc) {
+		struct xvtc_config config = {
+			.hblank_start = width,
+			.hsync_start = width + 1,
+			.vblank_start = height,
+			.vsync_start = height + 1,
+		};
+		unsigned int htotal;
+		unsigned int vtotal;
+
+		htotal = min_t(unsigned int, XVTC_MAX_HSIZE,
+			       v4l2_ctrl_g_ctrl(xtpg->hblank) + width);
+		vtotal = min_t(unsigned int, XVTC_MAX_VSIZE,
+			       v4l2_ctrl_g_ctrl(xtpg->vblank) + height);
+
+		config.hsync_end = htotal - 1;
+		config.hsize = htotal;
+		config.vsync_end = vtotal - 1;
+		config.vsize = vtotal;
+
+		xvtc_generator_start(xtpg->vtc, &config);
+	}
+
+	/*
+	 * Configure the bayer phase and video timing mux based on the
+	 * operation mode (passthrough or test pattern generation). The test
+	 * pattern can be modified by the control set handler, we thus need to
+	 * take the control lock here to avoid races.
+	 */
+	mutex_lock(xtpg->ctrl_handler.lock);
+
+	xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
+			 XTPG_PATTERN_MASK, xtpg->pattern->cur.val);
+
+	/*
+	 * Switching between passthrough and test pattern generation modes isn't
+	 * allowed during streaming, update the control range accordingly.
+	 */
+	passthrough = xtpg->pattern->cur.val == 0;
+	__xtpg_update_pattern_control(xtpg, passthrough, !passthrough);
+
+	xtpg->streaming = true;
+
+	mutex_unlock(xtpg->ctrl_handler.lock);
+
+	/*
+	 * For TPG v5.0, the bayer phase needs to be off for the pass through
+	 * mode, otherwise the external input would be subsampled.
+	 */
+	bayer_phase = passthrough ? XTPG_BAYER_PHASE_OFF
+		    : xtpg_get_bayer_phase(xtpg->formats[0].code);
+	xvip_write(&xtpg->xvip, XTPG_BAYER_PHASE, bayer_phase);
+
+	if (xtpg->vtmux_gpio)
+		gpiod_set_value_cansleep(xtpg->vtmux_gpio, !passthrough);
+
+	xvip_start(&xtpg->xvip);
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Pad Operations
+ */
+
+static struct v4l2_mbus_framefmt *
+__xtpg_get_pad_format(struct xtpg_device *xtpg, struct v4l2_subdev_fh *fh,
+		      unsigned int pad, u32 which)
+{
+	switch (which) {
+	case V4L2_SUBDEV_FORMAT_TRY:
+		return v4l2_subdev_get_try_format(fh, pad);
+	case V4L2_SUBDEV_FORMAT_ACTIVE:
+		return &xtpg->formats[pad];
+	default:
+		return NULL;
+	}
+}
+
+static int xtpg_get_format(struct v4l2_subdev *subdev,
+			   struct v4l2_subdev_fh *fh,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct xtpg_device *xtpg = to_tpg(subdev);
+
+	fmt->format = *__xtpg_get_pad_format(xtpg, fh, fmt->pad, fmt->which);
+
+	return 0;
+}
+
+static int xtpg_set_format(struct v4l2_subdev *subdev,
+			   struct v4l2_subdev_fh *fh,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct xtpg_device *xtpg = to_tpg(subdev);
+	struct v4l2_mbus_framefmt *__format;
+	u32 bayer_phase;
+
+	__format = __xtpg_get_pad_format(xtpg, fh, fmt->pad, fmt->which);
+
+	/* In two pads mode the source pad format is always identical to the
+	 * sink pad format.
+	 */
+	if (xtpg->npads == 2 && fmt->pad == 1) {
+		fmt->format = *__format;
+		return 0;
+	}
+
+	/* Bayer phase is configurable at runtime */
+	if (xtpg->bayer) {
+		bayer_phase = xtpg_get_bayer_phase(fmt->format.code);
+		if (bayer_phase != XTPG_BAYER_PHASE_OFF)
+			__format->code = fmt->format.code;
+	}
+
+	xvip_set_format_size(__format, fmt);
+
+	fmt->format = *__format;
+
+	/* Propagate the format to the source pad. */
+	if (xtpg->npads == 2) {
+		__format = __xtpg_get_pad_format(xtpg, fh, 1, fmt->which);
+		*__format = fmt->format;
+	}
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Operations
+ */
+
+static int xtpg_enum_frame_size(struct v4l2_subdev *subdev,
+				struct v4l2_subdev_fh *fh,
+				struct v4l2_subdev_frame_size_enum *fse)
+{
+	struct v4l2_mbus_framefmt *format;
+
+	format = v4l2_subdev_get_try_format(fh, fse->pad);
+
+	if (fse->index || fse->code != format->code)
+		return -EINVAL;
+
+	/* Min / max values for pad 0 is always fixed in both one and two pads
+	 * modes. In two pads mode, the source pad(= 1) size is identical to
+	 * the sink pad size */
+	if (fse->pad == 0) {
+		fse->min_width = XVIP_MIN_WIDTH;
+		fse->max_width = XVIP_MAX_WIDTH;
+		fse->min_height = XVIP_MIN_HEIGHT;
+		fse->max_height = XVIP_MAX_HEIGHT;
+	} else {
+		fse->min_width = format->width;
+		fse->max_width = format->width;
+		fse->min_height = format->height;
+		fse->max_height = format->height;
+	}
+
+	return 0;
+}
+
+static int xtpg_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
+{
+	struct xtpg_device *xtpg = to_tpg(subdev);
+
+	*v4l2_subdev_get_try_format(fh, 0) = xtpg->default_format;
+
+	if (xtpg->npads == 2)
+		*v4l2_subdev_get_try_format(fh, 1) = xtpg->default_format;
+
+	return 0;
+}
+
+static int xtpg_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
+{
+	return 0;
+}
+
+static int xtpg_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct xtpg_device *xtpg = container_of(ctrl->handler,
+						struct xtpg_device,
+						ctrl_handler);
+	switch (ctrl->id) {
+	case V4L2_CID_TEST_PATTERN:
+		xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
+				 XTPG_PATTERN_MASK, ctrl->val);
+		return 0;
+	case V4L2_CID_XILINX_TPG_CROSS_HAIRS:
+		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
+				XTPG_PATTERN_CONTROL_CROSS_HAIRS, ctrl->val);
+		return 0;
+	case V4L2_CID_XILINX_TPG_MOVING_BOX:
+		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
+				XTPG_PATTERN_CONTROL_MOVING_BOX, ctrl->val);
+		return 0;
+	case V4L2_CID_XILINX_TPG_COLOR_MASK:
+		xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
+				 XTPG_PATTERN_CONTROL_COLOR_MASK_MASK,
+				 ctrl->val <<
+				 XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT);
+		return 0;
+	case V4L2_CID_XILINX_TPG_STUCK_PIXEL:
+		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
+				XTPG_PATTERN_CONTROL_STUCK_PIXEL, ctrl->val);
+		return 0;
+	case V4L2_CID_XILINX_TPG_NOISE:
+		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
+				XTPG_PATTERN_CONTROL_NOISE, ctrl->val);
+		return 0;
+	case V4L2_CID_XILINX_TPG_MOTION:
+		xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
+				XTPG_PATTERN_CONTROL_MOTION, ctrl->val);
+		return 0;
+	case V4L2_CID_XILINX_TPG_MOTION_SPEED:
+		xvip_write(&xtpg->xvip, XTPG_MOTION_SPEED, ctrl->val);
+		return 0;
+	case V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW:
+		xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS,
+				 XTPG_CROSS_HAIRS_ROW_MASK,
+				 ctrl->val << XTPG_CROSS_HAIRS_ROW_SHIFT);
+		return 0;
+	case V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN:
+		xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS,
+				 XTPG_CROSS_HAIRS_COLUMN_MASK,
+				 ctrl->val << XTPG_CROSS_HAIRS_COLUMN_SHIFT);
+		return 0;
+	case V4L2_CID_XILINX_TPG_ZPLATE_HOR_START:
+		xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL,
+				 XTPG_ZPLATE_START_MASK,
+				 ctrl->val << XTPG_ZPLATE_START_SHIFT);
+		return 0;
+	case V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED:
+		xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL,
+				 XTPG_ZPLATE_SPEED_MASK,
+				 ctrl->val << XTPG_ZPLATE_SPEED_SHIFT);
+		return 0;
+	case V4L2_CID_XILINX_TPG_ZPLATE_VER_START:
+		xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL,
+				 XTPG_ZPLATE_START_MASK,
+				 ctrl->val << XTPG_ZPLATE_START_SHIFT);
+		return 0;
+	case V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED:
+		xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL,
+				 XTPG_ZPLATE_SPEED_MASK,
+				 ctrl->val << XTPG_ZPLATE_SPEED_SHIFT);
+		return 0;
+	case V4L2_CID_XILINX_TPG_BOX_SIZE:
+		xvip_write(&xtpg->xvip, XTPG_BOX_SIZE, ctrl->val);
+		return 0;
+	case V4L2_CID_XILINX_TPG_BOX_COLOR:
+		xvip_write(&xtpg->xvip, XTPG_BOX_COLOR, ctrl->val);
+		return 0;
+	case V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH:
+		xvip_write(&xtpg->xvip, XTPG_STUCK_PIXEL_THRESH, ctrl->val);
+		return 0;
+	case V4L2_CID_XILINX_TPG_NOISE_GAIN:
+		xvip_write(&xtpg->xvip, XTPG_NOISE_GAIN, ctrl->val);
+		return 0;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops xtpg_ctrl_ops = {
+	.s_ctrl	= xtpg_s_ctrl,
+};
+
+static struct v4l2_subdev_core_ops xtpg_core_ops = {
+};
+
+static struct v4l2_subdev_video_ops xtpg_video_ops = {
+	.s_stream = xtpg_s_stream,
+};
+
+static struct v4l2_subdev_pad_ops xtpg_pad_ops = {
+	.enum_mbus_code		= xvip_enum_mbus_code,
+	.enum_frame_size	= xtpg_enum_frame_size,
+	.get_fmt		= xtpg_get_format,
+	.set_fmt		= xtpg_set_format,
+};
+
+static struct v4l2_subdev_ops xtpg_ops = {
+	.core   = &xtpg_core_ops,
+	.video  = &xtpg_video_ops,
+	.pad    = &xtpg_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops xtpg_internal_ops = {
+	.open	= xtpg_open,
+	.close	= xtpg_close,
+};
+
+/*
+ * Control Config
+ */
+
+static const char *const xtpg_pattern_strings[] = {
+	"Passthrough",
+	"Horizontal Ramp",
+	"Vertical Ramp",
+	"Temporal Ramp",
+	"Solid Red",
+	"Solid Green",
+	"Solid Blue",
+	"Solid Black",
+	"Solid White",
+	"Color Bars",
+	"Zone Plate",
+	"Tartan Color Bars",
+	"Cross Hatch",
+	"None",
+	"Vertical/Horizontal Ramps",
+	"Black/White Checker Board",
+};
+
+static struct v4l2_ctrl_config xtpg_ctrls[] = {
+	{
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_CROSS_HAIRS,
+		.name	= "Test Pattern: Cross Hairs",
+		.type	= V4L2_CTRL_TYPE_BOOLEAN,
+		.min	= false,
+		.max	= true,
+		.step	= 1,
+		.def	= 0,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_MOVING_BOX,
+		.name	= "Test Pattern: Moving Box",
+		.type	= V4L2_CTRL_TYPE_BOOLEAN,
+		.min	= false,
+		.max	= true,
+		.step	= 1,
+		.def	= 0,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_COLOR_MASK,
+		.name	= "Test Pattern: Color Mask",
+		.type	= V4L2_CTRL_TYPE_BITMASK,
+		.min	= 0,
+		.max	= 0xf,
+		.def	= 0,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_STUCK_PIXEL,
+		.name	= "Test Pattern: Stuck Pixel",
+		.type	= V4L2_CTRL_TYPE_BOOLEAN,
+		.min	= false,
+		.max	= true,
+		.step	= 1,
+		.def	= 0,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_NOISE,
+		.name	= "Test Pattern: Noise",
+		.type	= V4L2_CTRL_TYPE_BOOLEAN,
+		.min	= false,
+		.max	= true,
+		.step	= 1,
+		.def	= 0,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_MOTION,
+		.name	= "Test Pattern: Motion",
+		.type	= V4L2_CTRL_TYPE_BOOLEAN,
+		.min	= false,
+		.max	= true,
+		.step	= 1,
+		.def	= 0,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_MOTION_SPEED,
+		.name	= "Test Pattern: Motion Speed",
+		.type	= V4L2_CTRL_TYPE_INTEGER,
+		.min	= 0,
+		.max	= (1 << 8) - 1,
+		.step	= 1,
+		.def	= 4,
+		.flags	= V4L2_CTRL_FLAG_SLIDER,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW,
+		.name	= "Test Pattern: Cross Hairs Row",
+		.type	= V4L2_CTRL_TYPE_INTEGER,
+		.min	= 0,
+		.max	= (1 << 12) - 1,
+		.step	= 1,
+		.def	= 0x64,
+		.flags	= V4L2_CTRL_FLAG_SLIDER,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN,
+		.name	= "Test Pattern: Cross Hairs Column",
+		.type	= V4L2_CTRL_TYPE_INTEGER,
+		.min	= 0,
+		.max	= (1 << 12) - 1,
+		.step	= 1,
+		.def	= 0x64,
+		.flags	= V4L2_CTRL_FLAG_SLIDER,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_ZPLATE_HOR_START,
+		.name	= "Test Pattern: Zplate Horizontal Start Pos",
+		.type	= V4L2_CTRL_TYPE_INTEGER,
+		.min	= 0,
+		.max	= (1 << 16) - 1,
+		.step	= 1,
+		.def	= 0x1e,
+		.flags	= V4L2_CTRL_FLAG_SLIDER,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED,
+		.name	= "Test Pattern: Zplate Horizontal Speed",
+		.type	= V4L2_CTRL_TYPE_INTEGER,
+		.min	= 0,
+		.max	= (1 << 16) - 1,
+		.step	= 1,
+		.def	= 0,
+		.flags	= V4L2_CTRL_FLAG_SLIDER,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_ZPLATE_VER_START,
+		.name	= "Test Pattern: Zplate Vertical Start Pos",
+		.type	= V4L2_CTRL_TYPE_INTEGER,
+		.min	= 0,
+		.max	= (1 << 16) - 1,
+		.step	= 1,
+		.def	= 1,
+		.flags	= V4L2_CTRL_FLAG_SLIDER,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED,
+		.name	= "Test Pattern: Zplate Vertical Speed",
+		.type	= V4L2_CTRL_TYPE_INTEGER,
+		.min	= 0,
+		.max	= (1 << 16) - 1,
+		.step	= 1,
+		.def	= 0,
+		.flags	= V4L2_CTRL_FLAG_SLIDER,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_BOX_SIZE,
+		.name	= "Test Pattern: Box Size",
+		.type	= V4L2_CTRL_TYPE_INTEGER,
+		.min	= 0,
+		.max	= (1 << 12) - 1,
+		.step	= 1,
+		.def	= 0x32,
+		.flags	= V4L2_CTRL_FLAG_SLIDER,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_BOX_COLOR,
+		.name	= "Test Pattern: Box Color(RGB)",
+		.type	= V4L2_CTRL_TYPE_INTEGER,
+		.min	= 0,
+		.max	= (1 << 24) - 1,
+		.step	= 1,
+		.def	= 0,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH,
+		.name	= "Test Pattern: Stuck Pixel threshold",
+		.type	= V4L2_CTRL_TYPE_INTEGER,
+		.min	= 0,
+		.max	= (1 << 16) - 1,
+		.step	= 1,
+		.def	= 0,
+		.flags	= V4L2_CTRL_FLAG_SLIDER,
+	}, {
+		.ops	= &xtpg_ctrl_ops,
+		.id	= V4L2_CID_XILINX_TPG_NOISE_GAIN,
+		.name	= "Test Pattern: Noise Gain",
+		.type	= V4L2_CTRL_TYPE_INTEGER,
+		.min	= 0,
+		.max	= (1 << 8) - 1,
+		.step	= 1,
+		.def	= 0,
+		.flags	= V4L2_CTRL_FLAG_SLIDER,
+	},
+};
+
+/* -----------------------------------------------------------------------------
+ * Media Operations
+ */
+
+static const struct media_entity_operations xtpg_media_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
+/* -----------------------------------------------------------------------------
+ * Power Management
+ */
+
+static int __maybe_unused xtpg_pm_suspend(struct device *dev)
+{
+	struct xtpg_device *xtpg = dev_get_drvdata(dev);
+
+	xvip_suspend(&xtpg->xvip);
+
+	return 0;
+}
+
+static int __maybe_unused xtpg_pm_resume(struct device *dev)
+{
+	struct xtpg_device *xtpg = dev_get_drvdata(dev);
+
+	xvip_resume(&xtpg->xvip);
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Platform Device Driver
+ */
+
+static int xtpg_parse_of(struct xtpg_device *xtpg)
+{
+	struct device *dev = xtpg->xvip.dev;
+	struct device_node *node = xtpg->xvip.dev->of_node;
+	struct device_node *ports;
+	struct device_node *port;
+	unsigned int nports = 0;
+	bool has_endpoint = false;
+
+	ports = of_get_child_by_name(node, "ports");
+	if (ports == NULL)
+		ports = node;
+
+	for_each_child_of_node(ports, port) {
+		const struct xvip_video_format *format;
+		struct device_node *endpoint;
+
+		if (!port->name || of_node_cmp(port->name, "port"))
+			continue;
+
+		format = xvip_of_get_format(port);
+		if (IS_ERR(format)) {
+			dev_err(dev, "invalid format in DT");
+			return PTR_ERR(format);
+		}
+
+		/* Get and check the format description */
+		if (!xtpg->vip_format) {
+			xtpg->vip_format = format;
+		} else if (xtpg->vip_format != format) {
+			dev_err(dev, "in/out format mismatch in DT");
+			return -EINVAL;
+		}
+
+		if (nports == 0) {
+			endpoint = of_get_next_child(port, NULL);
+			if (endpoint)
+				has_endpoint = true;
+			of_node_put(endpoint);
+		}
+
+		/* Count the number of ports. */
+		nports++;
+	}
+
+	if (nports != 1 && nports != 2) {
+		dev_err(dev, "invalid number of ports %u\n", nports);
+		return -EINVAL;
+	}
+
+	xtpg->npads = nports;
+	if (nports == 2 && has_endpoint)
+		xtpg->has_input = true;
+
+	return 0;
+}
+
+static int xtpg_probe(struct platform_device *pdev)
+{
+	struct v4l2_subdev *subdev;
+	struct xtpg_device *xtpg;
+	u32 i, bayer_phase;
+	int ret;
+
+	xtpg = devm_kzalloc(&pdev->dev, sizeof(*xtpg), GFP_KERNEL);
+	if (!xtpg)
+		return -ENOMEM;
+
+	xtpg->xvip.dev = &pdev->dev;
+
+	ret = xtpg_parse_of(xtpg);
+	if (ret < 0)
+		return ret;
+
+	ret = xvip_init_resources(&xtpg->xvip);
+	if (ret < 0)
+		return ret;
+
+	xtpg->vtmux_gpio = devm_gpiod_get_optional(&pdev->dev, "timing",
+						   GPIOD_OUT_HIGH);
+	if (IS_ERR(xtpg->vtmux_gpio)) {
+		ret = PTR_ERR(xtpg->vtmux_gpio);
+		goto error;
+	}
+
+	xtpg->vtc = xvtc_of_get(pdev->dev.of_node);
+	if (IS_ERR(xtpg->vtc)) {
+		ret = PTR_ERR(xtpg->vtc);
+		goto error;
+	}
+
+	/* Reset and initialize the core */
+	xvip_reset(&xtpg->xvip);
+
+	/* Initialize V4L2 subdevice and media entity. Pad numbers depend on the
+	 * number of pads.
+	 */
+	if (xtpg->npads == 2) {
+		xtpg->pads[0].flags = MEDIA_PAD_FL_SINK;
+		xtpg->pads[1].flags = MEDIA_PAD_FL_SOURCE;
+	} else {
+		xtpg->pads[0].flags = MEDIA_PAD_FL_SOURCE;
+	}
+
+	/* Initialize the default format */
+	xtpg->default_format.code = xtpg->vip_format->code;
+	xtpg->default_format.field = V4L2_FIELD_NONE;
+	xtpg->default_format.colorspace = V4L2_COLORSPACE_SRGB;
+	xvip_get_frame_size(&xtpg->xvip, &xtpg->default_format);
+
+	bayer_phase = xtpg_get_bayer_phase(xtpg->vip_format->code);
+	if (bayer_phase != XTPG_BAYER_PHASE_OFF)
+		xtpg->bayer = true;
+
+	xtpg->formats[0] = xtpg->default_format;
+	if (xtpg->npads == 2)
+		xtpg->formats[1] = xtpg->default_format;
+
+	/* Initialize V4L2 subdevice and media entity */
+	subdev = &xtpg->xvip.subdev;
+	v4l2_subdev_init(subdev, &xtpg_ops);
+	subdev->dev = &pdev->dev;
+	subdev->internal_ops = &xtpg_internal_ops;
+	strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
+	v4l2_set_subdevdata(subdev, xtpg);
+	subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	subdev->entity.ops = &xtpg_media_ops;
+
+	ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads, 0);
+	if (ret < 0)
+		goto error;
+
+	v4l2_ctrl_handler_init(&xtpg->ctrl_handler, 3 + ARRAY_SIZE(xtpg_ctrls));
+
+	xtpg->vblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops,
+					 V4L2_CID_VBLANK, XTPG_MIN_VBLANK,
+					 XTPG_MAX_VBLANK, 1, 100);
+	xtpg->hblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops,
+					 V4L2_CID_HBLANK, XTPG_MIN_HBLANK,
+					 XTPG_MAX_HBLANK, 1, 100);
+	xtpg->pattern = v4l2_ctrl_new_std_menu_items(&xtpg->ctrl_handler,
+					&xtpg_ctrl_ops, V4L2_CID_TEST_PATTERN,
+					ARRAY_SIZE(xtpg_pattern_strings) - 1,
+					1, 9, xtpg_pattern_strings);
+
+	for (i = 0; i < ARRAY_SIZE(xtpg_ctrls); i++)
+		v4l2_ctrl_new_custom(&xtpg->ctrl_handler, &xtpg_ctrls[i], NULL);
+
+	if (xtpg->ctrl_handler.error) {
+		dev_err(&pdev->dev, "failed to add controls\n");
+		ret = xtpg->ctrl_handler.error;
+		goto error;
+	}
+	subdev->ctrl_handler = &xtpg->ctrl_handler;
+
+	xtpg_update_pattern_control(xtpg, true, true);
+
+	ret = v4l2_ctrl_handler_setup(&xtpg->ctrl_handler);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to set controls\n");
+		goto error;
+	}
+
+	platform_set_drvdata(pdev, xtpg);
+
+	xvip_print_version(&xtpg->xvip);
+
+	ret = v4l2_async_register_subdev(subdev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to register subdev\n");
+		goto error;
+	}
+
+	return 0;
+
+error:
+	v4l2_ctrl_handler_free(&xtpg->ctrl_handler);
+	media_entity_cleanup(&subdev->entity);
+	xvtc_put(xtpg->vtc);
+	xvip_cleanup_resources(&xtpg->xvip);
+	return ret;
+}
+
+static int xtpg_remove(struct platform_device *pdev)
+{
+	struct xtpg_device *xtpg = platform_get_drvdata(pdev);
+	struct v4l2_subdev *subdev = &xtpg->xvip.subdev;
+
+	v4l2_async_unregister_subdev(subdev);
+	v4l2_ctrl_handler_free(&xtpg->ctrl_handler);
+	media_entity_cleanup(&subdev->entity);
+
+	xvip_cleanup_resources(&xtpg->xvip);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(xtpg_pm_ops, xtpg_pm_suspend, xtpg_pm_resume);
+
+static const struct of_device_id xtpg_of_id_table[] = {
+	{ .compatible = "xlnx,v-tpg-5.0" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, xtpg_of_id_table);
+
+static struct platform_driver xtpg_driver = {
+	.driver = {
+		.name		= "xilinx-tpg",
+		.pm		= &xtpg_pm_ops,
+		.of_match_table	= xtpg_of_id_table,
+	},
+	.probe			= xtpg_probe,
+	.remove			= xtpg_remove,
+};
+
+module_platform_driver(xtpg_driver);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("Xilinx Test Pattern Generator Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index ed39ac8..f09cac8 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -434,6 +434,7 @@ header-y += wireless.h
 header-y += x25.h
 header-y += xattr.h
 header-y += xfrm.h
+header-y += xilinx-v4l2-controls.h
 header-y += hw_breakpoint.h
 header-y += zorro.h
 header-y += zorro_ids.h
diff --git a/include/uapi/linux/xilinx-v4l2-controls.h b/include/uapi/linux/xilinx-v4l2-controls.h
new file mode 100644
index 0000000..59e38db
--- /dev/null
+++ b/include/uapi/linux/xilinx-v4l2-controls.h
@@ -0,0 +1,73 @@
+/*
+ * Xilinx Controls Header
+ *
+ * Copyright (C) 2013-2014 Ideas on Board
+ * Copyright (C) 2013-2014 Xilinx, Inc.
+ *
+ * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
+ *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __UAPI_XILINX_V4L2_CONTROLS_H__
+#define __UAPI_XILINX_V4L2_CONTROLS_H__
+
+#include <linux/v4l2-controls.h>
+
+#define V4L2_CID_XILINX_OFFSET	0xc000
+#define V4L2_CID_XILINX_BASE	(V4L2_CID_USER_BASE + V4L2_CID_XILINX_OFFSET)
+
+/*
+ * Private Controls for Xilinx Video IPs
+ */
+
+/*
+ * Xilinx TPG Video IP
+ */
+
+#define V4L2_CID_XILINX_TPG			(V4L2_CID_USER_BASE + 0xc000)
+
+/* Draw cross hairs */
+#define V4L2_CID_XILINX_TPG_CROSS_HAIRS		(V4L2_CID_XILINX_TPG + 1)
+/* Enable a moving box */
+#define V4L2_CID_XILINX_TPG_MOVING_BOX		(V4L2_CID_XILINX_TPG + 2)
+/* Mask out a color component */
+#define V4L2_CID_XILINX_TPG_COLOR_MASK		(V4L2_CID_XILINX_TPG + 3)
+/* Enable a stuck pixel feature */
+#define V4L2_CID_XILINX_TPG_STUCK_PIXEL		(V4L2_CID_XILINX_TPG + 4)
+/* Enable a noisy output */
+#define V4L2_CID_XILINX_TPG_NOISE		(V4L2_CID_XILINX_TPG + 5)
+/* Enable the motion feature */
+#define V4L2_CID_XILINX_TPG_MOTION		(V4L2_CID_XILINX_TPG + 6)
+/* Configure the motion speed of moving patterns */
+#define V4L2_CID_XILINX_TPG_MOTION_SPEED	(V4L2_CID_XILINX_TPG + 7)
+/* The row of horizontal cross hair location */
+#define V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW	(V4L2_CID_XILINX_TPG + 8)
+/* The colum of vertical cross hair location */
+#define V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN	(V4L2_CID_XILINX_TPG + 9)
+/* Set starting point of sine wave for horizontal component */
+#define V4L2_CID_XILINX_TPG_ZPLATE_HOR_START	(V4L2_CID_XILINX_TPG + 10)
+/* Set speed of the horizontal component */
+#define V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED	(V4L2_CID_XILINX_TPG + 11)
+/* Set starting point of sine wave for vertical component */
+#define V4L2_CID_XILINX_TPG_ZPLATE_VER_START	(V4L2_CID_XILINX_TPG + 12)
+/* Set speed of the vertical component */
+#define V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED	(V4L2_CID_XILINX_TPG + 13)
+/* Moving box size */
+#define V4L2_CID_XILINX_TPG_BOX_SIZE		(V4L2_CID_XILINX_TPG + 14)
+/* Moving box color */
+#define V4L2_CID_XILINX_TPG_BOX_COLOR		(V4L2_CID_XILINX_TPG + 15)
+/* Upper limit count of generated stuck pixels */
+#define V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH	(V4L2_CID_XILINX_TPG + 16)
+/* Noise level */
+#define V4L2_CID_XILINX_TPG_NOISE_GAIN		(V4L2_CID_XILINX_TPG + 17)
+
+#endif /* __UAPI_XILINX_V4L2_CONTROLS_H__ */
-- 
2.0.4

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

* Re: [PATCH v4 05/10] v4l: of: Add v4l2_of_parse_link() function
  2014-12-01 20:13 ` [PATCH v4 05/10] v4l: of: Add v4l2_of_parse_link() function Laurent Pinchart
@ 2014-12-03 12:30   ` Sakari Ailus
  2014-12-03 15:02   ` Sylwester Nawrocki
  1 sibling, 0 replies; 20+ messages in thread
From: Sakari Ailus @ 2014-12-03 12:30 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, Michal Simek, Chris Kohn, Hyun Kwon, Sylwester Nawrocki

On Mon, Dec 01, 2014 at 10:13:35PM +0200, Laurent Pinchart wrote:
> The function fills a link data structure with the device node and port
> number at both the local and remote ends of a link defined by one of its
> endpoint nodes.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
>  drivers/media/v4l2-core/v4l2-of.c | 61 +++++++++++++++++++++++++++++++++++++++
>  include/media/v4l2-of.h           | 27 +++++++++++++++++
>  2 files changed, 88 insertions(+)

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

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

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

* Re: [PATCH v4 05/10] v4l: of: Add v4l2_of_parse_link() function
  2014-12-01 20:13 ` [PATCH v4 05/10] v4l: of: Add v4l2_of_parse_link() function Laurent Pinchart
  2014-12-03 12:30   ` Sakari Ailus
@ 2014-12-03 15:02   ` Sylwester Nawrocki
  2014-12-03 15:10     ` Laurent Pinchart
  1 sibling, 1 reply; 20+ messages in thread
From: Sylwester Nawrocki @ 2014-12-03 15:02 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-media, Michal Simek, Chris Kohn, Hyun Kwon

Hi Laurent,

On 01/12/14 21:13, Laurent Pinchart wrote:
> The function fills a link data structure with the device node and port
> number at both the local and remote ends of a link defined by one of its
> endpoint nodes.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
>  drivers/media/v4l2-core/v4l2-of.c | 61 +++++++++++++++++++++++++++++++++++++++
>  include/media/v4l2-of.h           | 27 +++++++++++++++++
>  2 files changed, 88 insertions(+)
> 
> Cc: Sylwester Nawrocki <s.nawrocki@samsung.com>
> 
> diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c
> index b4ed9a9..c473479 100644
> --- a/drivers/media/v4l2-core/v4l2-of.c
> +++ b/drivers/media/v4l2-core/v4l2-of.c
> @@ -142,3 +142,64 @@ int v4l2_of_parse_endpoint(const struct device_node *node,
>  	return 0;
>  }
>  EXPORT_SYMBOL(v4l2_of_parse_endpoint);
> +
> +/**
> + * v4l2_of_parse_link() - parse a link between two endpoints
> + * @node: pointer to the endpoint at the local end of the link
> + * @link: pointer to the V4L2 OF link data structure
> + *
> + * Fill the link structure with the local and remote nodes and port numbers.
> + * The local_node and remote_node fields are set to point to the local and
> + * remote port parent nodes respectively (the port parent node being the parent

Not sure it that improves anything, but how about changing "remote port parent"
to "remote port's parent" ? I took me a while to understand this whole sentence.

Anyway the patch looks good to me.

Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>

> + * node of the port node if that node isn't a 'ports' node, or the grand-parent
> + * node of the port node otherwise).
> + *
> + * A reference is taken to both the local and remote nodes, the caller must use
> + * v4l2_of_put_link() to drop the references when done with the link.
> + *
> + * Return: 0 on success, or -ENOLINK if the remote endpoint can't be found.
> + */

--
Regards,
Sylwester

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

* Re: [PATCH v4 07/10] v4l: vb2: Fix race condition in _vb2_fop_release
  2014-12-01 20:13 ` [PATCH v4 07/10] v4l: vb2: Fix race condition in _vb2_fop_release Laurent Pinchart
@ 2014-12-03 15:07   ` Sylwester Nawrocki
  0 siblings, 0 replies; 20+ messages in thread
From: Sylwester Nawrocki @ 2014-12-03 15:07 UTC (permalink / raw)
  To: Laurent Pinchart, linux-media; +Cc: Michal Simek, Chris Kohn, Hyun Kwon

On 01/12/14 21:13, Laurent Pinchart wrote:
> The function releases the queue if the file being released is the queue
> owner. The check reads the queue->owner field without taking the queue
> lock, creating a race condition with functions that set the queue owner,
> such as vb2_ioctl_reqbufs() for instance.
> 
> Fix this by moving the queue->owner check within the mutex protected
> section.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>

Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>


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

* Re: [PATCH v4 05/10] v4l: of: Add v4l2_of_parse_link() function
  2014-12-03 15:02   ` Sylwester Nawrocki
@ 2014-12-03 15:10     ` Laurent Pinchart
  0 siblings, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2014-12-03 15:10 UTC (permalink / raw)
  To: Sylwester Nawrocki; +Cc: linux-media, Michal Simek, Chris Kohn, Hyun Kwon

Hi Sylwester,

Thank you for the review.

On Wednesday 03 December 2014 16:02:12 Sylwester Nawrocki wrote:
> Hi Laurent,
> 
> On 01/12/14 21:13, Laurent Pinchart wrote:
> > The function fills a link data structure with the device node and port
> > number at both the local and remote ends of a link defined by one of its
> > endpoint nodes.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
> > ---
> > 
> >  drivers/media/v4l2-core/v4l2-of.c | 61 ++++++++++++++++++++++++++++++++++
> >  include/media/v4l2-of.h           | 27 +++++++++++++++++
> >  2 files changed, 88 insertions(+)
> > 
> > Cc: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-of.c
> > b/drivers/media/v4l2-core/v4l2-of.c index b4ed9a9..c473479 100644
> > --- a/drivers/media/v4l2-core/v4l2-of.c
> > +++ b/drivers/media/v4l2-core/v4l2-of.c
> > @@ -142,3 +142,64 @@ int v4l2_of_parse_endpoint(const struct device_node
> > *node,> 
> >  	return 0;
> >  
> >  }
> >  EXPORT_SYMBOL(v4l2_of_parse_endpoint);
> > 
> > +
> > +/**
> > + * v4l2_of_parse_link() - parse a link between two endpoints
> > + * @node: pointer to the endpoint at the local end of the link
> > + * @link: pointer to the V4L2 OF link data structure
> > + *
> > + * Fill the link structure with the local and remote nodes and port
> > numbers.
> > + * The local_node and remote_node fields are set to point to the local
> > and
> > + * remote port parent nodes respectively (the port parent node being the
> > parent
>
> Not sure it that improves anything, but how about changing "remote port
> parent" to "remote port's parent" ? I took me a while to understand this
> whole sentence.

I'll fix that.
 
> Anyway the patch looks good to me.
> 
> Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> 
> > + * node of the port node if that node isn't a 'ports' node, or the
> > grand-parent + * node of the port node otherwise).
> > + *
> > + * A reference is taken to both the local and remote nodes, the caller
> > must use + * v4l2_of_put_link() to drop the references when done with the
> > link. + *
> > + * Return: 0 on success, or -ENOLINK if the remote endpoint can't be
> > found. + */

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH v4 08/10] v4l: xilinx: Add Xilinx Video IP core
  2014-12-01 20:13 ` [PATCH v4 08/10] v4l: xilinx: Add Xilinx Video IP core Laurent Pinchart
@ 2015-01-22  3:01       ` Laurent Pinchart
  0 siblings, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2015-01-22  3:01 UTC (permalink / raw)
  To: Chris Kohn, Hans Verkuil
  Cc: linux-media-u79uwXL29TY76Z2rM5mHXA, Michal Simek, Hyun Kwon,
	devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Hans and Chris,

On Monday 01 December 2014 22:13:38 Laurent Pinchart wrote:
> Xilinx platforms have no hardwired video capture or video processing
> interface. Users create capture and memory to memory processing
> pipelines in the FPGA fabric to suit their particular needs, by
> instantiating video IP cores from a large library.
> 
> The Xilinx Video IP core is a framework that models a video pipeline
> described in the device tree and expose the pipeline to userspace
> through the media controller and V4L2 APIs.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
> Signed-off-by: Hyun Kwon <hyun.kwon-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Radhey Shyam Pandey <radheys-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Michal Simek <michal.simek-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

[snip]

> diff --git a/Documentation/devicetree/bindings/media/xilinx/video.txt
> b/Documentation/devicetree/bindings/media/xilinx/video.txt new file mode
> 100644
> index 0000000..15720e4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/xilinx/video.txt
> @@ -0,0 +1,52 @@
> +DT bindings for Xilinx video IP cores
> +-------------------------------------
> +
> +Xilinx video IP cores process video streams by acting as video sinks and/or
> +sources. They are connected by links through their input and output ports,
> +creating a video pipeline.
> +
> +Each video IP core is represented by an AMBA bus child node in the device
> +tree using bindings documented in this directory. Connections between the
> IP
> +cores are represented as defined in ../video-interfaces.txt.
> +
> +The whole  pipeline is represented by an AMBA bus child node in the device
> +tree using bindings documented in ./xlnx,video.txt.
> +
> +Common properties
> +-----------------
> +
> +The following properties are common to all Xilinx video IP cores.
> +
> +- xlnx,video-format: This property represents a video format transmitted on
> an
> +  AXI bus between video IP cores. How the format relates to the IP core is
> +  decribed in the IP core bindings documentation. The following formats are
> +  supported.
> +
> +	rbg
> +	xrgb
> +	yuv422
> +	yuv444
> +	rggb
> +	grbg
> +	gbrg
> +	bggr
> +
> +- xlnx,video-width: This property qualifies the video format with the
> sample
> +  width expressed as a number of bits per pixel component. All components
> must
> +  use the same width.

Hans, last time we've discussed this on IRC you were not happy with the format 
description used in these DT bindings. Your argument was, if I remember 
correctly, that as the formats map directly to media bus codes, it would be 
better to use the media bus codes (or a string representation of them) in the 
bindings instead of creating a new format description. Is that correct ?

Chris, what's your opinion on that ? The RGB and YUV formats in the table 
below describe the hardware and come from table 1-4 on page 8 of 
http://www.xilinx.com/support/documentation/ip_documentation/axi_videoip/v1_0/ug934_axi_videoIP.pdf. 
The Bayer formats are not standardized in the document, and I don't think we 
need them at the moment.

> +The following table lists the supported formats and widths combinations,
> along
> +with the corresponding media bus pixel code.
> +
> +----------------+-------+--------------------------------------------------
> +Format		| Width	| Media bus code
> +----------------+-------+--------------------------------------------------
> +rbg		| 8	| V4L2_MBUS_FMT_RBG888_1X24
> +xrgb		| 8	| V4L2_MBUS_FMT_RGB888_1X32_PADHI
> +yuv422		| 8	| V4L2_MBUS_FMT_UYVY8_1X16
> +yuv444		| 8	| V4L2_MBUS_FMT_VUY888_1X24
> +rggb		| 8	| V4L2_MBUS_FMT_SRGGB8_1X8
> +grbg		| 8	| V4L2_MBUS_FMT_SGRBG8_1X8
> +gbrg		| 8	| V4L2_MBUS_FMT_SGBRG8_1X8
> +bggr		| 8	| V4L2_MBUS_FMT_SBGGR8_1X8
> +----------------+-------+--------------------------------------------------
> diff --git
> a/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
> b/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt new file
> mode 100644
> index 0000000..5a02270
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
> @@ -0,0 +1,55 @@
> +Xilinx Video IP Pipeline (VIPP)
> +-------------------------------
> +
> +General concept
> +---------------
> +
> +Xilinx video IP pipeline processes video streams through one or more Xilinx
> +video IP cores. Each video IP core is represented as documented in
> video.txt
> +and IP core specific documentation, xlnx,v-*.txt, in this directory. The DT
> +node of the VIPP represents as a top level node of the pipeline and defines
> +mappings between DMAs and the video IP cores.
> +
> +Required properties:
> +
> +- compatible: Must be "xlnx,video".
> +
> +- dmas, dma-names: List of one DMA specifier and identifier string (as
> defined
> +  in Documentation/devicetree/bindings/dma/dma.txt) per port. Each port
> +  requires a DMA channel with the identifier string set to "port" followed
> by
> +  the port index.
> +
> +- ports: Video port, using the DT bindings defined in
> ../video-interfaces.txt.
> +
> +Required port properties:
> +
> +- direction: should be either "input" or "output" depending on the
> direction
> +  of stream.
> +
> +Example:
> +
> +	video_cap {
> +		compatible = "xlnx,video";
> +		dmas = <&vdma_1 1>, <&vdma_3 1>;
> +		dma-names = "port0", "port1";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				direction = "input";
> +				vcap0_in0: endpoint {
> +					remote-endpoint = <&scaler0_out>;
> +				};
> +			};
> +			port@1 {
> +				reg = <1>;
> +				direction = "input";
> +				vcap0_in1: endpoint {
> +					remote-endpoint = <&switch_out1>;
> +				};
> +			};
> +		};
> +	};

-- 
Regards,

Laurent Pinchart

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v4 08/10] v4l: xilinx: Add Xilinx Video IP core
@ 2015-01-22  3:01       ` Laurent Pinchart
  0 siblings, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2015-01-22  3:01 UTC (permalink / raw)
  To: Chris Kohn, Hans Verkuil; +Cc: linux-media, Michal Simek, Hyun Kwon, devicetree

Hi Hans and Chris,

On Monday 01 December 2014 22:13:38 Laurent Pinchart wrote:
> Xilinx platforms have no hardwired video capture or video processing
> interface. Users create capture and memory to memory processing
> pipelines in the FPGA fabric to suit their particular needs, by
> instantiating video IP cores from a large library.
> 
> The Xilinx Video IP core is a framework that models a video pipeline
> described in the device tree and expose the pipeline to userspace
> through the media controller and V4L2 APIs.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Hyun Kwon <hyun.kwon@xilinx.com>
> Signed-off-by: Radhey Shyam Pandey <radheys@xilinx.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>

[snip]

> diff --git a/Documentation/devicetree/bindings/media/xilinx/video.txt
> b/Documentation/devicetree/bindings/media/xilinx/video.txt new file mode
> 100644
> index 0000000..15720e4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/xilinx/video.txt
> @@ -0,0 +1,52 @@
> +DT bindings for Xilinx video IP cores
> +-------------------------------------
> +
> +Xilinx video IP cores process video streams by acting as video sinks and/or
> +sources. They are connected by links through their input and output ports,
> +creating a video pipeline.
> +
> +Each video IP core is represented by an AMBA bus child node in the device
> +tree using bindings documented in this directory. Connections between the
> IP
> +cores are represented as defined in ../video-interfaces.txt.
> +
> +The whole  pipeline is represented by an AMBA bus child node in the device
> +tree using bindings documented in ./xlnx,video.txt.
> +
> +Common properties
> +-----------------
> +
> +The following properties are common to all Xilinx video IP cores.
> +
> +- xlnx,video-format: This property represents a video format transmitted on
> an
> +  AXI bus between video IP cores. How the format relates to the IP core is
> +  decribed in the IP core bindings documentation. The following formats are
> +  supported.
> +
> +	rbg
> +	xrgb
> +	yuv422
> +	yuv444
> +	rggb
> +	grbg
> +	gbrg
> +	bggr
> +
> +- xlnx,video-width: This property qualifies the video format with the
> sample
> +  width expressed as a number of bits per pixel component. All components
> must
> +  use the same width.

Hans, last time we've discussed this on IRC you were not happy with the format 
description used in these DT bindings. Your argument was, if I remember 
correctly, that as the formats map directly to media bus codes, it would be 
better to use the media bus codes (or a string representation of them) in the 
bindings instead of creating a new format description. Is that correct ?

Chris, what's your opinion on that ? The RGB and YUV formats in the table 
below describe the hardware and come from table 1-4 on page 8 of 
http://www.xilinx.com/support/documentation/ip_documentation/axi_videoip/v1_0/ug934_axi_videoIP.pdf. 
The Bayer formats are not standardized in the document, and I don't think we 
need them at the moment.

> +The following table lists the supported formats and widths combinations,
> along
> +with the corresponding media bus pixel code.
> +
> +----------------+-------+--------------------------------------------------
> +Format		| Width	| Media bus code
> +----------------+-------+--------------------------------------------------
> +rbg		| 8	| V4L2_MBUS_FMT_RBG888_1X24
> +xrgb		| 8	| V4L2_MBUS_FMT_RGB888_1X32_PADHI
> +yuv422		| 8	| V4L2_MBUS_FMT_UYVY8_1X16
> +yuv444		| 8	| V4L2_MBUS_FMT_VUY888_1X24
> +rggb		| 8	| V4L2_MBUS_FMT_SRGGB8_1X8
> +grbg		| 8	| V4L2_MBUS_FMT_SGRBG8_1X8
> +gbrg		| 8	| V4L2_MBUS_FMT_SGBRG8_1X8
> +bggr		| 8	| V4L2_MBUS_FMT_SBGGR8_1X8
> +----------------+-------+--------------------------------------------------
> diff --git
> a/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
> b/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt new file
> mode 100644
> index 0000000..5a02270
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
> @@ -0,0 +1,55 @@
> +Xilinx Video IP Pipeline (VIPP)
> +-------------------------------
> +
> +General concept
> +---------------
> +
> +Xilinx video IP pipeline processes video streams through one or more Xilinx
> +video IP cores. Each video IP core is represented as documented in
> video.txt
> +and IP core specific documentation, xlnx,v-*.txt, in this directory. The DT
> +node of the VIPP represents as a top level node of the pipeline and defines
> +mappings between DMAs and the video IP cores.
> +
> +Required properties:
> +
> +- compatible: Must be "xlnx,video".
> +
> +- dmas, dma-names: List of one DMA specifier and identifier string (as
> defined
> +  in Documentation/devicetree/bindings/dma/dma.txt) per port. Each port
> +  requires a DMA channel with the identifier string set to "port" followed
> by
> +  the port index.
> +
> +- ports: Video port, using the DT bindings defined in
> ../video-interfaces.txt.
> +
> +Required port properties:
> +
> +- direction: should be either "input" or "output" depending on the
> direction
> +  of stream.
> +
> +Example:
> +
> +	video_cap {
> +		compatible = "xlnx,video";
> +		dmas = <&vdma_1 1>, <&vdma_3 1>;
> +		dma-names = "port0", "port1";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				direction = "input";
> +				vcap0_in0: endpoint {
> +					remote-endpoint = <&scaler0_out>;
> +				};
> +			};
> +			port@1 {
> +				reg = <1>;
> +				direction = "input";
> +				vcap0_in1: endpoint {
> +					remote-endpoint = <&switch_out1>;
> +				};
> +			};
> +		};
> +	};

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH v4 08/10] v4l: xilinx: Add Xilinx Video IP core
  2015-01-22  3:01       ` Laurent Pinchart
@ 2015-01-22  9:43         ` Hans Verkuil
  -1 siblings, 0 replies; 20+ messages in thread
From: Hans Verkuil @ 2015-01-22  9:43 UTC (permalink / raw)
  To: Laurent Pinchart, Chris Kohn
  Cc: linux-media-u79uwXL29TY76Z2rM5mHXA, Michal Simek, Hyun Kwon,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On 01/22/15 04:01, Laurent Pinchart wrote:
> Hi Hans and Chris,
> 
> On Monday 01 December 2014 22:13:38 Laurent Pinchart wrote:
>> Xilinx platforms have no hardwired video capture or video processing
>> interface. Users create capture and memory to memory processing
>> pipelines in the FPGA fabric to suit their particular needs, by
>> instantiating video IP cores from a large library.
>>
>> The Xilinx Video IP core is a framework that models a video pipeline
>> described in the device tree and expose the pipeline to userspace
>> through the media controller and V4L2 APIs.
>>
>> Signed-off-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
>> Signed-off-by: Hyun Kwon <hyun.kwon-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
>> Signed-off-by: Radhey Shyam Pandey <radheys-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
>> Signed-off-by: Michal Simek <michal.simek-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
> 
> [snip]
> 
>> diff --git a/Documentation/devicetree/bindings/media/xilinx/video.txt
>> b/Documentation/devicetree/bindings/media/xilinx/video.txt new file mode
>> 100644
>> index 0000000..15720e4
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/media/xilinx/video.txt
>> @@ -0,0 +1,52 @@
>> +DT bindings for Xilinx video IP cores
>> +-------------------------------------
>> +
>> +Xilinx video IP cores process video streams by acting as video sinks and/or
>> +sources. They are connected by links through their input and output ports,
>> +creating a video pipeline.
>> +
>> +Each video IP core is represented by an AMBA bus child node in the device
>> +tree using bindings documented in this directory. Connections between the
>> IP
>> +cores are represented as defined in ../video-interfaces.txt.
>> +
>> +The whole  pipeline is represented by an AMBA bus child node in the device
>> +tree using bindings documented in ./xlnx,video.txt.
>> +
>> +Common properties
>> +-----------------
>> +
>> +The following properties are common to all Xilinx video IP cores.
>> +
>> +- xlnx,video-format: This property represents a video format transmitted on
>> an
>> +  AXI bus between video IP cores. How the format relates to the IP core is
>> +  decribed in the IP core bindings documentation. The following formats are
>> +  supported.
>> +
>> +	rbg
>> +	xrgb
>> +	yuv422
>> +	yuv444
>> +	rggb
>> +	grbg
>> +	gbrg
>> +	bggr
>> +
>> +- xlnx,video-width: This property qualifies the video format with the
>> sample
>> +  width expressed as a number of bits per pixel component. All components
>> must
>> +  use the same width.
> 
> Hans, last time we've discussed this on IRC you were not happy with the format 
> description used in these DT bindings. Your argument was, if I remember 
> correctly, that as the formats map directly to media bus codes, it would be 
> better to use the media bus codes (or a string representation of them) in the 
> bindings instead of creating a new format description. Is that correct ?

Correct. Where possible I think the names should map to the mediabus names.
So uyvy instead of yuv422, srggb instead of rggb, etc.

Regards,

	Hans

> 
> Chris, what's your opinion on that ? The RGB and YUV formats in the table 
> below describe the hardware and come from table 1-4 on page 8 of 
> http://www.xilinx.com/support/documentation/ip_documentation/axi_videoip/v1_0/ug934_axi_videoIP.pdf. 
> The Bayer formats are not standardized in the document, and I don't think we 
> need them at the moment.
> 
>> +The following table lists the supported formats and widths combinations,
>> along
>> +with the corresponding media bus pixel code.
>> +
>> +----------------+-------+--------------------------------------------------
>> +Format		| Width	| Media bus code
>> +----------------+-------+--------------------------------------------------
>> +rbg		| 8	| V4L2_MBUS_FMT_RBG888_1X24
>> +xrgb		| 8	| V4L2_MBUS_FMT_RGB888_1X32_PADHI
>> +yuv422		| 8	| V4L2_MBUS_FMT_UYVY8_1X16
>> +yuv444		| 8	| V4L2_MBUS_FMT_VUY888_1X24
>> +rggb		| 8	| V4L2_MBUS_FMT_SRGGB8_1X8
>> +grbg		| 8	| V4L2_MBUS_FMT_SGRBG8_1X8
>> +gbrg		| 8	| V4L2_MBUS_FMT_SGBRG8_1X8
>> +bggr		| 8	| V4L2_MBUS_FMT_SBGGR8_1X8
>> +----------------+-------+--------------------------------------------------
>> diff --git
>> a/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
>> b/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt new file
>> mode 100644
>> index 0000000..5a02270
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
>> @@ -0,0 +1,55 @@
>> +Xilinx Video IP Pipeline (VIPP)
>> +-------------------------------
>> +
>> +General concept
>> +---------------
>> +
>> +Xilinx video IP pipeline processes video streams through one or more Xilinx
>> +video IP cores. Each video IP core is represented as documented in
>> video.txt
>> +and IP core specific documentation, xlnx,v-*.txt, in this directory. The DT
>> +node of the VIPP represents as a top level node of the pipeline and defines
>> +mappings between DMAs and the video IP cores.
>> +
>> +Required properties:
>> +
>> +- compatible: Must be "xlnx,video".
>> +
>> +- dmas, dma-names: List of one DMA specifier and identifier string (as
>> defined
>> +  in Documentation/devicetree/bindings/dma/dma.txt) per port. Each port
>> +  requires a DMA channel with the identifier string set to "port" followed
>> by
>> +  the port index.
>> +
>> +- ports: Video port, using the DT bindings defined in
>> ../video-interfaces.txt.
>> +
>> +Required port properties:
>> +
>> +- direction: should be either "input" or "output" depending on the
>> direction
>> +  of stream.
>> +
>> +Example:
>> +
>> +	video_cap {
>> +		compatible = "xlnx,video";
>> +		dmas = <&vdma_1 1>, <&vdma_3 1>;
>> +		dma-names = "port0", "port1";
>> +
>> +		ports {
>> +			#address-cells = <1>;
>> +			#size-cells = <0>;
>> +
>> +			port@0 {
>> +				reg = <0>;
>> +				direction = "input";
>> +				vcap0_in0: endpoint {
>> +					remote-endpoint = <&scaler0_out>;
>> +				};
>> +			};
>> +			port@1 {
>> +				reg = <1>;
>> +				direction = "input";
>> +				vcap0_in1: endpoint {
>> +					remote-endpoint = <&switch_out1>;
>> +				};
>> +			};
>> +		};
>> +	};
> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v4 08/10] v4l: xilinx: Add Xilinx Video IP core
@ 2015-01-22  9:43         ` Hans Verkuil
  0 siblings, 0 replies; 20+ messages in thread
From: Hans Verkuil @ 2015-01-22  9:43 UTC (permalink / raw)
  To: Laurent Pinchart, Chris Kohn
  Cc: linux-media, Michal Simek, Hyun Kwon, devicetree

On 01/22/15 04:01, Laurent Pinchart wrote:
> Hi Hans and Chris,
> 
> On Monday 01 December 2014 22:13:38 Laurent Pinchart wrote:
>> Xilinx platforms have no hardwired video capture or video processing
>> interface. Users create capture and memory to memory processing
>> pipelines in the FPGA fabric to suit their particular needs, by
>> instantiating video IP cores from a large library.
>>
>> The Xilinx Video IP core is a framework that models a video pipeline
>> described in the device tree and expose the pipeline to userspace
>> through the media controller and V4L2 APIs.
>>
>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>> Signed-off-by: Hyun Kwon <hyun.kwon@xilinx.com>
>> Signed-off-by: Radhey Shyam Pandey <radheys@xilinx.com>
>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> 
> [snip]
> 
>> diff --git a/Documentation/devicetree/bindings/media/xilinx/video.txt
>> b/Documentation/devicetree/bindings/media/xilinx/video.txt new file mode
>> 100644
>> index 0000000..15720e4
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/media/xilinx/video.txt
>> @@ -0,0 +1,52 @@
>> +DT bindings for Xilinx video IP cores
>> +-------------------------------------
>> +
>> +Xilinx video IP cores process video streams by acting as video sinks and/or
>> +sources. They are connected by links through their input and output ports,
>> +creating a video pipeline.
>> +
>> +Each video IP core is represented by an AMBA bus child node in the device
>> +tree using bindings documented in this directory. Connections between the
>> IP
>> +cores are represented as defined in ../video-interfaces.txt.
>> +
>> +The whole  pipeline is represented by an AMBA bus child node in the device
>> +tree using bindings documented in ./xlnx,video.txt.
>> +
>> +Common properties
>> +-----------------
>> +
>> +The following properties are common to all Xilinx video IP cores.
>> +
>> +- xlnx,video-format: This property represents a video format transmitted on
>> an
>> +  AXI bus between video IP cores. How the format relates to the IP core is
>> +  decribed in the IP core bindings documentation. The following formats are
>> +  supported.
>> +
>> +	rbg
>> +	xrgb
>> +	yuv422
>> +	yuv444
>> +	rggb
>> +	grbg
>> +	gbrg
>> +	bggr
>> +
>> +- xlnx,video-width: This property qualifies the video format with the
>> sample
>> +  width expressed as a number of bits per pixel component. All components
>> must
>> +  use the same width.
> 
> Hans, last time we've discussed this on IRC you were not happy with the format 
> description used in these DT bindings. Your argument was, if I remember 
> correctly, that as the formats map directly to media bus codes, it would be 
> better to use the media bus codes (or a string representation of them) in the 
> bindings instead of creating a new format description. Is that correct ?

Correct. Where possible I think the names should map to the mediabus names.
So uyvy instead of yuv422, srggb instead of rggb, etc.

Regards,

	Hans

> 
> Chris, what's your opinion on that ? The RGB and YUV formats in the table 
> below describe the hardware and come from table 1-4 on page 8 of 
> http://www.xilinx.com/support/documentation/ip_documentation/axi_videoip/v1_0/ug934_axi_videoIP.pdf. 
> The Bayer formats are not standardized in the document, and I don't think we 
> need them at the moment.
> 
>> +The following table lists the supported formats and widths combinations,
>> along
>> +with the corresponding media bus pixel code.
>> +
>> +----------------+-------+--------------------------------------------------
>> +Format		| Width	| Media bus code
>> +----------------+-------+--------------------------------------------------
>> +rbg		| 8	| V4L2_MBUS_FMT_RBG888_1X24
>> +xrgb		| 8	| V4L2_MBUS_FMT_RGB888_1X32_PADHI
>> +yuv422		| 8	| V4L2_MBUS_FMT_UYVY8_1X16
>> +yuv444		| 8	| V4L2_MBUS_FMT_VUY888_1X24
>> +rggb		| 8	| V4L2_MBUS_FMT_SRGGB8_1X8
>> +grbg		| 8	| V4L2_MBUS_FMT_SGRBG8_1X8
>> +gbrg		| 8	| V4L2_MBUS_FMT_SGBRG8_1X8
>> +bggr		| 8	| V4L2_MBUS_FMT_SBGGR8_1X8
>> +----------------+-------+--------------------------------------------------
>> diff --git
>> a/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
>> b/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt new file
>> mode 100644
>> index 0000000..5a02270
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
>> @@ -0,0 +1,55 @@
>> +Xilinx Video IP Pipeline (VIPP)
>> +-------------------------------
>> +
>> +General concept
>> +---------------
>> +
>> +Xilinx video IP pipeline processes video streams through one or more Xilinx
>> +video IP cores. Each video IP core is represented as documented in
>> video.txt
>> +and IP core specific documentation, xlnx,v-*.txt, in this directory. The DT
>> +node of the VIPP represents as a top level node of the pipeline and defines
>> +mappings between DMAs and the video IP cores.
>> +
>> +Required properties:
>> +
>> +- compatible: Must be "xlnx,video".
>> +
>> +- dmas, dma-names: List of one DMA specifier and identifier string (as
>> defined
>> +  in Documentation/devicetree/bindings/dma/dma.txt) per port. Each port
>> +  requires a DMA channel with the identifier string set to "port" followed
>> by
>> +  the port index.
>> +
>> +- ports: Video port, using the DT bindings defined in
>> ../video-interfaces.txt.
>> +
>> +Required port properties:
>> +
>> +- direction: should be either "input" or "output" depending on the
>> direction
>> +  of stream.
>> +
>> +Example:
>> +
>> +	video_cap {
>> +		compatible = "xlnx,video";
>> +		dmas = <&vdma_1 1>, <&vdma_3 1>;
>> +		dma-names = "port0", "port1";
>> +
>> +		ports {
>> +			#address-cells = <1>;
>> +			#size-cells = <0>;
>> +
>> +			port@0 {
>> +				reg = <0>;
>> +				direction = "input";
>> +				vcap0_in0: endpoint {
>> +					remote-endpoint = <&scaler0_out>;
>> +				};
>> +			};
>> +			port@1 {
>> +				reg = <1>;
>> +				direction = "input";
>> +				vcap0_in1: endpoint {
>> +					remote-endpoint = <&switch_out1>;
>> +				};
>> +			};
>> +		};
>> +	};
> 


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

* RE: [PATCH v4 08/10] v4l: xilinx: Add Xilinx Video IP core
  2015-01-22  9:43         ` Hans Verkuil
  (?)
@ 2015-01-26 19:37         ` Chris Kohn
  -1 siblings, 0 replies; 20+ messages in thread
From: Chris Kohn @ 2015-01-26 19:37 UTC (permalink / raw)
  To: Hans Verkuil, Laurent Pinchart
  Cc: linux-media, Michal Simek, Hyun Kwon, devicetree

Hans and Laurent,

> -----Original Message-----
> From: Hans Verkuil [mailto:hverkuil@xs4all.nl]
> Sent: Thursday, January 22, 2015 1:44 AM
> To: Laurent Pinchart; Chris Kohn
> Cc: linux-media@vger.kernel.org; Michal Simek; Hyun Kwon;
> devicetree@vger.kernel.org
> Subject: Re: [PATCH v4 08/10] v4l: xilinx: Add Xilinx Video IP core
>
> On 01/22/15 04:01, Laurent Pinchart wrote:
> > Hi Hans and Chris,
> >
> > On Monday 01 December 2014 22:13:38 Laurent Pinchart wrote:
> >> Xilinx platforms have no hardwired video capture or video processing
> >> interface. Users create capture and memory to memory processing
> >> pipelines in the FPGA fabric to suit their particular needs, by
> >> instantiating video IP cores from a large library.
> >>
> >> The Xilinx Video IP core is a framework that models a video pipeline
> >> described in the device tree and expose the pipeline to userspace
> >> through the media controller and V4L2 APIs.
> >>
> >> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> >> Signed-off-by: Hyun Kwon <hyun.kwon@xilinx.com>
> >> Signed-off-by: Radhey Shyam Pandey <radheys@xilinx.com>
> >> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> >
> > [snip]
> >
> >> diff --git a/Documentation/devicetree/bindings/media/xilinx/video.txt
> >> b/Documentation/devicetree/bindings/media/xilinx/video.txt new file
> >> mode
> >> 100644
> >> index 0000000..15720e4
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/media/xilinx/video.txt
> >> @@ -0,0 +1,52 @@
> >> +DT bindings for Xilinx video IP cores
> >> +-------------------------------------
> >> +
> >> +Xilinx video IP cores process video streams by acting as video sinks
> >> +and/or sources. They are connected by links through their input and
> >> +output ports, creating a video pipeline.
> >> +
> >> +Each video IP core is represented by an AMBA bus child node in the
> >> +device tree using bindings documented in this directory. Connections
> >> +between the
> >> IP
> >> +cores are represented as defined in ../video-interfaces.txt.
> >> +
> >> +The whole  pipeline is represented by an AMBA bus child node in the
> >> +device tree using bindings documented in ./xlnx,video.txt.
> >> +
> >> +Common properties
> >> +-----------------
> >> +
> >> +The following properties are common to all Xilinx video IP cores.
> >> +
> >> +- xlnx,video-format: This property represents a video format
> >> +transmitted on
> >> an
> >> +  AXI bus between video IP cores. How the format relates to the IP
> >> + core is  decribed in the IP core bindings documentation. The
> >> + following formats are  supported.
> >> +
> >> +  rbg
> >> +  xrgb
> >> +  yuv422
> >> +  yuv444
> >> +  rggb
> >> +  grbg
> >> +  gbrg
> >> +  bggr
> >> +
> >> +- xlnx,video-width: This property qualifies the video format with
> >> +the
> >> sample
> >> +  width expressed as a number of bits per pixel component. All
> >> + components
> >> must
> >> +  use the same width.
> >
> > Hans, last time we've discussed this on IRC you were not happy with
> > the format description used in these DT bindings. Your argument was,
> > if I remember correctly, that as the formats map directly to media bus
> > codes, it would be better to use the media bus codes (or a string
> > representation of them) in the bindings instead of creating a new format
> description. Is that correct ?
>
> Correct. Where possible I think the names should map to the mediabus names.
> So uyvy instead of yuv422, srggb instead of rggb, etc.

A string representation of the mediabus names sounds good to me.

Cheers,
Chris

> >
> > Chris, what's your opinion on that ? The RGB and YUV formats in the
> > table below describe the hardware and come from table 1-4 on page 8 of
> >
> http://www.xilinx.com/support/documentation/ip_documentation/axi_videoip/
> v1_0/ug934_axi_videoIP.pdf.
> > The Bayer formats are not standardized in the document, and I don't
> > think we need them at the moment.
> >
> >> +The following table lists the supported formats and widths
> >> +combinations,
> >> along
> >> +with the corresponding media bus pixel code.
> >> +
> >> +----------------+-------+-------------------------------------------
> >> +----------------+-------+-------
> >> +Format            | Width | Media bus code
> >> +----------------+-------+-------------------------------------------
> >> +----------------+-------+-------
> >> +rbg               | 8     | V4L2_MBUS_FMT_RBG888_1X24
> >> +xrgb              | 8     | V4L2_MBUS_FMT_RGB888_1X32_PADHI
> >> +yuv422            | 8     | V4L2_MBUS_FMT_UYVY8_1X16
> >> +yuv444            | 8     | V4L2_MBUS_FMT_VUY888_1X24
> >> +rggb              | 8     | V4L2_MBUS_FMT_SRGGB8_1X8
> >> +grbg              | 8     | V4L2_MBUS_FMT_SGRBG8_1X8
> >> +gbrg              | 8     | V4L2_MBUS_FMT_SGBRG8_1X8
> >> +bggr              | 8     | V4L2_MBUS_FMT_SBGGR8_1X8
> >> +----------------+-------+-------------------------------------------
> >> +----------------+-------+-------
> >> diff --git
> >> a/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
> >> b/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt new
> >> file mode 100644 index 0000000..5a02270
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
> >> @@ -0,0 +1,55 @@
> >> +Xilinx Video IP Pipeline (VIPP)
> >> +-------------------------------
> >> +
> >> +General concept
> >> +---------------
> >> +
> >> +Xilinx video IP pipeline processes video streams through one or more
> >> +Xilinx video IP cores. Each video IP core is represented as
> >> +documented in
> >> video.txt
> >> +and IP core specific documentation, xlnx,v-*.txt, in this directory.
> >> +The DT node of the VIPP represents as a top level node of the
> >> +pipeline and defines mappings between DMAs and the video IP cores.
> >> +
> >> +Required properties:
> >> +
> >> +- compatible: Must be "xlnx,video".
> >> +
> >> +- dmas, dma-names: List of one DMA specifier and identifier string
> >> +(as
> >> defined
> >> +  in Documentation/devicetree/bindings/dma/dma.txt) per port. Each
> >> + port  requires a DMA channel with the identifier string set to
> >> + "port" followed
> >> by
> >> +  the port index.
> >> +
> >> +- ports: Video port, using the DT bindings defined in
> >> ../video-interfaces.txt.
> >> +
> >> +Required port properties:
> >> +
> >> +- direction: should be either "input" or "output" depending on the
> >> direction
> >> +  of stream.
> >> +
> >> +Example:
> >> +
> >> +  video_cap {
> >> +          compatible = "xlnx,video";
> >> +          dmas = <&vdma_1 1>, <&vdma_3 1>;
> >> +          dma-names = "port0", "port1";
> >> +
> >> +          ports {
> >> +                  #address-cells = <1>;
> >> +                  #size-cells = <0>;
> >> +
> >> +                  port@0 {
> >> +                          reg = <0>;
> >> +                          direction = "input";
> >> +                          vcap0_in0: endpoint {
> >> +                                  remote-endpoint = <&scaler0_out>;
> >> +                          };
> >> +                  };
> >> +                  port@1 {
> >> +                          reg = <1>;
> >> +                          direction = "input";
> >> +                          vcap0_in1: endpoint {
> >> +                                  remote-endpoint = <&switch_out1>;
> >> +                          };
> >> +                  };
> >> +          };
> >> +  };
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

end of thread, other threads:[~2015-01-26 19:37 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-01 20:13 [PATCH v4 00/10] Xilinx Video IP Core support Laurent Pinchart
2014-12-01 20:13 ` [PATCH v4 01/10] media: entity: Document the media_entity_ops structure Laurent Pinchart
2014-12-01 20:13 ` [PATCH v4 02/10] v4l: Add RBG and RGB 8:8:8 media bus formats on 24 and 32 bit busses Laurent Pinchart
2014-12-01 20:13 ` [PATCH v4 03/10] v4l: Sort YUV formats of v4l2_mbus_pixelcode Laurent Pinchart
2014-12-01 20:13 ` [PATCH v4 04/10] v4l: Add VUY8 24 bits bus format Laurent Pinchart
2014-12-01 20:13 ` [PATCH v4 05/10] v4l: of: Add v4l2_of_parse_link() function Laurent Pinchart
2014-12-03 12:30   ` Sakari Ailus
2014-12-03 15:02   ` Sylwester Nawrocki
2014-12-03 15:10     ` Laurent Pinchart
2014-12-01 20:13 ` [PATCH v4 06/10] v4l: vb2: Fix race condition in vb2_fop_poll Laurent Pinchart
2014-12-01 20:13 ` [PATCH v4 07/10] v4l: vb2: Fix race condition in _vb2_fop_release Laurent Pinchart
2014-12-03 15:07   ` Sylwester Nawrocki
2014-12-01 20:13 ` [PATCH v4 08/10] v4l: xilinx: Add Xilinx Video IP core Laurent Pinchart
     [not found]   ` <1417464820-6718-9-git-send-email-laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
2015-01-22  3:01     ` Laurent Pinchart
2015-01-22  3:01       ` Laurent Pinchart
2015-01-22  9:43       ` Hans Verkuil
2015-01-22  9:43         ` Hans Verkuil
2015-01-26 19:37         ` Chris Kohn
2014-12-01 20:13 ` [PATCH v4 09/10] v4l: xilinx: Add Video Timing Controller driver Laurent Pinchart
2014-12-01 20:13 ` [PATCH v4 10/10] v4l: xilinx: Add Test Pattern Generator driver Laurent Pinchart

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.