[PATCH v7 8/8] media: vsp1: Move video configuration to a cached dlb

2018-03-07 Thread Kieran Bingham
We are now able to configure a pipeline directly into a local display
list body. Take advantage of this fact, and create a cacheable body to
store the configuration of the pipeline in the video object.

vsp1_video_pipeline_run() is now the last user of the pipe->dl object.
Convert this function to use the cached video->config body and obtain a
local display list reference.

Attach the video->config body to the display list when needed before
committing to hardware.

The pipe object is marked as un-configured when resuming from a suspend.
This ensures that when the hardware is reset - our cached configuration
will be re-attached to the next committed DL.

Signed-off-by: Kieran Bingham 
---

v3:
 - 's/fragment/body/', 's/fragments/bodies/'
 - video dlb cache allocation increased from 2 to 3 dlbs

Our video DL usage now looks like the below output:

dl->body0 contains our disposable runtime configuration. Max 41.
dl_child->body0 is our partition specific configuration. Max 12.
dl->bodies shows our constant configuration and LUTs.

  These two are LUT/CLU:
 * dl->bodies[x]->num_entries 256 / max 256
 * dl->bodies[x]->num_entries 4914 / max 4914

Which shows that our 'constant' configuration cache is currently
utilised to a maximum of 64 entries.

trace-cmd report | \
grep max | sed 's/.*vsp1_dl_list_commit://g' | sort | uniq;

  dl->body0->num_entries 13 / max 128
  dl->body0->num_entries 14 / max 128
  dl->body0->num_entries 16 / max 128
  dl->body0->num_entries 20 / max 128
  dl->body0->num_entries 27 / max 128
  dl->body0->num_entries 34 / max 128
  dl->body0->num_entries 41 / max 128
  dl_child->body0->num_entries 10 / max 128
  dl_child->body0->num_entries 12 / max 128
  dl->bodies[x]->num_entries 15 / max 128
  dl->bodies[x]->num_entries 16 / max 128
  dl->bodies[x]->num_entries 17 / max 128
  dl->bodies[x]->num_entries 18 / max 128
  dl->bodies[x]->num_entries 20 / max 128
  dl->bodies[x]->num_entries 21 / max 128
  dl->bodies[x]->num_entries 256 / max 256
  dl->bodies[x]->num_entries 31 / max 128
  dl->bodies[x]->num_entries 32 / max 128
  dl->bodies[x]->num_entries 39 / max 128
  dl->bodies[x]->num_entries 40 / max 128
  dl->bodies[x]->num_entries 47 / max 128
  dl->bodies[x]->num_entries 48 / max 128
  dl->bodies[x]->num_entries 4914 / max 4914
  dl->bodies[x]->num_entries 55 / max 128
  dl->bodies[x]->num_entries 56 / max 128
  dl->bodies[x]->num_entries 63 / max 128
  dl->bodies[x]->num_entries 64 / max 128

v4:
 - Adjust pipe configured flag to be reset on resume rather than suspend
 - rename dl_child, dl_next

 drivers/media/platform/vsp1/vsp1_pipe.c  |  7 +++-
 drivers/media/platform/vsp1/vsp1_pipe.h  |  4 +-
 drivers/media/platform/vsp1/vsp1_video.c | 67 -
 drivers/media/platform/vsp1/vsp1_video.h |  2 +-
 4 files changed, 54 insertions(+), 26 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c 
b/drivers/media/platform/vsp1/vsp1_pipe.c
index 5012643583b6..fa445b1a2e38 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -249,6 +249,7 @@ void vsp1_pipeline_run(struct vsp1_pipeline *pipe)
vsp1_write(vsp1, VI6_CMD(pipe->output->entity.index),
   VI6_CMD_STRCMD);
pipe->state = VSP1_PIPELINE_RUNNING;
+   pipe->configured = true;
}
 
pipe->buffers_ready = 0;
@@ -470,6 +471,12 @@ void vsp1_pipelines_resume(struct vsp1_device *vsp1)
continue;
 
spin_lock_irqsave(>irqlock, flags);
+   /*
+* The hardware may have been reset during a suspend and will
+* need a full reconfiguration
+*/
+   pipe->configured = false;
+
if (vsp1_pipeline_ready(pipe))
vsp1_pipeline_run(pipe);
spin_unlock_irqrestore(>irqlock, flags);
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h 
b/drivers/media/platform/vsp1/vsp1_pipe.h
index 90d29492b9b9..e7ad6211b4d0 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -90,6 +90,7 @@ struct vsp1_partition {
  * @irqlock: protects the pipeline state
  * @state: current state
  * @wq: wait queue to wait for state change completion
+ * @configured: flag determining if the hardware has run since reset
  * @frame_end: frame end interrupt handler
  * @lock: protects the pipeline use count and stream count
  * @kref: pipeline reference count
@@ -117,6 +118,7 @@ struct vsp1_pipeline {
spinlock_t irqlock;
enum vsp1_pipeline_state state;
wait_queue_head_t wq;
+   bool configured;
 
void (*frame_end)(struct vsp1_pipeline *pipe, bool completed);
 
@@ -143,8 +145,6 @@ struct vsp1_pipeline {
 */
struct list_head entities;
 
-   struct vsp1_dl_list *dl;
-
unsigned int partitions;
struct 

[PATCH v7 7/8] media: vsp1: Adapt entities to configure into a body

2018-03-07 Thread Kieran Bingham
Currently the entities store their configurations into a display list.
Adapt this such that the code can be configured into a body directly,
allowing greater flexibility and control of the content.

All users of vsp1_dl_list_write() are removed in this process, thus it
too is removed.

A helper, vsp1_dl_list_get_body0() is provided to access the internal body0
from the display list.

Signed-off-by: Kieran Bingham 

---
v7
 - Rebase
 - s/prepare/configure_stream/
 - s/configure/configure_frame/

 drivers/media/platform/vsp1/vsp1_bru.c| 22 ++---
 drivers/media/platform/vsp1/vsp1_clu.c| 22 ++---
 drivers/media/platform/vsp1/vsp1_dl.c | 12 ++-
 drivers/media/platform/vsp1/vsp1_dl.h |  2 +-
 drivers/media/platform/vsp1/vsp1_drm.c| 20 +++
 drivers/media/platform/vsp1/vsp1_entity.c | 15 -
 drivers/media/platform/vsp1/vsp1_entity.h | 11 +++---
 drivers/media/platform/vsp1/vsp1_hgo.c| 16 -
 drivers/media/platform/vsp1/vsp1_hgt.c| 18 +-
 drivers/media/platform/vsp1/vsp1_hsit.c   | 10 +++---
 drivers/media/platform/vsp1/vsp1_lif.c| 15 -
 drivers/media/platform/vsp1/vsp1_lut.c| 21 ++--
 drivers/media/platform/vsp1/vsp1_pipe.c   |  4 +-
 drivers/media/platform/vsp1/vsp1_pipe.h   |  3 +-
 drivers/media/platform/vsp1/vsp1_rpf.c| 39 +++---
 drivers/media/platform/vsp1/vsp1_sru.c| 14 
 drivers/media/platform/vsp1/vsp1_uds.c| 24 +++---
 drivers/media/platform/vsp1/vsp1_uds.h|  2 +-
 drivers/media/platform/vsp1/vsp1_video.c  | 11 --
 drivers/media/platform/vsp1/vsp1_wpf.c| 42 
 20 files changed, 172 insertions(+), 151 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_bru.c 
b/drivers/media/platform/vsp1/vsp1_bru.c
index d6fd265eaccb..7b9cf78b4be8 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -30,10 +30,10 @@
  * Device Access
  */
 
-static inline void vsp1_bru_write(struct vsp1_bru *bru, struct vsp1_dl_list 
*dl,
- u32 reg, u32 data)
+static inline void vsp1_bru_write(struct vsp1_bru *bru,
+ struct vsp1_dl_body *dlb, u32 reg, u32 data)
 {
-   vsp1_dl_list_write(dl, bru->base + reg, data);
+   vsp1_dl_body_write(dlb, bru->base + reg, data);
 }
 
 /* 
-
@@ -287,7 +287,7 @@ static const struct v4l2_subdev_ops bru_ops = {
 
 static void bru_configure_stream(struct vsp1_entity *entity,
 struct vsp1_pipeline *pipe,
-struct vsp1_dl_list *dl)
+struct vsp1_dl_body *dlb)
 {
struct vsp1_bru *bru = to_bru(>subdev);
struct v4l2_mbus_framefmt *format;
@@ -309,7 +309,7 @@ static void bru_configure_stream(struct vsp1_entity *entity,
 * format at the pipeline output is premultiplied.
 */
flags = pipe->output ? pipe->output->format.flags : 0;
-   vsp1_bru_write(bru, dl, VI6_BRU_INCTRL,
+   vsp1_bru_write(bru, dlb, VI6_BRU_INCTRL,
   flags & V4L2_PIX_FMT_FLAG_PREMUL_ALPHA ?
   0 : VI6_BRU_INCTRL_NRM);
 
@@ -317,12 +317,12 @@ static void bru_configure_stream(struct vsp1_entity 
*entity,
 * Set the background position to cover the whole output image and
 * configure its color.
 */
-   vsp1_bru_write(bru, dl, VI6_BRU_VIRRPF_SIZE,
+   vsp1_bru_write(bru, dlb, VI6_BRU_VIRRPF_SIZE,
   (format->width << VI6_BRU_VIRRPF_SIZE_HSIZE_SHIFT) |
   (format->height << VI6_BRU_VIRRPF_SIZE_VSIZE_SHIFT));
-   vsp1_bru_write(bru, dl, VI6_BRU_VIRRPF_LOC, 0);
+   vsp1_bru_write(bru, dlb, VI6_BRU_VIRRPF_LOC, 0);
 
-   vsp1_bru_write(bru, dl, VI6_BRU_VIRRPF_COL, bru->bgcolor |
+   vsp1_bru_write(bru, dlb, VI6_BRU_VIRRPF_COL, bru->bgcolor |
   (0xff << VI6_BRU_VIRRPF_COL_A_SHIFT));
 
/*
@@ -332,7 +332,7 @@ static void bru_configure_stream(struct vsp1_entity *entity,
 * unit.
 */
if (entity->type == VSP1_ENTITY_BRU)
-   vsp1_bru_write(bru, dl, VI6_BRU_ROP,
+   vsp1_bru_write(bru, dlb, VI6_BRU_ROP,
   VI6_BRU_ROP_DSTSEL_BRUIN(1) |
   VI6_BRU_ROP_CROP(VI6_ROP_NOP) |
   VI6_BRU_ROP_AROP(VI6_ROP_NOP));
@@ -374,7 +374,7 @@ static void bru_configure_stream(struct vsp1_entity *entity,
if (!(entity->type == VSP1_ENTITY_BRU && i == 1))
ctrl |= VI6_BRU_CTRL_SRCSEL_BRUIN(i);
 
-   vsp1_bru_write(bru, dl, VI6_BRU_CTRL(i), ctrl);
+   vsp1_bru_write(bru, dlb, VI6_BRU_CTRL(i), ctrl);
 
/*
 * Harcode the blending formula to
@@ -389,7 

[PATCH v7 0/8] vsp1: TLB optimisation and DL caching

2018-03-07 Thread Kieran Bingham
Each display list currently allocates an area of DMA memory to store register
settings for the VSP1 to process. Each of these allocations adds pressure to
the IPMMU TLB entries.

We can reduce the pressure by pre-allocating larger areas and dividing the area
across multiple bodies represented as a pool.

With this reconfiguration of bodies, we can adapt the configuration code to
separate out constant hardware configuration and cache it for re-use.

The patches provided in this series can be found at:
  git://git.kernel.org/pub/scm/linux/kernel/git/kbingham/rcar.git  
tags/vsp1/tlb-optimise/v7

I hope that this series is at a stage where it could be integrated now.  It has
had some thorough testing and is already integrated in both renesas-drivers and
renesas-bsp. (except for the minor changes in v7 that is...)

Please note that checkpatch complains on patch 6/8 in this series:

v7-0006-media-vsp1-Refactor-display-list-configure-operations.patch
--
WARNING: function definition argument 'struct vsp1_entity *' should also have 
an identifier name
#290: FILE: drivers/media/platform/vsp1/vsp1_entity.h:82:
+   void (*configure_stream)(struct vsp1_entity *, struct vsp1_pipeline *,

However - this complaint is regarding pre-existing code. I have only renamed
the function pointers.  I do also disagree with checkpatch here - as there is
no need to provide an identifier name, and it does not improve readability in
this instance to state:
...(vsp1_entity *entity, struct vsp1_pipeline *pipe)

Thus - I have ignored these warnings.


Changelog:
--

v7:
 - Rebased on to linux-media/master (v4.16-rc4)
 - Clean up the formatting of the vsp1_dl_list_add_body()
 - Fix formatting and white space
 -  s/prepare/configure_stream/
 -  s/configure/configure_frame/

v6:
 - Rebased on to linux-media/master (v4.16-rc1)
 - Removed DRM/UIF (DISCOM/ColorKey) updates

v5:
 - Rebased on to renesas-drivers-2018-01-09-v4.15-rc7 to fix conflicts
   with DRM and UIF updates on VSP1 driver

v4:
 - Rebased to v4.14
 * v4l: vsp1: Use reference counting for bodies
   - Fix up reference handling comments

 * v4l: vsp1: Provide a body pool
   - Provide comment explaining extra allocation on body pool
 highlighting area for optimisation later.

 * v4l: vsp1: Refactor display list configure operations
   - Fix up comment to describe yuv_mode caching rather than format

 * vsp1: Adapt entities to configure into a body
   - Rename vsp1_dl_list_get_body() to vsp1_dl_list_get_body0()

 * v4l: vsp1: Move video configuration to a cached dlb
   - Adjust pipe configured flag to be reset on resume rather than suspend
   - rename dl_child, dl_next

Testing:

The VSP unit tests have been run on this patch set with the following results:

--- Test loop 1 ---
- vsp-unit-test-.sh
Test Conditions:
  Platform  Renesas Salvator-X 2nd version board based on r8a7795 ES2.0+
  Kernel release4.16.0-rc4-arm64-renesas-01067-g397eb3811ec0
  convert   /usr/bin/convert
  compare   /usr/bin/compare
  killall   /usr/bin/killall
  raw2rgbpnm/usr/bin/raw2rgbpnm
  stress/usr/bin/stress
  yavta /usr/bin/yavta
- vsp-unit-test-0001.sh
Testing WPF packing in RGB332: pass
Testing WPF packing in ARGB555: pass
Testing WPF packing in XRGB555: pass
Testing WPF packing in RGB565: pass
Testing WPF packing in BGR24: pass
Testing WPF packing in RGB24: pass
Testing WPF packing in ABGR32: pass
Testing WPF packing in ARGB32: pass
Testing WPF packing in XBGR32: pass
Testing WPF packing in XRGB32: pass
- vsp-unit-test-0002.sh
Testing WPF packing in NV12M: pass
Testing WPF packing in NV16M: pass
Testing WPF packing in NV21M: pass
Testing WPF packing in NV61M: pass
Testing WPF packing in UYVY: pass
Testing WPF packing in VYUY: skip
Testing WPF packing in YUV420M: pass
Testing WPF packing in YUV422M: pass
Testing WPF packing in YUV444M: pass
Testing WPF packing in YVU420M: pass
Testing WPF packing in YVU422M: pass
Testing WPF packing in YVU444M: pass
Testing WPF packing in YUYV: pass
Testing WPF packing in YVYU: pass
- vsp-unit-test-0003.sh
Testing scaling from 640x640 to 640x480 in RGB24: pass
Testing scaling from 1024x768 to 640x480 in RGB24: pass
Testing scaling from 640x480 to 1024x768 in RGB24: pass
Testing scaling from 640x640 to 640x480 in YUV444M: pass
Testing scaling from 1024x768 to 640x480 in YUV444M: pass
Testing scaling from 640x480 to 1024x768 in YUV444M: pass
- vsp-unit-test-0004.sh
Testing histogram in RGB24: pass
Testing histogram in YUV444M: pass
- vsp-unit-test-0005.sh
Testing RPF.0: pass
Testing RPF.1: pass
Testing RPF.2: pass
Testing RPF.3: pass
Testing RPF.4: pass
- vsp-unit-test-0006.sh
Testing invalid pipeline with no RPF: pass
Testing invalid pipeline with no WPF: pass
- vsp-unit-test-0007.sh
Testing BRU in RGB24 with 1 inputs: pass
Testing BRU in RGB24 with 2 inputs: pass

[PATCH v7 3/8] media: vsp1: Provide a body pool

2018-03-07 Thread Kieran Bingham
Each display list allocates a body to store register values in a dma
accessible buffer from a dma_alloc_wc() allocation. Each of these
results in an entry in the TLB, and a large number of display list
allocations adds pressure to this resource.

Reduce TLB pressure on the IPMMUs by allocating multiple display list
bodies in a single allocation, and providing these to the display list
through a 'body pool'. A pool can be allocated by the display list
manager or entities which require their own body allocations.

Signed-off-by: Kieran Bingham 

---
v4:
 - Provide comment explaining extra allocation on body pool
   highlighting area for optimisation later.

v3:
 - s/fragment/body/, s/fragments/bodies/
 - qty -> num_bodies
 - indentation fix
 - s/vsp1_dl_body_pool_{alloc,free}/vsp1_dl_body_pool_{create,destroy}/'
 - Add kerneldoc to non-static functions

v2:
 - assign dlb->dma correctly

 drivers/media/platform/vsp1/vsp1_dl.c | 163 +++-
 drivers/media/platform/vsp1/vsp1_dl.h |   8 +-
 2 files changed, 171 insertions(+)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index 67cc16c1b8e3..0208e72cb356 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -45,6 +45,8 @@ struct vsp1_dl_entry {
 /**
  * struct vsp1_dl_body - Display list body
  * @list: entry in the display list list of bodies
+ * @free: entry in the pool free body list
+ * @pool: pool to which this body belongs
  * @vsp1: the VSP1 device
  * @entries: array of entries
  * @dma: DMA address of the entries
@@ -54,6 +56,9 @@ struct vsp1_dl_entry {
  */
 struct vsp1_dl_body {
struct list_head list;
+   struct list_head free;
+
+   struct vsp1_dl_body_pool *pool;
struct vsp1_device *vsp1;
 
struct vsp1_dl_entry *entries;
@@ -65,6 +70,30 @@ struct vsp1_dl_body {
 };
 
 /**
+ * struct vsp1_dl_body_pool - display list body pool
+ * @dma: DMA address of the entries
+ * @size: size of the full DMA memory pool in bytes
+ * @mem: CPU memory pointer for the pool
+ * @bodies: Array of DLB structures for the pool
+ * @free: List of free DLB entries
+ * @lock: Protects the pool and free list
+ * @vsp1: the VSP1 device
+ */
+struct vsp1_dl_body_pool {
+   /* DMA allocation */
+   dma_addr_t dma;
+   size_t size;
+   void *mem;
+
+   /* Body management */
+   struct vsp1_dl_body *bodies;
+   struct list_head free;
+   spinlock_t lock;
+
+   struct vsp1_device *vsp1;
+};
+
+/**
  * struct vsp1_dl_list - Display list
  * @list: entry in the display list manager lists
  * @dlm: the display list manager
@@ -105,6 +134,7 @@ enum vsp1_dl_mode {
  * @active: list currently being processed (loaded) by hardware
  * @queued: list queued to the hardware (written to the DL registers)
  * @pending: list waiting to be queued to the hardware
+ * @pool: body pool for the display list bodies
  * @gc_work: bodies garbage collector work struct
  * @gc_bodies: array of display list bodies waiting to be freed
  */
@@ -120,6 +150,8 @@ struct vsp1_dl_manager {
struct vsp1_dl_list *queued;
struct vsp1_dl_list *pending;
 
+   struct vsp1_dl_body_pool *pool;
+
struct work_struct gc_work;
struct list_head gc_bodies;
 };
@@ -128,6 +160,137 @@ struct vsp1_dl_manager {
  * Display List Body Management
  */
 
+/**
+ * vsp1_dl_body_pool_create - Create a pool of bodies from a single allocation
+ * @vsp1: The VSP1 device
+ * @num_bodies: The quantity of bodies to allocate
+ * @num_entries: The maximum number of entries that the body can contain
+ * @extra_size: Extra allocation provided for the bodies
+ *
+ * Allocate a pool of display list bodies each with enough memory to contain 
the
+ * requested number of entries.
+ *
+ * Return a pointer to a pool on success or NULL if memory can't be allocated.
+ */
+struct vsp1_dl_body_pool *
+vsp1_dl_body_pool_create(struct vsp1_device *vsp1, unsigned int num_bodies,
+unsigned int num_entries, size_t extra_size)
+{
+   struct vsp1_dl_body_pool *pool;
+   size_t dlb_size;
+   unsigned int i;
+
+   pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+   if (!pool)
+   return NULL;
+
+   pool->vsp1 = vsp1;
+
+   /*
+* Todo: 'extra_size' is only used by vsp1_dlm_create(), to allocate
+* extra memory for the display list header. We need only one header per
+* display list, not per display list body, thus this allocation is
+* extraneous and should be reworked in the future.
+*/
+   dlb_size = num_entries * sizeof(struct vsp1_dl_entry) + extra_size;
+   pool->size = dlb_size * num_bodies;
+
+   pool->bodies = kcalloc(num_bodies, sizeof(*pool->bodies), GFP_KERNEL);
+   if (!pool->bodies) {
+   kfree(pool);
+   return NULL;
+   }
+
+   pool->mem = 

[PATCH v7 1/8] media: vsp1: Reword uses of 'fragment' as 'body'

2018-03-07 Thread Kieran Bingham
Throughout the codebase, the term 'fragment' is used to represent a
display list body. This term duplicates the 'body' which is already in
use.

The datasheet references these objects as a body, therefore replace all
mentions of a fragment with a body, along with the corresponding
pluralised terms.

Signed-off-by: Kieran Bingham 

---
v7
 - Clean up the formatting of the vsp1_dl_list_add_body()

 drivers/media/platform/vsp1/vsp1_clu.c |  10 +-
 drivers/media/platform/vsp1/vsp1_dl.c  | 109 --
 drivers/media/platform/vsp1/vsp1_dl.h  |  13 +--
 drivers/media/platform/vsp1/vsp1_lut.c |   8 +-
 4 files changed, 69 insertions(+), 71 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_clu.c 
b/drivers/media/platform/vsp1/vsp1_clu.c
index f2fb26e5ab4e..9621afa3658c 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.c
+++ b/drivers/media/platform/vsp1/vsp1_clu.c
@@ -47,19 +47,19 @@ static int clu_set_table(struct vsp1_clu *clu, struct 
v4l2_ctrl *ctrl)
struct vsp1_dl_body *dlb;
unsigned int i;
 
-   dlb = vsp1_dl_fragment_alloc(clu->entity.vsp1, 1 + 17 * 17 * 17);
+   dlb = vsp1_dl_body_alloc(clu->entity.vsp1, 1 + 17 * 17 * 17);
if (!dlb)
return -ENOMEM;
 
-   vsp1_dl_fragment_write(dlb, VI6_CLU_ADDR, 0);
+   vsp1_dl_body_write(dlb, VI6_CLU_ADDR, 0);
for (i = 0; i < 17 * 17 * 17; ++i)
-   vsp1_dl_fragment_write(dlb, VI6_CLU_DATA, ctrl->p_new.p_u32[i]);
+   vsp1_dl_body_write(dlb, VI6_CLU_DATA, ctrl->p_new.p_u32[i]);
 
spin_lock_irq(>lock);
swap(clu->clu, dlb);
spin_unlock_irq(>lock);
 
-   vsp1_dl_fragment_free(dlb);
+   vsp1_dl_body_free(dlb);
return 0;
 }
 
@@ -256,7 +256,7 @@ static void clu_configure(struct vsp1_entity *entity,
spin_unlock_irqrestore(>lock, flags);
 
if (dlb)
-   vsp1_dl_list_add_fragment(dl, dlb);
+   vsp1_dl_list_add_body(dl, dlb);
break;
}
 }
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index 0b86ed01e85d..caed441f5f0c 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -69,7 +69,7 @@ struct vsp1_dl_body {
  * @header: display list header, NULL for headerless lists
  * @dma: DMA address for the header
  * @body0: first display list body
- * @fragments: list of extra display list bodies
+ * @bodies: list of extra display list bodies
  * @has_chain: if true, indicates that there's a partition chain
  * @chain: entry in the display list partition chain
  */
@@ -81,7 +81,7 @@ struct vsp1_dl_list {
dma_addr_t dma;
 
struct vsp1_dl_body body0;
-   struct list_head fragments;
+   struct list_head bodies;
 
bool has_chain;
struct list_head chain;
@@ -98,13 +98,13 @@ enum vsp1_dl_mode {
  * @mode: display list operation mode (header or headerless)
  * @singleshot: execute the display list in single-shot mode
  * @vsp1: the VSP1 device
- * @lock: protects the free, active, queued, pending and gc_fragments lists
+ * @lock: protects the free, active, queued, pending and gc_bodies lists
  * @free: array of all free display lists
  * @active: list currently being processed (loaded) by hardware
  * @queued: list queued to the hardware (written to the DL registers)
  * @pending: list waiting to be queued to the hardware
- * @gc_work: fragments garbage collector work struct
- * @gc_fragments: array of display list fragments waiting to be freed
+ * @gc_work: bodies garbage collector work struct
+ * @gc_bodies: array of display list bodies waiting to be freed
  */
 struct vsp1_dl_manager {
unsigned int index;
@@ -119,7 +119,7 @@ struct vsp1_dl_manager {
struct vsp1_dl_list *pending;
 
struct work_struct gc_work;
-   struct list_head gc_fragments;
+   struct list_head gc_bodies;
 };
 
 /* 
-
@@ -157,17 +157,16 @@ static void vsp1_dl_body_cleanup(struct vsp1_dl_body *dlb)
 }
 
 /**
- * vsp1_dl_fragment_alloc - Allocate a display list fragment
+ * vsp1_dl_body_alloc - Allocate a display list body
  * @vsp1: The VSP1 device
- * @num_entries: The maximum number of entries that the fragment can contain
+ * @num_entries: The maximum number of entries that the body can contain
  *
- * Allocate a display list fragment with enough memory to contain the requested
+ * Allocate a display list body with enough memory to contain the requested
  * number of entries.
  *
- * Return a pointer to a fragment on success or NULL if memory can't be
- * allocated.
+ * Return a pointer to a body on success or NULL if memory can't be allocated.
  */
-struct vsp1_dl_body *vsp1_dl_fragment_alloc(struct vsp1_device *vsp1,
+struct vsp1_dl_body *vsp1_dl_body_alloc(struct vsp1_device *vsp1,

[PATCH v7 2/8] media: vsp1: Protect bodies against overflow

2018-03-07 Thread Kieran Bingham
The body write function relies on the code never asking it to write more
than the entries available in the list.

Currently with each list body containing 256 entries, this is fine, but
we can reduce this number greatly saving memory. In preparation of this
add a level of protection to catch any buffer overflows.

Signed-off-by: Kieran Bingham 
Reviewed-by: Laurent Pinchart 

---

v3:
 - adapt for new 'body' terminology
 - simplify WARN_ON macro usage

 drivers/media/platform/vsp1/vsp1_dl.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index caed441f5f0c..67cc16c1b8e3 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -50,6 +50,7 @@ struct vsp1_dl_entry {
  * @dma: DMA address of the entries
  * @size: size of the DMA memory in bytes
  * @num_entries: number of stored entries
+ * @max_entries: number of entries available
  */
 struct vsp1_dl_body {
struct list_head list;
@@ -60,6 +61,7 @@ struct vsp1_dl_body {
size_t size;
 
unsigned int num_entries;
+   unsigned int max_entries;
 };
 
 /**
@@ -139,6 +141,7 @@ static int vsp1_dl_body_init(struct vsp1_device *vsp1,
 
dlb->vsp1 = vsp1;
dlb->size = size;
+   dlb->max_entries = num_entries;
 
dlb->entries = dma_alloc_wc(vsp1->bus_master, dlb->size, >dma,
GFP_KERNEL);
@@ -220,6 +223,10 @@ void vsp1_dl_body_free(struct vsp1_dl_body *dlb)
  */
 void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 reg, u32 data)
 {
+   if (WARN_ONCE(dlb->num_entries >= dlb->max_entries,
+ "DLB size exceeded (max %u)", dlb->max_entries))
+   return;
+
dlb->entries[dlb->num_entries].addr = reg;
dlb->entries[dlb->num_entries].data = data;
dlb->num_entries++;
-- 
git-series 0.9.1


[PATCH v7 4/8] media: vsp1: Convert display lists to use new body pool

2018-03-07 Thread Kieran Bingham
Adapt the dl->body0 object to use an object from the body pool. This
greatly reduces the pressure on the TLB for IPMMU use cases, as all of
the lists use a single allocation for the main body.

The CLU and LUT objects pre-allocate a pool containing three bodies,
allowing a userspace update before the hardware has committed a previous
set of tables.

Bodies are no longer 'freed' in interrupt context, but instead released
back to their respective pools. This allows us to remove the garbage
collector in the DLM.

Signed-off-by: Kieran Bingham 

---
v3:
 - 's/fragment/body', 's/fragments/bodies/'
 - CLU/LUT now allocate 3 bodies
 - vsp1_dl_list_fragments_free -> vsp1_dl_list_bodies_put

v2:
 - Use dl->body0->max_entries to determine header offset, instead of the
   global constant VSP1_DL_NUM_ENTRIES which is incorrect.
 - squash updates for LUT, CLU, and fragment cleanup into single patch.
   (Not fully bisectable when separated)

 drivers/media/platform/vsp1/vsp1_clu.c |  27 ++-
 drivers/media/platform/vsp1/vsp1_clu.h |   1 +-
 drivers/media/platform/vsp1/vsp1_dl.c  | 223 ++
 drivers/media/platform/vsp1/vsp1_dl.h  |   3 +-
 drivers/media/platform/vsp1/vsp1_lut.c |  27 ++-
 drivers/media/platform/vsp1/vsp1_lut.h |   1 +-
 6 files changed, 101 insertions(+), 181 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_clu.c 
b/drivers/media/platform/vsp1/vsp1_clu.c
index 9621afa3658c..2018144470c5 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.c
+++ b/drivers/media/platform/vsp1/vsp1_clu.c
@@ -23,6 +23,8 @@
 #define CLU_MIN_SIZE   4U
 #define CLU_MAX_SIZE   8190U
 
+#define CLU_SIZE   (17 * 17 * 17)
+
 /* 
-
  * Device Access
  */
@@ -47,19 +49,19 @@ static int clu_set_table(struct vsp1_clu *clu, struct 
v4l2_ctrl *ctrl)
struct vsp1_dl_body *dlb;
unsigned int i;
 
-   dlb = vsp1_dl_body_alloc(clu->entity.vsp1, 1 + 17 * 17 * 17);
+   dlb = vsp1_dl_body_get(clu->pool);
if (!dlb)
return -ENOMEM;
 
vsp1_dl_body_write(dlb, VI6_CLU_ADDR, 0);
-   for (i = 0; i < 17 * 17 * 17; ++i)
+   for (i = 0; i < CLU_SIZE; ++i)
vsp1_dl_body_write(dlb, VI6_CLU_DATA, ctrl->p_new.p_u32[i]);
 
spin_lock_irq(>lock);
swap(clu->clu, dlb);
spin_unlock_irq(>lock);
 
-   vsp1_dl_body_free(dlb);
+   vsp1_dl_body_put(dlb);
return 0;
 }
 
@@ -261,8 +263,16 @@ static void clu_configure(struct vsp1_entity *entity,
}
 }
 
+static void clu_destroy(struct vsp1_entity *entity)
+{
+   struct vsp1_clu *clu = to_clu(>subdev);
+
+   vsp1_dl_body_pool_destroy(clu->pool);
+}
+
 static const struct vsp1_entity_operations clu_entity_ops = {
.configure = clu_configure,
+   .destroy = clu_destroy,
 };
 
 /* 
-
@@ -288,6 +298,17 @@ struct vsp1_clu *vsp1_clu_create(struct vsp1_device *vsp1)
if (ret < 0)
return ERR_PTR(ret);
 
+   /*
+* Pre-allocate a body pool, with 3 bodies allowing a userspace update
+* before the hardware has committed a previous set of tables, handling
+* both the queued and pending dl entries. One extra entry is added to
+* the CLU_SIZE to allow for the VI6_CLU_ADDR header.
+*/
+   clu->pool = vsp1_dl_body_pool_create(clu->entity.vsp1, 3, CLU_SIZE + 1,
+0);
+   if (!clu->pool)
+   return ERR_PTR(-ENOMEM);
+
/* Initialize the control handler. */
v4l2_ctrl_handler_init(>ctrls, 2);
v4l2_ctrl_new_custom(>ctrls, _table_control, NULL);
diff --git a/drivers/media/platform/vsp1/vsp1_clu.h 
b/drivers/media/platform/vsp1/vsp1_clu.h
index 036e0a2f1a42..fa3fe856725b 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.h
+++ b/drivers/media/platform/vsp1/vsp1_clu.h
@@ -36,6 +36,7 @@ struct vsp1_clu {
spinlock_t lock;
unsigned int mode;
struct vsp1_dl_body *clu;
+   struct vsp1_dl_body_pool *pool;
 };
 
 static inline struct vsp1_clu *to_clu(struct v4l2_subdev *subdev)
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index 0208e72cb356..74476726451c 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -111,7 +111,7 @@ struct vsp1_dl_list {
struct vsp1_dl_header *header;
dma_addr_t dma;
 
-   struct vsp1_dl_body body0;
+   struct vsp1_dl_body *body0;
struct list_head bodies;
 
bool has_chain;
@@ -135,8 +135,6 @@ enum vsp1_dl_mode {
  * @queued: list queued to the hardware (written to the DL registers)
  * @pending: list waiting to be queued to the hardware
  * @pool: body pool for the display list bodies
- * 

[PATCH v7 5/8] media: vsp1: Use reference counting for bodies

2018-03-07 Thread Kieran Bingham
Extend the display list body with a reference count, allowing bodies to
be kept as long as a reference is maintained. This provides the ability
to keep a cached copy of bodies which will not change, so that they can
be re-applied to multiple display lists.

Signed-off-by: Kieran Bingham 

---
This could be squashed into the body update code, but it's not a
straightforward squash as the refcounts will affect both:
  v4l: vsp1: Provide a body pool
and
  v4l: vsp1: Convert display lists to use new body pool
therefore, I have kept this separate to prevent breaking bisectability
of the vsp-tests.

v3:
 - 's/fragment/body/'

v4:
 - Fix up reference handling comments.

 drivers/media/platform/vsp1/vsp1_clu.c |  7 ++-
 drivers/media/platform/vsp1/vsp1_dl.c  | 15 ++-
 drivers/media/platform/vsp1/vsp1_lut.c |  7 ++-
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_clu.c 
b/drivers/media/platform/vsp1/vsp1_clu.c
index 2018144470c5..b2a39a6ef7e4 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.c
+++ b/drivers/media/platform/vsp1/vsp1_clu.c
@@ -257,8 +257,13 @@ static void clu_configure(struct vsp1_entity *entity,
clu->clu = NULL;
spin_unlock_irqrestore(>lock, flags);
 
-   if (dlb)
+   if (dlb) {
vsp1_dl_list_add_body(dl, dlb);
+
+   /* release our local reference */
+   vsp1_dl_body_put(dlb);
+   }
+
break;
}
 }
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index 74476726451c..134865287c02 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -58,6 +59,8 @@ struct vsp1_dl_body {
struct list_head list;
struct list_head free;
 
+   refcount_t refcnt;
+
struct vsp1_dl_body_pool *pool;
struct vsp1_device *vsp1;
 
@@ -259,6 +262,7 @@ struct vsp1_dl_body *vsp1_dl_body_get(struct 
vsp1_dl_body_pool *pool)
if (!list_empty(>free)) {
dlb = list_first_entry(>free, struct vsp1_dl_body, free);
list_del(>free);
+   refcount_set(>refcnt, 1);
}
 
spin_unlock_irqrestore(>lock, flags);
@@ -279,6 +283,9 @@ void vsp1_dl_body_put(struct vsp1_dl_body *dlb)
if (!dlb)
return;
 
+   if (!refcount_dec_and_test(>refcnt))
+   return;
+
dlb->num_entries = 0;
 
spin_lock_irqsave(>pool->lock, flags);
@@ -465,7 +472,11 @@ void vsp1_dl_list_write(struct vsp1_dl_list *dl, u32 reg, 
u32 data)
  * in the order in which bodies are added.
  *
  * Adding a body to a display list passes ownership of the body to the list. 
The
- * caller must not touch the body after this call.
+ * caller retains its reference to the fragment when adding it to the display
+ * list, but is not allowed to add new entries to the body.
+ *
+ * The reference must be explicitly released by a call to vsp1_dl_body_put()
+ * when the body isn't needed anymore.
  *
  * Additional bodies are only usable for display lists in header mode.
  * Attempting to add a body to a header-less display list will return an error.
@@ -476,6 +487,8 @@ int vsp1_dl_list_add_body(struct vsp1_dl_list *dl, struct 
vsp1_dl_body *dlb)
if (dl->dlm->mode != VSP1_DL_MODE_HEADER)
return -EINVAL;
 
+   refcount_inc(>refcnt);
+
list_add_tail(>list, >bodies);
 
return 0;
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c 
b/drivers/media/platform/vsp1/vsp1_lut.c
index 262cb72139d6..77cf7137a0f2 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.c
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -213,8 +213,13 @@ static void lut_configure(struct vsp1_entity *entity,
lut->lut = NULL;
spin_unlock_irqrestore(>lock, flags);
 
-   if (dlb)
+   if (dlb) {
vsp1_dl_list_add_body(dl, dlb);
+
+   /* release our local reference */
+   vsp1_dl_body_put(dlb);
+   }
+
break;
}
 }
-- 
git-series 0.9.1


[PATCH v7 6/8] media: vsp1: Refactor display list configure operations

2018-03-07 Thread Kieran Bingham
The entities provide a single .configure operation which configures the
object into the target display list, based on the vsp1_entity_params
selection.

This restricts us to a single function prototype for both static
configuration (the pre-stream INIT stage) and the dynamic runtime stages
for both each frame - and each partition therein.

Split the configure function into two parts, '.configure_stream()' and
'.configure_frame()', merging both the VSP1_ENTITY_PARAMS_RUNTIME and
VSP1_ENTITY_PARAMS_PARTITION stages into a single call through the
.configure_frame(). The configuration for individual partitions is
handled by passing the partition number to the configure call, and
processing any runtime stage actions on the first partition only.

Signed-off-by: Kieran Bingham 

---
v7
 - Fix formatting and white space
 - s/prepare/configure_stream/
 - s/configure/configure_frame/

 drivers/media/platform/vsp1/vsp1_bru.c|  12 +-
 drivers/media/platform/vsp1/vsp1_clu.c|  50 +---
 drivers/media/platform/vsp1/vsp1_dl.h |   1 +-
 drivers/media/platform/vsp1/vsp1_drm.c|  21 +--
 drivers/media/platform/vsp1/vsp1_entity.c |  17 +-
 drivers/media/platform/vsp1/vsp1_entity.h |  33 +--
 drivers/media/platform/vsp1/vsp1_hgo.c|  12 +-
 drivers/media/platform/vsp1/vsp1_hgt.c|  12 +-
 drivers/media/platform/vsp1/vsp1_hsit.c   |  12 +-
 drivers/media/platform/vsp1/vsp1_lif.c|  12 +-
 drivers/media/platform/vsp1/vsp1_lut.c|  32 +-
 drivers/media/platform/vsp1/vsp1_rpf.c| 164 ++---
 drivers/media/platform/vsp1/vsp1_sru.c|  12 +-
 drivers/media/platform/vsp1/vsp1_uds.c|  57 ++--
 drivers/media/platform/vsp1/vsp1_video.c  |  24 +--
 drivers/media/platform/vsp1/vsp1_wpf.c| 299 ---
 16 files changed, 378 insertions(+), 392 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_bru.c 
b/drivers/media/platform/vsp1/vsp1_bru.c
index e8fd2ae3b3eb..d6fd265eaccb 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -285,19 +285,15 @@ static const struct v4l2_subdev_ops bru_ops = {
  * VSP1 Entity Operations
  */
 
-static void bru_configure(struct vsp1_entity *entity,
- struct vsp1_pipeline *pipe,
- struct vsp1_dl_list *dl,
- enum vsp1_entity_params params)
+static void bru_configure_stream(struct vsp1_entity *entity,
+struct vsp1_pipeline *pipe,
+struct vsp1_dl_list *dl)
 {
struct vsp1_bru *bru = to_bru(>subdev);
struct v4l2_mbus_framefmt *format;
unsigned int flags;
unsigned int i;
 
-   if (params != VSP1_ENTITY_PARAMS_INIT)
-   return;
-
format = vsp1_entity_get_pad_format(>entity, bru->entity.config,
bru->entity.source_pad);
 
@@ -404,7 +400,7 @@ static void bru_configure(struct vsp1_entity *entity,
 }
 
 static const struct vsp1_entity_operations bru_entity_ops = {
-   .configure = bru_configure,
+   .configure_stream = bru_configure_stream,
 };
 
 /* 
-
diff --git a/drivers/media/platform/vsp1/vsp1_clu.c 
b/drivers/media/platform/vsp1/vsp1_clu.c
index b2a39a6ef7e4..b8d8af6d4910 100644
--- a/drivers/media/platform/vsp1/vsp1_clu.c
+++ b/drivers/media/platform/vsp1/vsp1_clu.c
@@ -213,37 +213,36 @@ static const struct v4l2_subdev_ops clu_ops = {
 /* 
-
  * VSP1 Entity Operations
  */
+static void clu_configure_stream(struct vsp1_entity *entity,
+struct vsp1_pipeline *pipe,
+struct vsp1_dl_list *dl)
+{
+   struct vsp1_clu *clu = to_clu(>subdev);
+
+   /*
+* The yuv_mode can't be changed during streaming. Cache it internally
+* for future runtime configuration calls.
+*/
+   struct v4l2_mbus_framefmt *format;
+
+   format = vsp1_entity_get_pad_format(>entity,
+   clu->entity.config,
+   CLU_PAD_SINK);
+   clu->yuv_mode = format->code == MEDIA_BUS_FMT_AYUV8_1X32;
+}
 
-static void clu_configure(struct vsp1_entity *entity,
- struct vsp1_pipeline *pipe,
- struct vsp1_dl_list *dl,
- enum vsp1_entity_params params)
+static void clu_configure_frame(struct vsp1_entity *entity,
+   struct vsp1_pipeline *pipe,
+   struct vsp1_dl_list *dl,
+   unsigned int partition)
 {
struct vsp1_clu *clu = to_clu(>subdev);
struct vsp1_dl_body *dlb;
unsigned long flags;
u32 ctrl = VI6_CLU_CTRL_AAI | VI6_CLU_CTRL_MVS | VI6_CLU_CTRL_EN;
 
-   

Re: [PATCH v2] i2c: adv748x: afe: fix sparse warning

2018-03-07 Thread Kieran Bingham
Hi Niklas,

Thank you for your patch.

On 07/03/18 22:58, Niklas Söderlund wrote:
> This fixes the following sparse warning:
> 
> drivers/media/i2c/adv748x/adv748x-afe.c:294:34:expected unsigned int 
> [usertype] *signal
> drivers/media/i2c/adv748x/adv748x-afe.c:294:34:got int *
> drivers/media/i2c/adv748x/adv748x-afe.c:294:34: warning: incorrect type in 
> argument 2 (different signedness)
> 
> Signed-off-by: Niklas Söderlund 

Reviewed-by: Kieran Bingham 


> ---
> 
> * Changes since v1
> - Use u32 instead of unsigned int as suggested by Geert.
> ---
>  drivers/media/i2c/adv748x/adv748x-afe.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c 
> b/drivers/media/i2c/adv748x/adv748x-afe.c
> index 5188178588c9067d..61514bae7e5ceb42 100644
> --- a/drivers/media/i2c/adv748x/adv748x-afe.c
> +++ b/drivers/media/i2c/adv748x/adv748x-afe.c
> @@ -275,7 +275,8 @@ static int adv748x_afe_s_stream(struct v4l2_subdev *sd, 
> int enable)
>  {
>   struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
>   struct adv748x_state *state = adv748x_afe_to_state(afe);
> - int ret, signal = V4L2_IN_ST_NO_SIGNAL;
> + u32 signal = V4L2_IN_ST_NO_SIGNAL;
> + int ret;
>  
>   mutex_lock(>mutex);
>  
> 


Re: [PATCH v2] i2c: adv748x: afe: fix sparse warning

2018-03-07 Thread Niklas Söderlund
CC linux-media.

It's linux-me...@vger.kernel.org not linux-me...@vger.kernel.or, sorry
for the noise.

On 2018-03-07 23:58:16 +0100, Niklas Söderlund wrote:
> This fixes the following sparse warning:
> 
> drivers/media/i2c/adv748x/adv748x-afe.c:294:34:expected unsigned int 
> [usertype] *signal
> drivers/media/i2c/adv748x/adv748x-afe.c:294:34:got int *
> drivers/media/i2c/adv748x/adv748x-afe.c:294:34: warning: incorrect type in 
> argument 2 (different signedness)
> 
> Signed-off-by: Niklas Söderlund 
> 
> ---
> 
> * Changes since v1
> - Use u32 instead of unsigned int as suggested by Geert.
> ---
>  drivers/media/i2c/adv748x/adv748x-afe.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c 
> b/drivers/media/i2c/adv748x/adv748x-afe.c
> index 5188178588c9067d..61514bae7e5ceb42 100644
> --- a/drivers/media/i2c/adv748x/adv748x-afe.c
> +++ b/drivers/media/i2c/adv748x/adv748x-afe.c
> @@ -275,7 +275,8 @@ static int adv748x_afe_s_stream(struct v4l2_subdev *sd, 
> int enable)
>  {
>   struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
>   struct adv748x_state *state = adv748x_afe_to_state(afe);
> - int ret, signal = V4L2_IN_ST_NO_SIGNAL;
> + u32 signal = V4L2_IN_ST_NO_SIGNAL;
> + int ret;
>  
>   mutex_lock(>mutex);
>  
> -- 
> 2.16.2
> 

-- 
Regards,
Niklas Söderlund


Re: [PATCH v2] i2c: adv748x: afe: fix sparse warning

2018-03-07 Thread Niklas Söderlund
CC linux-media.

It's linux-me...@vger.kernel.org not linux-me...@vger.kernel.or, sorry 
for the noise.

On 2018-03-07 23:58:16 +0100, Niklas Söderlund wrote:
> This fixes the following sparse warning:
> 
> drivers/media/i2c/adv748x/adv748x-afe.c:294:34:expected unsigned int 
> [usertype] *signal
> drivers/media/i2c/adv748x/adv748x-afe.c:294:34:got int *
> drivers/media/i2c/adv748x/adv748x-afe.c:294:34: warning: incorrect type in 
> argument 2 (different signedness)
> 
> Signed-off-by: Niklas Söderlund 
> 
> ---
> 
> * Changes since v1
> - Use u32 instead of unsigned int as suggested by Geert.
> ---
>  drivers/media/i2c/adv748x/adv748x-afe.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c 
> b/drivers/media/i2c/adv748x/adv748x-afe.c
> index 5188178588c9067d..61514bae7e5ceb42 100644
> --- a/drivers/media/i2c/adv748x/adv748x-afe.c
> +++ b/drivers/media/i2c/adv748x/adv748x-afe.c
> @@ -275,7 +275,8 @@ static int adv748x_afe_s_stream(struct v4l2_subdev *sd, 
> int enable)
>  {
>   struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
>   struct adv748x_state *state = adv748x_afe_to_state(afe);
> - int ret, signal = V4L2_IN_ST_NO_SIGNAL;
> + u32 signal = V4L2_IN_ST_NO_SIGNAL;
> + int ret;
>  
>   mutex_lock(>mutex);
>  
> -- 
> 2.16.2
> 

-- 
Regards,
Niklas Söderlund


[PATCH v2] i2c: adv748x: afe: fix sparse warning

2018-03-07 Thread Niklas Söderlund
This fixes the following sparse warning:

drivers/media/i2c/adv748x/adv748x-afe.c:294:34:expected unsigned int 
[usertype] *signal
drivers/media/i2c/adv748x/adv748x-afe.c:294:34:got int *
drivers/media/i2c/adv748x/adv748x-afe.c:294:34: warning: incorrect type in 
argument 2 (different signedness)

Signed-off-by: Niklas Söderlund 

---

* Changes since v1
- Use u32 instead of unsigned int as suggested by Geert.
---
 drivers/media/i2c/adv748x/adv748x-afe.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c 
b/drivers/media/i2c/adv748x/adv748x-afe.c
index 5188178588c9067d..61514bae7e5ceb42 100644
--- a/drivers/media/i2c/adv748x/adv748x-afe.c
+++ b/drivers/media/i2c/adv748x/adv748x-afe.c
@@ -275,7 +275,8 @@ static int adv748x_afe_s_stream(struct v4l2_subdev *sd, int 
enable)
 {
struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
struct adv748x_state *state = adv748x_afe_to_state(afe);
-   int ret, signal = V4L2_IN_ST_NO_SIGNAL;
+   u32 signal = V4L2_IN_ST_NO_SIGNAL;
+   int ret;
 
mutex_lock(>mutex);
 
-- 
2.16.2



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

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

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

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



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

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

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

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



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

2018-03-07 Thread Niklas Söderlund
From: Fabrizio Castro 

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

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

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



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

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

Signed-off-by: Niklas Söderlund 

---

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

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



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

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

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

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

---

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

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

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

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

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

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

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

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

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

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 38 ++
 drivers/media/platform/rcar-vin/rcar-vin.h |  2 ++
 2 files changed, 40 insertions(+)

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



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

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

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

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

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



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

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

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

Signed-off-by: Niklas Söderlund 

---

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

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 680b25f610d1d8bb..c4be0bcb8b16f941 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -138,67 +138,60 @@ static int rvin_format_align(struct rvin_dev *vin, struct 
v4l2_pix_format *pix)
  * V4L2
  */
 
-static void rvin_reset_crop_compose(struct rvin_dev *vin)
-{
-   vin->crop.top = vin->crop.left = 0;
-   vin->crop.width = vin->source.width;
-   vin->crop.height = vin->source.height;
-
-   vin->compose.top = vin->compose.left = 0;
-   vin->compose.width = vin->format.width;
-   vin->compose.height = vin->format.height;
-}
-
 static int rvin_reset_format(struct rvin_dev *vin)
 {
struct v4l2_subdev_format fmt = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+   .pad = vin->digital->source_pad,
};
-   struct v4l2_mbus_framefmt *mf = 
int ret;
 
-   fmt.pad = vin->digital->source_pad;
-
ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, );
if (ret)
return ret;
 
-   vin->format.width   = mf->width;
-   vin->format.height  = mf->height;
-   vin->format.colorspace  = mf->colorspace;
-   vin->format.field   = mf->field;
+   v4l2_fill_pix_format(>format, );
 
-   rvin_reset_crop_compose(vin);
+   ret = rvin_format_align(vin, >format);
+   if (ret)
+   return ret;
 
-   vin->format.bytesperline = rvin_format_bytesperline(>format);
-   vin->format.sizeimage = rvin_format_sizeimage(>format);
+   vin->source.top = vin->crop.top = 0;
+   vin->source.left = vin->crop.left = 0;
+   vin->source.width = vin->crop.width = vin->format.width;
+   vin->source.height = vin->crop.height = vin->format.height;
+
+   vin->compose.top = vin->compose.left = 0;
+   vin->compose.width = vin->format.width;
+   vin->compose.height = vin->format.height;
 
return 0;
 }
 
-static int __rvin_try_format_source(struct rvin_dev *vin,
-   u32 which,
-   struct v4l2_pix_format *pix,
-   struct rvin_source_fmt *source)
+static int rvin_try_format(struct rvin_dev *vin, u32 which,
+  struct v4l2_pix_format *pix,
+  struct v4l2_rect *crop, struct v4l2_rect *compose)
 {
-   struct v4l2_subdev *sd;
+   struct v4l2_subdev *sd = vin_to_source(vin);
struct v4l2_subdev_pad_config *pad_cfg;
struct v4l2_subdev_format format = {
.which = which,
+   .pad = vin->digital->source_pad,
};
enum v4l2_field field;
u32 width, height;
int ret;
 
-   sd = vin_to_source(vin);
-
-   v4l2_fill_mbus_format(, pix, vin->digital->code);
-
pad_cfg = v4l2_subdev_alloc_pad_config(sd);
if (pad_cfg == NULL)
return -ENOMEM;
 
-   format.pad = vin->digital->source_pad;
+   if (!rvin_format_from_pixel(pix->pixelformat) ||
+   (vin->info->model == RCAR_M1 &&
+pix->pixelformat == V4L2_PIX_FMT_XBGR32))
+   pix->pixelformat = RVIN_DEFAULT_FORMAT;
+
+   v4l2_fill_mbus_format(, pix, vin->digital->code);
 
/* Allow the video device to override field and to scale */
field = pix->field;
@@ -211,39 +204,34 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
 
v4l2_fill_pix_format(pix, );
 
-   source->width = pix->width;
-   source->height = pix->height;
+   crop->top = crop->left = 0;
+   crop->width = pix->width;
+   crop->height = pix->height;
+
+   /*
+* If source is ALTERNATE the driver will use the VIN hardware
+* to INTERLACE it. The crop height then needs to be doubled.
+*/
+   if (pix->field == V4L2_FIELD_ALTERNATE)
+   crop->height *= 2;
+
+   if 

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

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

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

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



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

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

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

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

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

2018-03-07 Thread Niklas Söderlund
Hi,

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

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

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

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

For convenience the series can be fetched from:

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

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

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

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

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

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

* Changes since v10
- Corrected spelling in comments and commit messages.
- Reworked 'rcar-vin: read subdevice format for crop only when needed'
  to only get the source format once per operation.
- Moved some patches around to make it easier to review, moved:
- rcar-vin: set a default field to fallback on
- rcar-vin: fix handling of single field frames (top, bottom and alternate 
fields)
- rcar-vin: update bytesperline and sizeimage calculation
- rcar-vin: break out format alignment and checking
- rcar-vin: update pixelformat check for M1
  Before:
- rcar-vin: read subdevice format for crop only when needed
- Rename variable 'code' to 'mbus_code' in struct rvin_dev.
- Add comment describing no locking is needed in
  rvin_set_channel_routing().
- Check return value of pm_runtime_get_sync() in
  rvin_set_channel_routing().
- Rework 'rcar-vin: add check for colorspace' to not try to check the
  format, instead force a default format. This should be revisited once
  either v4l2-compliance or v4l2 framework changes are worked out to
  allow for MC centric drivers to validate user supplied colorspace.
- Add error checking for pm_runtime_get_sync() and
  v4l2_pipeline_pm_use().
- Change mutex_lock() to mutex_lock_interruptible() in rvin_mc_open().
- Rewrote documentation for struct rvin_group_route.
- Rename rvin_mc_parse_v4l2() to rvin_mc_parse_of_endpoint().
- Reword error messages in rvin_mc_parse_of_endpoint().
- Removed unneeded loop in rvin_mc_parse_of_endpoint().
- Remove check !is_media_entity_v4l2_subdev() in
  rvin_group_entity_to_csi_id().
- Add documentation for the algorithm used to figure out if a link can
  be enabled or not in rvin_group_link_notify().
- Break out format validation to rvin_mc_validate_format().
- Include two DT documentation patches from Fabrizio Castro which
  previously where mentioned as the only dependency for this series.
- Added reviewed tags from Laurent, Thanks!

* Changes since v9
- Fixed mistakes in the device tree description pointed out by  Laurent.
- GenX -> GenX platforms
- portX -> port X
- Explicitly state the on Gen3 platforms port 0 can only describe
  one endpoint and that only VIN instances connected to external
  pins should have a port 0 node.
- s/which is/connected to/ in he endpoint description for Gen3
  platforms.
- Update some poorly written commit messages.
- Moved the digital subdevice attach and detach code to two separate
  functions to increase readability.
- Rename the struct rvin_info member chip to model to better describe
  its purpose.
- Change the video name from "rcar_vin e6ef.video" to "VINx output"
  where x is the VIN 

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

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

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

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

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

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

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

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

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

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

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

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

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



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

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

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

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



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

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

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

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

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

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

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

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



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

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

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

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



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

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

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

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

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



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

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

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

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

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

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

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

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

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



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

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

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

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

Signed-off-by: Niklas Söderlund 

---

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

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

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

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

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 133 +++--
 1 file changed, 126 insertions(+), 7 deletions(-)

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

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

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

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

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

Signed-off-by: Niklas Söderlund 
---
 drivers/media/platform/rcar-vin/rcar-dma.c  | 15 +--
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 40 +++--
 2 files changed, 10 insertions(+), 45 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index fd14be20a6604d7a..c8831e189d362c8b 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -617,7 +617,6 @@ static int rvin_setup(struct rvin_dev *vin)
case V4L2_FIELD_INTERLACED_BT:
vnmc = VNMC_IM_FULL | VNMC_FOC;
break;
-   case V4L2_FIELD_ALTERNATE:
case V4L2_FIELD_NONE:
if (vin->continuous) {
vnmc = VNMC_IM_ODD_EVEN;
@@ -757,18 +756,6 @@ static int rvin_get_active_slot(struct rvin_dev *vin, u32 
vnms)
return 0;
 }
 
-static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms)
-{
-   if (vin->format.field == V4L2_FIELD_ALTERNATE) {
-   /* If FS is set it's a Even field */
-   if (vnms & VNMS_FS)
-   return V4L2_FIELD_BOTTOM;
-   return V4L2_FIELD_TOP;
-   }
-
-   return vin->format.field;
-}
-
 static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr)
 {
const struct rvin_video_format *fmt;
@@ -941,7 +928,7 @@ static irqreturn_t rvin_irq(int irq, void *data)
goto done;
 
/* Capture frame */
-   vin->queue_buf[slot]->field = rvin_get_active_field(vin, vnms);
+   vin->queue_buf[slot]->field = vin->format.field;
vin->queue_buf[slot]->sequence = sequence;
vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns();
vb2_buffer_done(>queue_buf[slot]->vb2_buf, VB2_BUF_STATE_DONE);
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c 
b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index ebcd78b1bb6e8cb6..b76d59be64e0132d 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -121,33 +121,6 @@ static int rvin_reset_format(struct rvin_dev *vin)
vin->format.colorspace  = mf->colorspace;
vin->format.field   = mf->field;
 
-   /*
-* If the subdevice uses ALTERNATE field mode and G_STD is
-* implemented use the VIN HW to combine the two fields to
-* one INTERLACED frame. The ALTERNATE field mode can still
-* be requested in S_FMT and be respected, this is just the
-* default which is applied at probing or when S_STD is called.
-*/
-   if (vin->format.field == V4L2_FIELD_ALTERNATE &&
-   v4l2_subdev_has_op(vin_to_source(vin), video, g_std))
-   vin->format.field = V4L2_FIELD_INTERLACED;
-
-   switch (vin->format.field) {
-   case V4L2_FIELD_TOP:
-   case V4L2_FIELD_BOTTOM:
-   case V4L2_FIELD_ALTERNATE:
-   vin->format.height /= 2;
-   break;
-   case V4L2_FIELD_NONE:
-   case V4L2_FIELD_INTERLACED_TB:
-   case V4L2_FIELD_INTERLACED_BT:
-   case V4L2_FIELD_INTERLACED:
-   break;
-   default:
-   vin->format.field = RVIN_DEFAULT_FIELD;
-   break;
-   }
-
rvin_reset_crop_compose(vin);
 
vin->format.bytesperline = rvin_format_bytesperline(>format);
@@ -233,15 +206,20 @@ static int __rvin_try_format(struct rvin_dev *vin,
switch (pix->field) {
case V4L2_FIELD_TOP:
case V4L2_FIELD_BOTTOM:
-   case V4L2_FIELD_ALTERNATE:
-   pix->height /= 2;
-   source->height /= 2;
-   break;
case V4L2_FIELD_NONE:
case V4L2_FIELD_INTERLACED_TB:
   

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

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

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

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



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

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

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

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

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

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

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

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



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

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

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

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

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

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

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

2018-03-07 Thread Niklas Söderlund
From: Fabrizio Castro 

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

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

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



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

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

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

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



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

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

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

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

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

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

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

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

Signed-off-by: Niklas Söderlund 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/platform/rcar-vin/rcar-core.c | 108 +++-
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  35 -
 2 files changed, 74 insertions(+), 69 deletions(-)

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

Re: [PATCH v2 3/3] dt-bindings: rcar-gen3-phy-usb3: Add bindings for r8a77965

2018-03-07 Thread Rob Herring
On Mon, Mar 05, 2018 at 02:32:45PM +0900, Yoshihiro Shimoda wrote:
> This patch adds bindings for r8a77965 (R-Car M3-N).
> 
> Signed-off-by: Yoshihiro Shimoda 
> ---
>  Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Rob Herring 



Re: [PATCH v2 1/3] dt-bindings: rcar-gen3-phy-usb2: Add bindings for r8a77965

2018-03-07 Thread Rob Herring
On Mon, Mar 05, 2018 at 02:32:43PM +0900, Yoshihiro Shimoda wrote:
> This patch adds support for r8a77965 (R-Car M3-N).
> 
> Signed-off-by: Yoshihiro Shimoda 
> ---
>  Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Rob Herring 


[GIT PULL FOR renesas-drivers] VSP1 dynamic BRU/BRS allocation

2018-03-07 Thread Laurent Pinchart
Hi Geert,

The following changes since commit 15ea2df9143729a2b722d4ca2b52cfa14a819d8e:

  media: ov2685: mark PM functions as __maybe_unused (2018-02-26 10:38:56 
-0500)

are available in the Git repository at:

  git://linuxtv.org/pinchartl/media.git tags/v4l2-vsp1-bru-brs-v1-20180226

for you to fetch changes up to 66de53df73042978c8560a2a596a4e9b7a6bb485:

  v4l: vsp1: Rename BRU to BRx (2018-03-07 21:41:34 +0200)


Laurent Pinchart (15):
  v4l: vsp1: Don't start/stop media pipeline for DRM
  v4l: vsp1: Remove outdated comment
  v4l: vsp1: Remove unused field from vsp1_drm_pipeline structure
  v4l: vsp1: Store pipeline pointer in vsp1_entity
  v4l: vsp1: Use vsp1_entity.pipe to check if entity belongs to a pipeline
  v4l: vsp1: Share duplicated DRM pipeline configuration code
  v4l: vsp1: Move DRM atomic commit pipeline setup to separate function
  v4l: vsp1: Setup BRU at atomic commit time
  v4l: vsp1: Replace manual DRM pipeline input setup in vsp1_du_setup_lif
  v4l: vsp1: Move DRM pipeline output setup code to a function
  v4l: vsp1: Add per-display list completion notification support
  v4l: vsp1: Generalize detection of entity removal from DRM pipeline
  v4l: vsp1: Assign BRU and BRS to pipelines dynamically
  v4l: vsp1: Add BRx dynamic assignment debugging messages
  v4l: vsp1: Rename BRU to BRx

 drivers/media/platform/vsp1/Makefile   |   2 +-
 drivers/media/platform/vsp1/vsp1.h |   6 +-
 drivers/media/platform/vsp1/{vsp1_bru.c => vsp1_brx.c} | 202 +++---
 drivers/media/platform/vsp1/{vsp1_bru.h => vsp1_brx.h} |  18 +-
 drivers/media/platform/vsp1/vsp1_dl.c  |  27 +-
 drivers/media/platform/vsp1/vsp1_dl.h  |   4 +-
 drivers/media/platform/vsp1/vsp1_drm.c | 829 ++--
 drivers/media/platform/vsp1/vsp1_drm.h |  16 +-
 drivers/media/platform/vsp1/vsp1_drv.c |   8 +-
 drivers/media/platform/vsp1/vsp1_entity.h  |   2 +
 drivers/media/platform/vsp1/vsp1_histo.c   |   2 +-
 drivers/media/platform/vsp1/vsp1_histo.h   |   3 -
 drivers/media/platform/vsp1/vsp1_pipe.c|  50 +-
 drivers/media/platform/vsp1/vsp1_pipe.h|   7 +-
 drivers/media/platform/vsp1/vsp1_rpf.c |  12 +-
 drivers/media/platform/vsp1/vsp1_rwpf.h|   4 +-
 drivers/media/platform/vsp1/vsp1_video.c   |  37 +-
 drivers/media/platform/vsp1/vsp1_wpf.c |   8 +-
 18 files changed, 705 insertions(+), 532 deletions(-)
 rename drivers/media/platform/vsp1/{vsp1_bru.c => vsp1_brx.c} (63%)
 rename drivers/media/platform/vsp1/{vsp1_bru.h => vsp1_brx.h} (66%)

-- 
Regards,

Laurent Pinchart



Re: [PATCH v2 2/2] drm: rcar-du: add R8A77970 support

2018-03-07 Thread Laurent Pinchart
Hi Sergei,

Thank you for the patch.

On Thursday, 18 January 2018 23:05:59 EET Sergei Shtylyov wrote:
> Add support for the R-Car V3M (R8A77970) SoC to the R-Car DU driver.
> 
> Signed-off-by: Sergei Shtylyov 

Reviewed-by: Laurent Pinchart 

and applied to my tree.

> ---
> Changes in version 2:
> - removed  the 'model' and 'dpll_ch' field initializers;
> - fixed up the DU port numbers;
> - split the DU bindings and the LVDS driver updates into a separate patches;
> - removed  the check before the DPTSR write (to be done in a separate
> patch).
> 
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c |   21 +
>  1 file changed, 21 insertions(+)
> 
> Index: linux/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> ===
> --- linux.orig/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ linux/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -249,6 +249,26 @@ static const struct rcar_du_device_info
>   .dpll_ch =  BIT(1),
>  };
> 
> +static const struct rcar_du_device_info rcar_du_r8a77970_info = {
> + .gen = 3,
> + .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
> +   | RCAR_DU_FEATURE_EXT_CTRL_REGS
> +   | RCAR_DU_FEATURE_VSP1_SOURCE,
> + .num_crtcs = 1,
> + .routes = {
> + /* R8A77970 has one RGB output and one LVDS output. */
> + [RCAR_DU_OUTPUT_DPAD0] = {
> + .possible_crtcs = BIT(0),
> + .port = 0,
> + },
> + [RCAR_DU_OUTPUT_LVDS0] = {
> + .possible_crtcs = BIT(0),
> + .port = 1,
> + },
> + },
> + .num_lvds = 1,
> +};
> +
>  static const struct of_device_id rcar_du_of_table[] = {
>   { .compatible = "renesas,du-r8a7743", .data = _du_r8a7743_info },
>   { .compatible = "renesas,du-r8a7745", .data = _du_r8a7745_info },
> @@ -260,6 +280,7 @@ static const struct of_device_id rcar_du
>   { .compatible = "renesas,du-r8a7794", .data = _du_r8a7794_info },
>   { .compatible = "renesas,du-r8a7795", .data = _du_r8a7795_info },
>   { .compatible = "renesas,du-r8a7796", .data = _du_r8a7796_info },
> + { .compatible = "renesas,du-r8a77970", .data = _du_r8a77970_info },
>   { }
>  };


-- 
Regards,

Laurent Pinchart



Re: [PATCH v2 1/2] DT: display: renesas,du: document R8A77970 bindings

2018-03-07 Thread Laurent Pinchart
Hi Sergei,

Thank you for the patch.

On Thursday, 18 January 2018 23:05:58 EET Sergei Shtylyov wrote:
> Document the R-Car V3M (R8A77970) SoC in the R-Car DU bindings.
> 
> Signed-off-by: Sergei Shtylyov 

Reviewed-by: Laurent Pinchart 

and applied to my tree with the subject prefixed changed per Rob's request.

> ---
> Changes in version 2:
> - documented  R8A77970 DU ports;
> - patch split from the main R8A77970 DU support patch.
> 
>  Documentation/devicetree/bindings/display/renesas,du.txt |2 ++
>  1 file changed, 2 insertions(+)
> 
> Index: linux/Documentation/devicetree/bindings/display/renesas,du.txt
> ===
> --- linux.orig/Documentation/devicetree/bindings/display/renesas,du.txt
> +++ linux/Documentation/devicetree/bindings/display/renesas,du.txt
> @@ -13,6 +13,7 @@ Required Properties:
>  - "renesas,du-r8a7794" for R8A7794 (R-Car E2) compatible DU
>  - "renesas,du-r8a7795" for R8A7795 (R-Car H3) compatible DU
>  - "renesas,du-r8a7796" for R8A7796 (R-Car M3-W) compatible DU
> +- "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU
> 
>- reg: A list of base address and length of each memory resource, one for
> each entry in the reg-names property.
> @@ -63,6 +64,7 @@ corresponding to each DU output.
>   R8A7794 (R-Car E2)   DPAD 0 DPAD 1 -  -
>   R8A7795 (R-Car H3)   DPAD 0 HDMI 0 HDMI 1 LVDS 0
>   R8A7796 (R-Car M3-W) DPAD 0 HDMI 0 LVDS 0 -
> + R8A77970 (R-Car V3M) DPAD 0 LVDS 0 -  -
> 
> 
>  Example: R8A7795 (R-Car H3) ES2.0 DU


-- 
Regards,

Laurent Pinchart



Re: [PATCH] ravb: remove erroneous comment

2018-03-07 Thread David Miller
From: Niklas Söderlund 
Date: Sat,  3 Mar 2018 23:39:54 +0100

> When addressing a review comment in a early version of the offending
> patch a comment where left in which should have been removed. Remove the
> comment to keep it consistent with the code.
> 
> Fixes: 75efa06f457bbed3 ("ravb: add support for changing MTU")
> Reported-by: Sergei Shtylyov 
> Signed-off-by: Niklas Söderlund 

Applied to net-next, thanks.


Re: [PATCH v2] dt-bindings: net: renesas-ravb: Make stream buffer optional

2018-03-07 Thread David Miller
From: Geert Uytterhoeven 
Date: Fri,  2 Mar 2018 16:01:48 +0100

> The Stream Buffer for EtherAVB-IF (STBE) is an optional component, and
> is not present on all SoCs.
> 
> Document this in the DT bindings, including a list of SoCs that do have
> it.
> 
> Fixes: 785ec87483d1e24a ("ravb: document R8A77970 bindings")
> Fixes: f231c4178a655b09 ("dt-bindings: net: renesas-ravb: Add support for 
> R8A77995 RAVB")
> Signed-off-by: Geert Uytterhoeven 
> Reviewed-by: Simon Horman 
> Acked-by: Sergei Shtylyov 
> Reviewed-by: Rob Herring 
> ---
> v2:
>   - Add Reviewed-by, Acked-by,
>   - Add R-Car M3-N.

Applied, thanks Geert.


RE: [PATCH] arm64: dts: renesas: r8a7795: Add IPMMU-PV1 device node

2018-03-07 Thread Yoshihiro Shimoda
Hi Simon-san,

> From: Simon Horman, Sent: Tuesday, March 6, 2018 6:35 PM
> 
> Add r8a7795 IPMMU-PV1 and keep it disabled by default.
> 
> This device is not present in r8a7795 ES1.x and
> is removed from the DT of those SoCs.
> 
> This corrects an omission in
> 3b7e7848f0e8 ("arm64: dts: renesas: r8a7795: Add IPMMU device nodes")
> 
> This does not have any runtime effect.
> 
> Reported-by: Yoshihiro Shimoda 
> Signed-off-by: Simon Horman 

Thank you for the patch!

Reviewed-by: Yoshihiro Shimoda 

Best regards,
Yoshihiro Shimoda




Re: [PATCH 2/3] arm64: dts: renesas: r8a7795: sort subnodes of the cpu node

2018-03-07 Thread Geert Uytterhoeven
Hi Simon,

On Wed, Mar 7, 2018 at 10:40 AM, Simon Horman
 wrote:
> Sort subnodes of the cpu node alphanumerically.
>
> This is part of an ongoing effort to provide consistent node
> order in the DT of Renesas SoCs to improve maintainability.
>
> This should not have any run-time effect.
>
> Signed-off-by: Simon Horman 

Thanks for your patch!

> --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
> @@ -34,6 +34,50 @@
> #address-cells = <1>;
> #size-cells = <0>;
>
> +   a53_0: cpu@100 {
> +   compatible = "arm,cortex-a53", "arm,armv8";
> +   reg = <0x100>;
> +   device_type = "cpu";
> +   power-domains = < R8A7795_PD_CA53_CPU0>;
> +   next-level-cache = <_CA53>;
> +   enable-method = "psci";
> +   clocks =< CPG_CORE R8A7795_CLK_Z2>;
> +   operating-points-v2 = <_opp>;
> +   };

[...]

> a57_0: cpu@0 {
> compatible = "arm,cortex-a57", "arm,armv8";
> reg = <0x0>;

Given the CPU nodes do have reg properties and unit addresses, shouldn't
they be sorted by these values, instead of alphabetically?

Gr{oetje,eeting}s,

Geert

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

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


[PATCH 1/3] arm64: dts: renesas: r8a7795: sort subnodes of the root node

2018-03-07 Thread Simon Horman
Sort subnodes of the root node alphanumerically.

This is part of an ongoing effort to provide consistent node
order in the DT of Renesas SoCs to improve maintainability.

This should not have any run-time effect.

Signed-off-by: Simon Horman 
---
 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi 
b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index 09953cda3a55..119c245b4ee2 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -247,18 +247,6 @@
clock-frequency = <0>;
};
 
-   pmu_a57 {
-   compatible = "arm,cortex-a57-pmu";
-   interrupts-extended = < GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
- < GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
- < GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
- < GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
-   interrupt-affinity = <_0>,
-<_1>,
-<_2>,
-<_3>;
-   };
-
pmu_a53 {
compatible = "arm,cortex-a53-pmu";
interrupts-extended = < GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
@@ -271,6 +259,18 @@
 <_3>;
};
 
+   pmu_a57 {
+   compatible = "arm,cortex-a57-pmu";
+   interrupts-extended = < GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+ < GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+ < GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ < GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+   interrupt-affinity = <_0>,
+<_1>,
+<_2>,
+<_3>;
+   };
+
psci {
compatible = "arm,psci-1.0", "arm,psci-0.2";
method = "smc";
-- 
2.11.0



[PATCH 3/3] arm64: dts: renesas: r8a7795: sort subnodes of the soc node

2018-03-07 Thread Simon Horman
Sort subnodes of the soc node.
The primary key is the bus address.
The secondary key is the IP block.
The tertiary key is the node name.

This is part of an ongoing effort to provide consistent node
order in the DT of Renesas SoCs to improve maintainability.

This should not have any run-time effect.

Signed-off-by: Simon Horman 
---
 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 1844 +++---
 1 file changed, 922 insertions(+), 922 deletions(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi 
b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index d2ecb1dfa487..abed81796ce5 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -291,23 +291,6 @@
#size-cells = <2>;
ranges;
 
-   gic: interrupt-controller@f101 {
-   compatible = "arm,gic-400";
-   #interrupt-cells = <3>;
-   #address-cells = <0>;
-   interrupt-controller;
-   reg = <0x0 0xf101 0 0x1000>,
- <0x0 0xf102 0 0x2>,
- <0x0 0xf104 0 0x2>,
- <0x0 0xf106 0 0x2>;
-   interrupts = ;
-   clocks = < CPG_MOD 408>;
-   clock-names = "clk";
-   power-domains = < R8A7795_PD_ALWAYS_ON>;
-   resets = < 408>;
-   };
-
wdt0: watchdog@e602 {
compatible = "renesas,r8a7795-wdt", 
"renesas,rcar-gen3-wdt";
reg = <0 0xe602 0 0x0c>;
@@ -437,6 +420,11 @@
resets = < 905>;
};
 
+   pfc: pin-controller@e606 {
+   compatible = "renesas,pfc-r8a7795";
+   reg = <0 0xe606 0 0x50c>;
+   };
+
cpg: clock-controller@e615 {
compatible = "renesas,r8a7795-cpg-mssr";
reg = <0 0xe615 0 0x1000>;
@@ -452,20 +440,25 @@
reg = <0 0xe616 0 0x0200>;
};
 
-   prr: chipid@fff00044 {
-   compatible = "renesas,prr";
-   reg = <0 0xfff00044 0 4>;
-   };
-
sysc: system-controller@e618 {
compatible = "renesas,r8a7795-sysc";
reg = <0 0xe618 0 0x0400>;
#power-domain-cells = <1>;
};
 
-   pfc: pin-controller@e606 {
-   compatible = "renesas,pfc-r8a7795";
-   reg = <0 0xe606 0 0x50c>;
+   tsc: thermal@e6198000 {
+   compatible = "renesas,r8a7795-thermal";
+   reg = <0 0xe6198000 0 0x100>,
+ <0 0xe61a 0 0x100>,
+ <0 0xe61a8000 0 0x100>;
+   interrupts = ,
+,
+;
+   clocks = < CPG_MOD 522>;
+   power-domains = < R8A7795_PD_ALWAYS_ON>;
+   resets = < 522>;
+   #thermal-sensor-cells = <1>;
+   status = "okay";
};
 
intc_ex: interrupt-controller@e61c {
@@ -484,144 +477,320 @@
resets = < 407>;
};
 
-   ipmmu_vi0: mmu@febd {
-   compatible = "renesas,ipmmu-r8a7795";
-   reg = <0 0xfebd 0 0x1000>;
-   renesas,ipmmu-main = <_mm 14>;
+   i2c0: i2c@e650 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   compatible = "renesas,i2c-r8a7795",
+"renesas,rcar-gen3-i2c";
+   reg = <0 0xe650 0 0x40>;
+   interrupts = ;
+   clocks = < CPG_MOD 931>;
power-domains = < R8A7795_PD_ALWAYS_ON>;
-   #iommu-cells = <1>;
+   resets = < 931>;
+   dmas = < 0x91>, < 0x90>;
+   dma-names = "tx", "rx";
+   i2c-scl-internal-delay-ns = <110>;
+   status = "disabled";
};
 
-   ipmmu_vi1: mmu@febe {
-   compatible = "renesas,ipmmu-r8a7795";
-   reg = <0 0xfebe 0 0x1000>;
-   renesas,ipmmu-main = <_mm 15>;
+   i2c1: i2c@e6508000 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   compatible = "renesas,i2c-r8a7795",
+

[PATCH 0/3] arm64: dts: renesas: r8a7795: sort nodes

2018-03-07 Thread Simon Horman
Sort nodes of the r8a7785 DT.

This is part of an ongoing effort to provide consistent node
order in the DT of Renesas SoCs to improve maintainability.

This should not have any run-time effect.

Based on renesas-devel-20180306-v4.16-rc4

Simon Horman (3):
  arm64: dts: renesas: r8a7795: sort subnodes of the root node
  arm64: dts: renesas: r8a7795: sort subnodes of the cpu node
  arm64: dts: renesas: r8a7795: sort subnodes of the soc node

 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 1912 +++---
 1 file changed, 956 insertions(+), 956 deletions(-)

-- 
2.11.0



[PATCH 2/3] arm64: dts: renesas: r8a7795: sort subnodes of the cpu node

2018-03-07 Thread Simon Horman
Sort subnodes of the cpu node alphanumerically.

This is part of an ongoing effort to provide consistent node
order in the DT of Renesas SoCs to improve maintainability.

This should not have any run-time effect.

Signed-off-by: Simon Horman 
---
 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 88 
 1 file changed, 44 insertions(+), 44 deletions(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi 
b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index 119c245b4ee2..d2ecb1dfa487 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -34,6 +34,50 @@
#address-cells = <1>;
#size-cells = <0>;
 
+   a53_0: cpu@100 {
+   compatible = "arm,cortex-a53", "arm,armv8";
+   reg = <0x100>;
+   device_type = "cpu";
+   power-domains = < R8A7795_PD_CA53_CPU0>;
+   next-level-cache = <_CA53>;
+   enable-method = "psci";
+   clocks =< CPG_CORE R8A7795_CLK_Z2>;
+   operating-points-v2 = <_opp>;
+   };
+
+   a53_1: cpu@101 {
+   compatible = "arm,cortex-a53","arm,armv8";
+   reg = <0x101>;
+   device_type = "cpu";
+   power-domains = < R8A7795_PD_CA53_CPU1>;
+   next-level-cache = <_CA53>;
+   enable-method = "psci";
+   clocks =< CPG_CORE R8A7795_CLK_Z2>;
+   operating-points-v2 = <_opp>;
+   };
+
+   a53_2: cpu@102 {
+   compatible = "arm,cortex-a53","arm,armv8";
+   reg = <0x102>;
+   device_type = "cpu";
+   power-domains = < R8A7795_PD_CA53_CPU2>;
+   next-level-cache = <_CA53>;
+   enable-method = "psci";
+   clocks =< CPG_CORE R8A7795_CLK_Z2>;
+   operating-points-v2 = <_opp>;
+   };
+
+   a53_3: cpu@103 {
+   compatible = "arm,cortex-a53","arm,armv8";
+   reg = <0x103>;
+   device_type = "cpu";
+   power-domains = < R8A7795_PD_CA53_CPU3>;
+   next-level-cache = <_CA53>;
+   enable-method = "psci";
+   clocks =< CPG_CORE R8A7795_CLK_Z2>;
+   operating-points-v2 = <_opp>;
+   };
+
a57_0: cpu@0 {
compatible = "arm,cortex-a57", "arm,armv8";
reg = <0x0>;
@@ -82,50 +126,6 @@
#cooling-cells = <2>;
};
 
-   a53_0: cpu@100 {
-   compatible = "arm,cortex-a53", "arm,armv8";
-   reg = <0x100>;
-   device_type = "cpu";
-   power-domains = < R8A7795_PD_CA53_CPU0>;
-   next-level-cache = <_CA53>;
-   enable-method = "psci";
-   clocks =< CPG_CORE R8A7795_CLK_Z2>;
-   operating-points-v2 = <_opp>;
-   };
-
-   a53_1: cpu@101 {
-   compatible = "arm,cortex-a53","arm,armv8";
-   reg = <0x101>;
-   device_type = "cpu";
-   power-domains = < R8A7795_PD_CA53_CPU1>;
-   next-level-cache = <_CA53>;
-   enable-method = "psci";
-   clocks =< CPG_CORE R8A7795_CLK_Z2>;
-   operating-points-v2 = <_opp>;
-   };
-
-   a53_2: cpu@102 {
-   compatible = "arm,cortex-a53","arm,armv8";
-   reg = <0x102>;
-   device_type = "cpu";
-   power-domains = < R8A7795_PD_CA53_CPU2>;
-   next-level-cache = <_CA53>;
-   enable-method = "psci";
-   clocks =< CPG_CORE R8A7795_CLK_Z2>;
-   operating-points-v2 = <_opp>;
-   };
-
-   a53_3: cpu@103 {
-   compatible = "arm,cortex-a53","arm,armv8";
-   reg = <0x103>;
-   device_type = "cpu";
-   power-domains = < R8A7795_PD_CA53_CPU3>;
-   next-level-cache = <_CA53>;
-   enable-method = "psci";
-   clocks =< CPG_CORE R8A7795_CLK_Z2>;
-   operating-points-v2 = <_opp>;
-   };
-
L2_CA57: cache-controller-0 {
compatible = "cache";
power-domains = < R8A7795_PD_CA57_SCU>;
-- 
2.11.0



[PATCH] PCI: fix semicolon.cocci warnings

2018-03-07 Thread Julia Lawall
From: Fengguang Wu 

 Remove unneeded semicolon.

Generated by: scripts/coccinelle/misc/semicolon.cocci

Signed-off-by: Fengguang Wu 
Signed-off-by: Julia Lawall 
---

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
pci-header-cleanup
head:   40fb7646c6ec16d2fd3de422be876baca9edf86a
commit: c44f2aed62c2314f1c0ecda606716090b73cc730 [4/5] PCI: improve
compile test coverage
:: branch date: 9 hours ago
:: commit date: 9 hours ago


 pcie-rcar.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -435,7 +435,7 @@ static void rcar_pcie_force_speedup(stru
}

msleep(1);
-   };
+   }

dev_err(dev, "Speed change timed out\n");



Re: [PATCH 2/2] pinctrl: sh-pfc: add R8A77980 PFC support

2018-03-07 Thread Geert Uytterhoeven
Hi Sergei,

On Tue, Mar 6, 2018 at 6:15 PM, Sergei Shtylyov
 wrote:
> On 03/06/2018 01:59 PM, Geert Uytterhoeven wrote:
>>> Add the PFC support for the R8A77980 SoC including pin groups for some
>>> on-chip devices such as AVB, CAN-FD, GETHER, [H]SCIF, I2C, INTC-EX, MMC,
>>> MSIOF, PWM, and VIN...
>>>
>>> Based on the original (and large) patch by Vladimir Barinov.
>>>
>>> Signed-off-by: Vladimir Barinov 
>>> Signed-off-by: Sergei Shtylyov 
>>
>> Thanks for your patch!
>>
>> To avoid scaring off potential reviewers, it may be better to not 
>> include that
>> many pin groups and functions in future initial submissions.
>> This also helps if issues are detected during review in some of them 
>> (like
>> below), delaying queuing of basic functionality and other correct parts.
>>
>> I only looked at CPU_ALL_PORT(), pins, groups, and functions.
>> Comments below.
>>
>>> --- /dev/null
>>> +++ renesas-drivers/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
>>
>>> +/* - AVB 
>>>  */
>>> +static const unsigned int avb_link_pins[] = {
>>> +   /* AVB_LINK */
>>> +   RCAR_GP_PIN(1, 18),
>>> +};
>>> +static const unsigned int avb_link_mux[] = {
>>> +   AVB_LINK_MARK,
>>> +};
>>> +static const unsigned int avb_magic_pins[] = {
>>> +   /* AVB_MAGIC */
>>> +   RCAR_GP_PIN(1, 16),
>>> +};
>>> +static const unsigned int avb_magic_mux[] = {
>>> +   AVB_MAGIC_MARK,
>>> +};
>>> +static const unsigned int avb_phy_int_pins[] = {
>>> +   /* AVB_PHY_INT */
>>> +   RCAR_GP_PIN(1, 17),
>>> +};
>>> +static const unsigned int avb_phy_int_mux[] = {
>>> +   AVB_PHY_INT_MARK,
>>> +};
>>> +static const unsigned int avb_mdio_pins[] = {
>>> +   /* AVB_MDC, AVB_MDIO */
>>> +   RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14),
>>> +};
>>> +static const unsigned int avb_mdio_mux[] = {
>>> +   AVB_MDC_MARK, AVB_MDIO_MARK,
>>> +};
>>
>> The grouping is different from other R-Car Gen3 SoCs.
>
>Not true AFAICS -- only the group naming is different.

 Oh, so we can have both groups names, and be compatible?
>>>
>>>Probably. Just not sure if there's any worth to have the same groups for 
>>> the not
>>> pin compatible SoCs. Care to elaborate?
>>
>> So I have compared all AVB/(G)ETHER pin groups on supported SoCs,
>> to solve the issue for good, hopefully.
>>
>> EtherAVB:
>> 
>>
>> R-Car Gen2:
>>
>>   Common (r8a7790/r8a7791/r8a7792/r8a7793/r8a7794) AVB:
>>
>> link = { LINK }
>> magic = { MAGIC }
>> phy_int = { PHY_INT }
>> mdio = { MDC, MDIO }
>> mii = { COL, CRS, RX_CLK, RXD[0-3], RX_DV, RX_ER, TX_CLK, TXD[0-3],
>> TX_EN, TX_ER }
>> gmii = { COL, CRS, GTX_CLK, GTXREFCLK, RX_CLK, RXD[0-7], RX_DV, RX_ER,
>
>Oops! GTXREFCLK is not a part of GMII (at least according to Wikipedia) ...

According to the datasheet, it's the "GMII reference clock signal", which is an
input, and can be used as one of the options for the gPTP clock.
So that makes it optional.

We have only two in-tree users of RAVB:
iwg20d-q7-common.dtsi
r8a7745-iwg22d-sodimm.dts

On both, GTXREFCLK is wired to the CLK125_NDO/LED_MODE _input_ of the
KSZ9031MNXIA PHY, so there it is used as an output?

>>  TX_CLK, TXD[0-7], TX_EN, TX_ER }
>>
>>   AVB exceptions:
>> - r8a7790 "mii" lacks TX_ER (should it?)
>
>This signal is optional.

But currently there's no way to enable it on r8a7790?
If it is optional, it should have its own pingroup.

And this is inconsistent with the other R-Car Gen2 platforms.

>> - r8a7792 has match = { AVTP_MATCH }
>>
>>
>> R-Car Gen3:
>>
>>   r8a7795/r8a7795-es1/r8a7796/r8a77965/r8a77995 AVB:
>>
>> link = { LINK }
>> magic = { MAGIC }
>> phy_int = { PHY_INT }
>> mdc = { MDC, MDIO }
>> mii = { RD[0-3], RXC, RX_CTL, TD[0-3], TXC, TXCREFCLK, TX_CTL }
>
>Oops again! TXREFCLK doen't belong in MII...

We cannot move it out because of backwards compatibility (this is DT ABI).
But we can create a new group named "rgmii" without it, and add a separate
"txcrefclk" group.

>> avtp_pps = { AVTP_PPS }
>> avtp_match = { AVTP_MATCH }
>> avtp_capture = { AVTP_CAPTURE }
>>
>> Notes:
>>   - { MDC, MDIO } groups is named "mdc" instead of "mdio"
>>   - Supports RGMII, but group is named "mii"
>
>Oops... I blame Renesas! :-)
>
>>   Sergei's r8a77970 AVB proposal:
>>
>> link = { LINK }
>> magic = { MAGIC }
>> phy_int = { PHY_INT }
>>   * mdio = { MDC, MDIO }
>> mii = { RD[0-3], RXC, RX_CTL, TD[0-3], TXC, TXCREFCLK, TX_CTL }
>> avtp_pps = { AVTP_PPS }
>> avtp_match = { AVTP_MATCH }
>> 

RE: [PATCH 3/5] arm64: dts: renesas: r8a7795: Add cpu capacity-dmips-mhz

2018-03-07 Thread Gaku Inami
Hi Geert-san, Simon-san,

> -Original Message-
> From: linux-renesas-soc-ow...@vger.kernel.org 
> [mailto:linux-renesas-soc-ow...@vger.kernel.org] On Behalf Of Simon
> Horman
> Sent: Wednesday, March 7, 2018 5:11 PM
[snip]
> >
> > Documentation/devicetree/bindings/arm/cpu-capacity.txt:
> >
> > "capacity-dmips-mhz is an optional cpu node [1] property: u32 value
> >  representing CPU capacity expressed in normalized DMIPS/MHz. At boot time, 
> > the
> >  maximum frequency available to the cpu is then used to calculate the 
> > capacity
> >  value internally used by the kernel."
> >
> > IIUIC, you should thus not use 15532585 and 6241541 directly, but
> > scale them to the frequency.
> >
> > So the formula for CA53 becomes:
> >
> > 1024 / (15532585 / 1500) * (6241541 / 1200) = 514
> >
> > > Considering cpufreq is available later, is it better to set the value(514)
> > > for CA53 scaled by different maximum frequencies?
> >
> > DT describes the hardware, not software limitations, so IMHO 514 is the 
> > correct
> > value.

Sorry, I misunderstood the intention of definition in DT.
Thanks for your detailed explanation. I understood it.

> Yes agreed. Please refresh this patchset accordingly.

I will update v2 patch.

Regards,
Inami


Re: [PATCH] media: platform: Drop OF dependency of VIDEO_RENESAS_VSP1

2018-03-07 Thread Simon Horman
On Tue, Mar 06, 2018 at 01:37:38PM -0300, Mauro Carvalho Chehab wrote:
> Em Tue, 06 Mar 2018 18:35:32 +0200
> Laurent Pinchart  escreveu:
> 
> > Hi Mauro,
> > 
> > On Tuesday, 6 March 2018 18:25:15 EET Mauro Carvalho Chehab wrote:
> > > Em Mon, 26 Feb 2018 19:09:10 +0100 Geert Uytterhoeven escreveu:  
> > > > VIDEO_RENESAS_VSP1 depends on ARCH_RENESAS && OF.
> > > > As ARCH_RENESAS implies OF, the latter can be dropped.
> > > > 
> > > > Signed-off-by: Geert Uytterhoeven 
> > > > ---
> > > > 
> > > >  drivers/media/platform/Kconfig | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/media/platform/Kconfig
> > > > b/drivers/media/platform/Kconfig index 
> > > > 614fbef08ddcabb0..2b8b1ad0edd9eb31
> > > > 100644
> > > > --- a/drivers/media/platform/Kconfig
> > > > +++ b/drivers/media/platform/Kconfig
> > > > @@ -448,7 +448,7 @@ config VIDEO_RENESAS_FCP
> > > > 
> > > >  config VIDEO_RENESAS_VSP1
> > > >  
> > > > tristate "Renesas VSP1 Video Processing Engine"
> > > > depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA
> > > > 
> > > > -   depends on (ARCH_RENESAS && OF) || COMPILE_TEST
> > > > +   depends on ARCH_RENESAS || COMPILE_TEST  
> > > 
> > > That is not correct!
> > > 
> > > COMPILE_TEST doesn't depend on OF. With this patch, it will likely
> > > cause build failures with randconfigs.  
> > 
> > ARCH_RENESAS implies OF, so replacing (ARCH_RENESAS && OF) with 
> > ARCH_RENESAS 
> > doesn't change anything. The driver can be compiled with COMPILE_TEST and 
> > !OF 
> > both before and after this patch.

FWIIW, I think this is a useful cleanup.

> OK!
> > 
> > > > depends on (!ARM64 && !VIDEO_RENESAS_FCP) || VIDEO_RENESAS_FCP
> > > > select VIDEOBUF2_DMA_CONTIG
> > > > select VIDEOBUF2_VMALLOC  
> > 
> 
> 
> 
> Thanks,
> Mauro
> 


Re: [PATCH 3/5] arm64: dts: renesas: r8a7795: Add cpu capacity-dmips-mhz

2018-03-07 Thread Simon Horman
On Wed, Mar 07, 2018 at 08:47:43AM +0100, Geert Uytterhoeven wrote:
> Hi Inami-san,
> 
> On Wed, Mar 7, 2018 at 2:48 AM, Gaku Inami  wrote:
> >> From: geert.uytterhoe...@gmail.com [mailto:geert.uytterhoe...@gmail.com] 
> >> On Behalf Of Geert Uytterhoeven
> >> Sent: Monday, March 5, 2018 7:24 PM
> > [snip]
> >>
> >> 411 for the A53 cores sounds a bit low to me, though.
> >> Documentation/devicetree/bindings/arm/cpu-capacity.txt uses 578.
> >>
> >> Perhaps you already took into account the maximum clock frequencies?
> >> According to the binding document, you should not do that (cfr.
> >> "final capacities are 1024 for cluster0 and 446 for cluster1" in the
> >> bindings doc).
> >
> > Thanks for your review.
> >
> > I set 411 for CA53 based on dhrystone measurement and current 
> > implementation.
> >
> > The average in 10 times of measurement as follows:
> >
> >   cpu   max-freq   dhrystone
> >   -
> >   A57   1500 MHz  15532585 lps/s
> >   A53   1200 MHz   6241541 lps/s
> >
> > With the value of CA57 is scaled at 1024, I end up with 411 for CA53.
> > However, since cpufreq is not available on renesas-devel-20180212-v4.16-rc1,
> > the final capacity is set by directly using capacity-dmips-mhz in dt as 
> > below.
> 
> Documentation/devicetree/bindings/arm/cpu-capacity.txt:
> 
> "capacity-dmips-mhz is an optional cpu node [1] property: u32 value
>  representing CPU capacity expressed in normalized DMIPS/MHz. At boot time, 
> the
>  maximum frequency available to the cpu is then used to calculate the capacity
>  value internally used by the kernel."
> 
> IIUIC, you should thus not use 15532585 and 6241541 directly, but
> scale them to the frequency.
> 
> So the formula for CA53 becomes:
> 
> 1024 / (15532585 / 1500) * (6241541 / 1200) = 514
> 
> > Considering cpufreq is available later, is it better to set the value(514)
> > for CA53 scaled by different maximum frequencies?
> 
> DT describes the hardware, not software limitations, so IMHO 514 is the 
> correct
> value.

Yes agreed. Please refresh this patchset accordingly.


Re: [PATCH 1/3] dt-bindings: iommu: ipmmu-vmsa: Add device tree support for r8a774[35]

2018-03-07 Thread Simon Horman
[CC Alex Williamson]

It looks like the last patch to this file was taken by Alex.
Perhaps he would be willing to take this one too if it it was
reposted with him CCed.

On Tue, Mar 06, 2018 at 04:55:44PM +, Fabrizio Castro wrote:
> Dear All,
> 
> I am very sorry to bother you, do you know who is supposed to take this patch?
> 
> Thanks,
> Fab
> 
> > -Original Message-
> > From: Biju Das [mailto:biju@bp.renesas.com]
> > Sent: 24 January 2018 15:42
> > To: Joerg Roedel ; Laurent Pinchart 
> > ; Geert Uytterhoeven
> > 
> > Cc: Simon Horman ; Magnus Damm ; 
> > Chris Paterson
> > ; Fabrizio Castro 
> > ; io...@lists.linux-foundation.org; linux-
> > renesas-...@vger.kernel.org; Biju Das 
> > Subject: [PATCH 1/3] dt-bindings: iommu: ipmmu-vmsa: Add device tree 
> > support for r8a774[35]
> >
> > Document r8a774[35] specific compatible strings. The Renesas RZ/G1[ME]
> > (r8a774[35]) IPMMU are identical to the R-Car Gen2 family.
> >
> > Signed-off-by: Biju Das 
> > Reviewed-by: Chris Paterson 
> > ---
> >  Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt | 5 -
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
> > b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
> > index 857df92..7d300af 100644
> > --- a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
> > +++ b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
> > @@ -11,12 +11,15 @@ Required Properties:
> >  the device is compatible with the R-Car Gen2 VMSA-compatible IPMMU.
> >
> >  - "renesas,ipmmu-r8a73a4" for the R8A73A4 (R-Mobile APE6) IPMMU.
> > +- "renesas,ipmmu-r8a7743" for the R8A7743 (RZ/G1M) IPMMU.
> > +- "renesas,ipmmu-r8a7745" for the R8A7745 (RZ/G1E) IPMMU.
> >  - "renesas,ipmmu-r8a7790" for the R8A7790 (R-Car H2) IPMMU.
> >  - "renesas,ipmmu-r8a7791" for the R8A7791 (R-Car M2-W) IPMMU.
> >  - "renesas,ipmmu-r8a7793" for the R8A7793 (R-Car M2-N) IPMMU.
> >  - "renesas,ipmmu-r8a7794" for the R8A7794 (R-Car E2) IPMMU.
> >  - "renesas,ipmmu-r8a7795" for the R8A7795 (R-Car H3) IPMMU.
> > -- "renesas,ipmmu-vmsa" for generic R-Car Gen2 VMSA-compatible IPMMU.
> > +- "renesas,ipmmu-vmsa" for generic R-Car Gen2 or RZ/G1 VMSA-compatible
> > +   IPMMU.
> >
> >- reg: Base address and size of the IPMMU registers.
> >- interrupts: Specifiers for the MMU fault interrupts. For instances that
> > --
> > 2.7.4
> 
> 
> 
> 
> Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, 
> Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered 
> No. 04586709.
>