Re: [PATCH] imx.rst: fix typo

2018-03-13 Thread Steve Longerbeam

Acked-by: Steve Longerbeam 


On 03/13/2018 11:29 AM, Hans Verkuil wrote:

Multpiple -> Multiple

Signed-off-by: Hans Verkuil 
---
diff --git a/Documentation/media/v4l-drivers/imx.rst 
b/Documentation/media/v4l-drivers/imx.rst
index 18e3141304bb..65d3d15eb159 100644
--- a/Documentation/media/v4l-drivers/imx.rst
+++ b/Documentation/media/v4l-drivers/imx.rst
@@ -109,7 +109,7 @@ imx6-mipi-csi2
  This is the MIPI CSI-2 receiver entity. It has one sink pad to receive
  the MIPI CSI-2 stream (usually from a MIPI CSI-2 camera sensor). It has
  four source pads, corresponding to the four MIPI CSI-2 demuxed virtual
-channel outputs. Multpiple source pads can be enabled to independently
+channel outputs. Multiple source pads can be enabled to independently
  stream from multiple virtual channels.

  This entity actually consists of two sub-blocks. One is the MIPI CSI-2




[PATCH] pixfmt-v4l2.rst: fix broken enum :c:type:

2018-03-13 Thread Hans Verkuil
:c:type:: -> :c:type:

Signed-off-by: Hans Verkuil 
---
diff --git a/Documentation/media/uapi/v4l/pixfmt-v4l2.rst 
b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst
index 2ee164c25637..6622938c1b41 100644
--- a/Documentation/media/uapi/v4l/pixfmt-v4l2.rst
+++ b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst
@@ -40,7 +40,7 @@ Single-planar format structure
RGB formats in :ref:`rgb-formats`, YUV formats in
:ref:`yuv-formats`, and reserved codes in
:ref:`reserved-formats`
-* - enum :c:type::`v4l2_field`
+* - enum :c:type:`v4l2_field`
   - ``field``
   - Video images are typically interlaced. Applications can request to
capture or output only the top or bottom field, or both fields


Re: [PATCH 1/3] rcar-vin: remove duplicated check of state in irq handler

2018-03-13 Thread Hans Verkuil
On 03/09/2018 04:09 PM, Niklas Söderlund wrote:
> This is an error from when the driver where converted from soc-camera.

where -> was

> There is absolutely no gain to check the state variable two times to be
> extra sure if the hardware is stopped.

I'll wait for v2 before applying this.

Regards,

Hans

> 
> Signed-off-by: Niklas Söderlund 
> ---
>  drivers/media/platform/rcar-vin/rcar-dma.c | 6 --
>  1 file changed, 6 deletions(-)
> 
> diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
> b/drivers/media/platform/rcar-vin/rcar-dma.c
> index 23fdff7a7370842e..b4be75d5009080f7 100644
> --- a/drivers/media/platform/rcar-vin/rcar-dma.c
> +++ b/drivers/media/platform/rcar-vin/rcar-dma.c
> @@ -916,12 +916,6 @@ static irqreturn_t rvin_irq(int irq, void *data)
>   rvin_ack_interrupt(vin);
>   handled = 1;
>  
> - /* Nothing to do if capture status is 'STOPPED' */
> - if (vin->state == STOPPED) {
> - vin_dbg(vin, "IRQ while state stopped\n");
> - goto done;
> - }
> -
>   /* Nothing to do if capture status is 'STOPPING' */
>   if (vin->state == STOPPING) {
>   vin_dbg(vin, "IRQ while state stopping\n");
> 



[PATCH] imx.rst: fix typo

2018-03-13 Thread Hans Verkuil
Multpiple -> Multiple

Signed-off-by: Hans Verkuil 
---
diff --git a/Documentation/media/v4l-drivers/imx.rst 
b/Documentation/media/v4l-drivers/imx.rst
index 18e3141304bb..65d3d15eb159 100644
--- a/Documentation/media/v4l-drivers/imx.rst
+++ b/Documentation/media/v4l-drivers/imx.rst
@@ -109,7 +109,7 @@ imx6-mipi-csi2
 This is the MIPI CSI-2 receiver entity. It has one sink pad to receive
 the MIPI CSI-2 stream (usually from a MIPI CSI-2 camera sensor). It has
 four source pads, corresponding to the four MIPI CSI-2 demuxed virtual
-channel outputs. Multpiple source pads can be enabled to independently
+channel outputs. Multiple source pads can be enabled to independently
 stream from multiple virtual channels.

 This entity actually consists of two sub-blocks. One is the MIPI CSI-2


Re: [PATCH 3/3] rcar-vin: use scratch buffer and always run in continuous mode

2018-03-13 Thread Hans Verkuil
On 03/09/2018 04:09 PM, Niklas Söderlund wrote:
> Instead of switching capture mode depending on how many buffers are
> available use a scratch buffer and always run in continuous mode. By
> using a scratch buffer the responsiveness of the capture loop is
> increased as it can keep running even if there are no buffers available
> from userspace.
> 
> As soon as a userspace queues a buffer it is inserted into the capture
> loop and returned as soon as it is filled. This is a improvement on the
> previous logic where the whole capture loop was stopped and switched to
> single capture mode if userspace did not feed the VIN driver buffers at
> the same time it consumed them. To make matters worse it was difficult
> for the driver to reenter continues mode if it entered single mode even

continues -> continuous

> if userspace started to queue buffers faster. This resulted in
> suboptimal performance where if userspace where delayed for a short
> period the ongoing capture would be slowed down and run in single mode
> until the capturing process where restarted.
> 
> An additional effect of this change is that the capture logic can be
> made much simple as we know that continues mode will always be used.

ditto

> 
> Signed-off-by: Niklas Söderlund 
> ---
>  drivers/media/platform/rcar-vin/rcar-dma.c | 187 
> -
>  drivers/media/platform/rcar-vin/rcar-vin.h |   6 +-
>  2 files changed, 52 insertions(+), 141 deletions(-)
> 
> diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
> b/drivers/media/platform/rcar-vin/rcar-dma.c
> index 8ea73cdc9a720abe..208cf8a0ea77002d 100644
> --- a/drivers/media/platform/rcar-vin/rcar-dma.c
> +++ b/drivers/media/platform/rcar-vin/rcar-dma.c
> @@ -168,12 +168,8 @@ static int rvin_setup(struct rvin_dev *vin)
>   break;
>   case V4L2_FIELD_ALTERNATE:
>   case V4L2_FIELD_NONE:
> - if (vin->continuous) {
> - vnmc = VNMC_IM_ODD_EVEN;
> - progressive = true;
> - } else {
> - vnmc = VNMC_IM_ODD;
> - }
> + vnmc = VNMC_IM_ODD_EVEN;
> + progressive = true;
>   break;
>   default:
>   vnmc = VNMC_IM_ODD;
> @@ -298,14 +294,6 @@ static bool rvin_capture_active(struct rvin_dev *vin)
>   return rvin_read(vin, VNMS_REG) & VNMS_CA;
>  }
>  
> -static int rvin_get_active_slot(struct rvin_dev *vin, u32 vnms)
> -{
> - if (vin->continuous)
> - return (vnms & VNMS_FBS_MASK) >> VNMS_FBS_SHIFT;
> -
> - return 0;
> -}
> -
>  static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms)
>  {
>   if (vin->format.field == V4L2_FIELD_ALTERNATE) {
> @@ -344,76 +332,47 @@ static void rvin_set_slot_addr(struct rvin_dev *vin, 
> int slot, dma_addr_t addr)
>   rvin_write(vin, offset, VNMB_REG(slot));
>  }
>  
> -/* Moves a buffer from the queue to the HW slots */
> -static bool rvin_fill_hw_slot(struct rvin_dev *vin, int slot)
> +/*
> + * Moves a buffer from the queue to the HW slot. If no buffer is
> + * available use the scratch buffer. The scratch buffer is never
> + * returned to userspace, its only function is to enable the capture
> + * loop to keep running.
> + */
> +static void rvin_fill_hw_slot(struct rvin_dev *vin, int slot)
>  {
>   struct rvin_buffer *buf;
>   struct vb2_v4l2_buffer *vbuf;
> - dma_addr_t phys_addr_top;
> -
> - if (vin->queue_buf[slot] != NULL)
> - return true;
> + dma_addr_t phys_addr;
>  
> - if (list_empty(>buf_list))
> - return false;
> + /* A already populated slot shall never be overwritten. */
> + if (WARN_ON(vin->queue_buf[slot] != NULL))
> + return;
>  
>   vin_dbg(vin, "Filling HW slot: %d\n", slot);
>  
> - /* Keep track of buffer we give to HW */
> - buf = list_entry(vin->buf_list.next, struct rvin_buffer, list);
> - vbuf = >vb;
> - list_del_init(to_buf_list(vbuf));
> - vin->queue_buf[slot] = vbuf;
> -
> - /* Setup DMA */
> - phys_addr_top = vb2_dma_contig_plane_dma_addr(>vb2_buf, 0);
> - rvin_set_slot_addr(vin, slot, phys_addr_top);
> -
> - return true;
> -}
> -
> -static bool rvin_fill_hw(struct rvin_dev *vin)
> -{
> - int slot, limit;
> -
> - limit = vin->continuous ? HW_BUFFER_NUM : 1;
> -
> - for (slot = 0; slot < limit; slot++)
> - if (!rvin_fill_hw_slot(vin, slot))
> - return false;
> - return true;
> -}
> -
> -static void rvin_capture_on(struct rvin_dev *vin)
> -{
> - vin_dbg(vin, "Capture on in %s mode\n",
> - vin->continuous ? "continuous" : "single");
> + if (list_empty(>buf_list)) {
> + vin->queue_buf[slot] = NULL;
> + phys_addr = vin->scratch_phys;
> + } else {
> + /* Keep track of buffer we give to HW */
> + buf = list_entry(vin->buf_list.next, struct 

[PATCH] media: staging/imx: fill vb2_v4l2_buffer sequence entry

2018-03-13 Thread Peter Seiderer
Signed-off-by: Peter Seiderer 
---
 drivers/staging/media/imx/imx-media-csi.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index 5a195f80a24d..3a6a645b9dce 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -111,6 +111,7 @@ struct csi_priv {
struct v4l2_ctrl_handler ctrl_hdlr;
 
int stream_count; /* streaming counter */
+   __u32 frame_sequence; /* frame sequence counter */
bool last_eof;   /* waiting for last EOF at stream off */
bool nfb4eof;/* NFB4EOF encountered during streaming */
struct completion last_eof_comp;
@@ -234,8 +235,11 @@ static void csi_vb2_buf_done(struct csi_priv *priv)
struct vb2_buffer *vb;
dma_addr_t phys;
 
+   priv->frame_sequence++;
+
done = priv->active_vb2_buf[priv->ipu_buf_num];
if (done) {
+   done->vbuf.sequence = priv->frame_sequence;
vb = >vbuf.vb2_buf;
vb->timestamp = ktime_get_ns();
vb2_buffer_done(vb, priv->nfb4eof ?
@@ -543,6 +547,7 @@ static int csi_idmac_start(struct csi_priv *priv)
 
/* init EOF completion waitq */
init_completion(>last_eof_comp);
+   priv->frame_sequence = 0;
priv->last_eof = false;
priv->nfb4eof = false;
 
-- 
2.16.2



[GIT PULL for 4.17] Pile of atomisp patches

2018-03-13 Thread Sakari Ailus
Hi Mauro,

Here's the usual pile of atomisp driver patches. Along with the usual
cleanups, there's a fix that disables atomisp_compat_ioctl32 as well.


The following changes since commit 3f127ce11353fd1071cae9b65bc13add6aec6b90:

  media: em28xx-cards: fix em28xx_duplicate_dev() (2018-03-08 06:06:51 -0500)

are available in the git repository at:

  ssh://linuxtv.org/git/sailus/media_tree.git atomisp

for you to fetch changes up to f105c0b9eae0646ed6d05e6a56a29bb1461e6b9f:

  staging: media: Replace "cant" with "can't" (2018-03-09 10:56:05 +0200)


Alona Solntseva (1):
  drivers: staging: media: atomisp: pci: atomisp2: css2400: fix misspellings

Arnd Bergmann (1):
  staging: media: atomisp: remove pointless string copy

Arushi Singhal (1):
  staging: media: Replace "cant" with "can't"

Colin Ian King (1):
  media: staging: atomisp: remove redundant assignments to various variables

Corentin Labbe (3):
  staging: media: remove remains of VIDEO_ATOMISP_OV8858
  staging: media: atomisp2: remove unused headers
  staging: media: atomisp: Remove inclusion of non-existing directories

Hans Verkuil (1):
  atomisp_fops.c: disable atomisp_compat_ioctl32

Jeremy Sowden (1):
  media: atomisp: convert default struct values to use compound-literals 
with designated initializers.

 drivers/staging/media/atomisp/i2c/Kconfig  |   12 -
 .../media/atomisp/i2c/ov5693/atomisp-ov5693.c  |2 +-
 drivers/staging/media/atomisp/i2c/ov8858.c | 2169 
 drivers/staging/media/atomisp/i2c/ov8858.h | 1474 -
 drivers/staging/media/atomisp/i2c/ov8858_btns.h| 1276 
 .../media/atomisp/include/linux/vlv2_plat_clock.h  |   30 -
 .../staging/media/atomisp/pci/atomisp2/Makefile|   10 -
 .../media/atomisp/pci/atomisp2/atomisp_cmd.c   |2 +-
 .../atomisp/pci/atomisp2/atomisp_compat_css20.c|2 +-
 .../media/atomisp/pci/atomisp2/atomisp_fops.c  |6 +
 .../media/atomisp/pci/atomisp2/atomisp_v4l2.c  |1 -
 .../css2400/css_2400_system/hrt/gp_regs_defs.h |   22 -
 .../atomisp2/css2400/css_2400_system/hrt/sp_hrt.h  |   24 -
 .../css_2401_csi2p_system/hrt/gp_regs_defs.h   |   22 -
 .../css2400/css_2401_csi2p_system/hrt/sp_hrt.h |   24 -
 .../css2400/css_2401_system/hrt/gp_regs_defs.h |   22 -
 .../atomisp2/css2400/css_2401_system/hrt/sp_hrt.h  |   24 -
 .../atomisp/pci/atomisp2/css2400/css_api_version.h |  673 --
 .../host/hive_isp_css_ddr_hrt_modified.h   |  148 --
 .../host/hive_isp_css_hrt_modified.h   |   79 -
 .../hive_isp_css_common/input_formatter_global.h   |   16 -
 .../css2400/hive_isp_css_common/resource_global.h  |   35 -
 .../css2400/hive_isp_css_common/xmem_global.h  |   20 -
 .../atomisp2/css2400/hive_isp_css_include/bamem.h  |   46 -
 .../css2400/hive_isp_css_include/bbb_config.h  |   27 -
 .../css2400/hive_isp_css_include/cpu_mem_support.h |   59 -
 .../hive_isp_css_include/host/isp2400_config.h |   24 -
 .../hive_isp_css_include/host/isp2500_config.h |   29 -
 .../hive_isp_css_include/host/isp2600_config.h |   34 -
 .../hive_isp_css_include/host/isp2601_config.h |   70 -
 .../css2400/hive_isp_css_include/host/isp_config.h |   24 -
 .../css2400/hive_isp_css_include/host/isp_op1w.h   |  844 
 .../hive_isp_css_include/host/isp_op1w_types.h |   54 -
 .../css2400/hive_isp_css_include/host/isp_op2w.h   |  674 --
 .../hive_isp_css_include/host/isp_op2w_types.h |   49 -
 .../hive_isp_css_include/host/isp_op_count.h   |  226 --
 .../hive_isp_css_include/host/osys_public.h|   20 -
 .../hive_isp_css_include/host/pipeline_public.h|   18 -
 .../hive_isp_css_include/host/ref_vector_func.h| 1221 ---
 .../host/ref_vector_func_types.h   |  385 
 .../atomisp2/css2400/hive_isp_css_include/mpmath.h |  329 ---
 .../atomisp2/css2400/hive_isp_css_include/osys.h   |   47 -
 .../css2400/hive_isp_css_include/stream_buffer.h   |   47 -
 .../css2400/hive_isp_css_include/vector_func.h |   38 -
 .../css2400/hive_isp_css_include/vector_ops.h  |   31 -
 .../atomisp2/css2400/hive_isp_css_include/xmem.h   |   46 -
 .../css2400/hive_isp_css_shared/socket_global.h|   53 -
 .../hive_isp_css_shared/stream_buffer_global.h |   26 -
 .../pci/atomisp2/css2400/ia_css_frame_public.h |   29 +-
 .../atomisp/pci/atomisp2/css2400/ia_css_pipe.h |  113 +-
 .../pci/atomisp2/css2400/ia_css_pipe_public.h  |  108 +-
 .../atomisp/pci/atomisp2/css2400/ia_css_types.h|   64 +-
 .../css2400/isp/kernels/aa/aa_2/ia_css_aa2_state.h |   41 -
 .../bayer_ls_1.0/ia_css_bayer_load_param.h |   20 -
 .../bayer_ls/bayer_ls_1.0/ia_css_bayer_ls_param.h  |   42 -
 .../bayer_ls_1.0/ia_css_bayer_store_param.h|   21 -
 .../css2400/isp/kernels/bnlm/ia_css_bnlm_state.h   |   31 -
 .../isp/kernels/cnr/cnr_1.0/ia_css_cnr_state.h

RE: [PATCH 02/11] media: vsp1: use kernel __packed for structures

2018-03-13 Thread David Laight
From: Kieran Bingham
> Sent: 09 March 2018 22:04
> The kernel provides a __packed definition to abstract away from the
> compiler specific attributes tag.
> 
> Convert all packed structures in VSP1 to use it.
> 
> Signed-off-by: Kieran Bingham 
> ---
>  drivers/media/platform/vsp1/vsp1_dl.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
> b/drivers/media/platform/vsp1/vsp1_dl.c
> index 37e2c984fbf3..382e45c2054e 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -29,19 +29,19 @@
>  struct vsp1_dl_header_list {
>   u32 num_bytes;
>   u32 addr;
> -} __attribute__((__packed__));
> +} __packed;
> 
>  struct vsp1_dl_header {
>   u32 num_lists;
>   struct vsp1_dl_header_list lists[8];
>   u32 next_header;
>   u32 flags;
> -} __attribute__((__packed__));
> +} __packed;
> 
>  struct vsp1_dl_entry {
>   u32 addr;
>   u32 data;
> -} __attribute__((__packed__));
> +} __packed;

Do these structures ever actually appear in misaligned memory?
If they don't then they shouldn't be marked 'packed'.

David



Re: [RFCv4,19/21] media: vim2m: add request support

2018-03-13 Thread Alexandre Courbot
On Fri, Mar 9, 2018 at 11:35 PM, Paul Kocialkowski
 wrote:
> Hi,
>
> On Thu, 2018-03-08 at 22:48 +0900, Alexandre Courbot wrote:
>> Hi Paul!
>>
>> Thanks a lot for taking the time to try this! I am also working on
>> getting it to work with an actual driver, but you apparently found
>> rough edges that I missed.
>>
>> On Thu, Mar 8, 2018 at 1:37 AM, Paul Kocialkowski
>>  wrote:
>> > Hi,
>> >
>> > First off, I'd like to take the occasion to say thank-you for your
>> > work.
>> > This is a major piece of plumbing that is required for me to add
>> > support
>> > for the Allwinner CedarX VPU hardware in upstream Linux. Other
>> > drivers,
>> > such as tegra-vde (that was recently merged in staging) are also
>> > badly
>> > in need of this API.
>> >
>> > I have a few comments based on my experience integrating this
>> > request
>> > API with the Cedrus VPU driver (and the associated libva backend),
>> > that
>> > also concern the vim2m driver.
>> >
>> > On Tue, 2018-02-20 at 13:44 +0900, Alexandre Courbot wrote:
>> > > Set the necessary ops for supporting requests in vim2m.
>> > >
>> > > Signed-off-by: Alexandre Courbot 
>> > > ---
>> > >  drivers/media/platform/Kconfig |  1 +
>> > >  drivers/media/platform/vim2m.c | 75
>> > > ++
>> > >  2 files changed, 76 insertions(+)
>> > >
>> > > diff --git a/drivers/media/platform/Kconfig
>> > > b/drivers/media/platform/Kconfig
>> > > index 614fbef08ddc..09be0b5f9afe 100644
>> > > --- a/drivers/media/platform/Kconfig
>> > > +++ b/drivers/media/platform/Kconfig
>> >
>> > [...]
>> >
>> > > +static int vim2m_request_submit(struct media_request *req,
>> > > + struct media_request_entity_data
>> > > *_data)
>> > > +{
>> > > + struct v4l2_request_entity_data *data;
>> > > +
>> > > + data = to_v4l2_entity_data(_data);
>> >
>> > We need to call v4l2_m2m_try_schedule here so that m2m scheduling
>> > can
>> > happen when only 2 buffers were queued and no other action was taken
>> > from usespace. In that scenario, m2m scheduling currently doesn't
>> > happen.
>>
>> I don't think I understand the sequence of events that results in
>> v4l2_m2m_try_schedule() not being called. Do you mean something like:
>>
>> *
>> * QBUF on output queue with request set
>> * QBUF on capture queue
>> * SUBMIT_REQUEST
>>
>> ?
>>
>> The call to vb2_request_submit() right after should trigger
>> v4l2_m2m_try_schedule(), since the buffers associated to the request
>> will enter the vb2 queue and be passed to the m2m framework, which
>> will then call v4l2_m2m_try_schedule(). Or maybe you are thinking
>> about a different sequence of events?
>
> This is indeed the sequence of events that I'm seeing, but the
> scheduling call simply did not happen on vb2_request_submit. I suppose I will 
> need to investigate some more to find out exactly why.
>
> IIRC, the m2m qbuf function is called (and fails to schedule) when the
> ioctl happens, not when the task is submitted.
>
> This issue is seen with vim2m as well as the rencently-submitted sunxi-
> cedrus driver (with the in-driver calls to v4l2_m2m_try_schedule
> removed, obviously). If needs be, I could provide a standalone test
> program to reproduce it.

If you have a standalone program that can reproduce this on vim2m,
then I would like to see it indeed, if only to understand what I have
missed.

Thanks,
Alex.


[PATCH v3 0/2] media: Introduce Omnivision OV2680 driver

2018-03-13 Thread Rui Miguel Silva
Add driver and bindings for the OV2680 2 megapixel CMOS 1/5" sensor, which has
a single MIPI lane interface and output format of 10-bit Raw RGB.

Features supported are described in PATCH 2/2.

v2->v3:
Rob Herring:
- add Reviewed-by tag to dts PATCH 1/1

Sakari Ailus:
- align register values with bracket
- redone the {write|read}_reg i2c functions
- add bayer order handling with flip and mirror controls
- fix error path in probe release resources
- remove i2c_device_id and use probe_new

Myself:
- remove ; at the end of macros

v1->v2:
Fabio Estevam:
- s/OV5640/OV2680 in PATCH 1/2 changelog

Sakari Ailus:
- add description on endpoint properties in bindings
- add single endpoint in bindings
- drop OF dependency
- cleanup includes
- fix case in Color Bars
- remove frame rate selection
- 8/16/24 bit register access in the same transaction
- merge _reset and _soft_reset to _enable and rename it to power_on 
- _gain_set use only the gain value (drop & 0x7ff)
- _gain_get remove the (0x377)
- single write/read at _exposure_set/get use write_reg24/read_reg24
- move mode_set_direct to _mode_set
- _mode_set set auto exposure/gain based on ctrl value
- s_frame_interval equal to g_frame_interval
- use closest match from: v4l: common: Add a function to obtain best size 
from a list 
- check v4l2_ctrl_new_std return in _init

- fix gain manual value in auto_cluster

Cheers,
Rui

Rui Miguel Silva (2):
  media: ov2680: dt: Add bindings for OV2680
  media: ov2680: Add Omnivision OV2680 sensor driver

 .../devicetree/bindings/media/i2c/ov2680.txt   |   40 +
 drivers/media/i2c/Kconfig  |   12 +
 drivers/media/i2c/Makefile |1 +
 drivers/media/i2c/ov2680.c | 1130 
 4 files changed, 1183 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ov2680.txt
 create mode 100644 drivers/media/i2c/ov2680.c

-- 
2.16.2



[PATCH v3 1/2] media: ov2680: dt: Add bindings for OV2680

2018-03-13 Thread Rui Miguel Silva
Add device tree binding documentation for the OV2680 camera sensor.

Reviewed-by: Rob Herring 
CC: devicet...@vger.kernel.org
Signed-off-by: Rui Miguel Silva 
---
 .../devicetree/bindings/media/i2c/ov2680.txt   | 40 ++
 1 file changed, 40 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ov2680.txt

diff --git a/Documentation/devicetree/bindings/media/i2c/ov2680.txt 
b/Documentation/devicetree/bindings/media/i2c/ov2680.txt
new file mode 100644
index ..0e29f1a113c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/ov2680.txt
@@ -0,0 +1,40 @@
+* Omnivision OV2680 MIPI CSI-2 sensor
+
+Required Properties:
+- compatible: should be "ovti,ov2680".
+- clocks: reference to the xvclk input clock.
+- clock-names: should be "xvclk".
+
+Optional Properties:
+- powerdown-gpios: reference to the GPIO connected to the powerdown pin,
+if any. This is an active high signal to the OV2680.
+
+The device node must contain one 'port' child node for its digital output
+video port, and this port must have a single endpoint in accordance with
+ the video interface bindings defined in
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Endpoint node required properties for CSI-2 connection are:
+- remote-endpoint: a phandle to the bus receiver's endpoint node.
+- clock-lanes: should be set to <0> (clock lane on hardware lane 0).
+- data-lanes: should be set to <1> (one CSI-2 lane supported).
+ 
+Example:
+
+ {
+   ov2680: camera-sensor@36 {
+   compatible = "ovti,ov2680";
+   reg = <0x36>;
+   clocks = <>;
+   clock-names = "xvclk";
+   powerdown-gpios = < 3 GPIO_ACTIVE_HIGH>;
+
+   port {
+   ov2680_mipi_ep: endpoint {
+   remote-endpoint = <_sensor_ep>;
+   clock-lanes = <0>;
+   data-lanes = <1>;
+   };
+   };
+   };
+};
-- 
2.16.2



Re: [PATCH] media: omap3isp: fix unbalanced dma_iommu_mapping

2018-03-13 Thread Sakari Ailus
Hi Suman,

Thanks for the patch.

On Mon, Mar 12, 2018 at 11:52:07AM -0500, Suman Anna wrote:
> The OMAP3 ISP driver manages its MMU mappings through the IOMMU-aware
> ARM DMA backend. The current code creates a dma_iommu_mapping and
> attaches this to the ISP device, but never detaches the mapping in
> either the probe failure paths or the driver remove path resulting
> in an unbalanced mapping refcount and a memory leak. Fix this properly.
> 
> Reported-by: Pavel Machek 
> Signed-off-by: Suman Anna 
> Tested-by: Pavel Machek 
> ---
> Hi Mauro, Laurent,
> 
> This fixes an issue reported by Pavel and discussed on this
> thread,
> https://marc.info/?l=linux-omap=152051945803598=2
> 
> Posting this again to the appropriate lists.
> 
> regards
> Suman
> 
>  drivers/media/platform/omap3isp/isp.c | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/omap3isp/isp.c 
> b/drivers/media/platform/omap3isp/isp.c
> index 8eb000e3d8fd..c7d667bfc2af 100644
> --- a/drivers/media/platform/omap3isp/isp.c
> +++ b/drivers/media/platform/omap3isp/isp.c
> @@ -1945,6 +1945,7 @@ static int isp_initialize_modules(struct isp_device 
> *isp)
>  
>  static void isp_detach_iommu(struct isp_device *isp)
>  {
> + arm_iommu_detach_device(isp->dev);
>   arm_iommu_release_mapping(isp->mapping);
>   isp->mapping = NULL;
>  }
> @@ -1971,13 +1972,15 @@ static int isp_attach_iommu(struct isp_device *isp)
>   ret = arm_iommu_attach_device(isp->dev, mapping);
>   if (ret < 0) {
>   dev_err(isp->dev, "failed to attach device to VA mapping\n");
> - goto error;
> + goto error_attach;

Instead of changing the label here, could you return immediately where the
previous point of error handling is? No need to add another label.

After fixing that you can add:

Acked-by: Sakari Ailus 

>   }
>  
>   return 0;
>  
> +error_attach:
> + arm_iommu_release_mapping(isp->mapping);
> + isp->mapping = NULL;
>  error:
> - isp_detach_iommu(isp);
>   return ret;
>  }
>  
> 

-- 
Sakari Ailus
e-mail: sakari.ai...@iki.fi


[PATCH v3 2/2] media: ov2680: Add Omnivision OV2680 sensor driver

2018-03-13 Thread Rui Miguel Silva
This patch adds V4L2 sub-device driver for OV2680 image sensor.
The OV2680 is a 1/5" CMOS color sensor from Omnivision.
Supports output format: 10-bit Raw RGB.
The OV2680 has a single lane MIPI interface.

The driver exposes following V4L2 controls:
- auto/manual exposure,
- exposure,
- auto/manual gain,
- gain,
- horizontal/vertical flip,
- test pattern menu.
Supported resolution are only: QUXGA, 720P, UXGA.

Signed-off-by: Rui Miguel Silva 
---
 drivers/media/i2c/Kconfig  |   12 +
 drivers/media/i2c/Makefile |1 +
 drivers/media/i2c/ov2680.c | 1130 
 3 files changed, 1143 insertions(+)
 create mode 100644 drivers/media/i2c/ov2680.c

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 9f18cd296841..39dc9f236ffa 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -586,6 +586,18 @@ config VIDEO_OV2659
  To compile this driver as a module, choose M here: the
  module will be called ov2659.
 
+config VIDEO_OV2680
+   tristate "OmniVision OV2680 sensor support"
+   depends on GPIOLIB && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+   depends on MEDIA_CAMERA_SUPPORT
+   select V4L2_FWNODE
+   ---help---
+ This is a Video4Linux2 sensor-level driver for the OmniVision
+ OV2680 camera sensor with a MIPI CSI-2 interface.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ov2680.
+
 config VIDEO_OV5640
tristate "OmniVision OV5640 sensor support"
depends on OF
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index c0f94cd8d56d..d0aba4d37b8d 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o
 obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
 obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
 obj-$(CONFIG_VIDEO_OV2640) += ov2640.o
+obj-$(CONFIG_VIDEO_OV2680) += ov2680.o
 obj-$(CONFIG_VIDEO_OV5640) += ov5640.o
 obj-$(CONFIG_VIDEO_OV5645) += ov5645.o
 obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
new file mode 100644
index ..a17971ce71bc
--- /dev/null
+++ b/drivers/media/i2c/ov2680.c
@@ -0,0 +1,1130 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Omnivision OV2680 CMOS Image Sensor driver
+ *
+ * Copyright (C) 2018 Linaro Ltd
+ *
+ * Based on OV5640 Sensor Driver
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2014-2017 Mentor Graphics Inc.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define OV2680_XVCLK_MIN   600
+#define OV2680_XVCLK_MAX   2400
+
+#define OV2680_CHIP_ID 0x2680
+
+#define OV2680_REG_STREAM_CTRL 0x0100
+#define OV2680_REG_SOFT_RESET  0x0103
+
+#define OV2680_REG_CHIP_ID_HIGH0x300a
+#define OV2680_REG_CHIP_ID_LOW 0x300b
+
+#define OV2680_REG_R_MANUAL0x3503
+#define OV2680_REG_GAIN_PK 0x350a
+#define OV2680_REG_EXPOSURE_PK_HIGH0x3500
+#define OV2680_REG_TIMING_HTS  0x380c
+#define OV2680_REG_TIMING_VTS  0x380e
+#define OV2680_REG_FORMAT1 0x3820
+#define OV2680_REG_FORMAT2 0x3821
+
+#define OV2680_REG_ISP_CTRL00  0x5080
+
+#define OV2680_FRAME_RATE  30
+
+#define OV2680_REG_VALUE_8BIT  1
+#define OV2680_REG_VALUE_16BIT 2
+#define OV2680_REG_VALUE_24BIT 3
+
+enum ov2680_mode_id {
+   OV2680_MODE_QUXGA_800_600,
+   OV2680_MODE_720P_1280_720,
+   OV2680_MODE_UXGA_1600_1200,
+   OV2680_MODE_MAX,
+};
+
+struct reg_value {
+   u16 reg_addr;
+   u8 val;
+};
+
+struct ov2680_mode_info {
+   const char *name;
+   enum ov2680_mode_id id;
+   u32 width;
+   u32 height;
+   const struct reg_value *reg_data;
+   u32 reg_data_size;
+};
+
+struct ov2680_ctrls {
+   struct v4l2_ctrl_handler handler;
+   struct {
+   struct v4l2_ctrl *auto_exp;
+   struct v4l2_ctrl *exposure;
+   };
+   struct {
+   struct v4l2_ctrl *auto_gain;
+   struct v4l2_ctrl *gain;
+   };
+
+   struct v4l2_ctrl *hflip;
+   struct v4l2_ctrl *vflip;
+   struct v4l2_ctrl *test_pattern;
+};
+
+struct ov2680_dev {
+   struct i2c_client   *i2c_client;
+   struct v4l2_subdev  sd;
+
+   struct media_padpad;
+   struct clk  *xvclk;
+   u32 xvclk_freq;
+
+   struct gpio_desc*pwdn_gpio;
+   struct mutexlock; /* protect members */
+
+   boolmode_pending_changes;
+   boolis_enabled;
+   bool   

Re: [PATCH 02/11] media: vsp1: use kernel __packed for structures

2018-03-13 Thread Kieran Bingham
Hi David,

On 13/03/18 11:20, David Laight wrote:
> From: Kieran Bingham
>> Sent: 09 March 2018 22:04
>> The kernel provides a __packed definition to abstract away from the
>> compiler specific attributes tag.
>>
>> Convert all packed structures in VSP1 to use it.
>>
>> Signed-off-by: Kieran Bingham 
>> ---
>>  drivers/media/platform/vsp1/vsp1_dl.c | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
>> b/drivers/media/platform/vsp1/vsp1_dl.c
>> index 37e2c984fbf3..382e45c2054e 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -29,19 +29,19 @@
>>  struct vsp1_dl_header_list {
>>  u32 num_bytes;
>>  u32 addr;
>> -} __attribute__((__packed__));
>> +} __packed;
>>
>>  struct vsp1_dl_header {
>>  u32 num_lists;
>>  struct vsp1_dl_header_list lists[8];
>>  u32 next_header;
>>  u32 flags;
>> -} __attribute__((__packed__));
>> +} __packed;
>>
>>  struct vsp1_dl_entry {
>>  u32 addr;
>>  u32 data;
>> -} __attribute__((__packed__));
>> +} __packed;
> 
> Do these structures ever actually appear in misaligned memory?
> If they don't then they shouldn't be marked 'packed'.

I believe the declaration is to ensure that the struct definition is not altered
by the compiler as these structures specifically define the layout of how the
memory is read by the VSP1 hardware.

Certainly 2 u32's sequentially stored in a struct are unlikely to be moved or
rearranged by the compiler (though I believe it would be free to do so if it
chose without this attribute), but I think the declaration shows the intent of
the memory structure.

Isn't this a common approach throughout the kernel when dealing with hardware
defined memory structures ?

Regards
--
Kieran


> 
>   David
> 


Re: [PATCH v8 13/13] [media] v4l: Document explicit synchronization behavior

2018-03-13 Thread jacopo mondi
Hi Gustavo,
  a very small comment below

On Fri, Mar 09, 2018 at 02:49:20PM -0300, Gustavo Padovan wrote:
> From: Gustavo Padovan 
>
> Add section to VIDIOC_QBUF and VIDIOC_QUERY_BUF about it
>
> v6:   - Close some gaps in the docs (Hans)
>
> v5:
>   - Remove V4L2_CAP_ORDERED
>   - Add doc about V4L2_FMT_FLAG_UNORDERED
>
> v4:
>   - Document ordering behavior for in-fences
>   - Document V4L2_CAP_ORDERED capability
>   - Remove doc about OUT_FENCE event
>   - Document immediate return of out-fence in QBUF
>
> v3:
>   - make the out_fence refer to the current buffer (Hans)
>   - Note what happens when the IN_FENCE is not set (Hans)
>
> v2:
>   - mention that fences are files (Hans)
>   - rework for the new API
>
> Signed-off-by: Gustavo Padovan 
> ---
>  Documentation/media/uapi/v4l/vidioc-qbuf.rst | 55 
> +++-
>  Documentation/media/uapi/v4l/vidioc-querybuf.rst | 12 --
>  2 files changed, 63 insertions(+), 4 deletions(-)
>
[snip]
> +Note the the same `fence_fd` field is used for both sending the in-fence as
> +input argument to receive the out-fence as a return argument. A buffer can
> +have both in-fence ond out-fence.

I feel like an "and" is missing here...

 the same `fence_fd` field is used for both sending the in-fence as
 input argument to receive the out-fence as a return argument

 the same `fence_fd` field is used for both sending the in-fence as
 input argument *and* to receive the out-fence as a return argument

I'm not a native speaker so I might be wrong though.

Thanks
   j


signature.asc
Description: PGP signature


[PATCH] media: s5p-mfc: Use real device for request_firmware() call

2018-03-13 Thread Marek Szyprowski
Provide proper (real) struct device to request_firmware() call. This fixes
following error messages:

(NULL device *): Direct firmware load for s5p-mfc-v6-v2.fw failed with error -2
(NULL device *): Direct firmware load for s5p-mfc-v6.fw failed with error -2

into a bit more meaningful ones:

s5p-mfc 1100.codec: Direct firmware load for s5p-mfc-v6-v2.fw failed with 
error -2
s5p-mfc 1100.codec: Direct firmware load for s5p-mfc-v6.fw failed with 
error -2

Signed-off-by: Marek Szyprowski 
---
 drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c 
b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
index f95cd76af537..ef9ae969d307 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
@@ -62,7 +62,7 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
if (!dev->variant->fw_name[i])
continue;
err = request_firmware((const struct firmware **)_blob,
-   dev->variant->fw_name[i], dev->v4l2_dev.dev);
+   dev->variant->fw_name[i], >plat_dev->dev);
if (!err) {
dev->fw_ver = (enum s5p_mfc_fw_ver) i;
break;
-- 
2.15.0



Re: [PATCH 09/11] media: vsp1: Provide support for extended command pools

2018-03-13 Thread Kieran Bingham
Hi Jacopo,

On 12/03/18 16:30, jacopo mondi wrote:
> Hi Kieran,
> just one small thing I noticed below...
> 
> On Fri, Mar 09, 2018 at 10:04:07PM +, Kieran Bingham wrote:
>> VSPD and VSP-DL devices can provide extended display lists supporting
>> extended command display list objects.
>>
>> These extended commands require their own dma memory areas for a header
>> and body specific to the command type.
>>
>> Implement a command pool to allocate all necessary memory in a single
>> DMA allocation to reduce pressure on the TLB, and provide convenvient
>> re-usable command objects for the entities to utilise.
>>
>> Signed-off-by: Kieran Bingham 
>> ---
>>  drivers/media/platform/vsp1/vsp1_dl.c | 189 +++-
>>  drivers/media/platform/vsp1/vsp1_dl.h |   3 +-
>>  2 files changed, 192 insertions(+)
>>
>> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
>> b/drivers/media/platform/vsp1/vsp1_dl.c
>> index 36440a2a2c8b..6d17b8bfa21c 100644
>> --- a/drivers/media/platform/vsp1/vsp1_dl.c
>> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
>> @@ -121,6 +121,30 @@ struct vsp1_dl_body_pool {
>>  };
>>
>>  /**
>> + * struct vsp1_cmd_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_cmd_pool {
>> +/* DMA allocation */
>> +dma_addr_t dma;
>> +size_t size;
>> +void *mem;
>> +
>> +struct vsp1_dl_ext_cmd *cmds;
>> +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
>> @@ -176,6 +200,7 @@ struct vsp1_dl_manager {
>>  struct vsp1_dl_list *pending;
>>
>>  struct vsp1_dl_body_pool *pool;
>> +struct vsp1_dl_cmd_pool *autfld_cmds;
>>  };
>>
>>  /* 
>> -
>> @@ -339,6 +364,139 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 
>> reg, u32 data)
>>  }
>>
>>  /* 
>> -
>> + * Display List Extended Command Management
>> + */
>> +
>> +enum vsp1_extcmd_type {
>> +VSP1_EXTCMD_AUTODISP,
>> +VSP1_EXTCMD_AUTOFLD,
>> +};
>> +
>> +struct vsp1_extended_command_info {
>> +u16 opcode;
>> +size_t body_size;
>> +} vsp1_extended_commands[] = {
>> +[VSP1_EXTCMD_AUTODISP] = { 0x02, 96 },
>> +[VSP1_EXTCMD_AUTOFLD]  = { 0x03, 160 },
>> +};
> 
> How about making this one static and const, since it does not get
> modified?

Good spot. Certainly. This is just a static descriptor table of the extended
command parameter sizes, so it should not change.  (but could be added to in
later hardware operations I presume).

Cheers

Kieran


> 
> Thanks
>j
> 


Re: coda: i.MX6 decoding performance issues for multi-streaming

2018-03-13 Thread Philipp Zabel
Hi Javier,

On Mon, 2018-03-12 at 17:54 +0100, Javier Martin wrote:
> Hi,
> we have an i.MX6 Solo based board running the latest mainline kernel 
> (4.15.3).
> 
> As part of our development we were measuring the decoding performance of 
> the i.MX6 coda chip.
> 
> For that purpose we are feeding the decoder with 640x368 @ 30fps H.264 
> streams that have been generated by another i.MX6 coda encoder 
> configured with fixed qp = 25 and gopsize = 16.
> 
> For 1-2 streams it works smoothly. However, when adding the 3rd stream 
> the first decoder instance starts to output these kind of errors:
> 
> DEC_PIC_SUCCESS = 2097153  -> 0x21
> DEC_PIC_SUCCESS = 2621441  -> 0x280001

I think these might be (recoverable?) error flags, but so far I have
never seen them myself.
I've had reports of those occurring occasionally with certain streams
(not encoded by coda, regardless of the number of running decoder
instances) though.

What is the coda firmware version you are using?

regards
Philipp


[PATCH] venus: vdec: fix format enumeration

2018-03-13 Thread Alexandre Courbot
find_format_by_index() stops enumerating formats as soon as the index
matches, and returns NULL if venus_helper_check_codec() finds out that
the format is not supported. This prevents formats to be properly
enumerated if a non-supported format is present, as the enumeration will
end with it.

Fix this by moving the call to venus_helper_check_codec() into the loop,
and keep enumerating when it fails.

Signed-off-by: Alexandre Courbot 

Change-Id: I4ff66e0b85172598efa59a6f01da8cb60597a6a5
---
 drivers/media/platform/qcom/venus/vdec.c | 13 +++--
 drivers/media/platform/qcom/venus/venc.c |  9 +++--
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index c9e9576bb08a..3677302cfe43 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -135,20 +135,21 @@ find_format_by_index(struct venus_inst *inst, unsigned 
int index, u32 type)
return NULL;
 
for (i = 0; i < size; i++) {
+   bool valid;
+
if (fmt[i].type != type)
continue;
-   if (k == index)
+   valid = (type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
+venus_helper_check_codec(inst, fmt[i].pixfmt));
+   if (k == index && valid)
break;
-   k++;
+   if (valid)
+   k++;
}
 
if (i == size)
return NULL;
 
-   if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
-   !venus_helper_check_codec(inst, fmt[i].pixfmt))
-   return NULL;
-
return [i];
 }
 
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index e3a10a852cad..5eba4c7cd52e 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -120,11 +120,16 @@ find_format_by_index(struct venus_inst *inst, unsigned 
int index, u32 type)
return NULL;
 
for (i = 0; i < size; i++) {
+   bool valid;
+
if (fmt[i].type != type)
continue;
-   if (k == index)
+   valid = (type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
+venus_helper_check_codec(inst, fmt[i].pixfmt));
+   if (k == index && valid)
break;
-   k++;
+   if (valid)
+   k++;
}
 
if (i == size)
-- 
2.16.2.660.g709887971b-goog



Re: [PATCH] [media] mceusb: add IR learning support features (IR carrier frequency measurement and wide-band/short range receiver)

2018-03-13 Thread Sean Young
Hi,

On Sun, Mar 11, 2018 at 05:40:28AM -0400, A Sun wrote:
> 
> Windows Media Center IR transceivers include two IR receivers;
> wide-band/short-range and narrow-band/long-range. The short-range
> (5cm distance) receiver is for IR learning and has IR carrier
> frequency measuring ability.
> 
> Add mceusb driver support to select the short range IR receiver
> and enable pass through of its IR carrier frequency measurements.
> 
> RC and LIRC already support these mceusb driver additions.

That's great, this feature has been missing for a long time. 

I've tested it with my four mceusb devices, and I get carrier reports with
all of them. Please see the notes below.

> Test platform:
> 
> Linux raspberrypi 4.9.59-v7+ #1047 SMP Sun Oct 29 12:19:23 GMT 2017 armv7l 
> GNU/Linux
> mceusb 1-1.2:1.0: Registered Pinnacle Systems PCTV Remote USB with mce 
> emulator interface version 1
> mceusb 1-1.2:1.0: 2 tx ports (0x0 cabled) and 2 rx sensors (0x1 active)
> 
> Sony TV remote control
> 
> ir-ctl from v4l-utils
> 
> pi@raspberrypi:~ $ ir-ctl -V
> IR raw version 1.12.3
> pi@raspberrypi:~ $ ir-ctl -w -m -d /dev/lirc0 -r
> ...
> pulse 600
> space 600
> pulse 1250
> space 550
> pulse 650
> space 600
> pulse 550
> space 600
> pulse 600
> space 600
> pulse 650
> carrier 38803

Sony protocol remotes have a 4Hz carrier, and I am getting lower values
for the carrier with other carrier frequencies as well. Any idea why?

> space 16777215
> ^C
> pi@raspberrypi:~ $ exit
> 
> Signed-off-by: A Sun 
> ---
>  drivers/media/rc/mceusb.c | 90 
> ++-
>  1 file changed, 82 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
> index a9187b0b4..8bbb0f2da 100644
> --- a/drivers/media/rc/mceusb.c
> +++ b/drivers/media/rc/mceusb.c
> @@ -42,7 +42,7 @@
>  #include 
>  #include 
>  
> -#define DRIVER_VERSION   "1.93"
> +#define DRIVER_VERSION   "1.94"
>  #define DRIVER_AUTHOR"Jarod Wilson "
>  #define DRIVER_DESC  "Windows Media Center Ed. eHome Infrared Transceiver " \
>   "device driver"
> @@ -427,6 +427,7 @@ struct mceusb_dev {
>   struct rc_dev *rc;
>  
>   /* optional features we can enable */
> + bool carrier_report_enabled;
>   bool learning_enabled;
>  
>   /* core device bits */
> @@ -475,6 +476,9 @@ struct mceusb_dev {
>   u8 txports_cabled;  /* bitmask of transmitters with cable */
>   u8 rxports_active;  /* bitmask of active receive sensors */
>  
> + /* receiver carrier frequency detection support */
> + u32 pulse_tunit;/* IR pulse "on" cumulative time units */
> +
>   /*
>* support for async error handler mceusb_deferred_kevent()
>* where usb_clear_halt(), usb_reset_configuration(),
> @@ -956,12 +960,60 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, 
> u32 carrier)
>  }
>  
>  /*
> + * Select or deselect the 2nd receiver port.
> + * Second receiver is learning mode, wide-band, short-range receiver.
> + * Only one receiver (long or short range) may be active at a time.
> + */
> +static int mceusb_set_rx_wideband(struct rc_dev *dev, int enable)
> +{
> + struct mceusb_dev *ir = dev->priv;
> + unsigned char cmdbuf[3] = { MCE_CMD_PORT_IR,
> + MCE_CMD_SETIRRXPORTEN, 0x00 };
> +
> + if (enable != 0 && enable != 1)
> + return -EINVAL;
> +
> + /*
> +  * cmdbuf[2] is receiver port number
> +  * port 1 is long range receiver
> +  * port 2 is short range receiver
> +  */
> + cmdbuf[2] = enable + 1;

You could do enable ? 2 : 1 here and do away with the check above. Enable
always is 0 or 1 anyway.

> + dev_dbg(ir->dev, "select %s-range receive sensor",
> + enable ? "short" : "long");
> + mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
> +
> + return 0;
> +}
> +
> +/*
> + * Enable/disable receiver carrier frequency pass through reporting.
> + * Frequency measurement only works with the short-range receiver.
> + * The long-range receiver always reports no carrier frequency
> + * (MCE_RSP_EQIRRXCFCNT, 0, 0) so we always ignore its report.
> + */
> +static int mceusb_set_rx_carrier_report(struct rc_dev *dev, int enable)
> +{
> + struct mceusb_dev *ir = dev->priv;
> +
> + if (enable != 0 && enable != 1)
> + return -EINVAL;

This is only called from lirc_dev.c, where the expression is:

ret = dev->s_carrier_report(dev, !!val);

There is no need to check for enable being not 0 or 1.

> +
> + dev_dbg(ir->dev, "%s short-range receiver carrier reporting",
> + enable ? "enable" : "disable");
> + ir->carrier_report_enabled = (enable == 1);

Since enable is 0 or 1, there is no need for the enable == 1 expression.

Note that the other drivers that support carrier reports (winbond-cir,
redrat3, ene-cir) all enable the wideband receiver when carrier reports
are 

Re: [PATCH v2 2/2] media: ov2680: Add Omnivision OV2680 sensor driver

2018-03-13 Thread Rui Miguel Silva

Hi Sakari,
Thanks for the review...

On Fri 09 Mar 2018 at 09:21, Sakari Ailus wrote:

Hi Miguel,

Thanks for the update.

On Wed, Feb 28, 2018 at 03:27:23PM +, Rui Miguel Silva 
wrote:

This patch adds V4L2 sub-device driver for OV2680 image sensor.
The OV2680 is a 1/5" CMOS color sensor from Omnivision.
Supports output format: 10-bit Raw RGB.
The OV2680 has a single lane MIPI interface.

The driver exposes following V4L2 controls:
- auto/manual exposure,
- exposure,
- auto/manual gain,
- gain,
- horizontal/vertical flip,
- test pattern menu.
Supported resolution are only: QUXGA, 720P, UXGA.

Signed-off-by: Rui Miguel Silva 
---
 drivers/media/i2c/Kconfig  |   12 +
 drivers/media/i2c/Makefile |1 +
 drivers/media/i2c/ov2680.c | 1094 
 

 3 files changed, 1107 insertions(+)
 create mode 100644 drivers/media/i2c/ov2680.c

diff --git a/drivers/media/i2c/Kconfig 
b/drivers/media/i2c/Kconfig

index 9f18cd296841..39dc9f236ffa 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -586,6 +586,18 @@ config VIDEO_OV2659
  To compile this driver as a module, choose M here: the
  module will be called ov2659.
 
+config VIDEO_OV2680

+   tristate "OmniVision OV2680 sensor support"
+	depends on GPIOLIB && VIDEO_V4L2 && I2C && 
VIDEO_V4L2_SUBDEV_API

+   depends on MEDIA_CAMERA_SUPPORT
+   select V4L2_FWNODE
+   ---help---
+	  This is a Video4Linux2 sensor-level driver for the 
OmniVision

+ OV2680 camera sensor with a MIPI CSI-2 interface.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ov2680.
+
 config VIDEO_OV5640
tristate "OmniVision OV5640 sensor support"
depends on OF
diff --git a/drivers/media/i2c/Makefile 
b/drivers/media/i2c/Makefile

index c0f94cd8d56d..d0aba4d37b8d 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += 
sony-btf-mpx.o

 obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
 obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
 obj-$(CONFIG_VIDEO_OV2640) += ov2640.o
+obj-$(CONFIG_VIDEO_OV2680) += ov2680.o
 obj-$(CONFIG_VIDEO_OV5640) += ov5640.o
 obj-$(CONFIG_VIDEO_OV5645) += ov5645.o
 obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
diff --git a/drivers/media/i2c/ov2680.c 
b/drivers/media/i2c/ov2680.c

new file mode 100644
index ..78f2be27a8f5
--- /dev/null
+++ b/drivers/media/i2c/ov2680.c
@@ -0,0 +1,1094 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Omnivision OV2680 CMOS Image Sensor driver
+ *
+ * Copyright (C) 2018 Linaro Ltd
+ *
+ * Based on OV5640 Sensor Driver
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All 
Rights Reserved.

+ * Copyright (C) 2014-2017 Mentor Graphics Inc.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define OV2680_XVCLK_MIN   600
+#define OV2680_XVCLK_MAX   2400
+
+#define OV2680_CHIP_ID 0x2680
+
+#define OV2680_REG_STREAM_CTRL 0x0100
+#define OV2680_REG_SOFT_RESET  0x0103
+
+#define OV2680_REG_CHIP_ID_HIGH0x300a
+#define OV2680_REG_CHIP_ID_LOW 0x300b
+
+#define OV2680_REG_R_MANUAL0x3503
+#define OV2680_REG_GAIN_PK 0x350a
+#define OV2680_REG_EXPOSURE_PK_HIGH0x3500
+#define OV2680_REG_TIMING_HTS  0x380c
+#define OV2680_REG_TIMING_VTS  0x380e
+#define OV2680_REG_FORMAT1 0x3820
+#define OV2680_REG_FORMAT2 0x3821
+
+#define OV2680_REG_ISP_CTRL00  0x5080
+
+#define OV2680_FRAME_RATE  30
+
+#define OV2680_REG_VALUE_8BIT  1
+#define OV2680_REG_VALUE_16BIT 2
+#define OV2680_REG_VALUE_24BIT 3
+
+enum ov2680_mode_id {
+   OV2680_MODE_QUXGA_800_600,
+   OV2680_MODE_720P_1280_720,
+   OV2680_MODE_UXGA_1600_1200,
+   OV2680_MODE_MAX,
+};
+
+struct reg_value {
+   u16 reg_addr;
+   u8 val;
+};
+
+struct ov2680_mode_info {
+   const char *name;
+   enum ov2680_mode_id id;
+   u32 width;
+   u32 height;
+   const struct reg_value *reg_data;
+   u32 reg_data_size;
+};
+
+struct ov2680_ctrls {
+   struct v4l2_ctrl_handler handler;
+   struct {
+   struct v4l2_ctrl *auto_exp;
+   struct v4l2_ctrl *exposure;
+   };
+   struct {
+   struct v4l2_ctrl *auto_gain;
+   struct v4l2_ctrl *gain;
+   };
+
+   struct v4l2_ctrl *hflip;
+   struct v4l2_ctrl *vflip;
+   struct v4l2_ctrl *test_pattern;
+};
+
+struct ov2680_dev {
+   struct i2c_client   *i2c_client;
+   struct v4l2_subdev  sd;
+
+   struct media_padpad;
+   struct clk  *xvclk;
+   u32 xvclk_freq;
+
+   struct gpio_desc*pwdn_gpio;
+	struct mutex			lock; 

Re: [PATCH v2 2/2] media: ov2680: Add Omnivision OV2680 sensor driver

2018-03-13 Thread Sakari Ailus
On Tue, Mar 13, 2018 at 11:16:33AM +, Rui Miguel Silva wrote:
...
> > > +static int ov2680_gain_set(struct ov2680_dev *sensor, bool
> > > auto_gain)
> > > +{
> > > + struct ov2680_ctrls *ctrls = >ctrls;
> > > + u32 gain;
> > > + int ret;
> > > +
> > > + ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(1),
> > > +  auto_gain ? 0 : BIT(1));
> > > + if (ret < 0)
> > > + return ret;
> > > +
> > > + if (auto_gain || !ctrls->gain->is_new)
> > > + return 0;
> > > +
> > > + gain = ctrls->gain->val;
> > > +
> > > + ret = ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int ov2680_gain_get(struct ov2680_dev *sensor)
> > > +{
> > > + u32 gain;
> > > + int ret;
> > > +
> > > + ret = ov2680_read_reg16(sensor, OV2680_REG_GAIN_PK, );
> > > + if (ret)
> > > + return ret;
> > > +
> > > + return gain;
> > > +}
> > > +
> > > +static int ov2680_auto_gain_enable(struct ov2680_dev *sensor)
> > > +{
> > > + return ov2680_gain_set(sensor, true);
> > 
> > Just call ov2780_gain_set() in the caller.
> 
> Here if you do not mind I would like to have it this way, on the caller
> side makes explicit that we are disabling/enabling the auto gain,
> instead of going and search what that bool parameter means.
> 
> but, if you do mind... ;)

How about renaming that function as e.g. ov2680_autogain_set()? That's what
it does, doesn't it?

Right now you have these functions doing nothing really useful, cluttering
up the code.

...

> > > +static const struct i2c_device_id ov2680_id[] = {
> > > + {"ov2680", 0},
> > > + { },
> > 
> > You can remove the i2c_device_id table if you use the probe_new callback
> > (instead of probe) below.
> 
> Well this one was hard to debug, so removing the device id table made
> the module not to be auto loaded, and after some debug I found the root
> cause and it looks it is addressed by this [0]. With that patch removing
> the device_id and use probe_new works as expected.
> 
> I will be sending v3 soon.

Great, thanks!

-- 
Sakari Ailus
sakari.ai...@linux.intel.com


Re: coda: i.MX6 decoding performance issues for multi-streaming

2018-03-13 Thread Fabio Estevam
Hi Javier,

On Mon, Mar 12, 2018 at 1:54 PM, Javier Martin  wrote:
> Hi,
> we have an i.MX6 Solo based board running the latest mainline kernel
> (4.15.3).
>
> As part of our development we were measuring the decoding performance of the
> i.MX6 coda chip.
>
> For that purpose we are feeding the decoder with 640x368 @ 30fps H.264
> streams that have been generated by another i.MX6 coda encoder configured
> with fixed qp = 25 and gopsize = 16.
>
> For 1-2 streams it works smoothly. However, when adding the 3rd stream the
> first decoder instance starts to output these kind of errors:
>
> DEC_PIC_SUCCESS = 2097153  -> 0x21
> DEC_PIC_SUCCESS = 2621441  -> 0x280001
>
> Every time one of these errors appears we can observe a weird artifact in
> the decoded video (pixelated macroblocks and/or jumps back in time).
>
> I tried looking at the original VPU lib implementation by Freescale [1] but
> they don't seem to handle these errors either. As I don't have access to any
> kind of Coda IP documentation it's quite hard to me to perform any
> additional debugging.
>
> Has anyone experienced these kind of performance issues too? I'm open to any
> suggestions and willing to perform extra tests to get to the bottom of this.

Are you passing 'capture-io-mode=dmabuf' in your Gstreamer pipeline?

This really improves the performance of video decoding.


[PATCH] media: cxd2880-spi: avoid out-of-bounds access warning

2018-03-13 Thread Arnd Bergmann
The -Warray-bounds warning in gcc-8 triggers for a newly added file:

drivers/media/spi/cxd2880-spi.c: In function 'cxd2880_write_reg':
drivers/media/spi/cxd2880-spi.c:111:3: error: 'memcpy' forming offset [133, 
258] is out of the bounds [0, 132] of object 'send_data' with type 'u8[132]' 
{aka 'unsigned char[132]'} [-Werror=array-bounds]

The problem appears to be that we have two range checks in this function,
first comparing against BURST_WRITE_MAX (128) and then comparing against
a literal '255'. The logic checking the buffer size looks at the second
one and decides that this might be the actual maximum data length.

This is understandable behavior from the compiler, but the code is actually
safe. Since the first check is already shorter, we can remove the loop
and only leave that. To be on the safe side in case BURST_WRITE_MAX might
be increased, I'm leaving the check against U8_MAX.

Fixes: bd24fcddf6b8 ("media: cxd2880-spi: Add support for CXD2880 SPI 
interface")
Cc: Martin Sebor 
Signed-off-by: Arnd Bergmann 
---
 drivers/media/spi/cxd2880-spi.c | 24 +++-
 1 file changed, 7 insertions(+), 17 deletions(-)

diff --git a/drivers/media/spi/cxd2880-spi.c b/drivers/media/spi/cxd2880-spi.c
index 4df3bd312f48..011a37c2f272 100644
--- a/drivers/media/spi/cxd2880-spi.c
+++ b/drivers/media/spi/cxd2880-spi.c
@@ -88,7 +88,7 @@ static int cxd2880_write_reg(struct spi_device *spi,
pr_err("invalid arg\n");
return -EINVAL;
}
-   if (size > BURST_WRITE_MAX) {
+   if (size > BURST_WRITE_MAX || size > U8_MAX) {
pr_err("data size > WRITE_MAX\n");
return -EINVAL;
}
@@ -101,24 +101,14 @@ static int cxd2880_write_reg(struct spi_device *spi,
send_data[0] = 0x0e;
write_data_top = data;
 
-   while (size > 0) {
-   send_data[1] = sub_address;
-   if (size > 255)
-   send_data[2] = 255;
-   else
-   send_data[2] = (u8)size;
+   send_data[1] = sub_address;
+   send_data[2] = (u8)size;
 
-   memcpy(_data[3], write_data_top, send_data[2]);
+   memcpy(_data[3], write_data_top, send_data[2]);
 
-   ret = cxd2880_write_spi(spi, send_data, send_data[2] + 3);
-   if (ret) {
-   pr_err("write spi failed %d\n", ret);
-   break;
-   }
-   sub_address += send_data[2];
-   write_data_top += send_data[2];
-   size -= send_data[2];
-   }
+   ret = cxd2880_write_spi(spi, send_data, send_data[2] + 3);
+   if (ret)
+   pr_err("write spi failed %d\n", ret);
 
return ret;
 }
-- 
2.9.0



[PATCH] media: ngene: avoid unused variable warning

2018-03-13 Thread Arnd Bergmann
The newly added pdev variable is only used in an #ifdef, causing a
build warning without CONFIG_PCI_MSI, unless we move the declaration
inside the same #ifdef:

drivers/media/pci/ngene/ngene-core.c: In function 'ngene_start':
drivers/media/pci/ngene/ngene-core.c:1328:17: error: unused variable 'pdev' 
[-Werror=unused-variable]

Fixes: 6795bf626482 ("media: ngene: convert kernellog printing from printk() to 
dev_*() macros")
Signed-off-by: Arnd Bergmann 
---
 drivers/media/pci/ngene/ngene-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/pci/ngene/ngene-core.c 
b/drivers/media/pci/ngene/ngene-core.c
index 3b9a1bfaf6c0..25f16833a475 100644
--- a/drivers/media/pci/ngene/ngene-core.c
+++ b/drivers/media/pci/ngene/ngene-core.c
@@ -1325,7 +1325,6 @@ static int ngene_buffer_config(struct ngene *dev)
 
 static int ngene_start(struct ngene *dev)
 {
-   struct device *pdev = >pci_dev->dev;
int stat;
int i;
 
@@ -1359,6 +1358,7 @@ static int ngene_start(struct ngene *dev)
 #ifdef CONFIG_PCI_MSI
/* enable MSI if kernel and card support it */
if (pci_msi_enabled() && dev->card_info->msi_supported) {
+   struct device *pdev = >pci_dev->dev;
unsigned long flags;
 
ngwritel(0, NGENE_INT_ENABLE);
-- 
2.9.0



[PATCH] media: imx: work around false-positive warning

2018-03-13 Thread Arnd Bergmann
The IS_ERR()/PTR_ERR() combination confuses gcc to the point that it
cannot prove the upstream_ep variable to be initialized:

drivers/staging/media/imx/imx-media-csi.c: In function 'csi_link_validate':
drivers/staging/media/imx/imx-media-csi.c:1025:20: error: 'upstream_ep' may be 
used uninitialized in this function [-Werror=maybe-uninitialized]
  priv->upstream_ep = upstream_ep;
  ~~^
drivers/staging/media/imx/imx-media-csi.c:1026:24: error: 
'upstream_ep.bus_type' may be used uninitialized in this function 
[-Werror=maybe-uninitialized]
  is_csi2 = (upstream_ep.bus_type == V4L2_MBUS_CSI2);
 ~~~^
drivers/staging/media/imx/imx-media-csi.c:127:19: error: 
'upstream_ep.bus.parallel.bus_width' may be used uninitialized in this function 
[-Werror=maybe-uninitialized]

I could come up with no good way to rewrite this function, as a last
resort, this adds an explicit zero-intialization of the structure.

Fixes: 52e17089d185 ("media: imx: Don't initialize vars that won't be used")
Signed-off-by: Arnd Bergmann 
---
 drivers/staging/media/imx/imx-media-csi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index 5a195f80a24d..887fed0c3ce0 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -1004,7 +1004,7 @@ static int csi_link_validate(struct v4l2_subdev *sd,
 struct v4l2_subdev_format *sink_fmt)
 {
struct csi_priv *priv = v4l2_get_subdevdata(sd);
-   struct v4l2_fwnode_endpoint upstream_ep;
+   struct v4l2_fwnode_endpoint upstream_ep = {};
const struct imx_media_pixfmt *incc;
bool is_csi2;
int ret;
-- 
2.9.0



Re: [PATCH 08/12] media: ov5640: Adjust the clock based on the expected rate

2018-03-13 Thread Maxime Ripard
Hi Sakari,

On Fri, Mar 09, 2018 at 01:16:24PM +0200, Sakari Ailus wrote:
> > + *
> > + *   +--+
> > + *   |  Oscillator  |
> 
> I wonder if this should be simply called external clock, that's what the
> sensor uses.

Ack

> > + *   +--+---+
> > + *  |
> > + *   +--+---+
> > + *   | System clock | - reg 0x3035, bits 4-7
> > + *   +--+---+
> > + *  |
> > + *   +--+---+ - reg 0x3036, for the multiplier
> > + *   | PLL  | - reg 0x3037, bits 4 for the root divider
> > + *   +--+---+ - reg 0x3037, bits 0-3 for the pre-divider
> > + *  |
> > + *   +--+---+
> > + *   | SCLK | - reg 0x3108, bits 0-1 for the root divider
> > + *   +--+---+
> > + *  |
> > + *   +--+---+
> > + *   |PCLK  | - reg 0x3108, bits 4-5 for the root divider
> > + *   +--+
> > + *
> > + * This is deviating from the datasheet at least for the register
> > + * 0x3108, since it's said here that the PCLK would be clocked from
> > + * the PLL. However, changing the SCLK divider value has a direct
> > + * effect on the PCLK rate, which wouldn't be the case if both PCLK
> > + * and SCLK were to be sourced from the PLL.
> > + *
> > + * These parameters also match perfectly the rate that is output by
> > + * the sensor, so we shouldn't have too much factors missing (or they
> > + * would be set to 1).
> > + */
> > +
> > +/*
> > + * FIXME: This is supposed to be ranging from 1 to 16, but the value
> > + * is always set to either 1 or 2 in the vendor kernels.
> 
> There could be limits for the clock rates after the first divider. In
> practice the clock rates are mostly one of the common frequencies (9,6; 12;
> 19,2 or 24 MHz) so there's no need to use the other values.

There's probably some limits on the various combinations as well. I
first tried to use the full range, and there was some combinations
that were not usable, even though the clock rate should have been
correct.

> > + */
> > +#define OV5640_SYSDIV_MIN  1
> > +#define OV5640_SYSDIV_MAX  2
> > +
> > +static unsigned long ov5640_calc_sysclk(struct ov5640_dev *sensor,
> > +   unsigned long rate,
> > +   u8 *sysdiv)
> > +{
> > +   unsigned long best = ~0;
> > +   u8 best_sysdiv = 1;
> > +   u8 _sysdiv;
> > +
> > +   for (_sysdiv = OV5640_SYSDIV_MIN;
> > +_sysdiv <= OV5640_SYSDIV_MAX;
> > +_sysdiv++) {
> > +   unsigned long tmp;
> > +
> > +   tmp = sensor->xclk_freq / _sysdiv;
> > +   if (abs(rate - tmp) < abs(rate - best)) {
> > +   best = tmp;
> > +   best_sysdiv = _sysdiv;
> > +   }
> > +
> > +   if (tmp == rate)
> > +   goto out;
> > +   }
> > +
> > +out:
> > +   *sysdiv = best_sysdiv;
> > +   return best;
> > +}
> > +
> > +/*
> > + * FIXME: This is supposed to be ranging from 1 to 8, but the value is
> > + * always set to 3 in the vendor kernels.
> > + */
> > +#define OV5640_PLL_PREDIV_MIN  3
> > +#define OV5640_PLL_PREDIV_MAX  3
> 
> Same reasoning here than above. I might leave a comment documenting the
> values the hardware supports, removing FIXME as this isn't really an issue
> as far as I see.

Ok, I'll do it then

> > +
> > +/*
> > + * FIXME: This is supposed to be ranging from 1 to 2, but the value is
> > + * always set to 1 in the vendor kernels.
> > + */
> > +#define OV5640_PLL_ROOT_DIV_MIN1
> > +#define OV5640_PLL_ROOT_DIV_MAX1
> > +
> > +#define OV5640_PLL_MULT_MIN4
> > +#define OV5640_PLL_MULT_MAX252
> > +
> > +static unsigned long ov5640_calc_pll(struct ov5640_dev *sensor,
> > +unsigned long rate,
> > +u8 *sysdiv, u8 *prediv, u8 *rdiv, u8 *mult)
> > +{
> > +   unsigned long best = ~0;
> > +   u8 best_sysdiv = 1, best_prediv = 1, best_mult = 1, best_rdiv = 1;
> > +   u8 _prediv, _mult, _rdiv;
> > +
> > +   for (_prediv = OV5640_PLL_PREDIV_MIN;
> > +_prediv <= OV5640_PLL_PREDIV_MAX;
> > +_prediv++) {
> > +   for (_mult = OV5640_PLL_MULT_MIN;
> > +_mult <= OV5640_PLL_MULT_MAX;
> > +_mult++) {
> > +   for (_rdiv = OV5640_PLL_ROOT_DIV_MIN;
> > +_rdiv <= OV5640_PLL_ROOT_DIV_MAX;
> > +_rdiv++) {
> > +   unsigned long pll;
> > +   unsigned long sysclk;
> > +   u8 _sysdiv;
> > +
> > +   /*
> > +* The PLL multiplier cannot be odd if
> > +* above 127.
> > +*/
> > +   if (_mult > 127 && !(_mult % 2))
> > +   continue;
> > +
> > +   sysclk = rate * _prediv * _rdiv / _mult;
> > +   sysclk = 

Re: [PATCH 00/12] media: ov5640: Misc cleanup and improvements

2018-03-13 Thread Hugues FRUCHET
Thanks Maxime for this great series !

I've tested this series successfully on STM32 platform, I had a 
regression on JPEG capture linked to revisit of clocking, but easy to fix.
I had another problem claimed by v4l2-compliance on format tests:
v4l2-test-formats.cpp(961): Video Capture: S_FMT(G_FMT) != G_FMT
this was more tricky to fix, it is linked to changes around framerate 
handling.

See my further comments in corresponding patchsets.

Best regards,
Hugues.

On 03/02/2018 03:34 PM, Maxime Ripard wrote:
> Hi,
> 
> Here is a "small" series that mostly cleans up the ov5640 driver code,
> slowly getting rid of the big data array for more understandable code
> (hopefully).
> 
> The biggest addition would be the clock rate computation at runtime,
> instead of relying on those arrays to setup the clock tree
> properly. As a side effect, it fixes the framerate that was off by
> around 10% on the smaller resolutions, and we now support 60fps.
> 
> This also introduces a bunch of new features.
> 
> Let me know what you think,
> Maxime
> 
> Maxime Ripard (10):
>media: ov5640: Don't force the auto exposure state at start time
>media: ov5640: Init properly the SCLK dividers
>media: ov5640: Change horizontal and vertical resolutions name
>media: ov5640: Add horizontal and vertical totals
>media: ov5640: Program the visible resolution
>media: ov5640: Adjust the clock based on the expected rate
>media: ov5640: Compute the clock rate at runtime
>media: ov5640: Enhance FPS handling
>media: ov5640: Add 60 fps support
>media: ov5640: Remove duplicate auto-exposure setup
> 
> Mylène Josserand (2):
>media: ov5640: Add auto-focus feature
>media: ov5640: Add light frequency control
> 
>   drivers/media/i2c/ov5640.c | 777 
> ++---
>   1 file changed, 452 insertions(+), 325 deletions(-)
> 

RE: [PATCH 02/11] media: vsp1: use kernel __packed for structures

2018-03-13 Thread David Laight
From: Kieran Bingham [mailto:kieran.bingham+rene...@ideasonboard.com]
> On 13/03/18 11:20, David Laight wrote:
> > From: Kieran Bingham
> >> Sent: 09 March 2018 22:04
> >> The kernel provides a __packed definition to abstract away from the
> >> compiler specific attributes tag.
> >>
> >> Convert all packed structures in VSP1 to use it.
> >>
> >> Signed-off-by: Kieran Bingham 
> >> ---
> >>  drivers/media/platform/vsp1/vsp1_dl.c | 6 +++---
> >>  1 file changed, 3 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
> >> b/drivers/media/platform/vsp1/vsp1_dl.c
> >> index 37e2c984fbf3..382e45c2054e 100644
> >> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> >> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> >> @@ -29,19 +29,19 @@
> >>  struct vsp1_dl_header_list {
> >>u32 num_bytes;
> >>u32 addr;
> >> -} __attribute__((__packed__));
> >> +} __packed;
> >>
> >>  struct vsp1_dl_header {
> >>u32 num_lists;
> >>struct vsp1_dl_header_list lists[8];
> >>u32 next_header;
> >>u32 flags;
> >> -} __attribute__((__packed__));
> >> +} __packed;
> >>
> >>  struct vsp1_dl_entry {
> >>u32 addr;
> >>u32 data;
> >> -} __attribute__((__packed__));
> >> +} __packed;
> >
> > Do these structures ever actually appear in misaligned memory?
> > If they don't then they shouldn't be marked 'packed'.
> 
> I believe the declaration is to ensure that the struct definition is not 
> altered
> by the compiler as these structures specifically define the layout of how the
> memory is read by the VSP1 hardware.

The C language and ABI define structure layouts.

> Certainly 2 u32's sequentially stored in a struct are unlikely to be moved or
> rearranged by the compiler (though I believe it would be free to do so if it
> chose without this attribute), but I think the declaration shows the intent of
> the memory structure.

The language requires the fields be in order and the ABI stops the compiler
adding 'random' padding.

> Isn't this a common approach throughout the kernel when dealing with hardware
> defined memory structures ?

Absolutely not.
__packed tells the compiler that the structure might be on any address boundary.
On many architectures this means the compiler must use byte accesses with shifts
and ors for every access.
The most a hardware defined structure will have is a compile-time assert
that it is the correct size (to avoid silly errors from changes).

David



Re: [PATCH 09/12] media: ov5640: Compute the clock rate at runtime

2018-03-13 Thread Hugues FRUCHET
Hi Maxime,

Below comments about JPEG issue.

On 03/02/2018 03:34 PM, Maxime Ripard wrote:
> The clock rate, while hardcoded until now, is actually a function of the
> resolution, framerate and bytes per pixel. Now that we have an algorithm to
> adjust our clock rate, we can select it dynamically when we change the
> mode.
> 
> This changes a bit the clock rate being used, with the following effect:
> 
> +--+--+--+--+-+-++---+
> | Hact | Vact | Htot | Vtot | FPS | Hardcoded clock | Computed clock | 
> Deviation |
> +--+--+--+--+-+-++---+
> |  640 |  480 | 1896 | 1080 |  15 |5600 |   61430400 | 8.84 % 
>|
> |  640 |  480 | 1896 | 1080 |  30 |   11200 |  122860800 | 8.84 % 
>|
> | 1024 |  768 | 1896 | 1080 |  15 |5600 |   61430400 | 8.84 % 
>|
> | 1024 |  768 | 1896 | 1080 |  30 |   11200 |  122860800 | 8.84 % 
>|
> |  320 |  240 | 1896 |  984 |  15 |5600 |   55969920 | 0.05 % 
>|
> |  320 |  240 | 1896 |  984 |  30 |   11200 |  111939840 | 0.05 % 
>|
> |  176 |  144 | 1896 |  984 |  15 |5600 |   55969920 | 0.05 % 
>|
> |  176 |  144 | 1896 |  984 |  30 |   11200 |  111939840 | 0.05 % 
>|
> |  720 |  480 | 1896 |  984 |  15 |5600 |   55969920 | 0.05 % 
>|
> |  720 |  480 | 1896 |  984 |  30 |   11200 |  111939840 | 0.05 % 
>|
> |  720 |  576 | 1896 |  984 |  15 |5600 |   55969920 | 0.05 % 
>|
> |  720 |  576 | 1896 |  984 |  30 |   11200 |  111939840 | 0.05 % 
>|
> | 1280 |  720 | 1892 |  740 |  15 |4200 |   42002400 | 0.01 % 
>|
> | 1280 |  720 | 1892 |  740 |  30 |8400 |   84004800 | 0.01 % 
>|
> | 1920 | 1080 | 2500 | 1120 |  15 |8400 |   8400 | 0.00 % 
>|
> | 1920 | 1080 | 2500 | 1120 |  30 |   16800 |  16800 | 0.00 % 
>|
> | 2592 | 1944 | 2844 | 1944 |  15 |8400 |  165862080 | 49.36 
> %   |
> +--+--+--+--+-+-++---+
> 
> Only the 640x480, 1024x768 and 2592x1944 modes are significantly affected
> by the new formula.
> 
> In this case, 640x480 and 1024x768 are actually fixed by this driver.
> Indeed, the sensor was sending data at, for example, 27.33fps instead of
> 30fps. This is -9%, which is roughly what we're seeing in the array.
> Testing these modes with the new clock setup actually fix that error, and
> data are now sent at around 30fps.
> 
> 2592x1944, on the other hand, is probably due to the fact that this mode
> can only be used using MIPI-CSI2, in a two lane mode. This would have to be
> tested though.
> 
> Signed-off-by: Maxime Ripard 
> ---
>   drivers/media/i2c/ov5640.c | 41 +
>   1 file changed, 17 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
> index 323cde27dd8b..bdf378d80e07 100644
> --- a/drivers/media/i2c/ov5640.c
> +++ b/drivers/media/i2c/ov5640.c
> @@ -126,6 +126,12 @@ static const struct ov5640_pixfmt ov5640_formats[] = {
>   { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB, },
>   };
>   
> +/*
> + * FIXME: If we ever have something else, we'll obviously need to have
> + * something smarter.
> + */
> +#define OV5640_FORMATS_BPP   2
> +

We have the case with JPEG which is 1 byte.

>   /*
>* FIXME: remove this when a subdev API becomes available
>* to set the MIPI CSI-2 virtual channel.
> @@ -172,7 +178,6 @@ struct ov5640_mode_info {
>   u32 htot;
>   u32 vact;
>   u32 vtot;
> - u32 clock;
>   const struct reg_value *reg_data;
>   u32 reg_data_size;
>   };
> @@ -696,7 +701,6 @@ static const struct reg_value 
> ov5640_setting_15fps_QSXGA_2592_1944[] = {
>   /* power-on sensor init reg table */
>   static const struct ov5640_mode_info ov5640_mode_init_data = {
>   0, SUBSAMPLING, 640, 1896, 480, 984,
> - 11200,
>   ov5640_init_setting_30fps_VGA,
>   ARRAY_SIZE(ov5640_init_setting_30fps_VGA),
>   };
> @@ -706,91 +710,74 @@ 
> ov5640_mode_data[OV5640_NUM_FRAMERATES][OV5640_NUM_MODES] = {
>   {
>   {OV5640_MODE_QCIF_176_144, SUBSAMPLING,
>176, 1896, 144, 984,
> -  5600,
>ov5640_setting_15fps_QCIF_176_144,
>ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
>   {OV5640_MODE_QVGA_320_240, SUBSAMPLING,
>320, 1896, 240, 984,
> -  5600,
>ov5640_setting_15fps_QVGA_320_240,
>ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
>   {OV5640_MODE_VGA_640_480, SUBSAMPLING,
>640, 1896, 480, 1080,
> -  5600,
>

Re: [PATCH 02/11] media: vsp1: use kernel __packed for structures

2018-03-13 Thread Kieran Bingham
Hi David,

On 13/03/18 13:38, David Laight wrote:
> From: Kieran Bingham [mailto:kieran.bingham+rene...@ideasonboard.com]
>> On 13/03/18 11:20, David Laight wrote:
>>> From: Kieran Bingham
 Sent: 09 March 2018 22:04
 The kernel provides a __packed definition to abstract away from the
 compiler specific attributes tag.

 Convert all packed structures in VSP1 to use it.

 Signed-off-by: Kieran Bingham 
 ---
  drivers/media/platform/vsp1/vsp1_dl.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

 diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
 b/drivers/media/platform/vsp1/vsp1_dl.c
 index 37e2c984fbf3..382e45c2054e 100644
 --- a/drivers/media/platform/vsp1/vsp1_dl.c
 +++ b/drivers/media/platform/vsp1/vsp1_dl.c
 @@ -29,19 +29,19 @@
  struct vsp1_dl_header_list {
u32 num_bytes;
u32 addr;
 -} __attribute__((__packed__));
 +} __packed;

  struct vsp1_dl_header {
u32 num_lists;
struct vsp1_dl_header_list lists[8];
u32 next_header;
u32 flags;
 -} __attribute__((__packed__));
 +} __packed;

  struct vsp1_dl_entry {
u32 addr;
u32 data;
 -} __attribute__((__packed__));
 +} __packed;
>>>
>>> Do these structures ever actually appear in misaligned memory?
>>> If they don't then they shouldn't be marked 'packed'.
>>
>> I believe the declaration is to ensure that the struct definition is not 
>> altered
>> by the compiler as these structures specifically define the layout of how the
>> memory is read by the VSP1 hardware.
> 
> The C language and ABI define structure layouts.
> 
>> Certainly 2 u32's sequentially stored in a struct are unlikely to be moved or
>> rearranged by the compiler (though I believe it would be free to do so if it
>> chose without this attribute), but I think the declaration shows the intent 
>> of
>> the memory structure.
> 
> The language requires the fields be in order and the ABI stops the compiler
> adding 'random' padding.
> 
>> Isn't this a common approach throughout the kernel when dealing with hardware
>> defined memory structures ?
> 
> Absolutely not.
> __packed tells the compiler that the structure might be on any address 
> boundary.
> On many architectures this means the compiler must use byte accesses with 
> shifts
> and ors for every access.
> The most a hardware defined structure will have is a compile-time assert
> that it is the correct size (to avoid silly errors from changes).



Ok - interesting, I see what you're saying - and certainly don't want the
compiler to be performing byte accesses on the structures unnecessarily.

I'm trying to distinguish the difference here. Is the single point that
 __packed

causes byte-access, where as

__attribute__((__packed__));

does not?

Looking at the GCC docs [0]: I see that  __attribute__((__packed__)) tells the
compiler that the "structure or union is placed to minimize the memory 
required".

However, the keil compiler docs[1] do certainly declare that __packed causes
byte alignment.

I was confused/thrown off here by the Kernel defining __packed as
__attribute__((packed)) at [2].

Do __attribute__((packed)) and __attribute__((__packed__)) differ ?

In which case, from what I've read so far I wish "__packed" was "__unaligned"...


[0]
https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute

[1] http://www.keil.com/support/man/docs/armcc/armcc_chr1359124230195.htm

[2]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/compiler-gcc.h?h=v4.16-rc5#n92


Regards

Kieran


>   David
> 


[PATCH] media: v4l: omap_vout: vrfb: remove an unused variable

2018-03-13 Thread Arnd Bergmann
We now get a warning after the 'dmadev' variable is no longer used:

drivers/media/platform/omap/omap_vout_vrfb.c: In function 
'omap_vout_prepare_vrfb':
drivers/media/platform/omap/omap_vout_vrfb.c:239:21: error: unused variable 
'dmadev' [-Werror=unused-variable]

Fixes: 8f0aa38292f2 ("media: v4l: omap_vout: vrfb: Use the wrapper for 
prep_interleaved_dma()")
Signed-off-by: Arnd Bergmann 
---
 drivers/media/platform/omap/omap_vout_vrfb.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c 
b/drivers/media/platform/omap/omap_vout_vrfb.c
index 72c0ac2cbf3d..1d8508237220 100644
--- a/drivers/media/platform/omap/omap_vout_vrfb.c
+++ b/drivers/media/platform/omap/omap_vout_vrfb.c
@@ -236,7 +236,6 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
struct dma_async_tx_descriptor *tx;
enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
struct dma_chan *chan = vout->vrfb_dma_tx.chan;
-   struct dma_device *dmadev = chan->device;
struct dma_interleaved_template *xt = vout->vrfb_dma_tx.xt;
dma_cookie_t cookie;
enum dma_status status;
-- 
2.9.0



Re: [PATCH] media: v4l: omap_vout: vrfb: remove an unused variable

2018-03-13 Thread Peter Ujfalusi


On 2018-03-13 14:05, Arnd Bergmann wrote:
> We now get a warning after the 'dmadev' variable is no longer used:
> 
> drivers/media/platform/omap/omap_vout_vrfb.c: In function 
> 'omap_vout_prepare_vrfb':
> drivers/media/platform/omap/omap_vout_vrfb.c:239:21: error: unused variable 
> 'dmadev' [-Werror=unused-variable]
> 
> Fixes: 8f0aa38292f2 ("media: v4l: omap_vout: vrfb: Use the wrapper for 
> prep_interleaved_dma()")
> Signed-off-by: Arnd Bergmann 

Reviewed-by: Peter Ujfalusi 

> ---
>  drivers/media/platform/omap/omap_vout_vrfb.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c 
> b/drivers/media/platform/omap/omap_vout_vrfb.c
> index 72c0ac2cbf3d..1d8508237220 100644
> --- a/drivers/media/platform/omap/omap_vout_vrfb.c
> +++ b/drivers/media/platform/omap/omap_vout_vrfb.c
> @@ -236,7 +236,6 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
>   struct dma_async_tx_descriptor *tx;
>   enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
>   struct dma_chan *chan = vout->vrfb_dma_tx.chan;
> - struct dma_device *dmadev = chan->device;
>   struct dma_interleaved_template *xt = vout->vrfb_dma_tx.xt;
>   dma_cookie_t cookie;
>   enum dma_status status;
> 

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


Re: [PATCH] media: ov5640: add missing output pixel format setting

2018-03-13 Thread Akinobu Mita
2018-03-13 1:18 GMT+09:00 Hugues FRUCHET :
> Hi Akinobu,
>
> Thanks for the patch, could you describe the test you made to reproduce
> the issue that I can test on my side ?
>
> I'm using usually yavta or Gstreamer, but I don't know how to trig the
> power on/off independently of streamon/off.

Capturing a single image by yavta and gstreamer can reproduce this issue
in my environment.  I use Xilinx Video IP driver for video device with
the following change in order to support pipeline power management.

https://patchwork.linuxtv.org/patch/46343/

With this change, when opening the video device, s_power() is called with
on=1 for subdevice.

I observed the following steps when capturing a single image by
'yavta -n1 -c1 -Ftest.raw /dev/video1'. (The output pixel format is
already set up by media-ctl before this run)

1. open /dev/video1
2. ov5640_s_power() is called with on=1
   (ov5640_s_power -> ov5640_set_power -> ov5640_restore_mode
-> ov5640_set_mode, and pending_mode_change is cleared)
3. ov5640_s_stream() is called with on=1
   (But ov5640_set_framefmt() is not called because pending_mode_change
has already been cleared  in step 2.)

As ov5640_set_framefmt() is not called, output pixel format cannot be
restored (OV5640_REG_FORMAT_CONTROL00 and OV5640_REG_ISP_FORMAT_MUX_CTRL).


[RfC PATCH] Add udmabuf misc device

2018-03-13 Thread Gerd Hoffmann
A driver to let userspace turn iovecs into dma-bufs.

Use case:  Allows qemu pass around dmabufs for the guest framebuffer.
https://www.kraxel.org/cgit/qemu/log/?h=sirius/udmabuf has an
experimental patch.

Also allows qemu to export guest virtio-gpu resources as host dmabufs.
Should be possible to use it to display guest wayland windows on the
host display server.  virtio-gpu ressources can be chunked so we will
actually need multiple iovec entries.  UNTESTED.

Want collect some feedback on the general approach with this RfC series.
Can this work?  If not, better ideas?

Question:  Must this be hooked into some kind of mlock accounting, to
limit the amout of memory userspace is allowed to pin this way?  Or will
get_user_pages_fast() handle that for me?

Known issue:  Driver API isn't complete yet.  Need add some flags, for
example to support read-only buffers.

Cc: David Airlie 
Cc: Tomeu Vizoso 
Signed-off-by: Gerd Hoffmann 
---
 include/uapi/linux/udmabuf.h |  21 
 drivers/dma-buf/udmabuf.c| 250 +++
 drivers/dma-buf/Kconfig  |   7 ++
 drivers/dma-buf/Makefile |   1 +
 4 files changed, 279 insertions(+)
 create mode 100644 include/uapi/linux/udmabuf.h
 create mode 100644 drivers/dma-buf/udmabuf.c

diff --git a/include/uapi/linux/udmabuf.h b/include/uapi/linux/udmabuf.h
new file mode 100644
index 00..fd2fa441fe
--- /dev/null
+++ b/include/uapi/linux/udmabuf.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_LINUX_UDMABUF_H
+#define _UAPI_LINUX_UDMABUF_H
+
+#include 
+#include 
+
+struct udmabuf_iovec {
+   __u64 base;
+   __u64 len;
+};
+
+struct udmabuf_create {
+   __u32 flags;
+   __u32 niov;
+   struct udmabuf_iovec iovs[];
+};
+
+#define UDMABUF_CREATE _IOW(0x42, 0x23, struct udmabuf_create)
+
+#endif /* _UAPI_LINUX_UDMABUF_H */
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
new file mode 100644
index 00..ec012d7ac7
--- /dev/null
+++ b/drivers/dma-buf/udmabuf.c
@@ -0,0 +1,250 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+struct udmabuf {
+   u32 pagecount;
+   struct page **pages;
+};
+
+static int udmabuf_vm_fault(struct vm_fault *vmf)
+{
+   struct vm_area_struct *vma = vmf->vma;
+   struct udmabuf *ubuf = vma->vm_private_data;
+
+   if (WARN_ON(vmf->pgoff >= ubuf->pagecount))
+   return VM_FAULT_SIGBUS;
+
+   vmf->page = ubuf->pages[vmf->pgoff];
+   get_page(vmf->page);
+   return 0;
+}
+
+static const struct vm_operations_struct udmabuf_vm_ops = {
+   .fault = udmabuf_vm_fault,
+};
+
+static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma)
+{
+   struct udmabuf *ubuf = buf->priv;
+
+   if ((vma->vm_flags & VM_SHARED) == 0)
+   return -EINVAL;
+
+   vma->vm_ops = _vm_ops;
+   vma->vm_private_data = ubuf;
+   return 0;
+}
+
+static struct sg_table *map_udmabuf(struct dma_buf_attachment *at,
+   enum dma_data_direction direction)
+{
+   struct udmabuf *ubuf = at->dmabuf->priv;
+   struct sg_table *sg;
+
+   sg = kzalloc(sizeof(*sg), GFP_KERNEL);
+   if (!sg)
+   goto err1;
+   if (sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->pagecount,
+ 0, ubuf->pagecount << PAGE_SHIFT,
+ GFP_KERNEL) < 0)
+   goto err2;
+   if (!dma_map_sg(at->dev, sg->sgl, sg->nents, direction))
+   goto err3;
+
+   return sg;
+
+err3:
+   sg_free_table(sg);
+err2:
+   kfree(sg);
+err1:
+   return ERR_PTR(-ENOMEM);
+}
+
+static void unmap_udmabuf(struct dma_buf_attachment *at,
+ struct sg_table *sg,
+ enum dma_data_direction direction)
+{
+   sg_free_table(sg);
+   kfree(sg);
+}
+
+static void release_udmabuf(struct dma_buf *buf)
+{
+   struct udmabuf *ubuf = buf->priv;
+   pgoff_t pg;
+
+   for (pg = 0; pg < ubuf->pagecount; pg++)
+   put_page(ubuf->pages[pg]);
+   kfree(ubuf->pages);
+   kfree(ubuf);
+}
+
+static void *kmap_atomic_udmabuf(struct dma_buf *buf, unsigned long offset)
+{
+   struct udmabuf *ubuf = buf->priv;
+   struct page *page = ubuf->pages[offset >> PAGE_SHIFT];
+
+   return kmap_atomic(page);
+}
+
+static void *kmap_udmabuf(struct dma_buf *buf, unsigned long offset)
+{
+   struct udmabuf *ubuf = buf->priv;
+   struct page *page = ubuf->pages[offset >> PAGE_SHIFT];
+
+   return kmap(page);
+}
+
+static struct dma_buf_ops udmabuf_ops = {
+   

Re: [PATCH 1/4] dma-buf: add optional invalidate_mappings callback

2018-03-13 Thread Daniel Vetter
On Tue, Mar 13, 2018 at 04:52:02PM +0100, Christian König wrote:
> Am 13.03.2018 um 16:17 schrieb Daniel Vetter:
> > [SNIP]
> > > > I think a helper which both unmaps _and_ waits for all the fences to 
> > > > clear
> > > > would be best, with some guarantees that it'll either fail or all the
> > > > mappings _will_ be gone. The locking for that one will be hilarious, 
> > > > since
> > > > we need to figure out dmabuf->lock vs. the reservation. I kinda prefer 
> > > > we
> > > > throw away the dmabuf->lock and superseed it entirely by the reservation
> > > > lock.
> > > Big NAK on that. The whole API is asynchronously, e.g. we never block for
> > > any operation to finish.
> > > 
> > > Otherwise you run into big trouble with cross device GPU resets and stuff
> > > like that.
> > But how will the unmapping work then? You can't throw the sg list away
> > before the dma stopped. The dma only stops once the fence is signalled.
> > The importer can't call dma_buf_detach because the reservation lock is
> > hogged already by the exporter trying to unmap everything.
> > 
> > How is this supposed to work?
> 
> Even after invalidation the sg list stays alive until it is explicitly
> destroyed by the importer using dma_buf_unmap_attachment() which in turn is
> only allowed after all fences have signaled.
> 
> The implementation is in ttm_bo_pipeline_gutting(), basically we use the
> same functionality as for pipelined moves/evictions which hangs the old
> backing store on a dummy object and destroys it after all fences signaled.
> 
> While the old sg list is still about to be destroyed the importer can
> request a new sg list for the new location of the DMA-buf using
> dma_buf_map_attachment(). This new location becomes valid after the move
> fence in the reservation object is signaled.
> 
> So from the CPU point of view multiple sg list could exists at the same time
> which allows us to have a seamless transition from the old to the new
> location from the GPU point of view.

Ok, so plan is to support fully pipeline moves and everything, with the
old sg tables lazily cleaned up. I was thinking more about evicting stuff
and throwing it out, where there's not going to be any new sg list but the
object is going to be swapped out.

I think some state flow charts (we can do SVG or DOT) in the kerneldoc
would be sweet.

> > Re GPU might cause a deadlock: Isn't that already a problem if you hold
> > reservations of buffers used on other gpus, which want those reservations
> > to complete the gpu reset, but that gpu reset blocks some fence that the
> > reservation holder is waiting for?
> 
> Correct, that's why amdgpu and TTM tries quite hard to never wait for a
> fence while a reservation object is locked.

We might have a fairly huge mismatch of expectations here :-/

> The only use case I haven't fixed so far is reaping deleted object during
> eviction, but that is only a matter of my free time to fix it.

Yeah, this is the hard one.

In general the assumption is that dma_fence will get signalled no matter
what you're doing, assuming the only thing you need is to not block
interrupts. The i915 gpu reset logic to make that work is a bit a work of
art ...

If we expect amdgpu and i915 to cooperate with shared buffers I guess one
has to give in. No idea how to do that best.

> > We have tons of fun with deadlocks against GPU resets, and loots of
> > testcases, and I kinda get the impression amdgpu is throwing a lot of
> > issues under the rug through trylock tricks that shut up lockdep, but
> > don't fix much really.
> 
> Hui? Why do you think that? The only trylock I'm aware of is during eviction
> and there it isn't a problem.

mmap fault handler had one too last time I looked, and it smelled fishy.

> > btw adding cross-release lockdep annotations for fences will probably turn
> > up _lots_ more bugs in this area.
> 
> At least for amdgpu that should be handled by now.

You're sure? :-)

Trouble is that cross-release wasn't even ever enabled, much less anyone
typed the dma_fence annotations. And just cross-release alone turned up
_lost_ of deadlocks in i915 between fences, async workers (userptr, gpu
reset) and core mm stuff.

I'd be seriously surprised if it wouldn't find an entire rats nest of
issues around dma_fence once we enable it.
-Daniel

> > > > > +  *
> > > > > +  * New mappings can be created immediately, but can't be used 
> > > > > before the
> > > > > +  * exclusive fence in the dma_bufs reservation object is 
> > > > > signaled.
> > > > > +  */
> > > > > + void (*invalidate_mappings)(struct dma_buf_attachment *attach);
> > > > Bunch of questions about exact semantics, but I very much like this. 
> > > > And I
> > > > think besides those technical details, the overall approach seems sound.
> > > Yeah this initial implementation was buggy like hell. Just wanted to 
> > > confirm
> > > that the idea is going in the right direction.
> > I wanted this 7 years ago, idea very much acked 

Re: [PATCH 10/12] media: ov5640: Enhance FPS handling

2018-03-13 Thread Hugues FRUCHET
Hi Maxime,

See below comments related to format compliance failing.

On 03/02/2018 03:34 PM, Maxime Ripard wrote:
> Now that we have moved the clock generation logic out of the bytes array,
> these arrays are identical between the 15fps and 30fps variants.
> 
> Remove the duplicate entries, and convert the code accordingly.
> 
> Signed-off-by: Maxime Ripard 
> ---
>   drivers/media/i2c/ov5640.c | 312 
> -
>   1 file changed, 56 insertions(+), 256 deletions(-)
> 
> diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
> index bdf378d80e07..5510a19281a4 100644
> --- a/drivers/media/i2c/ov5640.c
> +++ b/drivers/media/i2c/ov5640.c
> @@ -344,66 +344,7 @@ static const struct reg_value 
> ov5640_init_setting_30fps_VGA[] = {
>   {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3c00, 0x04, 0, 300},
>   };
>   
> -static const struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
> -
> - {0x3c07, 0x08, 0, 0},
> - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
> - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
> - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
> - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
> - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
> - {0x3810, 0x00, 0, 0},
> - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
> - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
> - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
> - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
> - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
> - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
> - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
> - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
> - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0},
> -};
> -
> -static const struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
> - {0x3c07, 0x08, 0, 0},
> - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
> - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
> - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
> - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
> - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
> - {0x3810, 0x00, 0, 0},
> - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
> - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
> - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
> - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
> - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
> - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
> - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
> - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
> - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
> -};
> -
> -static const struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
> -
> - {0x3c07, 0x08, 0, 0},
> - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
> - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
> - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
> - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
> - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
> - {0x3810, 0x00, 0, 0},
> - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
> - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
> - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
> - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
> - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
> - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
> - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
> - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
> - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0},
> -};
> -
> -static const struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
> +static const struct reg_value ov5640_setting_VGA_640_480[] = {
>   {0x3c07, 0x08, 0, 0},
>   {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
>   {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
> @@ -422,7 +363,7 @@ static const struct reg_value 
> ov5640_setting_15fps_XGA_1024_768[] = {
>   {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
>   };
>   
> -static const struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
> +static const struct 

Re: [PATCH 11/12] media: ov5640: Add 60 fps support

2018-03-13 Thread Hugues FRUCHET
Hi Maxime,

See below rest of comments regarding framerate and compliance failure.

On 03/02/2018 03:34 PM, Maxime Ripard wrote:
> Now that we have everything in place to compute the clock rate at runtime,
> we can enable the 60fps framerate for the mode we tested it with.
> 
> Signed-off-by: Maxime Ripard 
> ---
>   drivers/media/i2c/ov5640.c | 20 +++-
>   1 file changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
> index 5510a19281a4..03838f42fb82 100644
> --- a/drivers/media/i2c/ov5640.c
> +++ b/drivers/media/i2c/ov5640.c
> @@ -111,6 +111,7 @@ enum ov5640_mode_id {
>   enum ov5640_frame_rate {
>   OV5640_15_FPS = 0,
>   OV5640_30_FPS,
> + OV5640_60_FPS,
>   OV5640_NUM_FRAMERATES,
>   };
>   
> @@ -144,6 +145,7 @@ MODULE_PARM_DESC(virtual_channel,
>   static const int ov5640_framerates[] = {
>   [OV5640_15_FPS] = 15,
>   [OV5640_30_FPS] = 30,
> + [OV5640_60_FPS] = 60,
>   };
>   
>   /* regulator supplies */
> @@ -1447,6 +1449,11 @@ ov5640_find_mode(struct ov5640_dev *sensor, enum 
> ov5640_frame_rate fr,
>   fr != OV5640_15_FPS)
>   return NULL;
>   
> + /* Only 640x480 can operate at 60fps (for now) */
> + if (fr == OV5640_60_FPS &&
> + width != 640 && height != 480)
> + return NULL;
> +

Same comment as on patchset 10/12, VGA exception put in for loop:

for (i = OV5640_NUM_MODES - 1; i >= 0; i--) {
mode = _mode_data[i];

if (!mode->reg_data)
continue;

if ((nearest && mode->hact <= width &&
 mode->vact <= height) ||
(!nearest && mode->hact == width &&
 mode->vact == height)) {

/* 2592x1944 can only operate at 15fps */
if (mode->hact == 2592 && mode->vact == 1944 &&
fr != OV5640_15_FPS)
continue;/* next lower resolution */

/* Only 640x480 can operate at 60fps (for now) */
if (fr == OV5640_60_FPS &&
!(mode->hact == 640 && mode->vact == 480))
continue;/* next lower resolution */

break;/* select this resolution */
}
}


>   return mode;
>   }
>   
> @@ -1875,12 +1882,12 @@ static int ov5640_try_frame_interval(struct 
> ov5640_dev *sensor,
>   int ret;
>   
>   minfps = ov5640_framerates[OV5640_15_FPS];
> - maxfps = ov5640_framerates[OV5640_30_FPS];
> + maxfps = ov5640_framerates[OV5640_60_FPS];
>   
>   if (fi->numerator == 0) {
>   fi->denominator = maxfps;
>   fi->numerator = 1;
> - return OV5640_30_FPS;
> + return OV5640_60_FPS;

There is a problem here because we don't validate that 60fps is 
supported in the currently set mode, we must inject this framerate value 
in ov5640_find_mode(framerate, width, height) in order to validate it 
(-EINVAL if not supported):

  + ret = OV5640_60_FPS;
  + goto find_mode;
  + }
[...]
+find_mode:
mode = ov5640_find_mode(sensor, frame_rate, width, height, false);
return mode ? ret : -EINVAL;
  }

Then we have to catch error in ov5640_s_frame_interval() and return an 
acceptable frame interval to user:

frame_rate = ov5640_try_frame_interval(sensor, >interval,
   mode->hact, mode->vact);
-   if (frame_rate < 0)
-   frame_rate = OV5640_15_FPS;
-
-   sensor->current_fr = frame_rate;
-   sensor->frame_interval = fi->interval;
We also have to update current framerate only if framerate has been 
validated.

+   if (frame_rate < 0) {
+   /* return a valid frame interval value */
+   fi->interval = sensor->frame_interval;
goto out;
}

+   sensor->current_fr = frame_rate;
+   sensor->frame_interval = fi->interval;
sensor->pending_mode_change = true;
  out:


About 60 fps by default if (fi->numerator == 0): shouldn't we stick to a 
default value supported by all modes such as 30fps ?

>   }
>   
>   fps = DIV_ROUND_CLOSEST(fi->denominator, fi->numerator);
> @@ -1892,10 +1899,13 @@ static int ov5640_try_frame_interval(struct 
> ov5640_dev *sensor,
>   fi->denominator = minfps;
>   else if (2 * fps >= 2 * minfps + (maxfps - minfps))
>   fi->denominator = maxfps;
> - else
> - fi->denominator = minfps;
>   
> - ret = (fi->denominator == minfps) ? OV5640_15_FPS : OV5640_30_FPS;
> + if (fi->denominator == minfps)
> + ret = OV5640_15_FPS;
> + else if (fi->denominator == maxfps)
> + ret = OV5640_60_FPS;
> + else
> + ret = OV5640_30_FPS;
>   
>   

Re: [PATCH] media: omap3isp: fix unbalanced dma_iommu_mapping

2018-03-13 Thread Suman Anna
Hi Sakari,

On 03/13/2018 06:14 AM, Sakari Ailus wrote:
> Hi Suman,
> 
> Thanks for the patch.
> 
> On Mon, Mar 12, 2018 at 11:52:07AM -0500, Suman Anna wrote:
>> The OMAP3 ISP driver manages its MMU mappings through the IOMMU-aware
>> ARM DMA backend. The current code creates a dma_iommu_mapping and
>> attaches this to the ISP device, but never detaches the mapping in
>> either the probe failure paths or the driver remove path resulting
>> in an unbalanced mapping refcount and a memory leak. Fix this properly.
>>
>> Reported-by: Pavel Machek 
>> Signed-off-by: Suman Anna 
>> Tested-by: Pavel Machek 
>> ---
>> Hi Mauro, Laurent,
>>
>> This fixes an issue reported by Pavel and discussed on this
>> thread,
>> https://marc.info/?l=linux-omap=152051945803598=2
>>
>> Posting this again to the appropriate lists.
>>
>> regards
>> Suman
>>
>>  drivers/media/platform/omap3isp/isp.c | 7 +--
>>  1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/media/platform/omap3isp/isp.c 
>> b/drivers/media/platform/omap3isp/isp.c
>> index 8eb000e3d8fd..c7d667bfc2af 100644
>> --- a/drivers/media/platform/omap3isp/isp.c
>> +++ b/drivers/media/platform/omap3isp/isp.c
>> @@ -1945,6 +1945,7 @@ static int isp_initialize_modules(struct isp_device 
>> *isp)
>>  
>>  static void isp_detach_iommu(struct isp_device *isp)
>>  {
>> +arm_iommu_detach_device(isp->dev);
>>  arm_iommu_release_mapping(isp->mapping);
>>  isp->mapping = NULL;
>>  }
>> @@ -1971,13 +1972,15 @@ static int isp_attach_iommu(struct isp_device *isp)
>>  ret = arm_iommu_attach_device(isp->dev, mapping);
>>  if (ret < 0) {
>>  dev_err(isp->dev, "failed to attach device to VA mapping\n");
>> -goto error;
>> +goto error_attach;
> 
> Instead of changing the label here, could you return immediately where the
> previous point of error handling is? No need to add another label.

Yeah, I debated about this while doing the patch, and chose to retain
the previous common return on the error paths. There are only 2 error
paths, so didn't want to mix them up. If you still prefer the mixed
style, I can post a v2.

regards
Suman

> 
> After fixing that you can add:
> 
> Acked-by: Sakari Ailus 
> 
>>  }
>>  
>>  return 0;
>>  
>> +error_attach:
>> +arm_iommu_release_mapping(isp->mapping);
>> +isp->mapping = NULL;
>>  error:
>> -isp_detach_iommu(isp);
>>  return ret;
>>  }
>>  
>>
> 



Re: [PATCH 1/4] dma-buf: add optional invalidate_mappings callback

2018-03-13 Thread Christian König

Am 13.03.2018 um 16:17 schrieb Daniel Vetter:

[SNIP]

I think a helper which both unmaps _and_ waits for all the fences to clear
would be best, with some guarantees that it'll either fail or all the
mappings _will_ be gone. The locking for that one will be hilarious, since
we need to figure out dmabuf->lock vs. the reservation. I kinda prefer we
throw away the dmabuf->lock and superseed it entirely by the reservation
lock.

Big NAK on that. The whole API is asynchronously, e.g. we never block for
any operation to finish.

Otherwise you run into big trouble with cross device GPU resets and stuff
like that.

But how will the unmapping work then? You can't throw the sg list away
before the dma stopped. The dma only stops once the fence is signalled.
The importer can't call dma_buf_detach because the reservation lock is
hogged already by the exporter trying to unmap everything.

How is this supposed to work?


Even after invalidation the sg list stays alive until it is explicitly 
destroyed by the importer using dma_buf_unmap_attachment() which in turn 
is only allowed after all fences have signaled.


The implementation is in ttm_bo_pipeline_gutting(), basically we use the 
same functionality as for pipelined moves/evictions which hangs the old 
backing store on a dummy object and destroys it after all fences signaled.


While the old sg list is still about to be destroyed the importer can 
request a new sg list for the new location of the DMA-buf using 
dma_buf_map_attachment(). This new location becomes valid after the move 
fence in the reservation object is signaled.


So from the CPU point of view multiple sg list could exists at the same 
time which allows us to have a seamless transition from the old to the 
new location from the GPU point of view.



Re GPU might cause a deadlock: Isn't that already a problem if you hold
reservations of buffers used on other gpus, which want those reservations
to complete the gpu reset, but that gpu reset blocks some fence that the
reservation holder is waiting for?


Correct, that's why amdgpu and TTM tries quite hard to never wait for a 
fence while a reservation object is locked.


The only use case I haven't fixed so far is reaping deleted object 
during eviction, but that is only a matter of my free time to fix it.



We have tons of fun with deadlocks against GPU resets, and loots of
testcases, and I kinda get the impression amdgpu is throwing a lot of
issues under the rug through trylock tricks that shut up lockdep, but
don't fix much really.


Hui? Why do you think that? The only trylock I'm aware of is during 
eviction and there it isn't a problem.



btw adding cross-release lockdep annotations for fences will probably turn
up _lots_ more bugs in this area.


At least for amdgpu that should be handled by now.


+*
+* New mappings can be created immediately, but can't be used before the
+* exclusive fence in the dma_bufs reservation object is signaled.
+*/
+   void (*invalidate_mappings)(struct dma_buf_attachment *attach);

Bunch of questions about exact semantics, but I very much like this. And I
think besides those technical details, the overall approach seems sound.

Yeah this initial implementation was buggy like hell. Just wanted to confirm
that the idea is going in the right direction.

I wanted this 7 years ago, idea very much acked :-)


Ok, thanks. Good to know.

Christian.


Re: [PATCH 1/4] dma-buf: add optional invalidate_mappings callback

2018-03-13 Thread Daniel Vetter
On Mon, Mar 12, 2018 at 08:13:15PM +0100, Christian K??nig wrote:
> Am 12.03.2018 um 18:07 schrieb Daniel Vetter:
> > On Fri, Mar 09, 2018 at 08:11:41PM +0100, Christian K??nig wrote:
> > > [SNIP]
> > > +/**
> > > + * dma_buf_invalidate_mappings - invalidate all mappings of this dma_buf
> > > + *
> > > + * @dmabuf:  [in]buffer which mappings should be invalidated
> > > + *
> > > + * Informs all attachmenst that they need to destroy and recreated all 
> > > their
> > > + * mappings.
> > > + */
> > > +void dma_buf_invalidate_mappings(struct dma_buf *dmabuf)
> > > +{
> > > + struct dma_buf_attachment *attach;
> > > +
> > > + reservation_object_assert_held(dmabuf->resv);
> > > +
> > > + list_for_each_entry(attach, >attachments, node)
> > > + attach->invalidate_mappings(attach);
> > To make the locking work I think we also need to require importers to hold
> > the reservation object while attaching/detaching. Otherwise the list walk
> > above could go boom.
> 
> Oh, good point. Going, to fix this.
> 
> > [SNIP]
> > > + /**
> > > +  * @supports_mapping_invalidation:
> > > +  *
> > > +  * True for exporters which supports unpinned DMA-buf operation using
> > > +  * the reservation lock.
> > > +  *
> > > +  * When attachment->invalidate_mappings is set the @map_dma_buf and
> > > +  * @unmap_dma_buf callbacks can be called with the reservation lock
> > > +  * held.
> > > +  */
> > > + bool supports_mapping_invalidation;
> > Why do we need this? Importer could simply always register with the
> > invalidate_mapping hook registered, and exporters could use it when they
> > see fit. That gives us more lockdep coverage to make sure importers use
> > their attachment callbacks correctly (aka they hold the reservation
> > object).
> 
> One sole reason: Backward compability.
> 
> I didn't wanted to audit all those different drivers if they can handle
> being called with the reservation lock held.
> 
> > 
> > > +
> > >   /**
> > >* @map_dma_buf:
> > >*
> > > @@ -326,6 +338,29 @@ struct dma_buf_attachment {
> > >   struct device *dev;
> > >   struct list_head node;
> > >   void *priv;
> > > +
> > > + /**
> > > +  * @invalidate_mappings:
> > > +  *
> > > +  * Optional callback provided by the importer of the attachment which
> > > +  * must be set before mappings are created.
> > This doesn't work, it must be set before the attachment is created,
> > otherwise you race with your invalidate callback.
> 
> Another good point.
> 
> > 
> > I think the simplest option would be to add a new dma_buf_attach_dynamic
> > (well except a less crappy name).
> 
> Well how about adding an optional invalidate_mappings parameter to the
> existing dma_buf_attach?

Not sure that's best, it might confuse dumb importers and you need to
change all the callers. But up to you.

> > > +  *
> > > +  * If provided the exporter can avoid pinning the backing store while
> > > +  * mappings exists.
> > > +  *
> > > +  * The function is called with the lock of the reservation object
> > > +  * associated with the dma_buf held and the mapping function must be
> > > +  * called with this lock held as well. This makes sure that no mapping
> > > +  * is created concurrently with an ongoing invalidation.
> > > +  *
> > > +  * After the callback all existing mappings are still valid until all
> > > +  * fences in the dma_bufs reservation object are signaled, but should be
> > > +  * destroyed by the importer as soon as possible.
> > Do we guarantee that the importer will attach a fence, after which the
> > mapping will be gone? What about re-trying? Or just best effort (i.e. only
> > useful for evicting to try to make room).
> 
> The importer should attach fences for all it's operations with the DMA-buf.
> 
> > I think a helper which both unmaps _and_ waits for all the fences to clear
> > would be best, with some guarantees that it'll either fail or all the
> > mappings _will_ be gone. The locking for that one will be hilarious, since
> > we need to figure out dmabuf->lock vs. the reservation. I kinda prefer we
> > throw away the dmabuf->lock and superseed it entirely by the reservation
> > lock.
> 
> Big NAK on that. The whole API is asynchronously, e.g. we never block for
> any operation to finish.
> 
> Otherwise you run into big trouble with cross device GPU resets and stuff
> like that.

But how will the unmapping work then? You can't throw the sg list away
before the dma stopped. The dma only stops once the fence is signalled.
The importer can't call dma_buf_detach because the reservation lock is
hogged already by the exporter trying to unmap everything.

How is this supposed to work?

Re GPU might cause a deadlock: Isn't that already a problem if you hold
reservations of buffers used on other gpus, which want those reservations
to complete the gpu reset, but that gpu reset blocks some fence that the
reservation holder is waiting for?

We have tons of fun with deadlocks against GPU 

Re: [PATCH 1/3] rcar-vin: remove duplicated check of state in irq handler

2018-03-13 Thread Kieran Bingham
Hi Niklas,

Thanks for the patch series :) - I've been looking forward to seeing this one !

On 10/03/18 01:09, Niklas Söderlund wrote:
> This is an error from when the driver where converted from soc-camera.
> There is absolutely no gain to check the state variable two times to be
> extra sure if the hardware is stopped.

I'll not say this isn't a redundant check ... but isn't the check against two
different states, and thus the remaining check doesn't actually catch the case
now where state == STOPPED ?

(Perhaps state != RUNNING would be better ?, but I haven't checked the rest of
the code)

--
Kieran


> 
> Signed-off-by: Niklas Söderlund 
> ---
>  drivers/media/platform/rcar-vin/rcar-dma.c | 6 --
>  1 file changed, 6 deletions(-)
> 
> diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
> b/drivers/media/platform/rcar-vin/rcar-dma.c
> index 23fdff7a7370842e..b4be75d5009080f7 100644
> --- a/drivers/media/platform/rcar-vin/rcar-dma.c
> +++ b/drivers/media/platform/rcar-vin/rcar-dma.c
> @@ -916,12 +916,6 @@ static irqreturn_t rvin_irq(int irq, void *data)
>   rvin_ack_interrupt(vin);
>   handled = 1;
>  
> - /* Nothing to do if capture status is 'STOPPED' */
> - if (vin->state == STOPPED) {
> - vin_dbg(vin, "IRQ while state stopped\n");
> - goto done;
> - }
> -
>   /* Nothing to do if capture status is 'STOPPING' */
>   if (vin->state == STOPPING) {
>   vin_dbg(vin, "IRQ while state stopping\n");
> 


Re: [RfC PATCH] Add udmabuf misc device

2018-03-13 Thread Daniel Vetter
On Tue, Mar 13, 2018 at 04:48:26PM +0100, Gerd Hoffmann wrote:
> A driver to let userspace turn iovecs into dma-bufs.
> 
> Use case:  Allows qemu pass around dmabufs for the guest framebuffer.
> https://www.kraxel.org/cgit/qemu/log/?h=sirius/udmabuf has an
> experimental patch.
> 
> Also allows qemu to export guest virtio-gpu resources as host dmabufs.
> Should be possible to use it to display guest wayland windows on the
> host display server.  virtio-gpu ressources can be chunked so we will
> actually need multiple iovec entries.  UNTESTED.
> 
> Want collect some feedback on the general approach with this RfC series.
> Can this work?  If not, better ideas?
> 
> Question:  Must this be hooked into some kind of mlock accounting, to
> limit the amout of memory userspace is allowed to pin this way?  Or will
> get_user_pages_fast() handle that for me?

Either mlock account (because it's mlocked defacto), and get_user_pages
won't do that for you.

Or you write the full-blown userptr implementation, including mmu_notifier
support (see i915 or amdgpu), but that also requires Christian Königs
latest ->invalidate_mapping RFC for dma-buf (since atm exporting userptr
buffers is a no-go).

> 
> Known issue:  Driver API isn't complete yet.  Need add some flags, for
> example to support read-only buffers.

dma-buf has no concept of read-only. I don't think we can even enforce
that (not many iommus can enforce this iirc), so pretty much need to
require r/w memory.

> Cc: David Airlie 
> Cc: Tomeu Vizoso 
> Signed-off-by: Gerd Hoffmann 

btw there's also the hyperdmabuf stuff from the xen folks, but imo their
solution of forwarding the entire dma-buf api is over the top. This here
looks _much_ better, pls cc all the hyperdmabuf people on your next
version.

Overall I like the idea, but too lazy to review. Can maybe be bribed :-)

Oh, some kselftests for this stuff would be lovely.
-Daniel
> ---
>  include/uapi/linux/udmabuf.h |  21 
>  drivers/dma-buf/udmabuf.c| 250 
> +++
>  drivers/dma-buf/Kconfig  |   7 ++
>  drivers/dma-buf/Makefile |   1 +
>  4 files changed, 279 insertions(+)
>  create mode 100644 include/uapi/linux/udmabuf.h
>  create mode 100644 drivers/dma-buf/udmabuf.c
> 
> diff --git a/include/uapi/linux/udmabuf.h b/include/uapi/linux/udmabuf.h
> new file mode 100644
> index 00..fd2fa441fe
> --- /dev/null
> +++ b/include/uapi/linux/udmabuf.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +#ifndef _UAPI_LINUX_UDMABUF_H
> +#define _UAPI_LINUX_UDMABUF_H
> +
> +#include 
> +#include 
> +
> +struct udmabuf_iovec {
> + __u64 base;
> + __u64 len;
> +};
> +
> +struct udmabuf_create {
> + __u32 flags;
> + __u32 niov;
> + struct udmabuf_iovec iovs[];
> +};
> +
> +#define UDMABUF_CREATE _IOW(0x42, 0x23, struct udmabuf_create)
> +
> +#endif /* _UAPI_LINUX_UDMABUF_H */
> diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
> new file mode 100644
> index 00..ec012d7ac7
> --- /dev/null
> +++ b/drivers/dma-buf/udmabuf.c
> @@ -0,0 +1,250 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +struct udmabuf {
> + u32 pagecount;
> + struct page **pages;
> +};
> +
> +static int udmabuf_vm_fault(struct vm_fault *vmf)
> +{
> + struct vm_area_struct *vma = vmf->vma;
> + struct udmabuf *ubuf = vma->vm_private_data;
> +
> + if (WARN_ON(vmf->pgoff >= ubuf->pagecount))
> + return VM_FAULT_SIGBUS;
> +
> + vmf->page = ubuf->pages[vmf->pgoff];
> + get_page(vmf->page);
> + return 0;
> +}
> +
> +static const struct vm_operations_struct udmabuf_vm_ops = {
> + .fault = udmabuf_vm_fault,
> +};
> +
> +static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma)
> +{
> + struct udmabuf *ubuf = buf->priv;
> +
> + if ((vma->vm_flags & VM_SHARED) == 0)
> + return -EINVAL;
> +
> + vma->vm_ops = _vm_ops;
> + vma->vm_private_data = ubuf;
> + return 0;
> +}
> +
> +static struct sg_table *map_udmabuf(struct dma_buf_attachment *at,
> + enum dma_data_direction direction)
> +{
> + struct udmabuf *ubuf = at->dmabuf->priv;
> + struct sg_table *sg;
> +
> + sg = kzalloc(sizeof(*sg), GFP_KERNEL);
> + if (!sg)
> + goto err1;
> + if (sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->pagecount,
> +   0, ubuf->pagecount << PAGE_SHIFT,
> +   GFP_KERNEL) < 0)
> + goto err2;
> + if (!dma_map_sg(at->dev, sg->sgl, sg->nents, direction))
> + 

Re: Webcams not recognized on a Dell Latitude 5285 laptop

2018-03-13 Thread Andy Shevchenko
On Sun, Mar 11, 2018 at 2:38 PM, FRÉDÉRIC PARRENIN
 wrote:
> Dear Oliver and all,
>
> So I was expecting linux-4.16 to recognize my webcams, thanks to this new PCI 
> driver Oliver mentioned.
> Therefore I installed 4.16-rc4.
> Unfortunately, there is still no /dev/video* device
>
> Any idea what could be done to have these webcams working?

I guess you need a driver.
Cc: + Sakari, and thus leaving the complete message uncut.

>
> Thanks,
>
> Frederic
>
>
>> De: "FRÉDÉRIC PARRENIN" 
>> À: "Oliver Neukum" 
>> Cc: "linux-usb" 
>> Envoyé: Lundi 11 Décembre 2017 16:39:41
>> Objet: Re: Webcams not recognized on a Dell Latitude 5285 laptop
>
>> > > > it looks like you need the experimental driver posted here
>
>> > > > https://www.spinics.net/lists/linux-media/msg123268.html
>
>> > > Thanks for the information.
>> >> So, if I understand correctly, this driver will not be included in 4.15, 
>> >> will
>> > > it?
>> > > Any idea when this will be included in a release?
>
>> > I have no idea. Could you contact the original developers?
>> > The answer is interesting, but I have no idea.
>
>> It seems it will be included in the 4.16 release:
>
>> https://www.mail-archive.com/linux-media@vger.kernel.org/msg122619.html
>
>> Probably just a bit too late for 4.15.
>
>> Frederic
>
> !!! WARNING!!! New email address: frederic.parre...@univ-grenoble-alpes.fr
> http://pp.ige-grenoble.fr/pageperso/parrenif/index.html
>
> - Mail original -
>> De: "FRÉDÉRIC PARRENIN" 
>> À: "Oliver Neukum" 
>> Cc: "linux-usb" 
>> Envoyé: Lundi 11 Décembre 2017 16:39:41
>> Objet: Re: Webcams not recognized on a Dell Latitude 5285 laptop
>
>> > > > it looks like you need the experimental driver posted here
>
>> > > > https://www.spinics.net/lists/linux-media/msg123268.html
>
>> > > Thanks for the information.
>> >> So, if I understand correctly, this driver will not be included in 4.15, 
>> >> will
>> > > it?
>> > > Any idea when this will be included in a release?
>
>> > I have no idea. Could you contact the original developers?
>> > The answer is interesting, but I have no idea.
>
>> It seems it will be included in the 4.16 release:
>
>> https://www.mail-archive.com/linux-media@vger.kernel.org/msg122619.html
>
>> Probably just a bit too late for 4.15.
>
>> Frederic
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH] media: ngene: avoid unused variable warning

2018-03-13 Thread Daniel Scheller
Am Tue, 13 Mar 2018 14:06:03 +0100
schrieb Arnd Bergmann :

> The newly added pdev variable is only used in an #ifdef, causing a
> build warning without CONFIG_PCI_MSI, unless we move the declaration
> inside the same #ifdef:
> 
> drivers/media/pci/ngene/ngene-core.c: In function 'ngene_start':
> drivers/media/pci/ngene/ngene-core.c:1328:17: error: unused variable 'pdev' 
> [-Werror=unused-variable]
> 
> Fixes: 6795bf626482 ("media: ngene: convert kernellog printing from printk() 
> to dev_*() macros")
> Signed-off-by: Arnd Bergmann 

Acked-by: Daniel Scheller 

Thanks!

> ---
>  drivers/media/pci/ngene/ngene-core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/pci/ngene/ngene-core.c 
> b/drivers/media/pci/ngene/ngene-core.c
> index 3b9a1bfaf6c0..25f16833a475 100644
> --- a/drivers/media/pci/ngene/ngene-core.c
> +++ b/drivers/media/pci/ngene/ngene-core.c
> @@ -1325,7 +1325,6 @@ static int ngene_buffer_config(struct ngene *dev)
>  
>  static int ngene_start(struct ngene *dev)
>  {
> - struct device *pdev = >pci_dev->dev;
>   int stat;
>   int i;
>  
> @@ -1359,6 +1358,7 @@ static int ngene_start(struct ngene *dev)
>  #ifdef CONFIG_PCI_MSI
>   /* enable MSI if kernel and card support it */
>   if (pci_msi_enabled() && dev->card_info->msi_supported) {
> + struct device *pdev = >pci_dev->dev;
>   unsigned long flags;
>  
>   ngwritel(0, NGENE_INT_ENABLE);

Best regards,
Daniel Scheller
-- 
https://github.com/herrnst


Re: [PATCH 2/3] rcar-vin: allocate a scratch buffer at stream start

2018-03-13 Thread Kieran Bingham
Hi Niklas,

On 10/03/18 01:09, Niklas Söderlund wrote:
> Before starting capturing allocate a scratch buffer which can be used by

"Before starting a capture, allocate a..."
  (two 'ings' together doesn't sound right)

> the driver to give to the hardware if no buffers are available from
> userspace. The buffer is not used in this patch but prepares for future
> refactoring where the scratch buffer can be used to avoid the need to
> fallback on single capture mode if userspace don't queue buffers as fast

s/don't/doesn't/ or alternatively s/don't/can't/

> as the VIN driver consumes them.
> 
> Signed-off-by: Niklas Söderlund 

With minor comments attended to:

Reviewed-by: Kieran Bingham 

> ---
>  drivers/media/platform/rcar-vin/rcar-dma.c | 19 +++
>  drivers/media/platform/rcar-vin/rcar-vin.h |  4 
>  2 files changed, 23 insertions(+)
> 
> diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
> b/drivers/media/platform/rcar-vin/rcar-dma.c
> index b4be75d5009080f7..8ea73cdc9a720abe 100644
> --- a/drivers/media/platform/rcar-vin/rcar-dma.c
> +++ b/drivers/media/platform/rcar-vin/rcar-dma.c
> @@ -1070,6 +1070,17 @@ static int rvin_start_streaming(struct vb2_queue *vq, 
> unsigned int count)
>   unsigned long flags;
>   int ret;
>  
> + /* Allocate scratch buffer. */
> + vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage,
> +   >scratch_phys, GFP_KERNEL);
> + if (!vin->scratch) {
> + spin_lock_irqsave(>qlock, flags);
> + return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
> + spin_unlock_irqrestore(>qlock, flags);
> + vin_err(vin, "Failed to allocate scratch buffer\n");
> + return -ENOMEM;
> + }
> +
>   sd = vin_to_source(vin);
>   v4l2_subdev_call(sd, video, s_stream, 1);
>  
> @@ -1085,6 +1096,10 @@ static int rvin_start_streaming(struct vb2_queue *vq, 
> unsigned int count)
>  
>   spin_unlock_irqrestore(>qlock, flags);
>  
> + if (ret)
> + dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
> +   vin->scratch_phys);
> +
>   return ret;
>  }
>  
> @@ -1135,6 +1150,10 @@ static void rvin_stop_streaming(struct vb2_queue *vq)
>  
>   /* disable interrupts */
>   rvin_disable_interrupts(vin);
> +
> + /* Free scratch buffer. */
> + dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
> +   vin->scratch_phys);
>  }
>  
>  static const struct vb2_ops rvin_qops = {
> diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
> b/drivers/media/platform/rcar-vin/rcar-vin.h
> index 5382078143fb3869..11a981d707c7ca47 100644
> --- a/drivers/media/platform/rcar-vin/rcar-vin.h
> +++ b/drivers/media/platform/rcar-vin/rcar-vin.h
> @@ -102,6 +102,8 @@ struct rvin_graph_entity {
>   *
>   * @lock:protects @queue
>   * @queue:   vb2 buffers queue
> + * @scratch: cpu address for scratch buffer
> + * @scratch_phys:pysical address of the scratch buffer

s/pysical/physical/


>   *
>   * @qlock:   protects @queue_buf, @buf_list, @continuous, @sequence
>   *   @state
> @@ -130,6 +132,8 @@ struct rvin_dev {
>  
>   struct mutex lock;
>   struct vb2_queue queue;
> + void *scratch;
> + dma_addr_t scratch_phys;
>  
>   spinlock_t qlock;
>   struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM];
> 


Re: [PATCH v2] media: staging/imx: fill vb2_v4l2_buffer sequence entry

2018-03-13 Thread Fabio Estevam
Hi Peter,

On Tue, Mar 13, 2018 at 7:34 PM, Peter Seiderer  wrote:
> Signed-off-by: Peter Seiderer 

Could you please resend with a commit log explaining the reason for this patch?

Tahnks


[PATCH v3 1/3] [media] dvb_frontend: add S2X and misc. other enums

2018-03-13 Thread Daniel Scheller
From: Daniel Scheller 

Additional enums:
 * FEC ratios 1/4 and 1/3
 * 64/128/256-APSK modulations (DVB-S2X)
 * 15%, 10% and 5% rolloff factors (DVB-S2X)
 * 64K transmission mode (DVB-T2)

Add these enums to the frontend.h docs exceptions aswell (uapi docs are
updated separately).

Also, bump the DVB API version to 5.12 to make userspace aware of these
new enums.

Signed-off-by: Daniel Scheller 
---
v2 to v3:
- All new enum patches squashed into one commit
- DVB API bump to 5.12

Please take note of some additional things in the cover letter.

 Documentation/media/frontend.h.rst.exceptions |  9 +
 drivers/media/dvb-core/dvb_frontend.c |  9 +
 include/uapi/linux/dvb/frontend.h | 29 ++-
 include/uapi/linux/dvb/version.h  |  2 +-
 4 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/Documentation/media/frontend.h.rst.exceptions 
b/Documentation/media/frontend.h.rst.exceptions
index f7c4df620a52..c1643ce93426 100644
--- a/Documentation/media/frontend.h.rst.exceptions
+++ b/Documentation/media/frontend.h.rst.exceptions
@@ -84,6 +84,9 @@ ignore symbol APSK_16
 ignore symbol APSK_32
 ignore symbol DQPSK
 ignore symbol QAM_4_NR
+ignore symbol APSK_64
+ignore symbol APSK_128
+ignore symbol APSK_256
 
 ignore symbol SEC_VOLTAGE_13
 ignore symbol SEC_VOLTAGE_18
@@ -117,6 +120,8 @@ ignore symbol FEC_AUTO
 ignore symbol FEC_3_5
 ignore symbol FEC_9_10
 ignore symbol FEC_2_5
+ignore symbol FEC_1_4
+ignore symbol FEC_1_3
 
 ignore symbol TRANSMISSION_MODE_AUTO
 ignore symbol TRANSMISSION_MODE_1K
@@ -129,6 +134,7 @@ ignore symbol TRANSMISSION_MODE_C1
 ignore symbol TRANSMISSION_MODE_C3780
 ignore symbol TRANSMISSION_MODE_2K
 ignore symbol TRANSMISSION_MODE_8K
+ignore symbol TRANSMISSION_MODE_64K
 
 ignore symbol GUARD_INTERVAL_AUTO
 ignore symbol GUARD_INTERVAL_1_128
@@ -161,6 +167,9 @@ ignore symbol ROLLOFF_35
 ignore symbol ROLLOFF_20
 ignore symbol ROLLOFF_25
 ignore symbol ROLLOFF_AUTO
+ignore symbol ROLLOFF_15
+ignore symbol ROLLOFF_10
+ignore symbol ROLLOFF_5
 
 ignore symbol INVERSION_ON
 ignore symbol INVERSION_OFF
diff --git a/drivers/media/dvb-core/dvb_frontend.c 
b/drivers/media/dvb-core/dvb_frontend.c
index a7ed16e0841d..52c76e32f864 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -2183,6 +2183,15 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
break;
case SYS_DVBS2:
switch (c->rolloff) {
+   case ROLLOFF_5:
+   rolloff = 105;
+   break;
+   case ROLLOFF_10:
+   rolloff = 110;
+   break;
+   case ROLLOFF_15:
+   rolloff = 115;
+   break;
case ROLLOFF_20:
rolloff = 120;
break;
diff --git a/include/uapi/linux/dvb/frontend.h 
b/include/uapi/linux/dvb/frontend.h
index 4f9b4551c534..8bf1c63627a2 100644
--- a/include/uapi/linux/dvb/frontend.h
+++ b/include/uapi/linux/dvb/frontend.h
@@ -296,6 +296,8 @@ enum fe_spectral_inversion {
  * @FEC_3_5:  Forward Error Correction Code 3/5
  * @FEC_9_10: Forward Error Correction Code 9/10
  * @FEC_2_5:  Forward Error Correction Code 2/5
+ * @FEC_1_4:  Forward Error Correction Code 1/4
+ * @FEC_1_3:  Forward Error Correction Code 1/3
  *
  * Please note that not all FEC types are supported by a given standard.
  */
@@ -313,6 +315,8 @@ enum fe_code_rate {
FEC_3_5,
FEC_9_10,
FEC_2_5,
+   FEC_1_4,
+   FEC_1_3,
 };
 
 /**
@@ -331,6 +335,9 @@ enum fe_code_rate {
  * @APSK_32:   32-APSK modulation
  * @DQPSK: DQPSK modulation
  * @QAM_4_NR:  4-QAM-NR modulation
+ * @APSK_64:   64-APSK modulation
+ * @APSK_128:  128-APSK modulation
+ * @APSK_256:  256-APSK modulation
  *
  * Please note that not all modulations are supported by a given standard.
  *
@@ -350,6 +357,9 @@ enum fe_modulation {
APSK_32,
DQPSK,
QAM_4_NR,
+   APSK_64,
+   APSK_128,
+   APSK_256,
 };
 
 /**
@@ -374,6 +384,8 @@ enum fe_modulation {
  * Single Carrier (C=1) transmission mode (DTMB only)
  * @TRANSMISSION_MODE_C3780:
  * Multi Carrier (C=3780) transmission mode (DTMB only)
+ * @TRANSMISSION_MODE_64K:
+ * Transmission mode 64K
  *
  * Please note that not all transmission modes are supported by a given
  * standard.
@@ -388,6 +400,7 @@ enum fe_transmit_mode {
TRANSMISSION_MODE_32K,
TRANSMISSION_MODE_C1,
TRANSMISSION_MODE_C3780,
+   TRANSMISSION_MODE_64K,
 };
 
 /**
@@ -567,20 +580,26 @@ enum fe_pilot {
 
 /**
  * enum fe_rolloff - Rolloff factor
- * @ROLLOFF_35:Roloff factor: α=35%
- * @ROLLOFF_20:Roloff factor: α=20%
- * @ROLLOFF_25:Roloff factor: α=25%
- * @ROLLOFF_AUTO:  Auto-detect the roloff factor.
+ * 

[PATCH v3 3/3] [media] dvb-frontends/stv0910: more detailed reporting in get_frontend()

2018-03-13 Thread Daniel Scheller
From: Daniel Scheller 

The first two missing FECs in the modcod2fec fe_code_rate table were 1/4
and 1/3. Add them as they're now defined by the API. Also, report the
currently used S2 rolloff factor in get_frontend(). For cosmetic reasons,
also change all feroll_off occurences to fe_rolloff. In addition,
Richard Scobie  suggested to report the
currently active delivery system aswell, so add this while at it.

Signed-off-by: Daniel Scheller 
---
v2 to v3:
- Squashed all stv0910 get_frontend() reporting into a single commit

Please take note of some additional things in the cover letter.

 drivers/media/dvb-frontends/stv0910.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/media/dvb-frontends/stv0910.c 
b/drivers/media/dvb-frontends/stv0910.c
index 52355c14fd64..e12bc87de87b 100644
--- a/drivers/media/dvb-frontends/stv0910.c
+++ b/drivers/media/dvb-frontends/stv0910.c
@@ -113,7 +113,7 @@ struct stv {
enum fe_stv0910_mod_cod  mod_cod;
enum dvbs2_fectype   fectype;
u32  pilots;
-   enum fe_stv0910_roll_off feroll_off;
+   enum fe_stv0910_roll_off fe_rolloff;
 
int   is_standard_broadcast;
int   is_vcm;
@@ -541,7 +541,7 @@ static int get_signal_parameters(struct stv *state)
}
state->is_vcm = 0;
state->is_standard_broadcast = 1;
-   state->feroll_off = FE_SAT_35;
+   state->fe_rolloff = FE_SAT_35;
}
return 0;
 }
@@ -1300,14 +1300,14 @@ static int manage_matype_info(struct stv *state)
 
read_regs(state, RSTV0910_P2_MATSTR1 + state->regoff,
  bbheader, 2);
-   state->feroll_off =
+   state->fe_rolloff =
(enum fe_stv0910_roll_off)(bbheader[0] & 0x03);
state->is_vcm = (bbheader[0] & 0x10) == 0;
state->is_standard_broadcast = (bbheader[0] & 0xFC) == 0xF0;
} else if (state->receive_mode == RCVMODE_DVBS) {
state->is_vcm = 0;
state->is_standard_broadcast = 1;
-   state->feroll_off = FE_SAT_35;
+   state->fe_rolloff = FE_SAT_35;
}
return 0;
 }
@@ -1562,7 +1562,7 @@ static int get_frontend(struct dvb_frontend *fe,
APSK_32,
};
const enum fe_code_rate modcod2fec[0x20] = {
-   FEC_NONE, FEC_NONE, FEC_NONE, FEC_2_5,
+   FEC_NONE, FEC_1_4, FEC_1_3, FEC_2_5,
FEC_1_2, FEC_3_5, FEC_2_3, FEC_3_4,
FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10,
FEC_3_5, FEC_2_3, FEC_3_4, FEC_5_6,
@@ -1571,11 +1571,16 @@ static int get_frontend(struct dvb_frontend *fe,
FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9,
FEC_9_10
};
+   const enum fe_rolloff ro2ro[4] = {
+   ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_15,
+   };
read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, );
mc = ((tmp & 0x7c) >> 2);
p->pilot = (tmp & 0x01) ? PILOT_ON : PILOT_OFF;
p->modulation = modcod2mod[mc];
p->fec_inner = modcod2fec[mc];
+   p->rolloff = ro2ro[state->fe_rolloff];
+   p->delivery_system = SYS_DVBS2;
} else if (state->receive_mode == RCVMODE_DVBS) {
read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, );
switch (tmp & 0x1F) {
@@ -1599,6 +1604,7 @@ static int get_frontend(struct dvb_frontend *fe,
break;
}
p->rolloff = ROLLOFF_35;
+   p->delivery_system = SYS_DVBS;
}
 
if (state->receive_mode != RCVMODE_NONE) {
-- 
2.16.1



[PATCH v3 0/3] Add FEC rates, S2X params and 64K transmission

2018-03-13 Thread Daniel Scheller
From: Daniel Scheller 

Note: This v3 doesn't yet implement anything to allow userspace to detect
bits regarding S2X, nor does it implement anything new to report frontend
capabilities. At the moment, the main purpose for this is to enable any
demod frontend to report the current signal parameters more accurate.
Right now this (partially) is for the stv0910 demod, and with additional
hardware currently in development in mind which supports more S2X bits.
There's quite a lot missing from fe_caps right now which almost all
demods autodetect anyway, so let's at least properly report signal stats.

dddvb brings a few additional FEC rates (1/4 and 1/3), 64/128/256APSK
modulations and more rolloff factors (DVB-S2X), and 64K transmission mode
(DVB-T2). These rather trivial patches bring them to mainline, and puts
these missing bits into the stv0910's get_frontend() callback (FEC 1/4
and 1/3 are handled throughout the rest of the demod driver already). In
addition (as suggestion from Richard Scobie), the stv0910 driver now
reports it's active delivery system.

Changes from v2 to v3:
- API bits squashed into one commit, stv0910 changes squashed into another
  single commit
- DVB-S2X related bits added to the uAPI docs
- DVB API bumped to v5.12

Changes from v1 to v2:
- DVB-S2X rolloff factors and reporting
- report of the active delivery system in stv0910:get_frontend()

Daniel Scheller (3):
  [media] dvb_frontend: add S2X and misc. other enums
  [media] docs: documentation bits for S2X and the 64K transmission mode
  [media] dvb-frontends/stv0910: more detailed reporting in
get_frontend()

 Documentation/media/frontend.h.rst.exceptions  |  9 
 .../media/uapi/dvb/fe_property_parameters.rst  | 50 ++
 .../dvb/frontend-property-satellite-systems.rst|  8 ++--
 drivers/media/dvb-core/dvb_frontend.c  |  9 
 drivers/media/dvb-frontends/stv0910.c  | 16 ---
 include/uapi/linux/dvb/frontend.h  | 29 ++---
 include/uapi/linux/dvb/version.h   |  2 +-
 7 files changed, 90 insertions(+), 33 deletions(-)

-- 
2.16.1



[PATCH v3 2/3] [media] docs: documentation bits for S2X and the 64K transmission mode

2018-03-13 Thread Daniel Scheller
From: Daniel Scheller 

Add documentation bits regarding DVB-S2X. Since S2X only brings more
APSK modulations and rolloff's, notice that S2 equals S2X where
appropriate, and mention the additional modulations and rolloff's
at the appropriate places.

Signed-off-by: Daniel Scheller 
---
v2 to v3:
- Added these documentation bits

Please take note of some additional things in the cover letter.

 .../media/uapi/dvb/fe_property_parameters.rst  | 50 ++
 .../dvb/frontend-property-satellite-systems.rst|  8 ++--
 2 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/Documentation/media/uapi/dvb/fe_property_parameters.rst 
b/Documentation/media/uapi/dvb/fe_property_parameters.rst
index 3524dcae4604..fa98a0d6b3fc 100644
--- a/Documentation/media/uapi/dvb/fe_property_parameters.rst
+++ b/Documentation/media/uapi/dvb/fe_property_parameters.rst
@@ -92,7 +92,8 @@ DVB-C Annex B 64-QAM.
 DVB-T  QPSK, 16-QAM and 64-QAM.
 DVB-T2 QPSK, 16-QAM, 64-QAM and 256-QAM.
 DVB-S  No need to set. It supports only QPSK.
-DVB-S2 QPSK, 8-PSK, 16-APSK and 32-APSK.
+DVB-S2(X)  QPSK, 8-PSK, 16-APSK and 32-APSK. DVB-S2X additionally
+   supports 64-APSK, 128-APSK and 256-APSK.
 ISDB-T QPSK, DQPSK, 16-QAM and 64-QAM.
 ISDB-S 8-PSK, QPSK and BPSK.
 === ===
@@ -146,7 +147,8 @@ ISDB-T  5MHz, 6MHz, 7MHz and 8MHz, 
although most places
  :ref:`DTV-SYMBOL-RATE`, and the rolloff factor, with is fixed for
  DVB-C and DVB-S.
 
- For DVB-S2, the rolloff should also be set via :ref:`DTV-ROLLOFF`.
+ For DVB-S2 and DVB-S2X, the rolloff should also be set via
+ :ref:`DTV-ROLLOFF`.
 
 
 .. _DTV-INVERSION:
@@ -215,9 +217,9 @@ Currently not used.
 DTV_PILOT
 =
 
-Used on DVB-S2.
+Used on DVB-S2 and DVB-S2X.
 
-Sets DVB-S2 pilot.
+Sets DVB-S2(X) pilot.
 
 The acceptable values are defined by :c:type:`fe_pilot`.
 
@@ -227,12 +229,17 @@ The acceptable values are defined by :c:type:`fe_pilot`.
 DTV_ROLLOFF
 ===
 
-Used on DVB-S2.
+Used on DVB-S2 and DVB-S2X.
 
-Sets DVB-S2 rolloff.
+Sets DVB-S2(X) rolloff.
 
 The acceptable values are defined by :c:type:`fe_rolloff`.
 
+.. note::
+
+   Rolloff factors 15%, 10% an 5% are part of the DVB-S2X specifications
+   and thus are valid only for S2X-modulated transponders.
+
 
 .. _DTV-DISEQC-SLAVE-REPLY:
 
@@ -267,6 +274,12 @@ Specifies the type of the delivery system.
 
 The acceptable values are defined by :c:type:`fe_delivery_system`.
 
+.. note::
+
+   Since DVB-S2X only defines more rolloff's and more APSK modulations
+   without adding more attributes, DVB-S2X is handled via the DVB-S2
+   delivery system.
+
 
 .. _DTV-ISDBT-PARTIAL-RECEPTION:
 
@@ -894,7 +907,7 @@ The acceptable values are defined by 
:c:type:`fe_transmit_mode`.
 
#. DVB-T specifies 2K and 8K as valid sizes.
 
-   #. DVB-T2 specifies 1K, 2K, 4K, 8K, 16K and 32K.
+   #. DVB-T2 specifies 1K, 2K, 4K, 8K, 16K, 32K and 64K.
 
#. DTMB specifies C1 and C3780.
 
@@ -916,14 +929,14 @@ The acceptable values are defined by 
:c:type:`fe_hierarchy`.
 DTV_STREAM_ID
 =
 
-Used on DVB-S2, DVB-T2 and ISDB-S.
+Used on DVB-S2(X), DVB-T2 and ISDB-S.
 
-DVB-S2, DVB-T2 and ISDB-S support the transmission of several streams on
-a single transport stream. This property enables the digital TV driver to
-handle substream filtering, when supported by the hardware. By default,
+DVB-S2(X), DVB-T2 and ISDB-S support the transmission of several streams
+on a single transport stream. This property enables the digital TV driver
+to handle substream filtering, when supported by the hardware. By default,
 substream filtering is disabled.
 
-For DVB-S2 and DVB-T2, the valid substream id range is from 0 to 255.
+For DVB-S2(X) and DVB-T2, the valid substream id range is from 0 to 255.
 
 For ISDB, the valid substream id range is from 1 to 65535.
 
@@ -994,13 +1007,14 @@ use the special macro LNA_AUTO to set LNA auto
 DTV_SCRAMBLING_SEQUENCE_INDEX
 =
 
-Used on DVB-S2.
+Used on DVB-S2 and DVB-S2X.
 
-This 18 bit field, when present, carries the index of the DVB-S2 physical
-layer scrambling sequence as defined in clause 5.5.4 of EN 302 307.
-There is no explicit signalling method to convey scrambling sequence index
-to the receiver. If S2 satellite delivery system descriptor is available
-it can be used to read the scrambling sequence index (EN 300 468 table 41).
+This 18 bit field, when present, carries the index of the DVB-S2(X)
+physical layer scrambling sequence as defined in clause 5.5.4 of
+EN 302 307. There is no explicit signalling method to convey scrambling
+sequence index to the receiver. If S2 satellite delivery system descriptor
+is available it can be used to read the scrambling sequence 

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

2018-03-13 Thread Kieran Bingham
Hi Niklas

Thank you for this patch ...
I know it has been a lot of work getting this and the VIN together!

On 13/02/18 00:01, Niklas Söderlund wrote:
> A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver
> supports the R-Car Gen3 SoCs where separate CSI-2 hardware blocks are
> connected between the video sources and the video grabbers (VIN).
> 
> Driver is based on a prototype by Koji Matsuoka in the Renesas BSP.
> 
> Signed-off-by: Niklas Söderlund 
> Reviewed-by: Hans Verkuil 

I don't think there's actually anything major in the below - so with any
comments addressed, or specifically ignored you can add my:

Reviewed-by: Kieran Bingham 

tag if you like.


> ---
>  drivers/media/platform/rcar-vin/Kconfig |  12 +
>  drivers/media/platform/rcar-vin/Makefile|   1 +
>  drivers/media/platform/rcar-vin/rcar-csi2.c | 884 
> 
>  3 files changed, 897 insertions(+)
>  create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c
> 
> diff --git a/drivers/media/platform/rcar-vin/Kconfig 
> b/drivers/media/platform/rcar-vin/Kconfig
> index af4c98b44d2e22cb..6875f30c1ae42631 100644
> --- a/drivers/media/platform/rcar-vin/Kconfig
> +++ b/drivers/media/platform/rcar-vin/Kconfig
> @@ -1,3 +1,15 @@
> +config VIDEO_RCAR_CSI2
> + tristate "R-Car MIPI CSI-2 Receiver"
> + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF

I think I recall recently seeing that depending upon OF is redundant and not
necessary (though I think that's minor in this instance)


> + depends on ARCH_RENESAS || COMPILE_TEST
> + select V4L2_FWNODE
> + ---help---
> +   Support for Renesas R-Car MIPI CSI-2 receiver.
> +   Supports R-Car Gen3 SoCs.
> +
> +   To compile this driver as a module, choose M here: the
> +   module will be called rcar-csi2.
> +
>  config VIDEO_RCAR_VIN
>   tristate "R-Car Video Input (VIN) Driver"
>   depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && 
> MEDIA_CONTROLLER
> diff --git a/drivers/media/platform/rcar-vin/Makefile 
> b/drivers/media/platform/rcar-vin/Makefile
> index 48c5632c21dc060b..5ab803d3e7c1aa57 100644
> --- a/drivers/media/platform/rcar-vin/Makefile
> +++ b/drivers/media/platform/rcar-vin/Makefile
> @@ -1,3 +1,4 @@
>  rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o
>  
> +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o
>  obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o
> diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c 
> b/drivers/media/platform/rcar-vin/rcar-csi2.c
> new file mode 100644
> index ..c0c2a763151bc928
> --- /dev/null
> +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
> @@ -0,0 +1,884 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Driver for Renesas R-Car MIPI CSI-2 Receiver
> + *
> + * Copyright (C) 2018 Renesas Electronics Corp.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +/* Register offsets and bits */
> +
> +/* Control Timing Select */
> +#define TREF_REG 0x00
> +#define TREF_TREFBIT(0)
> +
> +/* Software Reset */
> +#define SRST_REG 0x04
> +#define SRST_SRSTBIT(0)
> +
> +/* PHY Operation Control */
> +#define PHYCNT_REG   0x08
> +#define PHYCNT_SHUTDOWNZ BIT(17)
> +#define PHYCNT_RSTZ  BIT(16)
> +#define PHYCNT_ENABLECLK BIT(4)
> +#define PHYCNT_ENABLE_3  BIT(3)
> +#define PHYCNT_ENABLE_2  BIT(2)
> +#define PHYCNT_ENABLE_1  BIT(1)
> +#define PHYCNT_ENABLE_0  BIT(0)
> +
> +/* Checksum Control */
> +#define CHKSUM_REG   0x0c
> +#define CHKSUM_ECC_ENBIT(1)
> +#define CHKSUM_CRC_ENBIT(0)
> +
> +/*
> + * Channel Data Type Select
> + * VCDT[0-15]:  Channel 1 VCDT[16-31]:  Channel 2
> + * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4
> + */
> +#define VCDT_REG 0x10
> +#define VCDT2_REG0x14
> +#define VCDT_VCDTN_ENBIT(15)
> +#define VCDT_SEL_VC(n)   (((n) & 0x3) << 8)
> +#define VCDT_SEL_DTN_ON  BIT(6)
> +#define VCDT_SEL_DT(n)   (((n) & 0x3f) << 0)
> +
> +/* Frame Data Type Select */
> +#define FRDT_REG 0x18
> +
> +/* Field Detection Control */
> +#define FLD_REG  0x1c
> +#define FLD_FLD_NUM(n)   (((n) & 0xff) << 16)
> +#define FLD_FLD_EN4  BIT(3)
> +#define FLD_FLD_EN3  BIT(2)
> +#define FLD_FLD_EN2  BIT(1)
> +#define FLD_FLD_EN   BIT(0)
> +
> +/* Automatic 

Re: [PATCH] media: staging/imx: fill vb2_v4l2_buffer sequence entry

2018-03-13 Thread Peter Seiderer
Hello Steve,

On Tue, 13 Mar 2018 15:03:07 -0700, Steve Longerbeam  
wrote:

> Hi Peter,
> 
> Thanks for the patch.
> 
> This needs to be done in imx-ic-prpencvf.c as well, see
> prp_vb2_buf_done().

Ahh, I see, would you prefer an follow up patch or
an v2 patch doing the changes on mx-media-csi.c and
imx-ic-prpencvf.c at once?

Regards,
Peter

> 
> Steve
> 
> 
> On 03/13/2018 01:00 PM, Peter Seiderer wrote:
> > Signed-off-by: Peter Seiderer 
> > ---
> >   drivers/staging/media/imx/imx-media-csi.c | 5 +
> >   1 file changed, 5 insertions(+)
> >
> > diff --git a/drivers/staging/media/imx/imx-media-csi.c 
> > b/drivers/staging/media/imx/imx-media-csi.c
> > index 5a195f80a24d..3a6a645b9dce 100644
> > --- a/drivers/staging/media/imx/imx-media-csi.c
> > +++ b/drivers/staging/media/imx/imx-media-csi.c
> > @@ -111,6 +111,7 @@ struct csi_priv {
> > struct v4l2_ctrl_handler ctrl_hdlr;
> >   
> > int stream_count; /* streaming counter */
> > +   __u32 frame_sequence; /* frame sequence counter */
> > bool last_eof;   /* waiting for last EOF at stream off */
> > bool nfb4eof;/* NFB4EOF encountered during streaming */
> > struct completion last_eof_comp;
> > @@ -234,8 +235,11 @@ static void csi_vb2_buf_done(struct csi_priv *priv)
> > struct vb2_buffer *vb;
> > dma_addr_t phys;
> >   
> > +   priv->frame_sequence++;
> > +
> > done = priv->active_vb2_buf[priv->ipu_buf_num];
> > if (done) {
> > +   done->vbuf.sequence = priv->frame_sequence;
> > vb = >vbuf.vb2_buf;
> > vb->timestamp = ktime_get_ns();
> > vb2_buffer_done(vb, priv->nfb4eof ?
> > @@ -543,6 +547,7 @@ static int csi_idmac_start(struct csi_priv *priv)
> >   
> > /* init EOF completion waitq */
> > init_completion(>last_eof_comp);
> > +   priv->frame_sequence = 0;
> > priv->last_eof = false;
> > priv->nfb4eof = false;
> > 
> 



Re: [PATCH] media: rc: meson-ir: add timeout on idle

2018-03-13 Thread Matthias Reichl
Hi Sean,

On Mon, Mar 12, 2018 at 01:58:11PM +, Sean Young wrote:
> On Mon, Mar 12, 2018 at 02:20:00PM +0100, Matthias Reichl wrote:
> > On Sun, Mar 11, 2018 at 12:55:19PM +, Sean Young wrote:
> > > That makes complete sense. I'm actually keen to get this lowered, since
> > > this makes it possible to lower the repeat period per-protocol, see
> > > commit d57ea877af38 which had to be reverted (the ite driver will
> > > need fixing up as well before this can happen).
> > 
> > I remember the commit, this issue hit us in LibreELEC testbuilds
> > as well :-)
> > 
> > > Lowering to below 125ms does increase the risk of regressions, so I
> > > am weary of that. Do you think there is benefit in doing this?
> > 
> > I'd also say stick to the 125ms default. The default settings
> > should always be safe ones IMO.
> 
> Well, yes. I just wanted to explore the ideal situation before making
> up our minds.
> 
> > People who want to optimize for the last bit of performance can
> > easily do that on their own, at their own risk.
> > 
> > 
> > Personally I've been using gpio-ir-recv on RPi with the default 125ms
> > timeout and a Hauppauge rc-5 remote for about 2 years now and I've
> > always been happy with that.
> 
> Ok. We should try to get this change for meson-ir ready for v4.17. I can
> write a patch later.

Thanks, it worked fine!

> > I have to acknowledge though that the responsiveness of a remote
> > with short messages, like rc-5, in combination with a low timeout
> > (I tested down to 10ms) is pretty impressive.
> 
> I've been thinking about this problem. What we could do is have a 
> per-protocol maximum space length, and repeat period. The timeout
> can then be set to a maximum space length (+safety margin), and the
> keyup timer can be set to timeout + repeat period (+safety margin).

This sounds like a very good idea. It won't help much with IR
receivers that have no configurable timeout or a large minimum
timeout (ite-cir has 100ms min, probably a hardware limitation?),
but for other receivers this'll be a nice improvement.

> If memory serves, the lirc daemon always sets the timeout with
> LIRC_SET_REC_TIMEOUT, so it would not affect lirc daemon decoding.

Current versions of Lirc (0.9.4 and newer) don't seem to use
LIRC_SET_REC_TIMEOUT but handle timeouts on it's own via a
timeout value in poll().

There's still some generic code in lircd.cpp that supports setting
timeouts via LIRC_SET_REC_TIMEOUT but the default plugin (which
handles /dev/lircX) doesn't implement any of the required 
get/set timeout ioctls.

strace on lircd 0.10.0 also shows that only LIRC_GET_FEATURES is
used.

Older Lirc versions (checked with 0.9.1 source I had here)
seem to be using LIRC_SET_REC_TIMEOUT.

So I think we should be fine here.

Not sure if there are other users of the /dev/lirc interface
that could be affected, I'm only familiar with lirc and the
tools from v4l-utils.

> Anyway, just an idea. Not something for v4.17.

No need to rush things, your idea looks good to me but better
test it thoroughly.

Drop me a line if you have a first implementation, I'd be happy
to help with testing.

so long,

Hias


[PATCH 03/18] af9013: dvbv5 cnr

2018-03-13 Thread Antti Palosaari
Implement dvbv5 cnr.

Signed-off-by: Antti Palosaari 
---
 drivers/media/dvb-frontends/af9013.c  | 88 +--
 drivers/media/dvb-frontends/af9013_priv.h |  1 +
 2 files changed, 84 insertions(+), 5 deletions(-)

diff --git a/drivers/media/dvb-frontends/af9013.c 
b/drivers/media/dvb-frontends/af9013.c
index 4cb6371572c5..b3d08e437478 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -46,6 +46,7 @@ struct af9013_state {
unsigned long set_frontend_jiffies;
unsigned long read_status_jiffies;
unsigned long strength_jiffies;
+   unsigned long cnr_jiffies;
bool first_tune;
bool i2c_gate_state;
unsigned int statistics_step:3;
@@ -179,7 +180,6 @@ static int af9013_statistics_snr_result(struct dvb_frontend 
*fe)
 {
struct af9013_state *state = fe->demodulator_priv;
struct i2c_client *client = state->client;
-   struct dtv_frontend_properties *c = >dtv_property_cache;
int ret, i, len;
unsigned int utmp;
u8 buf[3];
@@ -235,9 +235,6 @@ static int af9013_statistics_snr_result(struct dvb_frontend 
*fe)
}
state->snr = utmp * 10; /* dB/10 */
 
-   c->cnr.stat[0].svalue = 1000 * utmp;
-   c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
-
return 0;
 err:
dev_dbg(>dev, "failed %d\n", ret);
@@ -757,7 +754,7 @@ static int af9013_read_status(struct dvb_frontend *fe, enum 
fe_status *status)
struct dtv_frontend_properties *c = >dtv_property_cache;
int ret, stmp1;
unsigned int utmp, utmp1, utmp2, utmp3, utmp4;
-   u8 buf[2];
+   u8 buf[3];
 
dev_dbg(>dev, "\n");
 
@@ -869,6 +866,87 @@ static int af9013_read_status(struct dvb_frontend *fe, 
enum fe_status *status)
break;
}
 
+   /* CNR */
+   switch (state->fe_status & FE_HAS_VITERBI) {
+   case FE_HAS_VITERBI:
+   if (time_is_after_jiffies(state->cnr_jiffies + 
msecs_to_jiffies(2000)))
+   break;
+
+   /* Check if cnr ready */
+   ret = regmap_read(state->regmap, 0xd2e1, );
+   if (ret)
+   goto err;
+
+   if (!((utmp >> 3) & 0x01)) {
+   dev_dbg(>dev, "cnr not ready\n");
+   break;
+   }
+
+   /* Read value */
+   ret = regmap_bulk_read(state->regmap, 0xd2e3, buf, 3);
+   if (ret)
+   goto err;
+
+   utmp1 = buf[2] << 16 | buf[1] << 8 | buf[0] << 0;
+
+   /* Read current modulation */
+   ret = regmap_read(state->regmap, 0xd3c1, );
+   if (ret)
+   goto err;
+
+   switch ((utmp >> 6) & 3) {
+   case 0:
+   /*
+* QPSK
+* CNR[dB] 13 * -log10((169 - value) / value) + 2.6
+* value [653799, 168], 2.6 / 13 = 3355443
+*/
+   utmp1 = clamp(utmp1, 653799U, 168U);
+   utmp1 = ((u64)(intlog10(utmp1)
+   - intlog10(169 - utmp1)
+   + 3355443) * 13 * 1000) >> 24;
+   break;
+   case 1:
+   /*
+* QAM-16
+* CNR[dB] 6 * log10((value - 37) / (828000 - 
value)) + 15.7
+* value [371105, 827999], 15.7 / 6 = 43900382
+*/
+   utmp1 = clamp(utmp1, 371105U, 827999U);
+   utmp1 = ((u64)(intlog10(utmp1 - 37)
+   - intlog10(828000 - utmp1)
+   + 43900382) * 6 * 1000) >> 24;
+   break;
+   case 2:
+   /*
+* QAM-64
+* CNR[dB] 8 * log10((value - 193000) / (425000 - 
value)) + 23.8
+* value [193246, 424999], 23.8 / 8 = 49912218
+*/
+   utmp1 = clamp(utmp1, 193246U, 424999U);
+   utmp1 = ((u64)(intlog10(utmp1 - 193000)
+   - intlog10(425000 - utmp1)
+   + 49912218) * 8 * 1000) >> 24;
+   break;
+   default:
+   dev_dbg(>dev, "invalid modulation %u\n",
+   (utmp >> 6) & 3);
+   utmp1 = 0;
+   break;
+   }
+
+   dev_dbg(>dev, "cnr %u\n", utmp1);
+
+   state->cnr_jiffies = jiffies;
+
+   c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+   c->cnr.stat[0].svalue = utmp1;
+   break;
+   default:
+   c->cnr.stat[0].scale = 

[PATCH 10/18] af9013: remove all legacy media attach releated stuff

2018-03-13 Thread Antti Palosaari
No one is binding that driver through media attach so remove it and
all related dead code.

Signed-off-by: Antti Palosaari 
---
 drivers/media/dvb-frontends/af9013.c | 80 
 drivers/media/dvb-frontends/af9013.h | 42 ---
 2 files changed, 7 insertions(+), 115 deletions(-)

diff --git a/drivers/media/dvb-frontends/af9013.c 
b/drivers/media/dvb-frontends/af9013.c
index d55c5f67ce0f..15af3e9482df 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -48,7 +48,6 @@ struct af9013_state {
u32 dvbv3_ber;
u32 dvbv3_ucblocks;
bool first_tune;
-   bool i2c_gate_state;
 };
 
 static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval)
@@ -1031,45 +1030,6 @@ static int af9013_sleep(struct dvb_frontend *fe)
return ret;
 }
 
-static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-   int ret;
-   struct af9013_state *state = fe->demodulator_priv;
-   struct i2c_client *client = state->client;
-
-   dev_dbg(>dev, "enable %d\n", enable);
-
-   /* gate already open or close */
-   if (state->i2c_gate_state == enable)
-   return 0;
-
-   if (state->ts_mode == AF9013_TS_MODE_USB)
-   ret = regmap_update_bits(state->regmap, 0xd417, 0x08,
-enable << 3);
-   else
-   ret = regmap_update_bits(state->regmap, 0xd607, 0x04,
-enable << 2);
-   if (ret)
-   goto err;
-
-   state->i2c_gate_state = enable;
-
-   return 0;
-err:
-   dev_dbg(>dev, "failed %d\n", ret);
-   return ret;
-}
-
-static void af9013_release(struct dvb_frontend *fe)
-{
-   struct af9013_state *state = fe->demodulator_priv;
-   struct i2c_client *client = state->client;
-
-   dev_dbg(>dev, "\n");
-
-   i2c_unregister_device(client);
-}
-
 static const struct dvb_frontend_ops af9013_ops;
 
 static int af9013_download_firmware(struct af9013_state *state)
@@ -1172,40 +1132,6 @@ static int af9013_download_firmware(struct af9013_state 
*state)
return ret;
 }
 
-/*
- * XXX: That is wrapper to af9013_probe() via driver core in order to provide
- * proper I2C client for legacy media attach binding.
- * New users must use I2C client binding directly!
- */
-struct dvb_frontend *af9013_attach(const struct af9013_config *config,
-  struct i2c_adapter *i2c)
-{
-   struct i2c_client *client;
-   struct i2c_board_info board_info;
-   struct af9013_platform_data pdata;
-
-   pdata.clk = config->clock;
-   pdata.tuner = config->tuner;
-   pdata.if_frequency = config->if_frequency;
-   pdata.ts_mode = config->ts_mode;
-   pdata.ts_output_pin = 7;
-   pdata.spec_inv = config->spec_inv;
-   memcpy(_version, config->api_version, 
sizeof(pdata.api_version));
-   memcpy(, config->gpio, sizeof(pdata.gpio));
-   pdata.attach_in_use = true;
-
-   memset(_info, 0, sizeof(board_info));
-   strlcpy(board_info.type, "af9013", sizeof(board_info.type));
-   board_info.addr = config->i2c_addr;
-   board_info.platform_data = 
-   client = i2c_new_device(i2c, _info);
-   if (!client || !client->dev.driver)
-   return NULL;
-
-   return pdata.get_dvb_frontend(client);
-}
-EXPORT_SYMBOL(af9013_attach);
-
 static const struct dvb_frontend_ops af9013_ops = {
.delsys = { SYS_DVBT },
.info = {
@@ -1231,8 +1157,6 @@ static const struct dvb_frontend_ops af9013_ops = {
FE_CAN_MUTE_TS
},
 
-   .release = af9013_release,
-
.init = af9013_init,
.sleep = af9013_sleep,
 
@@ -1245,8 +1169,6 @@ static const struct dvb_frontend_ops af9013_ops = {
.read_signal_strength = af9013_read_signal_strength,
.read_ber = af9013_read_ber,
.read_ucblocks = af9013_read_ucblocks,
-
-   .i2c_gate_ctrl = af9013_i2c_gate_ctrl,
 };
 
 static struct dvb_frontend *af9013_get_dvb_frontend(struct i2c_client *client)
@@ -1546,8 +1468,6 @@ static int af9013_probe(struct i2c_client *client,
 
/* Create dvb frontend */
memcpy(>fe.ops, _ops, sizeof(state->fe.ops));
-   if (!pdata->attach_in_use)
-   state->fe.ops.release = NULL;
state->fe.demodulator_priv = state;
 
/* Setup callbacks */
diff --git a/drivers/media/dvb-frontends/af9013.h 
b/drivers/media/dvb-frontends/af9013.h
index ea63ff9242f2..8144d4270b58 100644
--- a/drivers/media/dvb-frontends/af9013.h
+++ b/drivers/media/dvb-frontends/af9013.h
@@ -38,13 +38,6 @@
  * @api_version: Firmware API version.
  * @gpio: GPIOs.
  * @get_dvb_frontend: Get DVB frontend callback.
- *
- * AF9013/5 GPIOs (mostly guessed):
- *   * demod#1-gpio#0 - set demod#2 i2c-addr for dual devices
- *   * demod#1-gpio#1 - xtal setting (?)
- *   * demod#1-gpio#3 - tuner#1
- *   * 

[PATCH 07/18] af9013: convert inittabs suitable for regmap_update_bits

2018-03-13 Thread Antti Palosaari
Convert inttabs to format (reg, mask, val) which are suitable
parameters to pass directly for regmap_update_bits.

Signed-off-by: Antti Palosaari 
---
 drivers/media/dvb-frontends/af9013.c  |   62 +-
 drivers/media/dvb-frontends/af9013_priv.h | 1488 +++--
 2 files changed, 782 insertions(+), 768 deletions(-)

diff --git a/drivers/media/dvb-frontends/af9013.c 
b/drivers/media/dvb-frontends/af9013.c
index e81dc827e1b8..87a55cd67e03 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -843,7 +843,7 @@ static int af9013_init(struct dvb_frontend *fe)
int ret, i, len;
unsigned int utmp;
u8 buf[3];
-   const struct af9013_reg_bit *init;
+   const struct af9013_reg_mask_val *tab;
 
dev_dbg(>dev, "\n");
 
@@ -898,72 +898,66 @@ static int af9013_init(struct dvb_frontend *fe)
if (ret)
goto err;
 
-   /* load OFSM settings */
-   dev_dbg(>dev, "load ofsm settings\n");
-   len = ARRAY_SIZE(ofsm_init);
-   init = ofsm_init;
+   /* Demod core settings */
+   dev_dbg(>dev, "load demod core settings\n");
+   len = ARRAY_SIZE(demod_init_tab);
+   tab = demod_init_tab;
for (i = 0; i < len; i++) {
-   u16 reg = init[i].addr;
-   u8 mask = GENMASK(init[i].pos + init[i].len - 1, init[i].pos);
-   u8 val = init[i].val << init[i].pos;
-
-   ret = regmap_update_bits(state->regmap, reg, mask, val);
+   ret = regmap_update_bits(state->regmap, tab[i].reg, tab[i].mask,
+tab[i].val);
if (ret)
goto err;
}
 
-   /* load tuner specific settings */
+   /* Demod tuner specific settings */
dev_dbg(>dev, "load tuner specific settings\n");
switch (state->tuner) {
case AF9013_TUNER_MXL5003D:
-   len = ARRAY_SIZE(tuner_init_mxl5003d);
-   init = tuner_init_mxl5003d;
+   len = ARRAY_SIZE(tuner_init_tab_mxl5003d);
+   tab = tuner_init_tab_mxl5003d;
break;
case AF9013_TUNER_MXL5005D:
case AF9013_TUNER_MXL5005R:
case AF9013_TUNER_MXL5007T:
-   len = ARRAY_SIZE(tuner_init_mxl5005);
-   init = tuner_init_mxl5005;
+   len = ARRAY_SIZE(tuner_init_tab_mxl5005);
+   tab = tuner_init_tab_mxl5005;
break;
case AF9013_TUNER_ENV77H11D5:
-   len = ARRAY_SIZE(tuner_init_env77h11d5);
-   init = tuner_init_env77h11d5;
+   len = ARRAY_SIZE(tuner_init_tab_env77h11d5);
+   tab = tuner_init_tab_env77h11d5;
break;
case AF9013_TUNER_MT2060:
-   len = ARRAY_SIZE(tuner_init_mt2060);
-   init = tuner_init_mt2060;
+   len = ARRAY_SIZE(tuner_init_tab_mt2060);
+   tab = tuner_init_tab_mt2060;
break;
case AF9013_TUNER_MC44S803:
-   len = ARRAY_SIZE(tuner_init_mc44s803);
-   init = tuner_init_mc44s803;
+   len = ARRAY_SIZE(tuner_init_tab_mc44s803);
+   tab = tuner_init_tab_mc44s803;
break;
case AF9013_TUNER_QT1010:
case AF9013_TUNER_QT1010A:
-   len = ARRAY_SIZE(tuner_init_qt1010);
-   init = tuner_init_qt1010;
+   len = ARRAY_SIZE(tuner_init_tab_qt1010);
+   tab = tuner_init_tab_qt1010;
break;
case AF9013_TUNER_MT2060_2:
-   len = ARRAY_SIZE(tuner_init_mt2060_2);
-   init = tuner_init_mt2060_2;
+   len = ARRAY_SIZE(tuner_init_tab_mt2060_2);
+   tab = tuner_init_tab_mt2060_2;
break;
case AF9013_TUNER_TDA18271:
case AF9013_TUNER_TDA18218:
-   len = ARRAY_SIZE(tuner_init_tda18271);
-   init = tuner_init_tda18271;
+   len = ARRAY_SIZE(tuner_init_tab_tda18271);
+   tab = tuner_init_tab_tda18271;
break;
case AF9013_TUNER_UNKNOWN:
default:
-   len = ARRAY_SIZE(tuner_init_unknown);
-   init = tuner_init_unknown;
+   len = ARRAY_SIZE(tuner_init_tab_unknown);
+   tab = tuner_init_tab_unknown;
break;
}
 
for (i = 0; i < len; i++) {
-   u16 reg = init[i].addr;
-   u8 mask = GENMASK(init[i].pos + init[i].len - 1, init[i].pos);
-   u8 val = init[i].val << init[i].pos;
-
-   ret = regmap_update_bits(state->regmap, reg, mask, val);
+   ret = regmap_update_bits(state->regmap, tab[i].reg, tab[i].mask,
+tab[i].val);
if (ret)
goto err;
}
diff --git a/drivers/media/dvb-frontends/af9013_priv.h 

[PATCH 05/18] af9013: wrap dvbv3 statistics via dvbv5

2018-03-13 Thread Antti Palosaari
Driver has calculated dvbv5 statistics, so use those as a base for
legacy dvbv3 statistics. Wrap and convert needed values to dvbv3,
remove old dvbv3 statistic implementations.

Signed-off-by: Antti Palosaari 
---
 drivers/media/dvb-frontends/af9013.c  | 306 +++---
 drivers/media/dvb-frontends/af9013_priv.h |  68 ---
 2 files changed, 22 insertions(+), 352 deletions(-)

diff --git a/drivers/media/dvb-frontends/af9013.c 
b/drivers/media/dvb-frontends/af9013.c
index a054e39510e0..e81dc827e1b8 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -33,12 +33,6 @@ struct af9013_state {
u8 api_version[4];
u8 gpio[4];
 
-   /* tuner/demod RF and IF AGC limits used for signal strength calc */
-   u8 signal_strength_en, rf_50, rf_80, if_50, if_80;
-   u16 signal_strength;
-   u32 ber;
-   u32 ucblocks;
-   u16 snr;
u32 bandwidth_hz;
enum fe_status fe_status;
/* RF and IF AGC limits used for signal strength calc */
@@ -48,10 +42,12 @@ struct af9013_state {
unsigned long strength_jiffies;
unsigned long cnr_jiffies;
unsigned long ber_ucb_jiffies;
+   u16 dvbv3_snr;
+   u16 dvbv3_strength;
+   u32 dvbv3_ber;
+   u32 dvbv3_ucblocks;
bool first_tune;
bool i2c_gate_state;
-   unsigned int statistics_step:3;
-   struct delayed_work statistics_work;
 };
 
 static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval)
@@ -106,228 +102,6 @@ static int af9013_set_gpio(struct af9013_state *state, u8 
gpio, u8 gpioval)
return ret;
 }
 
-static int af9013_statistics_ber_unc_start(struct dvb_frontend *fe)
-{
-   struct af9013_state *state = fe->demodulator_priv;
-   struct i2c_client *client = state->client;
-   int ret;
-
-   dev_dbg(>dev, "\n");
-
-   /* reset and start BER counter */
-   ret = regmap_update_bits(state->regmap, 0xd391, 0x10, 0x10);
-   if (ret)
-   goto err;
-
-   return 0;
-err:
-   dev_dbg(>dev, "failed %d\n", ret);
-   return ret;
-}
-
-static int af9013_statistics_ber_unc_result(struct dvb_frontend *fe)
-{
-   struct af9013_state *state = fe->demodulator_priv;
-   struct i2c_client *client = state->client;
-   int ret;
-   unsigned int utmp;
-   u8 buf[5];
-
-   dev_dbg(>dev, "\n");
-
-   /* check if error bit count is ready */
-   ret = regmap_read(state->regmap, 0xd391, );
-   if (ret)
-   goto err;
-
-   if (!((utmp >> 4) & 0x01)) {
-   dev_dbg(>dev, "not ready\n");
-   return 0;
-   }
-
-   ret = regmap_bulk_read(state->regmap, 0xd387, buf, 5);
-   if (ret)
-   goto err;
-
-   state->ber = (buf[2] << 16) | (buf[1] << 8) | buf[0];
-   state->ucblocks += (buf[4] << 8) | buf[3];
-
-   return 0;
-err:
-   dev_dbg(>dev, "failed %d\n", ret);
-   return ret;
-}
-
-static int af9013_statistics_snr_start(struct dvb_frontend *fe)
-{
-   struct af9013_state *state = fe->demodulator_priv;
-   struct i2c_client *client = state->client;
-   int ret;
-
-   dev_dbg(>dev, "\n");
-
-   /* start SNR meas */
-   ret = regmap_update_bits(state->regmap, 0xd2e1, 0x08, 0x08);
-   if (ret)
-   goto err;
-
-   return 0;
-err:
-   dev_dbg(>dev, "failed %d\n", ret);
-   return ret;
-}
-
-static int af9013_statistics_snr_result(struct dvb_frontend *fe)
-{
-   struct af9013_state *state = fe->demodulator_priv;
-   struct i2c_client *client = state->client;
-   int ret, i, len;
-   unsigned int utmp;
-   u8 buf[3];
-   u32 snr_val;
-   const struct af9013_snr *uninitialized_var(snr_lut);
-
-   dev_dbg(>dev, "\n");
-
-   /* check if SNR ready */
-   ret = regmap_read(state->regmap, 0xd2e1, );
-   if (ret)
-   goto err;
-
-   if (!((utmp >> 3) & 0x01)) {
-   dev_dbg(>dev, "not ready\n");
-   return 0;
-   }
-
-   /* read value */
-   ret = regmap_bulk_read(state->regmap, 0xd2e3, buf, 3);
-   if (ret)
-   goto err;
-
-   snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0];
-
-   /* read current modulation */
-   ret = regmap_read(state->regmap, 0xd3c1, );
-   if (ret)
-   goto err;
-
-   switch ((utmp >> 6) & 3) {
-   case 0:
-   len = ARRAY_SIZE(qpsk_snr_lut);
-   snr_lut = qpsk_snr_lut;
-   break;
-   case 1:
-   len = ARRAY_SIZE(qam16_snr_lut);
-   snr_lut = qam16_snr_lut;
-   break;
-   case 2:
-   len = ARRAY_SIZE(qam64_snr_lut);
-   snr_lut = qam64_snr_lut;
-   break;
-   default:
-   goto err;
-   }
-
-   for (i = 0; i < len; i++) {
-   utmp = snr_lut[i].snr;
-
-   if 

[PATCH 09/18] af9015: attach demod using i2c binding

2018-03-13 Thread Antti Palosaari
af9013 demod driver has i2c binding. Use it.

Signed-off-by: Antti Palosaari 
---
 drivers/media/usb/dvb-usb-v2/af9015.c | 158 --
 drivers/media/usb/dvb-usb-v2/af9015.h |   4 +-
 2 files changed, 96 insertions(+), 66 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c 
b/drivers/media/usb/dvb-usb-v2/af9015.c
index 7e4cce05b911..f07aa42535e5 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.c
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -148,8 +148,8 @@ static int af9015_write_reg_i2c(struct dvb_usb_device *d, 
u8 addr, u16 reg,
struct af9015_state *state = d_to_priv(d);
struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, };
 
-   if (addr == state->af9013_config[0].i2c_addr ||
-   addr == state->af9013_config[1].i2c_addr)
+   if (addr == state->af9013_i2c_addr[0] ||
+   addr == state->af9013_i2c_addr[1])
req.addr_len = 3;
 
return af9015_ctrl_msg(d, );
@@ -161,8 +161,8 @@ static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 
addr, u16 reg,
struct af9015_state *state = d_to_priv(d);
struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
 
-   if (addr == state->af9013_config[0].i2c_addr ||
-   addr == state->af9013_config[1].i2c_addr)
+   if (addr == state->af9013_i2c_addr[0] ||
+   addr == state->af9013_i2c_addr[1])
req.addr_len = 3;
 
return af9015_ctrl_msg(d, );
@@ -258,7 +258,7 @@ Due to that the only way to select correct tuner is use 
demodulator I2C-gate.
ret = -EOPNOTSUPP;
goto err;
}
-   if (msg[0].addr == state->af9013_config[0].i2c_addr)
+   if (msg[0].addr == state->af9013_i2c_addr[0])
req.cmd = WRITE_MEMORY;
else
req.cmd = WRITE_I2C;
@@ -276,7 +276,7 @@ Due to that the only way to select correct tuner is use 
demodulator I2C-gate.
ret = -EOPNOTSUPP;
goto err;
}
-   if (msg[0].addr == state->af9013_config[0].i2c_addr)
+   if (msg[0].addr == state->af9013_i2c_addr[0])
req.cmd = READ_MEMORY;
else
req.cmd = READ_I2C;
@@ -293,7 +293,7 @@ Due to that the only way to select correct tuner is use 
demodulator I2C-gate.
ret = -EOPNOTSUPP;
goto err;
}
-   if (msg[0].addr == state->af9013_config[0].i2c_addr) {
+   if (msg[0].addr == state->af9013_i2c_addr[0]) {
ret = -EINVAL;
goto err;
}
@@ -478,7 +478,7 @@ static int af9015_read_config(struct dvb_usb_device *d)
if (d->udev->speed == USB_SPEED_FULL)
state->dual_mode = 0;
 
-   state->af9013_config[0].i2c_addr = AF9015_I2C_DEMOD;
+   state->af9013_i2c_addr[0] = AF9015_I2C_DEMOD;
 
if (state->dual_mode) {
/* read 2nd demodulator I2C address */
@@ -487,7 +487,7 @@ static int af9015_read_config(struct dvb_usb_device *d)
if (ret)
goto error;
 
-   state->af9013_config[1].i2c_addr = val >> 1;
+   state->af9013_i2c_addr[1] = val >> 1;
}
 
for (i = 0; i < state->dual_mode + 1; i++) {
@@ -500,20 +500,20 @@ static int af9015_read_config(struct dvb_usb_device *d)
goto error;
switch (val) {
case 0:
-   state->af9013_config[i].clock = 2880;
+   state->af9013_pdata[i].clk = 2880;
break;
case 1:
-   state->af9013_config[i].clock = 2048;
+   state->af9013_pdata[i].clk = 2048;
break;
case 2:
-   state->af9013_config[i].clock = 2800;
+   state->af9013_pdata[i].clk = 2800;
break;
case 3:
-   state->af9013_config[i].clock = 2500;
+   state->af9013_pdata[i].clk = 2500;
break;
}
-   dev_dbg(>dev, "[%d] xtal %02x, clock %u\n",
-   i, val, state->af9013_config[i].clock);
+   dev_dbg(>dev, "[%d] xtal %02x, clk %u\n",
+   i, val, state->af9013_pdata[i].clk);
 
/* IF frequency */
req.addr = AF9015_EEPROM_IF1H + offset;
@@ -521,17 +521,17 @@ static int af9015_read_config(struct dvb_usb_device *d)
if (ret)
goto error;
 
-   state->af9013_config[i].if_frequency = val << 8;
+   state->af9013_pdata[i].if_frequency = val << 8;
 
req.addr = 

[PATCH 02/18] af9013: dvbv5 signal strength

2018-03-13 Thread Antti Palosaari
Implement dvbv5 signal strength estimate. We know tuner dependent
-80dBm and -50dBm agc values, construct line equation and use it to
map agc value to signal strength estimate.

Signed-off-by: Antti Palosaari 
---
 drivers/media/dvb-frontends/af9013.c | 83 +++-
 1 file changed, 81 insertions(+), 2 deletions(-)

diff --git a/drivers/media/dvb-frontends/af9013.c 
b/drivers/media/dvb-frontends/af9013.c
index 30cf837058da..4cb6371572c5 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -41,8 +41,11 @@ struct af9013_state {
u16 snr;
u32 bandwidth_hz;
enum fe_status fe_status;
+   /* RF and IF AGC limits used for signal strength calc */
+   u8 strength_en, rf_agc_50, rf_agc_80, if_agc_50, if_agc_80;
unsigned long set_frontend_jiffies;
unsigned long read_status_jiffies;
+   unsigned long strength_jiffies;
bool first_tune;
bool i2c_gate_state;
unsigned int statistics_step:3;
@@ -751,8 +754,12 @@ static int af9013_read_status(struct dvb_frontend *fe, 
enum fe_status *status)
 {
struct af9013_state *state = fe->demodulator_priv;
struct i2c_client *client = state->client;
-   int ret;
-   unsigned int utmp, utmp1;
+   struct dtv_frontend_properties *c = >dtv_property_cache;
+   int ret, stmp1;
+   unsigned int utmp, utmp1, utmp2, utmp3, utmp4;
+   u8 buf[2];
+
+   dev_dbg(>dev, "\n");
 
/*
 * Return status from the cache if it is younger than 2000ms with the
@@ -791,6 +798,77 @@ static int af9013_read_status(struct dvb_frontend *fe, 
enum fe_status *status)
*status = utmp1;
}
 
+   /* Signal strength */
+   switch (state->strength_en) {
+   case 0:
+   /* Check if we support signal strength */
+   ret = regmap_read(state->regmap, 0x9bee, );
+   if (ret)
+   goto err;
+
+   if ((utmp >> 0) & 0x01) {
+   /* Read agc values for signal strength estimation */
+   ret = regmap_read(state->regmap, 0x9bbd, );
+   if (ret)
+   goto err;
+   ret = regmap_read(state->regmap, 0x9bd0, );
+   if (ret)
+   goto err;
+   ret = regmap_read(state->regmap, 0x9be2, );
+   if (ret)
+   goto err;
+   ret = regmap_read(state->regmap, 0x9be4, );
+   if (ret)
+   goto err;
+
+   state->rf_agc_50 = utmp1;
+   state->rf_agc_80 = utmp2;
+   state->if_agc_50 = utmp3;
+   state->if_agc_80 = utmp4;
+   dev_dbg(>dev,
+   "rf_agc_50 %u, rf_agc_80 %u, if_agc_50 %u, 
if_agc_80 %u\n",
+   utmp1, utmp2, utmp3, utmp4);
+
+   state->strength_en = 1;
+   } else {
+   /* Signal strength is not supported */
+   state->strength_en = 2;
+   break;
+   }
+   /* Fall through */
+   case 1:
+   if (time_is_after_jiffies(state->strength_jiffies + 
msecs_to_jiffies(2000)))
+   break;
+
+   /* Read value */
+   ret = regmap_bulk_read(state->regmap, 0xd07c, buf, 2);
+   if (ret)
+   goto err;
+
+   /*
+* Construct line equation from tuner dependent -80/-50 dBm agc
+* limits and use it to map current agc value to dBm estimate
+*/
+   #define agc_gain (buf[0] + buf[1])
+   #define agc_gain_50dbm (state->rf_agc_50 + state->if_agc_50)
+   #define agc_gain_80dbm (state->rf_agc_80 + state->if_agc_80)
+   stmp1 = 3 * (agc_gain - agc_gain_80dbm) /
+   (agc_gain_50dbm - agc_gain_80dbm) - 8;
+
+   dev_dbg(>dev,
+   "strength %d, agc_gain %d, agc_gain_50dbm %d, 
agc_gain_80dbm %d\n",
+   stmp1, agc_gain, agc_gain_50dbm, agc_gain_80dbm);
+
+   state->strength_jiffies = jiffies;
+
+   c->strength.stat[0].scale = FE_SCALE_DECIBEL;
+   c->strength.stat[0].svalue = stmp1;
+   break;
+   default:
+   c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+   break;
+   }
+
return 0;
 err:
dev_dbg(>dev, "failed %d\n", ret);
@@ -1512,6 +1590,7 @@ static int af9013_probe(struct i2c_client *client,
 
/* Init stats to indicate which stats are supported */
c = >fe.dtv_property_cache;
+   c->strength.len = 1;

[PATCH 06/18] af9015: fix logging

2018-03-13 Thread Antti Palosaari
Pass correct device to dev_* logging functions, which allows us to
remove redundant KBUILD_MODNAME and __func__ parameters from log format.

Signed-off-by: Antti Palosaari 
---
 drivers/media/usb/dvb-usb-v2/af9015.c | 160 +-
 1 file changed, 81 insertions(+), 79 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c 
b/drivers/media/usb/dvb-usb-v2/af9015.c
index 8013659c41b1..7e4cce05b911 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.c
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -29,6 +29,7 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct 
req_t *req)
 #define REQ_HDR_LEN 8 /* send header size */
 #define ACK_HDR_LEN 2 /* rece header size */
struct af9015_state *state = d_to_priv(d);
+   struct usb_interface *intf = d->intf;
int ret, wlen, rlen;
u8 write = 1;
 
@@ -66,8 +67,7 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct 
req_t *req)
case BOOT:
break;
default:
-   dev_err(>udev->dev, "%s: unknown command=%d\n",
-   KBUILD_MODNAME, req->cmd);
+   dev_err(>dev, "unknown cmd %d\n", req->cmd);
ret = -EIO;
goto error;
}
@@ -75,8 +75,8 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct 
req_t *req)
/* buffer overflow check */
if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
(!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
-   dev_err(>udev->dev, "%s: too much data; cmd=%d len=%d\n",
-   KBUILD_MODNAME, req->cmd, req->data_len);
+   dev_err(>dev, "too much data, cmd %u, len %u\n",
+   req->cmd, req->data_len);
ret = -EINVAL;
goto error;
}
@@ -103,8 +103,7 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct 
req_t *req)
 
/* check status */
if (rlen && state->buf[1]) {
-   dev_err(>udev->dev, "%s: command failed=%d\n",
-   KBUILD_MODNAME, state->buf[1]);
+   dev_err(>dev, "cmd failed %u\n", state->buf[1]);
ret = -EIO;
goto error;
}
@@ -206,6 +205,7 @@ static int af9015_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msg[],
 {
struct dvb_usb_device *d = i2c_get_adapdata(adap);
struct af9015_state *state = d_to_priv(d);
+   struct usb_interface *intf = d->intf;
int ret;
u16 addr;
u8 mbox, addr_len;
@@ -307,15 +307,14 @@ Due to that the only way to select correct tuner is use 
demodulator I2C-gate.
ret = af9015_ctrl_msg(d, );
} else {
ret = -EOPNOTSUPP;
-   dev_dbg(>udev->dev, "%s: unknown msg, num %u\n",
-   __func__, num);
+   dev_dbg(>dev, "unknown msg, num %u\n", num);
}
if (ret)
goto err;
 
return num;
 err:
-   dev_dbg(>udev->dev, "%s: failed %d\n", __func__, ret);
+   dev_dbg(>dev, "failed %d\n", ret);
return ret;
 }
 
@@ -331,6 +330,7 @@ static struct i2c_algorithm af9015_i2c_algo = {
 
 static int af9015_identify_state(struct dvb_usb_device *d, const char **name)
 {
+   struct usb_interface *intf = d->intf;
int ret;
u8 reply;
struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, };
@@ -339,7 +339,7 @@ static int af9015_identify_state(struct dvb_usb_device *d, 
const char **name)
if (ret)
return ret;
 
-   dev_dbg(>udev->dev, "%s: reply=%02x\n", __func__, reply);
+   dev_dbg(>dev, "reply %02x\n", reply);
 
if (reply == 0x02)
ret = WARM;
@@ -353,10 +353,12 @@ static int af9015_download_firmware(struct dvb_usb_device 
*d,
const struct firmware *fw)
 {
struct af9015_state *state = d_to_priv(d);
+   struct usb_interface *intf = d->intf;
int i, len, remaining, ret;
struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
u16 checksum = 0;
-   dev_dbg(>udev->dev, "%s:\n", __func__);
+
+   dev_dbg(>dev, "\n");
 
/* calc checksum */
for (i = 0; i < fw->size; i++)
@@ -378,9 +380,8 @@ static int af9015_download_firmware(struct dvb_usb_device 
*d,
 
ret = af9015_ctrl_msg(d, );
if (ret) {
-   dev_err(>udev->dev,
-   "%s: firmware download failed=%d\n",
-   KBUILD_MODNAME, ret);
+   dev_err(>dev, "firmware download failed %d\n",
+   ret);
goto error;
}
}
@@ -390,8 +391,7 @@ static int af9015_download_firmware(struct dvb_usb_device 
*d,
req.data_len = 0;
ret = af9015_ctrl_msg(d, );
if (ret) {
-   

[PATCH 12/18] af9015: use af9013 demod pid filters

2018-03-13 Thread Antti Palosaari
PID filters are moved to af9013 demod driver as those are property of
demod. As pid filters are now implemented correctly by demod driver,
we could enable pid filter support for possible slave demod too on
dual tuner configuration.

Signed-off-by: Antti Palosaari 
---
 drivers/media/usb/dvb-usb-v2/af9015.c | 49 +--
 1 file changed, 18 insertions(+), 31 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c 
b/drivers/media/usb/dvb-usb-v2/af9015.c
index f07aa42535e5..8e2f704c6ca5 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.c
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -474,10 +474,6 @@ static int af9015_read_config(struct dvb_usb_device *d)
state->dual_mode = val;
dev_dbg(>dev, "ts mode %02x\n", state->dual_mode);
 
-   /* disable 2nd adapter because we don't have PID-filters */
-   if (d->udev->speed == USB_SPEED_FULL)
-   state->dual_mode = 0;
-
state->af9013_i2c_addr[0] = AF9015_I2C_DEMOD;
 
if (state->dual_mode) {
@@ -1045,43 +1041,28 @@ static int af9015_tuner_attach(struct dvb_usb_adapter 
*adap)
 
 static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
-   struct dvb_usb_device *d = adap_to_d(adap);
-   struct usb_interface *intf = d->intf;
+   struct af9015_state *state = adap_to_priv(adap);
+   struct af9013_platform_data *pdata = >af9013_pdata[adap->id];
int ret;
 
-   dev_dbg(>dev, "onoff %d\n", onoff);
-
-   if (onoff)
-   ret = af9015_set_reg_bit(d, 0xd503, 0);
-   else
-   ret = af9015_clear_reg_bit(d, 0xd503, 0);
+   mutex_lock(>fe_mutex);
+   ret = pdata->pid_filter_ctrl(adap->fe[0], onoff);
+   mutex_unlock(>fe_mutex);
 
return ret;
 }
 
-static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
-   int onoff)
+static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index,
+u16 pid, int onoff)
 {
-   struct dvb_usb_device *d = adap_to_d(adap);
-   struct usb_interface *intf = d->intf;
+   struct af9015_state *state = adap_to_priv(adap);
+   struct af9013_platform_data *pdata = >af9013_pdata[adap->id];
int ret;
-   u8 idx;
-
-   dev_dbg(>dev, "index %d, pid %04x, onoff %d\n",
-   index, pid, onoff);
 
-   ret = af9015_write_reg(d, 0xd505, (pid & 0xff));
-   if (ret)
-   goto error;
-
-   ret = af9015_write_reg(d, 0xd506, (pid >> 8));
-   if (ret)
-   goto error;
-
-   idx = ((index & 0x1f) | (1 << 5));
-   ret = af9015_write_reg(d, 0xd504, idx);
+   mutex_lock(>fe_mutex);
+   ret = pdata->pid_filter(adap->fe[0], index, pid, onoff);
+   mutex_unlock(>fe_mutex);
 
-error:
return ret;
 }
 
@@ -1448,6 +1429,12 @@ static struct dvb_usb_device_properties af9015_props = {
 
.stream = DVB_USB_STREAM_BULK(0x84, 8, 
TS_USB20_FRAME_SIZE),
}, {
+   .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+   DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+   .pid_filter_count = 32,
+   .pid_filter = af9015_pid_filter,
+   .pid_filter_ctrl = af9015_pid_filter_ctrl,
+
.stream = DVB_USB_STREAM_BULK(0x85, 8, 
TS_USB20_FRAME_SIZE),
},
},
-- 
2.14.3



[PATCH 15/18] af9015: enhance streaming config

2018-03-13 Thread Antti Palosaari
Replace static stream settings by one which enables and disables
stream interface when needed (TS streaming control).

1) Configure both TS IF and USB endpoints according to current use case

2) Disable streaming USB endpoints when streaming is stopped and
enable when streaming is started. Reduces sleep power consumption
slightly.

3) Reduce USB buffersize slightly, from 130848 to 98136 bytes

Signed-off-by: Antti Palosaari 
---
 drivers/media/usb/dvb-usb-v2/af9015.c | 220 ++
 drivers/media/usb/dvb-usb-v2/af9015.h |  14 +--
 2 files changed, 115 insertions(+), 119 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c 
b/drivers/media/usb/dvb-usb-v2/af9015.c
index 1f352307a00a..99e3b14d493e 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.c
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -607,11 +607,121 @@ static int af9015_get_stream_config(struct dvb_frontend 
*fe, u8 *ts_type,
dev_dbg(>dev, "adap %u\n", fe_to_adap(fe)->id);
 
if (d->udev->speed == USB_SPEED_FULL)
-   stream->u.bulk.buffersize = TS_USB11_FRAME_SIZE;
+   stream->u.bulk.buffersize = 5 * 188;
 
return 0;
 }
 
+static int af9015_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+   struct dvb_usb_device *d = fe_to_d(fe);
+   struct af9015_state *state = d_to_priv(d);
+   struct usb_interface *intf = d->intf;
+   int ret;
+   unsigned int utmp1, utmp2, reg1, reg2;
+   u8 buf[2];
+   const unsigned int adap_id = fe_to_adap(fe)->id;
+
+   dev_dbg(>dev, "adap id %d, onoff %d\n", adap_id, onoff);
+
+   if (state->usb_ts_if_configured[adap_id] == false) {
+   dev_dbg(>dev, "set usb and ts interface\n");
+
+   /* USB IF stream settings */
+   utmp1 = (d->udev->speed == USB_SPEED_FULL ? 5 : 87) * 188 / 4;
+   utmp2 = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4;
+
+   buf[0] = (utmp1 >> 0) & 0xff;
+   buf[1] = (utmp1 >> 8) & 0xff;
+   if (adap_id == 0) {
+   /* 1st USB IF (EP4) stream settings */
+   reg1 = 0xdd88;
+   reg2 = 0xdd0c;
+   } else {
+   /* 2nd USB IF (EP5) stream settings */
+   reg1 = 0xdd8a;
+   reg2 = 0xdd0d;
+   }
+
+   ret = af9015_write_regs(d, reg1, buf, 2);
+   if (ret)
+   goto err;
+   ret = af9015_write_reg(d, reg2, utmp2);
+   if (ret)
+   goto err;
+
+   /* TS IF settings */
+   if (state->dual_mode) {
+   ret = af9015_set_reg_bit(d, 0xd50b, 0);
+   if (ret)
+   goto err;
+   ret = af9015_set_reg_bit(d, 0xd520, 4);
+   if (ret)
+   goto err;
+   } else {
+   ret = af9015_clear_reg_bit(d, 0xd50b, 0);
+   if (ret)
+   goto err;
+   ret = af9015_clear_reg_bit(d, 0xd520, 4);
+   if (ret)
+   goto err;
+   }
+
+   state->usb_ts_if_configured[adap_id] = true;
+   }
+
+   if (adap_id == 0 && onoff) {
+   /* Adapter 0 stream on. EP4: clear NAK, enable, clear reset */
+   ret = af9015_clear_reg_bit(d, 0xdd13, 5);
+   if (ret)
+   goto err;
+   ret = af9015_set_reg_bit(d, 0xdd11, 5);
+   if (ret)
+   goto err;
+   ret = af9015_clear_reg_bit(d, 0xd507, 2);
+   if (ret)
+   goto err;
+   } else if (adap_id == 1 && onoff) {
+   /* Adapter 1 stream on. EP5: clear NAK, enable, clear reset */
+   ret = af9015_clear_reg_bit(d, 0xdd13, 6);
+   if (ret)
+   goto err;
+   ret = af9015_set_reg_bit(d, 0xdd11, 6);
+   if (ret)
+   goto err;
+   ret = af9015_clear_reg_bit(d, 0xd50b, 1);
+   if (ret)
+   goto err;
+   } else if (adap_id == 0 && !onoff) {
+   /* Adapter 0 stream off. EP4: set reset, disable, set NAK */
+   ret = af9015_set_reg_bit(d, 0xd507, 2);
+   if (ret)
+   goto err;
+   ret = af9015_clear_reg_bit(d, 0xdd11, 5);
+   if (ret)
+   goto err;
+   ret = af9015_set_reg_bit(d, 0xdd13, 5);
+   if (ret)
+   goto err;
+   } else if (adap_id == 1 && !onoff) {
+   /* Adapter 1 stream off. EP5: set reset, disable, set NAK */
+   ret = af9015_set_reg_bit(d, 0xd50b, 1);
+   if 

[PATCH 13/18] af9015: refactor firmware download

2018-03-13 Thread Antti Palosaari
Small revise, no functional changes.

Signed-off-by: Antti Palosaari 
---
 drivers/media/usb/dvb-usb-v2/af9015.c | 39 +++
 1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c 
b/drivers/media/usb/dvb-usb-v2/af9015.c
index 8e2f704c6ca5..ffd4b225e439 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.c
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -350,52 +350,47 @@ static int af9015_identify_state(struct dvb_usb_device 
*d, const char **name)
 }
 
 static int af9015_download_firmware(struct dvb_usb_device *d,
-   const struct firmware *fw)
+   const struct firmware *firmware)
 {
struct af9015_state *state = d_to_priv(d);
struct usb_interface *intf = d->intf;
-   int i, len, remaining, ret;
+   int ret, i, rem;
struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
-   u16 checksum = 0;
+   u16 checksum;
 
dev_dbg(>dev, "\n");
 
-   /* calc checksum */
-   for (i = 0; i < fw->size; i++)
-   checksum += fw->data[i];
+   /* Calc checksum, we need it when copy firmware to slave demod */
+   for (i = 0, checksum = 0; i < firmware->size; i++)
+   checksum += firmware->data[i];
 
-   state->firmware_size = fw->size;
+   state->firmware_size = firmware->size;
state->firmware_checksum = checksum;
 
-   #define FW_ADDR 0x5100 /* firmware start address */
-   #define LEN_MAX 55 /* max packet size */
-   for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
-   len = remaining;
-   if (len > LEN_MAX)
-   len = LEN_MAX;
-
-   req.data_len = len;
-   req.data = (u8 *) >data[fw->size - remaining];
-   req.addr = FW_ADDR + fw->size - remaining;
-
+   #define LEN_MAX (BUF_LEN - REQ_HDR_LEN) /* Max payload size */
+   for (rem = firmware->size; rem > 0; rem -= LEN_MAX) {
+   req.data_len = min(LEN_MAX, rem);
+   req.data = (u8 *) >data[firmware->size - rem];
+   req.addr = 0x5100 + firmware->size - rem;
ret = af9015_ctrl_msg(d, );
if (ret) {
dev_err(>dev, "firmware download failed %d\n",
ret);
-   goto error;
+   goto err;
}
}
 
-   /* firmware loaded, request boot */
req.cmd = BOOT;
req.data_len = 0;
ret = af9015_ctrl_msg(d, );
if (ret) {
dev_err(>dev, "firmware boot failed %d\n", ret);
-   goto error;
+   goto err;
}
 
-error:
+   return 0;
+err:
+   dev_dbg(>dev, "failed %d\n", ret);
return ret;
 }
 
-- 
2.14.3



[PATCH 04/18] af9013: dvbv5 ber and per

2018-03-13 Thread Antti Palosaari
Implement dvbv5 ber and per.

Signed-off-by: Antti Palosaari 
---
 drivers/media/dvb-frontends/af9013.c | 73 +++-
 1 file changed, 72 insertions(+), 1 deletion(-)

diff --git a/drivers/media/dvb-frontends/af9013.c 
b/drivers/media/dvb-frontends/af9013.c
index b3d08e437478..a054e39510e0 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -47,6 +47,7 @@ struct af9013_state {
unsigned long read_status_jiffies;
unsigned long strength_jiffies;
unsigned long cnr_jiffies;
+   unsigned long ber_ucb_jiffies;
bool first_tune;
bool i2c_gate_state;
unsigned int statistics_step:3;
@@ -754,7 +755,7 @@ static int af9013_read_status(struct dvb_frontend *fe, enum 
fe_status *status)
struct dtv_frontend_properties *c = >dtv_property_cache;
int ret, stmp1;
unsigned int utmp, utmp1, utmp2, utmp3, utmp4;
-   u8 buf[3];
+   u8 buf[7];
 
dev_dbg(>dev, "\n");
 
@@ -947,6 +948,72 @@ static int af9013_read_status(struct dvb_frontend *fe, 
enum fe_status *status)
break;
}
 
+   /* BER / PER */
+   switch (state->fe_status & FE_HAS_SYNC) {
+   case FE_HAS_SYNC:
+   if (time_is_after_jiffies(state->ber_ucb_jiffies + 
msecs_to_jiffies(2000)))
+   break;
+
+   /* Check if ber / ucb is ready */
+   ret = regmap_read(state->regmap, 0xd391, );
+   if (ret)
+   goto err;
+
+   if (!((utmp >> 4) & 0x01)) {
+   dev_dbg(>dev, "ber not ready\n");
+   break;
+   }
+
+   /* Read value */
+   ret = regmap_bulk_read(state->regmap, 0xd385, buf, 7);
+   if (ret)
+   goto err;
+
+   utmp1 = buf[4] << 16 | buf[3] << 8 | buf[2] << 0;
+   utmp2 = (buf[1] << 8 | buf[0] << 0) * 204 * 8;
+   utmp3 = buf[6] << 8 | buf[5] << 0;
+   utmp4 = buf[1] << 8 | buf[0] << 0;
+
+   /* Use 1 TS packets for measure */
+   if (utmp4 != 1) {
+   buf[0] = (1 >> 0) & 0xff;
+   buf[1] = (1 >> 8) & 0xff;
+   ret = regmap_bulk_write(state->regmap, 0xd385, buf, 2);
+   if (ret)
+   goto err;
+   }
+
+   /* Reset ber / ucb counter */
+   ret = regmap_update_bits(state->regmap, 0xd391, 0x20, 0x20);
+   if (ret)
+   goto err;
+
+   dev_dbg(>dev, "post_bit_error %u, post_bit_count %u\n",
+   utmp1, utmp2);
+   dev_dbg(>dev, "block_error %u, block_count %u\n",
+   utmp3, utmp4);
+
+   state->ber_ucb_jiffies = jiffies;
+
+   c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+   c->post_bit_error.stat[0].uvalue += utmp1;
+   c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+   c->post_bit_count.stat[0].uvalue += utmp2;
+
+   c->block_error.stat[0].scale = FE_SCALE_COUNTER;
+   c->block_error.stat[0].uvalue += utmp3;
+   c->block_count.stat[0].scale = FE_SCALE_COUNTER;
+   c->block_count.stat[0].uvalue += utmp4;
+   break;
+   default:
+   c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+   c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+   c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+   c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+   break;
+   }
+
return 0;
 err:
dev_dbg(>dev, "failed %d\n", ret);
@@ -1670,6 +1737,10 @@ static int af9013_probe(struct i2c_client *client,
c = >fe.dtv_property_cache;
c->strength.len = 1;
c->cnr.len = 1;
+   c->post_bit_error.len = 1;
+   c->post_bit_count.len = 1;
+   c->block_error.len = 1;
+   c->block_count.len = 1;
 
dev_info(>dev, "Afatech AF9013 successfully attached\n");
dev_info(>dev, "firmware version: %d.%d.%d.%d\n",
-- 
2.14.3



[PATCH 18/18] af9015: correct some coding style issues

2018-03-13 Thread Antti Palosaari
Correct coding style issues reported mostly by checkpatch.pl.

Signed-off-by: Antti Palosaari 
---
 drivers/media/usb/dvb-usb-v2/af9015.c | 172 +-
 1 file changed, 88 insertions(+), 84 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c 
b/drivers/media/usb/dvb-usb-v2/af9015.c
index 8379ef164fad..39f9ffce3caa 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.c
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -72,17 +72,19 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct 
req_t *req)
goto error;
}
 
-   /* buffer overflow check */
+   /* Buffer overflow check */
if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
-   (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
+   (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
dev_err(>dev, "too much data, cmd %u, len %u\n",
req->cmd, req->data_len);
ret = -EINVAL;
goto error;
}
 
-   /* write receives seq + status = 2 bytes
-  read receives seq + status + data = 2 + N bytes */
+   /*
+* Write receives seq + status = 2 bytes
+* Read receives seq + status + data = 2 + N bytes
+*/
wlen = REQ_HDR_LEN;
rlen = ACK_HDR_LEN;
if (write) {
@@ -96,8 +98,8 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct 
req_t *req)
if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
rlen = 0;
 
-   ret = dvb_usbv2_generic_rw_locked(d,
-   state->buf, wlen, state->buf, rlen);
+   ret = dvb_usbv2_generic_rw_locked(d, state->buf, wlen,
+ state->buf, rlen);
if (ret)
goto error;
 
@@ -118,7 +120,7 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct 
req_t *req)
 }
 
 static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
-   u8 val)
+   u8 val)
 {
struct af9015_state *state = d_to_priv(d);
struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, };
@@ -131,7 +133,7 @@ static int af9015_write_reg_i2c(struct dvb_usb_device *d, 
u8 addr, u16 reg,
 }
 
 static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
-   u8 *val)
+  u8 *val)
 {
struct af9015_state *state = d_to_priv(d);
struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
@@ -144,7 +146,7 @@ static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 
addr, u16 reg,
 }
 
 static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-   int num)
+  int num)
 {
struct dvb_usb_device *d = i2c_get_adapdata(adap);
struct af9015_state *state = d_to_priv(d);
@@ -154,28 +156,29 @@ static int af9015_i2c_xfer(struct i2c_adapter *adap, 
struct i2c_msg msg[],
u8 mbox, addr_len;
struct req_t req;
 
-/*
-The bus lock is needed because there is two tuners both using same I2C-address.
-Due to that the only way to select correct tuner is use demodulator I2C-gate.
-
-
-. AF9015 includes integrated AF9013 demodulator.
-.      .
-.| uC | |   demod| .   |tuner   |
-.|| || .   ||
-.|   AF9015   | |  AF9013/5  | .   |   MXL5003  |
-.||--+I2C---|-/ -|-.-I2C---||
-.||  |  | addr 0x38  | .   |  addr 0xc6 |
-.||  |  || .   ||
-.|..
-|      
-|  |   demod| |tuner   |
-|  || ||
-|  |   AF9013   | |   MXL5003  |
-+I2C---|-/ -|---I2C---||
-   | addr 0x3a  | |  addr 0xc6 |
-   || ||
-*/
+   /*
+* I2C multiplexing:
+* There could be two tuners, both using same I2C address. Demodulator
+* I2C-gate is only possibility to select correct tuner.
+*
+* ...
+* . AF9015 integrates AF9013 demodulator.
+* .     . 
+* .|   USB IF   | |   demod|.|   tuner|
+* .|| ||.   

[PATCH 14/18] af9015: refactor copy firmware to slave demod

2018-03-13 Thread Antti Palosaari
Small improvements.

Signed-off-by: Antti Palosaari 
---
 drivers/media/usb/dvb-usb-v2/af9015.c | 88 +--
 1 file changed, 44 insertions(+), 44 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c 
b/drivers/media/usb/dvb-usb-v2/af9015.c
index ffd4b225e439..1f352307a00a 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.c
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -720,79 +720,79 @@ static int af9015_copy_firmware(struct dvb_usb_device *d)
struct af9015_state *state = d_to_priv(d);
struct usb_interface *intf = d->intf;
int ret;
-   u8 fw_params[4];
-   u8 val, i;
-   struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
-   fw_params };
+   unsigned long timeout;
+   u8 val, firmware_info[4];
+   struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, 4, firmware_info};
 
dev_dbg(>dev, "\n");
 
-   fw_params[0] = state->firmware_size >> 8;
-   fw_params[1] = state->firmware_size & 0xff;
-   fw_params[2] = state->firmware_checksum >> 8;
-   fw_params[3] = state->firmware_checksum & 0xff;
+   firmware_info[0] = (state->firmware_size >> 8) & 0xff;
+   firmware_info[1] = (state->firmware_size >> 0) & 0xff;
+   firmware_info[2] = (state->firmware_checksum >> 8) & 0xff;
+   firmware_info[3] = (state->firmware_checksum >> 0) & 0xff;
 
-   ret = af9015_read_reg_i2c(d, state->af9013_i2c_addr[1],
-   0x98be, );
+   /* Check whether firmware is already running */
+   ret = af9015_read_reg_i2c(d, state->af9013_i2c_addr[1], 0x98be, );
if (ret)
-   goto error;
-   else
-   dev_dbg(>dev, "firmware status %02x\n", val);
+   goto err;
 
-   if (val == 0x0c) /* fw is running, no need for download */
-   goto exit;
+   dev_dbg(>dev, "firmware status %02x\n", val);
 
-   /* set I2C master clock to fast (to speed up firmware copy) */
-   ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
-   if (ret)
-   goto error;
+   if (val == 0x0c)
+   return 0;
 
-   msleep(50);
+   /* Set i2c clock to 625kHz to speed up firmware copy */
+   ret = af9015_write_reg(d, 0xd416, 0x04);
+   if (ret)
+   goto err;
 
-   /* copy firmware */
+   /* Copy firmware from master demod to slave demod */
ret = af9015_ctrl_msg(d, );
-   if (ret)
+   if (ret) {
dev_err(>dev, "firmware copy cmd failed %d\n", ret);
+   goto err;
+   }
 
-   dev_dbg(>dev, "firmware copy done\n");
-
-   /* set I2C master clock back to normal */
-   ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
+   /* Set i2c clock to 125kHz */
+   ret = af9015_write_reg(d, 0xd416, 0x14);
if (ret)
-   goto error;
+   goto err;
 
-   /* request boot firmware */
-   ret = af9015_write_reg_i2c(d, state->af9013_i2c_addr[1],
-   0xe205, 1);
-   dev_dbg(>dev, "firmware boot cmd status %d\n", ret);
+   /* Boot firmware */
+   ret = af9015_write_reg_i2c(d, state->af9013_i2c_addr[1], 0xe205, 0x01);
if (ret)
-   goto error;
+   goto err;
 
-   for (i = 0; i < 15; i++) {
-   msleep(100);
+   /* Poll firmware ready */
+   for (val = 0x00, timeout = jiffies + msecs_to_jiffies(1000);
+!time_after(jiffies, timeout) && val != 0x0c && val != 0x04;) {
+   msleep(20);
 
-   /* check firmware status */
+   /* Check firmware status. 0c=OK, 04=fail */
ret = af9015_read_reg_i2c(d, state->af9013_i2c_addr[1],
-   0x98be, );
-   dev_dbg(>dev, "firmware status cmd status %d, firmware 
status %02x\n",
-   ret, val);
+ 0x98be, );
if (ret)
-   goto error;
+   goto err;
 
-   if (val == 0x0c || val == 0x04) /* success or fail */
-   break;
+   dev_dbg(>dev, "firmware status %02x\n", val);
}
 
+   dev_dbg(>dev, "firmware boot took %u ms\n",
+   jiffies_to_msecs(jiffies) - (jiffies_to_msecs(timeout) - 1000));
+
if (val == 0x04) {
-   ret = -ETIMEDOUT;
+   ret = -ENODEV;
dev_err(>dev, "firmware did not run\n");
+   goto err;
} else if (val != 0x0c) {
ret = -ETIMEDOUT;
dev_err(>dev, "firmware boot timeout\n");
+   goto err;
}
 
-error:
-exit:
+   return 0;
+err:
+   dev_dbg(>dev, "failed %d\n", ret);
return ret;
 }
 
-- 
2.14.3



[PATCH 08/18] af9013: add i2c mux adapter for tuner bus

2018-03-13 Thread Antti Palosaari
Add muxed i2c adapter for demod tuner i2c bus gate control.

Signed-off-by: Antti Palosaari 
---
 drivers/media/dvb-frontends/Kconfig   |   2 +-
 drivers/media/dvb-frontends/af9013.c  | 126 +-
 drivers/media/dvb-frontends/af9013.h  |   1 +
 drivers/media/dvb-frontends/af9013_priv.h |   1 +
 4 files changed, 111 insertions(+), 19 deletions(-)

diff --git a/drivers/media/dvb-frontends/Kconfig 
b/drivers/media/dvb-frontends/Kconfig
index 687086cdb870..0712069fd9fe 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -462,7 +462,7 @@ config DVB_TDA10048
 
 config DVB_AF9013
tristate "Afatech AF9013 demodulator"
-   depends on DVB_CORE && I2C
+   depends on DVB_CORE && I2C && I2C_MUX
select REGMAP
default m if !MEDIA_SUBDRV_AUTOSELECT
help
diff --git a/drivers/media/dvb-frontends/af9013.c 
b/drivers/media/dvb-frontends/af9013.c
index 87a55cd67e03..d55c5f67ce0f 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -23,6 +23,7 @@
 struct af9013_state {
struct i2c_client *client;
struct regmap *regmap;
+   struct i2c_mux_core *muxc;
struct dvb_frontend fe;
u32 clk;
u8 tuner;
@@ -1257,9 +1258,65 @@ static struct dvb_frontend 
*af9013_get_dvb_frontend(struct i2c_client *client)
return >fe;
 }
 
+static struct i2c_adapter *af9013_get_i2c_adapter(struct i2c_client *client)
+{
+   struct af9013_state *state = i2c_get_clientdata(client);
+
+   dev_dbg(>dev, "\n");
+
+   return state->muxc->adapter[0];
+}
+
+/*
+ * XXX: Hackish solution. We use virtual register, reg bit 16, to carry info
+ * about i2c adapter locking. Own locking is needed because i2c mux call has
+ * already locked i2c adapter.
+ */
+static int af9013_select(struct i2c_mux_core *muxc, u32 chan)
+{
+   struct af9013_state *state = i2c_mux_priv(muxc);
+   struct i2c_client *client = state->client;
+   int ret;
+
+   dev_dbg(>dev, "\n");
+
+   if (state->ts_mode == AF9013_TS_MODE_USB)
+   ret = regmap_update_bits(state->regmap, 0x1d417, 0x08, 0x08);
+   else
+   ret = regmap_update_bits(state->regmap, 0x1d607, 0x04, 0x04);
+   if (ret)
+   goto err;
+
+   return 0;
+err:
+   dev_dbg(>dev, "failed %d\n", ret);
+   return ret;
+}
+
+static int af9013_deselect(struct i2c_mux_core *muxc, u32 chan)
+{
+   struct af9013_state *state = i2c_mux_priv(muxc);
+   struct i2c_client *client = state->client;
+   int ret;
+
+   dev_dbg(>dev, "\n");
+
+   if (state->ts_mode == AF9013_TS_MODE_USB)
+   ret = regmap_update_bits(state->regmap, 0x1d417, 0x08, 0x00);
+   else
+   ret = regmap_update_bits(state->regmap, 0x1d607, 0x04, 0x00);
+   if (ret)
+   goto err;
+
+   return 0;
+err:
+   dev_dbg(>dev, "failed %d\n", ret);
+   return ret;
+}
+
 /* Own I2C access routines needed for regmap as chip uses extra command byte */
 static int af9013_wregs(struct i2c_client *client, u8 cmd, u16 reg,
-   const u8 *val, int len)
+   const u8 *val, int len, u8 lock)
 {
int ret;
u8 buf[21];
@@ -1281,7 +1338,12 @@ static int af9013_wregs(struct i2c_client *client, u8 
cmd, u16 reg,
buf[1] = (reg >> 0) & 0xff;
buf[2] = cmd;
memcpy([3], val, len);
-   ret = i2c_transfer(client->adapter, msg, 1);
+
+   if (lock)
+   i2c_lock_adapter(client->adapter);
+   ret = __i2c_transfer(client->adapter, msg, 1);
+   if (lock)
+   i2c_unlock_adapter(client->adapter);
if (ret < 0) {
goto err;
} else if (ret != 1) {
@@ -1296,7 +1358,7 @@ static int af9013_wregs(struct i2c_client *client, u8 
cmd, u16 reg,
 }
 
 static int af9013_rregs(struct i2c_client *client, u8 cmd, u16 reg,
-   u8 *val, int len)
+   u8 *val, int len, u8 lock)
 {
int ret;
u8 buf[3];
@@ -1317,7 +1379,12 @@ static int af9013_rregs(struct i2c_client *client, u8 
cmd, u16 reg,
buf[0] = (reg >> 8) & 0xff;
buf[1] = (reg >> 0) & 0xff;
buf[2] = cmd;
-   ret = i2c_transfer(client->adapter, msg, 2);
+
+   if (lock)
+   i2c_lock_adapter(client->adapter);
+   ret = __i2c_transfer(client->adapter, msg, 2);
+   if (lock)
+   i2c_unlock_adapter(client->adapter);
if (ret < 0) {
goto err;
} else if (ret != 2) {
@@ -1337,25 +1404,27 @@ static int af9013_regmap_write(void *context, const 
void *data, size_t count)
struct af9013_state *state = i2c_get_clientdata(client);
int ret, i;
u8 cmd;
-   u16 reg = ((u8 *)data)[0] << 8|((u8 *)data)[1] << 0;
-   u8 *val = &((u8 *)data)[2];
-   const unsigned int len = count - 2;
+   u8 lock = 

[PATCH 01/18] af9013: change lock detection slightly

2018-03-13 Thread Antti Palosaari
Whilst rewritten largely, the basic logic remains same with one
exception: do not return immediately on success case. We are going to
add statistics that function and cannot return too early.

Signed-off-by: Antti Palosaari 
---
 drivers/media/dvb-frontends/af9013.c | 55 ++--
 1 file changed, 27 insertions(+), 28 deletions(-)

diff --git a/drivers/media/dvb-frontends/af9013.c 
b/drivers/media/dvb-frontends/af9013.c
index b8f3ebfc3e27..30cf837058da 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -752,45 +752,44 @@ static int af9013_read_status(struct dvb_frontend *fe, 
enum fe_status *status)
struct af9013_state *state = fe->demodulator_priv;
struct i2c_client *client = state->client;
int ret;
-   unsigned int utmp;
+   unsigned int utmp, utmp1;
 
/*
 * Return status from the cache if it is younger than 2000ms with the
 * exception of last tune is done during 4000ms.
 */
-   if (time_is_after_jiffies(
-   state->read_status_jiffies + msecs_to_jiffies(2000)) &&
-   time_is_before_jiffies(
-   state->set_frontend_jiffies + msecs_to_jiffies(4000))
-   ) {
-   *status = state->fe_status;
-   return 0;
+   if (time_is_after_jiffies(state->read_status_jiffies + 
msecs_to_jiffies(2000)) &&
+   time_is_before_jiffies(state->set_frontend_jiffies + 
msecs_to_jiffies(4000))) {
+   *status = state->fe_status;
} else {
-   *status = 0;
-   }
+   /* MPEG2 lock */
+   ret = regmap_read(state->regmap, 0xd507, );
+   if (ret)
+   goto err;
 
-   /* MPEG2 lock */
-   ret = regmap_read(state->regmap, 0xd507, );
-   if (ret)
-   goto err;
+   if ((utmp >> 6) & 0x01) {
+   utmp1 = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+   FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+   } else {
+   /* TPS lock */
+   ret = regmap_read(state->regmap, 0xd330, );
+   if (ret)
+   goto err;
 
-   if ((utmp >> 6) & 0x01)
-   *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
-   FE_HAS_SYNC | FE_HAS_LOCK;
+   if ((utmp >> 3) & 0x01)
+   utmp1 = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+   FE_HAS_VITERBI;
+   else
+   utmp1 = 0;
+   }
 
-   if (!*status) {
-   /* TPS lock */
-   ret = regmap_read(state->regmap, 0xd330, );
-   if (ret)
-   goto err;
+   dev_dbg(>dev, "fe_status %02x\n", utmp1);
 
-   if ((utmp >> 3) & 0x01)
-   *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
-   FE_HAS_VITERBI;
-   }
+   state->read_status_jiffies = jiffies;
 
-   state->fe_status = *status;
-   state->read_status_jiffies = jiffies;
+   state->fe_status = utmp1;
+   *status = utmp1;
+   }
 
return 0;
 err:
-- 
2.14.3



[PATCH 17/18] af9015: convert to regmap api

2018-03-13 Thread Antti Palosaari
Use regmap for chip register access.

Signed-off-by: Antti Palosaari 
---
 drivers/media/usb/dvb-usb-v2/Kconfig  |   1 +
 drivers/media/usb/dvb-usb-v2/af9015.c | 209 ++
 drivers/media/usb/dvb-usb-v2/af9015.h |   2 +
 3 files changed, 115 insertions(+), 97 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig 
b/drivers/media/usb/dvb-usb-v2/Kconfig
index 0e4944b2b0f4..09a52aae299a 100644
--- a/drivers/media/usb/dvb-usb-v2/Kconfig
+++ b/drivers/media/usb/dvb-usb-v2/Kconfig
@@ -16,6 +16,7 @@ config DVB_USB_V2
 config DVB_USB_AF9015
tristate "Afatech AF9015 DVB-T USB2.0 support"
depends on DVB_USB_V2
+   select REGMAP
select DVB_AF9013
select DVB_PLL  if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MT2060   if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c 
b/drivers/media/usb/dvb-usb-v2/af9015.c
index 99e3b14d493e..8379ef164fad 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.c
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -117,31 +117,6 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, 
struct req_t *req)
return ret;
 }
 
-static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
-   u8 len)
-{
-   struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
-   val};
-   return af9015_ctrl_msg(d, );
-}
-
-static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 
len)
-{
-   struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
-   val};
-   return af9015_ctrl_msg(d, );
-}
-
-static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
-{
-   return af9015_write_regs(d, addr, , 1);
-}
-
-static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
-{
-   return af9015_read_regs(d, addr, val, 1);
-}
-
 static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
u8 val)
 {
@@ -168,38 +143,6 @@ static int af9015_read_reg_i2c(struct dvb_usb_device *d, 
u8 addr, u16 reg,
return af9015_ctrl_msg(d, );
 }
 
-static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
-{
-   int ret;
-   u8 val, mask = 0x01;
-
-   ret = af9015_read_reg(d, addr, );
-   if (ret)
-   return ret;
-
-   mask <<= bit;
-   if (op) {
-   /* set bit */
-   val |= mask;
-   } else {
-   /* clear bit */
-   mask ^= 0xff;
-   val &= mask;
-   }
-
-   return af9015_write_reg(d, addr, val);
-}
-
-static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
-{
-   return af9015_do_reg_bit(d, addr, bit, 1);
-}
-
-static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
-{
-   return af9015_do_reg_bit(d, addr, bit, 0);
-}
-
 static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
int num)
 {
@@ -642,76 +585,73 @@ static int af9015_streaming_ctrl(struct dvb_frontend *fe, 
int onoff)
reg1 = 0xdd8a;
reg2 = 0xdd0d;
}
-
-   ret = af9015_write_regs(d, reg1, buf, 2);
+   ret = regmap_bulk_write(state->regmap, reg1, buf, 2);
if (ret)
goto err;
-   ret = af9015_write_reg(d, reg2, utmp2);
+   ret = regmap_write(state->regmap, reg2, utmp2);
if (ret)
goto err;
 
/* TS IF settings */
if (state->dual_mode) {
-   ret = af9015_set_reg_bit(d, 0xd50b, 0);
-   if (ret)
-   goto err;
-   ret = af9015_set_reg_bit(d, 0xd520, 4);
-   if (ret)
-   goto err;
+   utmp1 = 0x01;
+   utmp2 = 0x10;
} else {
-   ret = af9015_clear_reg_bit(d, 0xd50b, 0);
-   if (ret)
-   goto err;
-   ret = af9015_clear_reg_bit(d, 0xd520, 4);
-   if (ret)
-   goto err;
+   utmp1 = 0x00;
+   utmp2 = 0x00;
}
+   ret = regmap_update_bits(state->regmap, 0xd50b, 0x01, utmp1);
+   if (ret)
+   goto err;
+   ret = regmap_update_bits(state->regmap, 0xd520, 0x10, utmp2);
+   if (ret)
+   goto err;
 
state->usb_ts_if_configured[adap_id] = true;
}
 
if (adap_id == 0 && onoff) {
/* Adapter 0 stream on. EP4: clear NAK, enable, clear reset */
-   ret = af9015_clear_reg_bit(d, 0xdd13, 5);
+   ret = regmap_update_bits(state->regmap, 0xdd13, 0x20, 0x00);
  

[PATCH 16/18] dvb-usb-v2: add probe/disconnect callbacks

2018-03-13 Thread Antti Palosaari
Add probe and disconnect callbacks that behaves similarly than ones
used commonly on Linux driver model. We need those to get early / late
access to driver in order to use normal probe time stuff, like regmap,
extra bus adapters and so.

Signed-off-by: Antti Palosaari 
---
 drivers/media/usb/dvb-usb-v2/dvb_usb.h  |  4 
 drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 24 
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h 
b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
index d2e80537b2f7..3fd6cc0d6340 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
@@ -203,6 +203,8 @@ struct dvb_usb_adapter_properties {
  * @generic_bulk_ctrl_endpoint_response: bulk control endpoint number for
  *  receive
  * @generic_bulk_ctrl_delay: delay between bulk control sent and receive 
message
+ * @probe: like probe on driver model
+ * @disconnect: like disconnect on driver model
  * @identify_state: called to determine the firmware state (cold or warm) and
  *  return possible firmware file name to be loaded
  * @firmware: name of the firmware file to be loaded
@@ -239,6 +241,8 @@ struct dvb_usb_device_properties {
u8 generic_bulk_ctrl_endpoint_response;
unsigned int generic_bulk_ctrl_delay;
 
+   int (*probe)(struct dvb_usb_device *);
+   void (*disconnect)(struct dvb_usb_device *);
 #define WARM  0
 #define COLD  1
int (*identify_state) (struct dvb_usb_device *, const char **);
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c 
b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
index 2bf3bd81280a..afdcdbf005e9 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
@@ -854,8 +854,6 @@ static int dvb_usbv2_exit(struct dvb_usb_device *d)
dvb_usbv2_remote_exit(d);
dvb_usbv2_adapter_exit(d);
dvb_usbv2_i2c_exit(d);
-   kfree(d->priv);
-   kfree(d);
 
return 0;
 }
@@ -934,7 +932,7 @@ int dvb_usbv2_probe(struct usb_interface *intf,
if (intf->cur_altsetting->desc.bInterfaceNumber !=
d->props->bInterfaceNumber) {
ret = -ENODEV;
-   goto err_free_all;
+   goto err_kfree_d;
}
 
mutex_init(>usb_mutex);
@@ -946,10 +944,16 @@ int dvb_usbv2_probe(struct usb_interface *intf,
dev_err(>udev->dev, "%s: kzalloc() failed\n",
KBUILD_MODNAME);
ret = -ENOMEM;
-   goto err_free_all;
+   goto err_kfree_d;
}
}
 
+   if (d->props->probe) {
+   ret = d->props->probe(d);
+   if (ret)
+   goto err_kfree_priv;
+   }
+
if (d->props->identify_state) {
const char *name = NULL;
ret = d->props->identify_state(d, );
@@ -1001,6 +1005,12 @@ int dvb_usbv2_probe(struct usb_interface *intf,
return 0;
 err_free_all:
dvb_usbv2_exit(d);
+   if (d->props->disconnect)
+   d->props->disconnect(d);
+err_kfree_priv:
+   kfree(d->priv);
+err_kfree_d:
+   kfree(d);
 err:
dev_dbg(>dev, "%s: failed=%d\n", __func__, ret);
return ret;
@@ -1021,6 +1031,12 @@ void dvb_usbv2_disconnect(struct usb_interface *intf)
 
dvb_usbv2_exit(d);
 
+   if (d->props->disconnect)
+   d->props->disconnect(d);
+
+   kfree(d->priv);
+   kfree(d);
+
pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n",
KBUILD_MODNAME, drvname, devname);
kfree(devname);
-- 
2.14.3



[PATCH 11/18] af9013: add pid filter support

2018-03-13 Thread Antti Palosaari
af9013 demod has pid filter. Add support for it.

Signed-off-by: Antti Palosaari 
---
 drivers/media/dvb-frontends/af9013.c | 52 
 drivers/media/dvb-frontends/af9013.h |  5 
 2 files changed, 57 insertions(+)

diff --git a/drivers/media/dvb-frontends/af9013.c 
b/drivers/media/dvb-frontends/af9013.c
index 15af3e9482df..482bce49819a 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -1171,6 +1171,56 @@ static const struct dvb_frontend_ops af9013_ops = {
.read_ucblocks = af9013_read_ucblocks,
 };
 
+static int af9013_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
+{
+   struct af9013_state *state = fe->demodulator_priv;
+   struct i2c_client *client = state->client;
+   int ret;
+
+   dev_dbg(>dev, "onoff %d\n", onoff);
+
+   ret = regmap_update_bits(state->regmap, 0xd503, 0x01, onoff);
+   if (ret)
+   goto err;
+
+   return 0;
+err:
+   dev_dbg(>dev, "failed %d\n", ret);
+   return ret;
+}
+
+static int af9013_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid,
+int onoff)
+{
+   struct af9013_state *state = fe->demodulator_priv;
+   struct i2c_client *client = state->client;
+   int ret;
+   u8 buf[2];
+
+   dev_dbg(>dev, "index %d, pid %04x, onoff %d\n",
+   index, pid, onoff);
+
+   if (pid > 0x1fff) {
+   /* 0x2000 is kernel virtual pid for whole ts (all pids) */
+   ret = 0;
+   goto err;
+   }
+
+   buf[0] = (pid >> 0) & 0xff;
+   buf[1] = (pid >> 8) & 0xff;
+   ret = regmap_bulk_write(state->regmap, 0xd505, buf, 2);
+   if (ret)
+   goto err;
+   ret = regmap_write(state->regmap, 0xd504, onoff << 5 | index << 0);
+   if (ret)
+   goto err;
+
+   return 0;
+err:
+   dev_dbg(>dev, "failed %d\n", ret);
+   return ret;
+}
+
 static struct dvb_frontend *af9013_get_dvb_frontend(struct i2c_client *client)
 {
struct af9013_state *state = i2c_get_clientdata(client);
@@ -1473,6 +1523,8 @@ static int af9013_probe(struct i2c_client *client,
/* Setup callbacks */
pdata->get_dvb_frontend = af9013_get_dvb_frontend;
pdata->get_i2c_adapter = af9013_get_i2c_adapter;
+   pdata->pid_filter = af9013_pid_filter;
+   pdata->pid_filter_ctrl = af9013_pid_filter_ctrl;
 
/* Init stats to indicate which stats are supported */
c = >fe.dtv_property_cache;
diff --git a/drivers/media/dvb-frontends/af9013.h 
b/drivers/media/dvb-frontends/af9013.h
index 8144d4270b58..165ae29ccac4 100644
--- a/drivers/media/dvb-frontends/af9013.h
+++ b/drivers/media/dvb-frontends/af9013.h
@@ -38,6 +38,9 @@
  * @api_version: Firmware API version.
  * @gpio: GPIOs.
  * @get_dvb_frontend: Get DVB frontend callback.
+ * @get_i2c_adapter: Get I2C adapter.
+ * @pid_filter_ctrl: Control PID filter.
+ * @pid_filter: Set PID to PID filter.
  */
 struct af9013_platform_data {
/*
@@ -78,6 +81,8 @@ struct af9013_platform_data {
 
struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *);
struct i2c_adapter* (*get_i2c_adapter)(struct i2c_client *);
+   int (*pid_filter_ctrl)(struct dvb_frontend *, int);
+   int (*pid_filter)(struct dvb_frontend *, u8, u16, int);
 };
 
 /*
-- 
2.14.3



Re: [PATCH] media: staging/imx: fill vb2_v4l2_buffer sequence entry

2018-03-13 Thread Steve Longerbeam

Hi Peter,

Thanks for the patch.

This needs to be done in imx-ic-prpencvf.c as well, see
prp_vb2_buf_done().

Steve


On 03/13/2018 01:00 PM, Peter Seiderer wrote:

Signed-off-by: Peter Seiderer 
---
  drivers/staging/media/imx/imx-media-csi.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index 5a195f80a24d..3a6a645b9dce 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -111,6 +111,7 @@ struct csi_priv {
struct v4l2_ctrl_handler ctrl_hdlr;
  
  	int stream_count; /* streaming counter */

+   __u32 frame_sequence; /* frame sequence counter */
bool last_eof;   /* waiting for last EOF at stream off */
bool nfb4eof;/* NFB4EOF encountered during streaming */
struct completion last_eof_comp;
@@ -234,8 +235,11 @@ static void csi_vb2_buf_done(struct csi_priv *priv)
struct vb2_buffer *vb;
dma_addr_t phys;
  
+	priv->frame_sequence++;

+
done = priv->active_vb2_buf[priv->ipu_buf_num];
if (done) {
+   done->vbuf.sequence = priv->frame_sequence;
vb = >vbuf.vb2_buf;
vb->timestamp = ktime_get_ns();
vb2_buffer_done(vb, priv->nfb4eof ?
@@ -543,6 +547,7 @@ static int csi_idmac_start(struct csi_priv *priv)
  
  	/* init EOF completion waitq */

init_completion(>last_eof_comp);
+   priv->frame_sequence = 0;
priv->last_eof = false;
priv->nfb4eof = false;
  




Re: [PATCH] media: rc: meson-ir: lower timeout and make configurable

2018-03-13 Thread Matthias Reichl
On Mon, Mar 12, 2018 at 09:48:40PM +, Sean Young wrote:
> A timeout of 200ms is much longer than necessary, and delays the decoding
> decoding of a single scancode and the last scancode when a button is being
> held. This makes the remote seem sluggish.
> 
> If the min_timeout and max_timeout values are set, the timeout is
> configurable via the LIRC_SET_REC_TIMEOUT ioctl.
> 
> Signed-off-by: Sean Young 

Tested-by: Matthias Reichl 

Thanks a lot, this is working fine!

so long,

Hias

> ---
>  drivers/media/rc/meson-ir.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
> index 64b0aa4f4db7..f449b35d25e7 100644
> --- a/drivers/media/rc/meson-ir.c
> +++ b/drivers/media/rc/meson-ir.c
> @@ -144,7 +144,9 @@ static int meson_ir_probe(struct platform_device *pdev)
>   ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY;
>   ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
>   ir->rc->rx_resolution = US_TO_NS(MESON_TRATE);
> - ir->rc->timeout = MS_TO_NS(200);
> + ir->rc->min_timeout = 1;
> + ir->rc->timeout = IR_DEFAULT_TIMEOUT;
> + ir->rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
>   ir->rc->driver_name = DRIVER_NAME;
>  
>   spin_lock_init(>lock);
> -- 
> 2.14.3
> 


Re: [PATCH] media: staging/imx: fill vb2_v4l2_buffer sequence entry

2018-03-13 Thread Steve Longerbeam



On 03/13/2018 03:24 PM, Peter Seiderer wrote:

Hello Steve,

On Tue, 13 Mar 2018 15:03:07 -0700, Steve Longerbeam  
wrote:


Hi Peter,

Thanks for the patch.

This needs to be done in imx-ic-prpencvf.c as well, see
prp_vb2_buf_done().

Ahh, I see, would you prefer an follow up patch or
an v2 patch doing the changes on mx-media-csi.c and
imx-ic-prpencvf.c at once?


Hi Peter, a v2 patch would be fine.

Steve



On 03/13/2018 01:00 PM, Peter Seiderer wrote:

Signed-off-by: Peter Seiderer 
---
   drivers/staging/media/imx/imx-media-csi.c | 5 +
   1 file changed, 5 insertions(+)

diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index 5a195f80a24d..3a6a645b9dce 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -111,6 +111,7 @@ struct csi_priv {
struct v4l2_ctrl_handler ctrl_hdlr;
   
   	int stream_count; /* streaming counter */

+   __u32 frame_sequence; /* frame sequence counter */
bool last_eof;   /* waiting for last EOF at stream off */
bool nfb4eof;/* NFB4EOF encountered during streaming */
struct completion last_eof_comp;
@@ -234,8 +235,11 @@ static void csi_vb2_buf_done(struct csi_priv *priv)
struct vb2_buffer *vb;
dma_addr_t phys;
   
+	priv->frame_sequence++;

+
done = priv->active_vb2_buf[priv->ipu_buf_num];
if (done) {
+   done->vbuf.sequence = priv->frame_sequence;
vb = >vbuf.vb2_buf;
vb->timestamp = ktime_get_ns();
vb2_buffer_done(vb, priv->nfb4eof ?
@@ -543,6 +547,7 @@ static int csi_idmac_start(struct csi_priv *priv)
   
   	/* init EOF completion waitq */

init_completion(>last_eof_comp);
+   priv->frame_sequence = 0;
priv->last_eof = false;
priv->nfb4eof = false;
 




Re: [PATCH 02/11] media: vsp1: use kernel __packed for structures

2018-03-13 Thread Kieran Bingham
Hi David,

Just for reference here, I've posted a v2 of this patch now titled:
[PATCH v2 02/11] media: vsp1: Remove packed attributes from aligned structures

which removes the attributes instead of modifying them.

Thanks for the pointers!

Regards

Kieran

On 13/03/18 15:03, Kieran Bingham wrote:
> Hi David,
> 
> On 13/03/18 13:38, David Laight wrote:
>> From: Kieran Bingham [mailto:kieran.bingham+rene...@ideasonboard.com]
>>> On 13/03/18 11:20, David Laight wrote:
 From: Kieran Bingham
> Sent: 09 March 2018 22:04
> The kernel provides a __packed definition to abstract away from the
> compiler specific attributes tag.
>
> Convert all packed structures in VSP1 to use it.
>
> Signed-off-by: Kieran Bingham 
> ---
>  drivers/media/platform/vsp1/vsp1_dl.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
> b/drivers/media/platform/vsp1/vsp1_dl.c
> index 37e2c984fbf3..382e45c2054e 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -29,19 +29,19 @@
>  struct vsp1_dl_header_list {
>   u32 num_bytes;
>   u32 addr;
> -} __attribute__((__packed__));
> +} __packed;
>
>  struct vsp1_dl_header {
>   u32 num_lists;
>   struct vsp1_dl_header_list lists[8];
>   u32 next_header;
>   u32 flags;
> -} __attribute__((__packed__));
> +} __packed;
>
>  struct vsp1_dl_entry {
>   u32 addr;
>   u32 data;
> -} __attribute__((__packed__));
> +} __packed;

 Do these structures ever actually appear in misaligned memory?
 If they don't then they shouldn't be marked 'packed'.
>>>
>>> I believe the declaration is to ensure that the struct definition is not 
>>> altered
>>> by the compiler as these structures specifically define the layout of how 
>>> the
>>> memory is read by the VSP1 hardware.
>>
>> The C language and ABI define structure layouts.
>>
>>> Certainly 2 u32's sequentially stored in a struct are unlikely to be moved 
>>> or
>>> rearranged by the compiler (though I believe it would be free to do so if it
>>> chose without this attribute), but I think the declaration shows the intent 
>>> of
>>> the memory structure.
>>
>> The language requires the fields be in order and the ABI stops the compiler
>> adding 'random' padding.
>>
>>> Isn't this a common approach throughout the kernel when dealing with 
>>> hardware
>>> defined memory structures ?
>>
>> Absolutely not.
>> __packed tells the compiler that the structure might be on any address 
>> boundary.
>> On many architectures this means the compiler must use byte accesses with 
>> shifts
>> and ors for every access.
>> The most a hardware defined structure will have is a compile-time assert
>> that it is the correct size (to avoid silly errors from changes).
> 
> 
> 
> Ok - interesting, I see what you're saying - and certainly don't want the
> compiler to be performing byte accesses on the structures unnecessarily.
> 
> I'm trying to distinguish the difference here. Is the single point that
>  __packed
> 
> causes byte-access, where as
> 
> __attribute__((__packed__));
> 
> does not?
> 
> Looking at the GCC docs [0]: I see that  __attribute__((__packed__)) tells the
> compiler that the "structure or union is placed to minimize the memory 
> required".
> 
> However, the keil compiler docs[1] do certainly declare that __packed causes
> byte alignment.
> 
> I was confused/thrown off here by the Kernel defining __packed as
> __attribute__((packed)) at [2].
> 
> Do __attribute__((packed)) and __attribute__((__packed__)) differ ?
> 
> In which case, from what I've read so far I wish "__packed" was 
> "__unaligned"...
> 
> 
> [0]
> https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute
> 
> [1] http://www.keil.com/support/man/docs/armcc/armcc_chr1359124230195.htm
> 
> [2]
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/compiler-gcc.h?h=v4.16-rc5#n92
> 
> 
> Regards
> 
> Kieran
> 
> 
>>  David
>>


[PATCH v2] media: staging/imx: fill vb2_v4l2_buffer sequence entry

2018-03-13 Thread Peter Seiderer
Signed-off-by: Peter Seiderer 
---
 drivers/staging/media/imx/imx-ic-prpencvf.c | 5 +
 drivers/staging/media/imx/imx-media-csi.c   | 5 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c 
b/drivers/staging/media/imx/imx-ic-prpencvf.c
index ae453fd422f0..eaca74b72114 100644
--- a/drivers/staging/media/imx/imx-ic-prpencvf.c
+++ b/drivers/staging/media/imx/imx-ic-prpencvf.c
@@ -103,6 +103,7 @@ struct prp_priv {
int nfb4eof_irq;
 
int stream_count;
+   __u32 frame_sequence; /* frame sequence counter */
bool last_eof;  /* waiting for last EOF at stream off */
bool nfb4eof;/* NFB4EOF encountered during streaming */
struct completion last_eof_comp;
@@ -208,8 +209,11 @@ static void prp_vb2_buf_done(struct prp_priv *priv, struct 
ipuv3_channel *ch)
struct vb2_buffer *vb;
dma_addr_t phys;
 
+   priv->frame_sequence++;
+
done = priv->active_vb2_buf[priv->ipu_buf_num];
if (done) {
+   done->vbuf.sequence = priv->frame_sequence;
vb = >vbuf.vb2_buf;
vb->timestamp = ktime_get_ns();
vb2_buffer_done(vb, priv->nfb4eof ?
@@ -637,6 +641,7 @@ static int prp_start(struct prp_priv *priv)
 
/* init EOF completion waitq */
init_completion(>last_eof_comp);
+   priv->frame_sequence = 0;
priv->last_eof = false;
priv->nfb4eof = false;
 
diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index 5a195f80a24d..3a6a645b9dce 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -111,6 +111,7 @@ struct csi_priv {
struct v4l2_ctrl_handler ctrl_hdlr;
 
int stream_count; /* streaming counter */
+   __u32 frame_sequence; /* frame sequence counter */
bool last_eof;   /* waiting for last EOF at stream off */
bool nfb4eof;/* NFB4EOF encountered during streaming */
struct completion last_eof_comp;
@@ -234,8 +235,11 @@ static void csi_vb2_buf_done(struct csi_priv *priv)
struct vb2_buffer *vb;
dma_addr_t phys;
 
+   priv->frame_sequence++;
+
done = priv->active_vb2_buf[priv->ipu_buf_num];
if (done) {
+   done->vbuf.sequence = priv->frame_sequence;
vb = >vbuf.vb2_buf;
vb->timestamp = ktime_get_ns();
vb2_buffer_done(vb, priv->nfb4eof ?
@@ -543,6 +547,7 @@ static int csi_idmac_start(struct csi_priv *priv)
 
/* init EOF completion waitq */
init_completion(>last_eof_comp);
+   priv->frame_sequence = 0;
priv->last_eof = false;
priv->nfb4eof = false;
 
-- 
2.16.2



Re: [PATCH 1/4] dma-buf: add optional invalidate_mappings callback

2018-03-13 Thread Christian König

Am 13.03.2018 um 17:00 schrieb Daniel Vetter:

On Tue, Mar 13, 2018 at 04:52:02PM +0100, Christian König wrote:

Am 13.03.2018 um 16:17 schrieb Daniel Vetter:
[SNIP]

Ok, so plan is to support fully pipeline moves and everything, with the
old sg tables lazily cleaned up. I was thinking more about evicting stuff
and throwing it out, where there's not going to be any new sg list but the
object is going to be swapped out.


Yes, exactly. Well my example was the unlikely case when the object is 
swapped out and immediately swapped in again because somebody needs it.




I think some state flow charts (we can do SVG or DOT) in the kerneldoc
would be sweet.Yeah, probably a good idea.


Sounds good and I find it great that you're volunteering for that :D

Ok seriously, my drawing capabilities are a bit underdeveloped. So I 
would prefer if somebody could at least help with that.



Re GPU might cause a deadlock: Isn't that already a problem if you hold
reservations of buffers used on other gpus, which want those reservations
to complete the gpu reset, but that gpu reset blocks some fence that the
reservation holder is waiting for?

Correct, that's why amdgpu and TTM tries quite hard to never wait for a
fence while a reservation object is locked.

We might have a fairly huge mismatch of expectations here :-/


What do you mean with that?


The only use case I haven't fixed so far is reaping deleted object during
eviction, but that is only a matter of my free time to fix it.

Yeah, this is the hard one.


Actually it isn't so hard, it's just that I didn't had time so far to 
clean it up and we never hit that issue so far during our reset testing.


The main point missing just a bit of functionality in the reservation 
object and Chris and I already had a good idea how to implement that.



In general the assumption is that dma_fence will get signalled no matter
what you're doing, assuming the only thing you need is to not block
interrupts. The i915 gpu reset logic to make that work is a bit a work of
art ...


Correct, but I don't understand why that is so hard on i915? Our GPU 
scheduler makes all of that rather trivial, e.g. fences either signal 
correctly or are aborted and set as erroneous after a timeout.



If we expect amdgpu and i915 to cooperate with shared buffers I guess one
has to give in. No idea how to do that best.


Again at least from amdgpu side I don't see much of an issue with that. 
So what exactly do you have in mind here?



We have tons of fun with deadlocks against GPU resets, and loots of
testcases, and I kinda get the impression amdgpu is throwing a lot of
issues under the rug through trylock tricks that shut up lockdep, but
don't fix much really.

Hui? Why do you think that? The only trylock I'm aware of is during eviction
and there it isn't a problem.

mmap fault handler had one too last time I looked, and it smelled fishy.


Good point, never wrapped my head fully around that one either.


btw adding cross-release lockdep annotations for fences will probably turn
up _lots_ more bugs in this area.

At least for amdgpu that should be handled by now.

You're sure? :-)


Yes, except for fallback paths and bootup self tests we simply never 
wait for fences while holding locks.



Trouble is that cross-release wasn't even ever enabled, much less anyone
typed the dma_fence annotations. And just cross-release alone turned up
_lost_ of deadlocks in i915 between fences, async workers (userptr, gpu
reset) and core mm stuff.


Yeah, we had lots of fun with the mm locks as well but as far as I know 
Felix and I already fixed all of them.


Christian.


I'd be seriously surprised if it wouldn't find an entire rats nest of
issues around dma_fence once we enable it.
-Daniel


+*
+* New mappings can be created immediately, but can't be used before the
+* exclusive fence in the dma_bufs reservation object is signaled.
+*/
+   void (*invalidate_mappings)(struct dma_buf_attachment *attach);

Bunch of questions about exact semantics, but I very much like this. And I
think besides those technical details, the overall approach seems sound.

Yeah this initial implementation was buggy like hell. Just wanted to confirm
that the idea is going in the right direction.

I wanted this 7 years ago, idea very much acked :-)


Ok, thanks. Good to know.

Christian.




[PATCH v2 06/11] media: vsp1: Provide VSP1 feature helper macro

2018-03-13 Thread Kieran Bingham
The VSP1 devices define their specific capabilities through features
marked in their device info structure. Various parts of the code read
this info structure to infer if the features are available.

Wrap this into a more readable vsp1_feature(vsp1, f) macro to ensure
that usage is consistent throughout the driver.

Signed-off-by: Kieran Bingham 
---
 drivers/media/platform/vsp1/vsp1.h |  2 ++
 drivers/media/platform/vsp1/vsp1_drv.c | 16 
 drivers/media/platform/vsp1/vsp1_wpf.c |  6 +++---
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h 
b/drivers/media/platform/vsp1/vsp1.h
index 78ef838416b3..1c080538c993 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -69,6 +69,8 @@ struct vsp1_device_info {
bool uapi;
 };
 
+#define vsp1_feature(vsp1, f) ((vsp1)->info->features & (f))
+
 struct vsp1_device {
struct device *dev;
const struct vsp1_device_info *info;
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c 
b/drivers/media/platform/vsp1/vsp1_drv.c
index eed9516e25e1..6fa0019ffc6e 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -268,7 +268,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
}
 
/* Instantiate all the entities. */
-   if (vsp1->info->features & VSP1_HAS_BRS) {
+   if (vsp1_feature(vsp1, VSP1_HAS_BRS)) {
vsp1->brs = vsp1_bru_create(vsp1, VSP1_ENTITY_BRS);
if (IS_ERR(vsp1->brs)) {
ret = PTR_ERR(vsp1->brs);
@@ -278,7 +278,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
list_add_tail(>brs->entity.list_dev, >entities);
}
 
-   if (vsp1->info->features & VSP1_HAS_BRU) {
+   if (vsp1_feature(vsp1, VSP1_HAS_BRU)) {
vsp1->bru = vsp1_bru_create(vsp1, VSP1_ENTITY_BRU);
if (IS_ERR(vsp1->bru)) {
ret = PTR_ERR(vsp1->bru);
@@ -288,7 +288,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
list_add_tail(>bru->entity.list_dev, >entities);
}
 
-   if (vsp1->info->features & VSP1_HAS_CLU) {
+   if (vsp1_feature(vsp1, VSP1_HAS_CLU)) {
vsp1->clu = vsp1_clu_create(vsp1);
if (IS_ERR(vsp1->clu)) {
ret = PTR_ERR(vsp1->clu);
@@ -314,7 +314,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 
list_add_tail(>hst->entity.list_dev, >entities);
 
-   if (vsp1->info->features & VSP1_HAS_HGO && vsp1->info->uapi) {
+   if (vsp1_feature(vsp1, VSP1_HAS_HGO) && vsp1->info->uapi) {
vsp1->hgo = vsp1_hgo_create(vsp1);
if (IS_ERR(vsp1->hgo)) {
ret = PTR_ERR(vsp1->hgo);
@@ -325,7 +325,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
  >entities);
}
 
-   if (vsp1->info->features & VSP1_HAS_HGT && vsp1->info->uapi) {
+   if (vsp1_feature(vsp1, VSP1_HAS_HGT) && vsp1->info->uapi) {
vsp1->hgt = vsp1_hgt_create(vsp1);
if (IS_ERR(vsp1->hgt)) {
ret = PTR_ERR(vsp1->hgt);
@@ -356,7 +356,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
}
}
 
-   if (vsp1->info->features & VSP1_HAS_LUT) {
+   if (vsp1_feature(vsp1, VSP1_HAS_LUT)) {
vsp1->lut = vsp1_lut_create(vsp1);
if (IS_ERR(vsp1->lut)) {
ret = PTR_ERR(vsp1->lut);
@@ -390,7 +390,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
}
}
 
-   if (vsp1->info->features & VSP1_HAS_SRU) {
+   if (vsp1_feature(vsp1, VSP1_HAS_SRU)) {
vsp1->sru = vsp1_sru_create(vsp1);
if (IS_ERR(vsp1->sru)) {
ret = PTR_ERR(vsp1->sru);
@@ -524,7 +524,7 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
vsp1_write(vsp1, VI6_DPR_HSI_ROUTE, VI6_DPR_NODE_UNUSED);
vsp1_write(vsp1, VI6_DPR_BRU_ROUTE, VI6_DPR_NODE_UNUSED);
 
-   if (vsp1->info->features & VSP1_HAS_BRS)
+   if (vsp1_feature(vsp1, VSP1_HAS_BRS))
vsp1_write(vsp1, VI6_DPR_ILV_BRS_ROUTE, VI6_DPR_NODE_UNUSED);
 
vsp1_write(vsp1, VI6_DPR_HGO_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c 
b/drivers/media/platform/vsp1/vsp1_wpf.c
index 68218625549e..f90e474cf2cc 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -146,13 +146,13 @@ static int wpf_init_controls(struct vsp1_rwpf *wpf)
if (wpf->entity.index != 0) {
/* Only WPF0 supports flipping. */
num_flip_ctrls = 0;
-   } else if (vsp1->info->features & VSP1_HAS_WPF_HFLIP) {
+   } else if (vsp1_feature(vsp1, 

[PATCH v2 09/11] media: vsp1: Provide support for extended command pools

2018-03-13 Thread Kieran Bingham
VSPD and VSP-DL devices can provide extended display lists supporting
extended command display list objects.

These extended commands require their own dma memory areas for a header
and body specific to the command type.

Implement a command pool to allocate all necessary memory in a single
DMA allocation to reduce pressure on the TLB, and provide convenient
re-usable command objects for the entities to utilise.

Signed-off-by: Kieran Bingham 

---

v2:
 - Fix spelling typo in commit message
 - constify, and staticify the instantiation of vsp1_extended_commands
 - s/autfld_cmds/autofld_cmds/
 - staticify cmd pool functions (Thanks kbuild-bot)

 drivers/media/platform/vsp1/vsp1_dl.c | 190 +++-
 drivers/media/platform/vsp1/vsp1_dl.h |   3 +-
 2 files changed, 193 insertions(+)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index cd91b50deed1..d8392bd866f1 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -121,6 +121,30 @@ struct vsp1_dl_body_pool {
 };
 
 /**
+ * struct vsp1_cmd_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_cmd_pool {
+   /* DMA allocation */
+   dma_addr_t dma;
+   size_t size;
+   void *mem;
+
+   struct vsp1_dl_ext_cmd *cmds;
+   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
@@ -163,6 +187,7 @@ struct vsp1_dl_list {
  * @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
+ * @autofld_cmds: command pool to support auto-fld interlaced mode
  */
 struct vsp1_dl_manager {
unsigned int index;
@@ -176,6 +201,7 @@ struct vsp1_dl_manager {
struct vsp1_dl_list *pending;
 
struct vsp1_dl_body_pool *pool;
+   struct vsp1_dl_cmd_pool *autofld_cmds;
 };
 
 /* 
-
@@ -339,6 +365,139 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 
reg, u32 data)
 }
 
 /* 
-
+ * Display List Extended Command Management
+ */
+
+enum vsp1_extcmd_type {
+   VSP1_EXTCMD_AUTODISP,
+   VSP1_EXTCMD_AUTOFLD,
+};
+
+struct vsp1_extended_command_info {
+   u16 opcode;
+   size_t body_size;
+} static const vsp1_extended_commands[] = {
+   [VSP1_EXTCMD_AUTODISP] = { 0x02, 96 },
+   [VSP1_EXTCMD_AUTOFLD]  = { 0x03, 160 },
+};
+
+/**
+ * vsp1_dl_cmd_pool_create - Create a pool of commands from a single allocation
+ * @vsp1: The VSP1 device
+ * @type: The command pool type
+ * @num_commands: The quantity of commands to allocate
+ *
+ * Allocate a pool of commands each with enough memory to contain the private
+ * data of each command. The allocation sizes are dependent upon the command
+ * type.
+ *
+ * Return a pointer to a pool on success or NULL if memory can't be allocated.
+ */
+static struct vsp1_dl_cmd_pool *
+vsp1_dl_cmd_pool_create(struct vsp1_device *vsp1, enum vsp1_extcmd_type type,
+   unsigned int num_cmds)
+{
+   struct vsp1_dl_cmd_pool *pool;
+   unsigned int i;
+   size_t cmd_size;
+
+   pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+   if (!pool)
+   return NULL;
+
+   pool->cmds = kcalloc(num_cmds, sizeof(*pool->cmds), GFP_KERNEL);
+   if (!pool->cmds) {
+   kfree(pool);
+   return NULL;
+   }
+
+   cmd_size = sizeof(struct vsp1_dl_ext_cmd_header) +
+  vsp1_extended_commands[type].body_size;
+   cmd_size = ALIGN(cmd_size, 16);
+
+   pool->size = cmd_size * num_cmds;
+   pool->mem = dma_alloc_wc(vsp1->bus_master, pool->size, >dma,
+GFP_KERNEL);
+   if (!pool->mem) {
+   kfree(pool->cmds);
+   kfree(pool);
+   return NULL;
+   }
+
+   spin_lock_init(>lock);
+   INIT_LIST_HEAD(>free);
+
+   for (i = 0; i < num_cmds; ++i) {
+   struct vsp1_dl_ext_cmd *cmd = >cmds[i];
+   size_t cmd_offset = i * cmd_size;
+   size_t data_offset = sizeof(struct vsp1_dl_ext_cmd_header) +
+cmd_offset;
+
+   cmd->pool = pool;
+   cmd->cmd_opcode = vsp1_extended_commands[type].opcode;
+
+   /* TODO: Auto-disp can utilise more than one command per cmd */
+   

[PATCH v2 10/11] media: vsp1: Support Interlaced display pipelines

2018-03-13 Thread Kieran Bingham
Calculate the top and bottom fields for the interlaced frames and
utilise the extended display list command feature to implement the
auto-field operations. This allows the DU to update the VSP2 registers
dynamically based upon the currently processing field.

Signed-off-by: Kieran Bingham 

---

v2:
 - fix erroneous BIT value which enabled interlaced
 - fix field handling at frame_end interrupt

 drivers/media/platform/vsp1/vsp1_dl.c   | 10 -
 drivers/media/platform/vsp1/vsp1_drm.c  | 11 -
 drivers/media/platform/vsp1/vsp1_regs.h |  1 +-
 drivers/media/platform/vsp1/vsp1_rpf.c  | 72 --
 drivers/media/platform/vsp1/vsp1_rwpf.h |  1 +-
 include/media/vsp1.h|  1 +-
 6 files changed, 93 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index d8392bd866f1..08715ce6db1e 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -889,7 +889,9 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl)
  */
 bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
 {
+   struct vsp1_device *vsp1 = dlm->vsp1;
bool completed = false;
+   u32 status = vsp1_read(vsp1, VI6_STATUS);
 
spin_lock(>lock);
 
@@ -914,6 +916,14 @@ bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
goto done;
 
/*
+* Progressive streams report only TOP fields. If we have a BOTTOM
+* field, we are interlaced, and expect the frame to complete on the
+* next frame end interrupt.
+*/
+   if (status & VI6_STATUS_FLD_STD(dlm->index))
+   goto done;
+
+   /*
 * The device starts processing the queued display list right after the
 * frame end interrupt. The display list thus becomes active.
 */
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c 
b/drivers/media/platform/vsp1/vsp1_drm.c
index 0459b970e9da..a714c53601b6 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -368,6 +368,17 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int 
pipe_index,
return -EINVAL;
}
 
+   if (!(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)) && cfg->interlaced) {
+   /*
+* Interlaced support requires extended display lists to
+* provide the auto-fld feature with the DU.
+*/
+   dev_dbg(vsp1->dev, "Interlaced unsupported on this output\n");
+   return -EINVAL;
+   }
+
+   rpf->interlaced = cfg->interlaced;
+
rpf->fmtinfo = fmtinfo;
rpf->format.num_planes = fmtinfo->planes;
rpf->format.plane_fmt[0].bytesperline = cfg->pitch;
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h 
b/drivers/media/platform/vsp1/vsp1_regs.h
index 43ad68ff3167..e2dffbe82809 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -31,6 +31,7 @@
 #define VI6_SRESET_SRTS(n) (1 << (n))
 
 #define VI6_STATUS 0x0038
+#define VI6_STATUS_FLD_STD(n)  (1 << ((n) + 28))
 #define VI6_STATUS_SYS_ACT(n)  (1 << ((n) + 8))
 
 #define VI6_WPF_IRQ_ENB(n) (0x0048 + (n) * 12)
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c 
b/drivers/media/platform/vsp1/vsp1_rpf.c
index 67f2fb3e0611..86ac8f488b7a 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -24,6 +24,20 @@
 #define RPF_MAX_WIDTH  8190
 #define RPF_MAX_HEIGHT 8190
 
+/* Pre extended display list command data structure */
+struct vsp1_extcmd_auto_fld_body {
+   u32 top_y0;
+   u32 bottom_y0;
+   u32 top_c0;
+   u32 bottom_c0;
+   u32 top_c1;
+   u32 bottom_c1;
+   u32 reserved0;
+   u32 reserved1;
+} __packed;
+
+#define VSP1_DL_EXT_AUTOFLD_INTBIT(0)
+
 /* 
-
  * Device Access
  */
@@ -68,6 +82,14 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
pstride |= format->plane_fmt[1].bytesperline
<< VI6_RPF_SRCM_PSTRIDE_C_SHIFT;
 
+   /*
+* pstride has both STRIDE_Y and STRIDE_C, but multiplying the whole
+* of pstride by 2 is conveniently OK here as we are multiplying both
+* values.
+*/
+   if (rpf->interlaced)
+   pstride *= 2;
+
vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_PSTRIDE, pstride);
 
/* Format */
@@ -104,6 +126,9 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
top = compose->top;
}
 
+   if (rpf->interlaced)
+   top /= 2;
+
vsp1_rpf_write(rpf, dlb, VI6_RPF_LOC,
   (left << VI6_RPF_LOC_HCOORD_SHIFT) |
 

[PATCH v2 08/11] media: vsp1: Add support for extended display list headers

2018-03-13 Thread Kieran Bingham
Extended display list headers allow pre and post command lists to be
executed by the VSP pipeline. This provides the base support for
features such as AUTO_FLD (for interlaced support) and AUTO_DISP (for
supporting continuous camera preview pipelines.

Signed-off-by: Kieran Bingham 

---

v2:
 - remove __packed attributes

 drivers/media/platform/vsp1/vsp1.h  |  1 +-
 drivers/media/platform/vsp1/vsp1_dl.c   | 83 +-
 drivers/media/platform/vsp1/vsp1_dl.h   | 29 -
 drivers/media/platform/vsp1/vsp1_drv.c  |  7 +-
 drivers/media/platform/vsp1/vsp1_regs.h |  5 +-
 5 files changed, 116 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1.h 
b/drivers/media/platform/vsp1/vsp1.h
index 1c080538c993..bb3b32795206 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -55,6 +55,7 @@ struct vsp1_uds;
 #define VSP1_HAS_HGO   (1 << 7)
 #define VSP1_HAS_HGT   (1 << 8)
 #define VSP1_HAS_BRS   (1 << 9)
+#define VSP1_HAS_EXT_DL(1 << 10)
 
 struct vsp1_device_info {
u32 version;
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index 5f5706f8a84c..cd91b50deed1 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -26,6 +26,9 @@
 #define VSP1_DLH_INT_ENABLE(1 << 1)
 #define VSP1_DLH_AUTO_START(1 << 0)
 
+#define VSP1_DLH_EXT_PRE_CMD_EXEC  (1 << 9)
+#define VSP1_DLH_EXT_POST_CMD_EXEC (1 << 8)
+
 struct vsp1_dl_header_list {
u32 num_bytes;
u32 addr;
@@ -38,11 +41,34 @@ struct vsp1_dl_header {
u32 flags;
 };
 
+struct vsp1_dl_ext_header {
+   u32 reserved0;  /* alignment padding */
+
+   u16 pre_ext_cmd_qty;
+   u16 flags;
+   u32 pre_ext_cmd_plist;
+
+   u32 post_ext_cmd_qty;
+   u32 post_ext_cmd_plist;
+};
+
+struct vsp1_dl_header_extended {
+   struct vsp1_dl_header header;
+   struct vsp1_dl_ext_header ext;
+};
+
 struct vsp1_dl_entry {
u32 addr;
u32 data;
 };
 
+struct vsp1_dl_ext_cmd_header {
+   u32 cmd;
+   u32 flags;
+   u32 data;
+   u32 reserved;
+};
+
 /**
  * struct vsp1_dl_body - Display list body
  * @list: entry in the display list list of bodies
@@ -99,9 +125,12 @@ struct vsp1_dl_body_pool {
  * @list: entry in the display list manager lists
  * @dlm: the display list manager
  * @header: display list header
+ * @extended: extended display list header. NULL for normal lists
  * @dma: DMA address for the header
  * @body0: first display list body
  * @bodies: list of extra display list bodies
+ * @pre_cmd: pre cmd to be issued through extended dl header
+ * @post_cmd: post cmd to be issued through extended dl header
  * @has_chain: if true, indicates that there's a partition chain
  * @chain: entry in the display list partition chain
  */
@@ -110,11 +139,15 @@ struct vsp1_dl_list {
struct vsp1_dl_manager *dlm;
 
struct vsp1_dl_header *header;
+   struct vsp1_dl_ext_header *extended;
dma_addr_t dma;
 
struct vsp1_dl_body *body0;
struct list_head bodies;
 
+   struct vsp1_dl_ext_cmd *pre_cmd;
+   struct vsp1_dl_ext_cmd *post_cmd;
+
bool has_chain;
struct list_head chain;
 };
@@ -498,6 +531,14 @@ int vsp1_dl_list_add_chain(struct vsp1_dl_list *head,
return 0;
 }
 
+static void vsp1_dl_ext_cmd_fill_header(struct vsp1_dl_ext_cmd *cmd)
+{
+   cmd->cmds[0].cmd = cmd->cmd_opcode;
+   cmd->cmds[0].flags = cmd->flags;
+   cmd->cmds[0].data = cmd->data_dma;
+   cmd->cmds[0].reserved = 0;
+}
+
 static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last)
 {
struct vsp1_dl_manager *dlm = dl->dlm;
@@ -550,6 +591,27 @@ static void vsp1_dl_list_fill_header(struct vsp1_dl_list 
*dl, bool is_last)
 */
dl->header->flags = VSP1_DLH_INT_ENABLE;
}
+
+   if (!dl->extended)
+   return;
+
+   dl->extended->flags = 0;
+
+   if (dl->pre_cmd) {
+   dl->extended->pre_ext_cmd_plist = dl->pre_cmd->cmd_dma;
+   dl->extended->pre_ext_cmd_qty = dl->pre_cmd->num_cmds;
+   dl->extended->flags |= VSP1_DLH_EXT_PRE_CMD_EXEC;
+
+   vsp1_dl_ext_cmd_fill_header(dl->pre_cmd);
+   }
+
+   if (dl->post_cmd) {
+   dl->extended->pre_ext_cmd_plist = dl->post_cmd->cmd_dma;
+   dl->extended->pre_ext_cmd_qty = dl->post_cmd->num_cmds;
+   dl->extended->flags |= VSP1_DLH_EXT_POST_CMD_EXEC;
+
+   vsp1_dl_ext_cmd_fill_header(dl->pre_cmd);
+   }
 }
 
 static bool vsp1_dl_list_hw_update_pending(struct vsp1_dl_manager *dlm)
@@ -715,14 +777,20 @@ bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
 }
 
 /* Hardware Setup */
-void vsp1_dlm_setup(struct vsp1_device *vsp1)
+void 

[PATCH v2 11/11] drm: rcar-du: Support interlaced video output through vsp1

2018-03-13 Thread Kieran Bingham
Use the newly exposed VSP1 interface to enable interlaced frame support
through the VSP1 lif pipelines.

Signed-off-by: Kieran Bingham 
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 1 +
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c  | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c 
b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 5685d5af6998..9854d9deb944 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -248,6 +248,7 @@ static void rcar_du_crtc_set_display_timing(struct 
rcar_du_crtc *rcrtc)
/* Signal polarities */
value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0)
  | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0)
+ | ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? DSMR_ODEV : 0)
  | DSMR_DIPM_DISP | DSMR_CSPM;
rcar_du_crtc_write(rcrtc, DSMR, value);
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 2c260c33840b..5e47daef8bd2 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -178,6 +178,9 @@ static void rcar_du_vsp_plane_setup(struct 
rcar_du_vsp_plane *plane)
};
unsigned int i;
 
+   cfg.interlaced = !!(plane->plane.state->crtc->mode.flags
+   & DRM_MODE_FLAG_INTERLACE);
+
cfg.src.left = state->state.src.x1 >> 16;
cfg.src.top = state->state.src.y1 >> 16;
cfg.src.width = drm_rect_width(>state.src) >> 16;
-- 
git-series 0.9.1


[PATCH v2 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU

2018-03-13 Thread Kieran Bingham
Header mode display lists are now supported on all WPF outputs. To
support extended headers and auto-fld capabilities for interlaced mode
handling only header mode display lists can be used.

Disable the headerless display list configuration, and remove the dead
code.

Signed-off-by: Kieran Bingham 
---
 drivers/media/platform/vsp1/vsp1_dl.c | 107 ++-
 1 file changed, 27 insertions(+), 80 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index 680eedb6fc9f..5f5706f8a84c 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -98,7 +98,7 @@ struct vsp1_dl_body_pool {
  * struct vsp1_dl_list - Display list
  * @list: entry in the display list manager lists
  * @dlm: the display list manager
- * @header: display list header, NULL for headerless lists
+ * @header: display list header
  * @dma: DMA address for the header
  * @body0: first display list body
  * @bodies: list of extra display list bodies
@@ -119,15 +119,9 @@ struct vsp1_dl_list {
struct list_head chain;
 };
 
-enum vsp1_dl_mode {
-   VSP1_DL_MODE_HEADER,
-   VSP1_DL_MODE_HEADERLESS,
-};
-
 /**
  * struct vsp1_dl_manager - Display List manager
  * @index: index of the related WPF
- * @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_bodies lists
@@ -139,7 +133,6 @@ enum vsp1_dl_mode {
  */
 struct vsp1_dl_manager {
unsigned int index;
-   enum vsp1_dl_mode mode;
bool singleshot;
struct vsp1_device *vsp1;
 
@@ -320,6 +313,7 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct 
vsp1_dl_manager *dlm,
   struct vsp1_dl_body_pool *pool)
 {
struct vsp1_dl_list *dl;
+   size_t header_offset;
 
dl = kzalloc(sizeof(*dl), GFP_KERNEL);
if (!dl)
@@ -332,16 +326,15 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct 
vsp1_dl_manager *dlm,
dl->body0 = vsp1_dl_body_get(pool);
if (!dl->body0)
return NULL;
-   if (dlm->mode == VSP1_DL_MODE_HEADER) {
-   size_t header_offset = dl->body0->max_entries
-* sizeof(*dl->body0->entries);
 
-   dl->header = ((void *)dl->body0->entries) + header_offset;
-   dl->dma = dl->body0->dma + header_offset;
+   header_offset = dl->body0->max_entries
+* sizeof(*dl->body0->entries);
 
-   memset(dl->header, 0, sizeof(*dl->header));
-   dl->header->lists[0].addr = dl->body0->dma;
-   }
+   dl->header = ((void *)dl->body0->entries) + header_offset;
+   dl->dma = dl->body0->dma + header_offset;
+
+   memset(dl->header, 0, sizeof(*dl->header));
+   dl->header->lists[0].addr = dl->body0->dma;
 
return dl;
 }
@@ -473,16 +466,9 @@ struct vsp1_dl_body *vsp1_dl_list_get_body0(struct 
vsp1_dl_list *dl)
  *
  * 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.
  */
 int vsp1_dl_list_add_body(struct vsp1_dl_list *dl, struct vsp1_dl_body *dlb)
 {
-   /* Multi-body lists are only available in header mode. */
-   if (dl->dlm->mode != VSP1_DL_MODE_HEADER)
-   return -EINVAL;
-
refcount_inc(>refcnt);
 
list_add_tail(>list, >bodies);
@@ -503,17 +489,10 @@ int vsp1_dl_list_add_body(struct vsp1_dl_list *dl, struct 
vsp1_dl_body *dlb)
  * Adding a display list to a chain passes ownership of the display list to
  * the head display list item. The chain is released when the head dl item is
  * put back with __vsp1_dl_list_put().
- *
- * Chained display lists are only usable in header mode. Attempts to add a
- * display list to a chain in header-less mode will return an error.
  */
 int vsp1_dl_list_add_chain(struct vsp1_dl_list *head,
   struct vsp1_dl_list *dl)
 {
-   /* Chained lists are only available in header mode. */
-   if (head->dlm->mode != VSP1_DL_MODE_HEADER)
-   return -EINVAL;
-
head->has_chain = true;
list_add_tail(>chain, >chain);
return 0;
@@ -581,17 +560,10 @@ static bool vsp1_dl_list_hw_update_pending(struct 
vsp1_dl_manager *dlm)
return false;
 
/*
-* Check whether the VSP1 has taken the update. In headerless mode the
-* hardware indicates this by clearing the UPD bit in the DL_BODY_SIZE
-* register, and in header mode by clearing the UPDHDR bit in the CMD
-* register.
+* Check whether the VSP1 has taken the update. In header mode 

[PATCH v2 05/11] media: vsp1: Clean up DLM objects on error

2018-03-13 Thread Kieran Bingham
If there is an error allocating a display list within a DLM object
the existing display lists are not free'd, and neither is the DL body
pool.

Use the existing vsp1_dlm_destroy() function to clean up on error.

Signed-off-by: Kieran Bingham 
---
 drivers/media/platform/vsp1/vsp1_dl.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index 310ce81cd724..680eedb6fc9f 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -831,8 +831,10 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device 
*vsp1,
struct vsp1_dl_list *dl;
 
dl = vsp1_dl_list_alloc(dlm, dlm->pool);
-   if (!dl)
+   if (!dl) {
+   vsp1_dlm_destroy(dlm);
return NULL;
+   }
 
list_add_tail(>list, >free);
}
-- 
git-series 0.9.1


[PATCH v2 02/11] media: vsp1: Remove packed attributes from aligned structures

2018-03-13 Thread Kieran Bingham
The use of the packed attribute can cause a performance penalty for
all accesses to the struct members, as the compiler will assume that the
structure has the potential to have an unaligned base.

These structures are all correctly aligned and contain no holes, thus
the attribute is redundant and negatively impacts performance, so we
remove the attributes entirely.

Signed-off-by: Kieran Bingham 
---
v2
 - Remove attributes entirely

 drivers/media/platform/vsp1/vsp1_dl.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index 37e2c984fbf3..85795b55a357 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -29,19 +29,19 @@
 struct vsp1_dl_header_list {
u32 num_bytes;
u32 addr;
-} __attribute__((__packed__));
+};
 
 struct vsp1_dl_header {
u32 num_lists;
struct vsp1_dl_header_list lists[8];
u32 next_header;
u32 flags;
-} __attribute__((__packed__));
+};
 
 struct vsp1_dl_entry {
u32 addr;
u32 data;
-} __attribute__((__packed__));
+};
 
 /**
  * struct vsp1_dl_body - Display list body
-- 
git-series 0.9.1


[PATCH v2 01/11] media: vsp1: drm: Fix minor grammar error

2018-03-13 Thread Kieran Bingham
The pixel format is 'unsupported'. Fix the small debug message which
incorrectly declares this.

Signed-off-by: Kieran Bingham 
---
 drivers/media/platform/vsp1/vsp1_drm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/vsp1/vsp1_drm.c 
b/drivers/media/platform/vsp1/vsp1_drm.c
index 3c8b1952799d..0459b970e9da 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -363,7 +363,7 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int 
pipe_index,
 */
fmtinfo = vsp1_get_format_info(vsp1, cfg->pixelformat);
if (!fmtinfo) {
-   dev_dbg(vsp1->dev, "Unsupport pixel format %08x for RPF\n",
+   dev_dbg(vsp1->dev, "Unsupported pixel format %08x for RPF\n",
cfg->pixelformat);
return -EINVAL;
}
-- 
git-series 0.9.1


[PATCH v2 04/11] media: vsp1: Remove unused display list structure field

2018-03-13 Thread Kieran Bingham
The vsp1 reference in the vsp1_dl_body structure is not used.
Remove it.

Signed-off-by: Kieran Bingham 
---
 drivers/media/platform/vsp1/vsp1_dl.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index 8162f4ce66eb..310ce81cd724 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -48,7 +48,6 @@ struct vsp1_dl_entry {
  * @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
  * @size: size of the DMA memory in bytes
@@ -62,7 +61,6 @@ struct vsp1_dl_body {
refcount_t refcnt;
 
struct vsp1_dl_body_pool *pool;
-   struct vsp1_device *vsp1;
 
struct vsp1_dl_entry *entries;
dma_addr_t dma;
-- 
git-series 0.9.1


Re: [PATCH 1/3] rcar-vin: remove duplicated check of state in irq handler

2018-03-13 Thread Niklas Söderlund
Hi Kieran,

Thanks for your feedback.

On 2018-03-13 17:42:25 +0100, Kieran Bingham wrote:
> Hi Niklas,
> 
> Thanks for the patch series :) - I've been looking forward to seeing this one 
> !
> 
> On 10/03/18 01:09, Niklas Söderlund wrote:
> > This is an error from when the driver where converted from soc-camera.
> > There is absolutely no gain to check the state variable two times to be
> > extra sure if the hardware is stopped.
> 
> I'll not say this isn't a redundant check ... but isn't the check against two
> different states, and thus the remaining check doesn't actually catch the case
> now where state == STOPPED ?

Thanks for noticing this, you are correct. I think I need to refresh my 
glasses subscription after missing this :-)

> 
> (Perhaps state != RUNNING would be better ?, but I haven't checked the rest of
> the code)

I will respin this in a v2 and either use state != RUNNING or at least 
combine the two checks to prevent future embarrassing mistakes like 
this.

> 
> --
> Kieran
> 
> 
> > 
> > Signed-off-by: Niklas Söderlund 
> > ---
> >  drivers/media/platform/rcar-vin/rcar-dma.c | 6 --
> >  1 file changed, 6 deletions(-)
> > 
> > diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
> > b/drivers/media/platform/rcar-vin/rcar-dma.c
> > index 23fdff7a7370842e..b4be75d5009080f7 100644
> > --- a/drivers/media/platform/rcar-vin/rcar-dma.c
> > +++ b/drivers/media/platform/rcar-vin/rcar-dma.c
> > @@ -916,12 +916,6 @@ static irqreturn_t rvin_irq(int irq, void *data)
> > rvin_ack_interrupt(vin);
> > handled = 1;
> >  
> > -   /* Nothing to do if capture status is 'STOPPED' */
> > -   if (vin->state == STOPPED) {
> > -   vin_dbg(vin, "IRQ while state stopped\n");
> > -   goto done;
> > -   }
> > -
> > /* Nothing to do if capture status is 'STOPPING' */
> > if (vin->state == STOPPING) {
> > vin_dbg(vin, "IRQ while state stopping\n");
> > 

-- 
Regards,
Niklas Söderlund


[PATCH v2 00/11] R-Car DU Interlaced support through VSP1

2018-03-13 Thread Kieran Bingham
The Gen3 R-Car DU devices make use of the VSP to handle frame processing.

In this series we implement support for handling interlaced pipelines by using
the auto-fld feature of the VSP hardware.

The implementation is preceded by some cleanup work and refactoring, through
patches 1 to 6. These are trivial and could be collected earlier and
independently if this series requires further revisions.

Patch 7 makes a key distinctive change to remove all existing support for
headerless display lists throughout the VSP1 driver, and ensures that all
pipelines use the same code path. This simplifies the code and reduces
opportunity for untested code paths to exist.

Patches 8, 9 and 10 implement the relevant support in the VSP1 driver, before
patch 11 finally enables the feature through the drm R-Car DU driver.

This series is based upon my previous TLB optimise and body rework (v7), and is
available from the following URL:

  git://git.kernel.org/pub/scm/linux/kernel/git/kbingham/rcar.git
  tags/vsp1/du/interlaced/v2

ChangeLog:

v2:
 - media: vsp1: use kernel __packed for structures
became:
   media: vsp1: Remove packed attributes from aligned structures

 - media: vsp1: Add support for extended display list headers
   - No longer declares structs __packed

 - media: vsp1: Provide support for extended command pools
   - Fix spelling typo in commit message
   - constify, and staticify the instantiation of vsp1_extended_commands
   - s/autfld_cmds/autofld_cmds/
   - staticify cmd pool functions (Thanks kbuild-bot)

 - media: vsp1: Support Interlaced display pipelines
   - fix erroneous BIT value which enabled interlaced
   - fix field handling at frame_end interrupt

Kieran Bingham (11):
  media: vsp1: drm: Fix minor grammar error
  media: vsp1: Remove packed attributes from aligned structures
  media: vsp1: Rename dl_child to dl_next
  media: vsp1: Remove unused display list structure field
  media: vsp1: Clean up DLM objects on error
  media: vsp1: Provide VSP1 feature helper macro
  media: vsp1: Use header display lists for all WPF outputs linked to the DU
  media: vsp1: Add support for extended display list headers
  media: vsp1: Provide support for extended command pools
  media: vsp1: Support Interlaced display pipelines
  drm: rcar-du: Support interlaced video output through vsp1

 drivers/gpu/drm/rcar-du/rcar_du_crtc.c  |   1 +-
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c   |   3 +-
 drivers/media/platform/vsp1/vsp1.h  |   3 +-
 drivers/media/platform/vsp1/vsp1_dl.c   | 406 +++--
 drivers/media/platform/vsp1/vsp1_dl.h   |  32 +-
 drivers/media/platform/vsp1/vsp1_drm.c  |  13 +-
 drivers/media/platform/vsp1/vsp1_drv.c  |  23 +-
 drivers/media/platform/vsp1/vsp1_regs.h |   6 +-
 drivers/media/platform/vsp1/vsp1_rpf.c  |  72 +++-
 drivers/media/platform/vsp1/vsp1_rwpf.h |   1 +-
 drivers/media/platform/vsp1/vsp1_wpf.c  |   6 +-
 include/media/vsp1.h|   1 +-
 12 files changed, 455 insertions(+), 112 deletions(-)

base-commit: 397eb3811ec096d0ceefa1dbea2d0ae68feb0587
-- 
git-series 0.9.1


[PATCH v2 03/11] media: vsp1: Rename dl_child to dl_next

2018-03-13 Thread Kieran Bingham
Both vsp1_dl_list_commit() and __vsp1_dl_list_put() walk the display
list chain referencing the nodes as children, when in reality they are
siblings.

Update the terminology to 'dl_next' to be consistent with the
vsp1_video_pipeline_run() usage.

Signed-off-by: Kieran Bingham 
---
 drivers/media/platform/vsp1/vsp1_dl.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/vsp1/vsp1_dl.c 
b/drivers/media/platform/vsp1/vsp1_dl.c
index 85795b55a357..8162f4ce66eb 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -400,7 +400,7 @@ struct vsp1_dl_list *vsp1_dl_list_get(struct 
vsp1_dl_manager *dlm)
 /* This function must be called with the display list manager lock held.*/
 static void __vsp1_dl_list_put(struct vsp1_dl_list *dl)
 {
-   struct vsp1_dl_list *dl_child;
+   struct vsp1_dl_list *dl_next;
 
if (!dl)
return;
@@ -410,8 +410,8 @@ static void __vsp1_dl_list_put(struct vsp1_dl_list *dl)
 * hardware operation.
 */
if (dl->has_chain) {
-   list_for_each_entry(dl_child, >chain, chain)
-   __vsp1_dl_list_put(dl_child);
+   list_for_each_entry(dl_next, >chain, chain)
+   __vsp1_dl_list_put(dl_next);
}
 
dl->has_chain = false;
@@ -667,17 +667,17 @@ static void vsp1_dl_list_commit_singleshot(struct 
vsp1_dl_list *dl)
 void vsp1_dl_list_commit(struct vsp1_dl_list *dl)
 {
struct vsp1_dl_manager *dlm = dl->dlm;
-   struct vsp1_dl_list *dl_child;
+   struct vsp1_dl_list *dl_next;
unsigned long flags;
 
if (dlm->mode == VSP1_DL_MODE_HEADER) {
/* Fill the header for the head and chained display lists. */
vsp1_dl_list_fill_header(dl, list_empty(>chain));
 
-   list_for_each_entry(dl_child, >chain, chain) {
-   bool last = list_is_last(_child->chain, >chain);
+   list_for_each_entry(dl_next, >chain, chain) {
+   bool last = list_is_last(_next->chain, >chain);
 
-   vsp1_dl_list_fill_header(dl_child, last);
+   vsp1_dl_list_fill_header(dl_next, last);
}
}
 
-- 
git-series 0.9.1


Re: [PATCH v8 03/13] [media] omap3isp: group device capabilities

2018-03-13 Thread Hans Verkuil
On 03/09/2018 09:49 AM, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> Instead of putting V4L2_CAP_STREAMING everywhere, set device_caps
> earlier with this value.
> 
> Signed-off-by: Gustavo Padovan 
> ---
>  drivers/media/platform/omap3isp/ispvideo.c | 9 +
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/platform/omap3isp/ispvideo.c 
> b/drivers/media/platform/omap3isp/ispvideo.c
> index a751c89a3ea8..b4d4ef926749 100644
> --- a/drivers/media/platform/omap3isp/ispvideo.c
> +++ b/drivers/media/platform/omap3isp/ispvideo.c
> @@ -658,13 +658,14 @@ isp_video_querycap(struct file *file, void *fh, struct 
> v4l2_capability *cap)
>   strlcpy(cap->card, video->video.name, sizeof(cap->card));
>   strlcpy(cap->bus_info, "media", sizeof(cap->bus_info));
>  
> - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT
> - | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS;
> + cap->device_caps = V4L2_CAP_STREAMING;
> + cap->capabilities = cap->device_caps | V4L2_CAP_VIDEO_CAPTURE |
> + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_DEVICE_CAPS;

Same as in patch 1: I'd move this down to after the if-else. It makes more
sense that way.

>  
>   if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
> - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
> + cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE;
>   else
> - cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
> + cap->device_caps |= V4L2_CAP_VIDEO_OUTPUT;
>  
>   return 0;
>  }
> 

Regards,

Hans


Re: [PATCH v8 04/13] [media] vb2: add is_unordered callback for drivers

2018-03-13 Thread Hans Verkuil
On 03/09/2018 09:49 AM, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> Explicit synchronization benefits a lot from ordered queues, they fit
> better in a pipeline with DRM for example so create a opt-in way for
> drivers notify videobuf2 that the queue is unordered.
> 
> Drivers don't need implement it if the queue is ordered.
> 
> v2:   - improve comments for is_unordered flag (Hans)
> 
> v3:   - make it bool (Hans)
>   - create vb2_ops_set_unordered() helper
> 
> Signed-off-by: Gustavo Padovan 
> ---
>  drivers/media/common/videobuf2/videobuf2-v4l2.c |  6 ++
>  include/media/videobuf2-core.h  |  6 ++
>  include/media/videobuf2-v4l2.h  | 10 ++
>  3 files changed, 22 insertions(+)
> 
> diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
> b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> index 886a2d8d5c6c..68291ba8632d 100644
> --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
> +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> @@ -961,6 +961,12 @@ void vb2_ops_wait_finish(struct vb2_queue *vq)
>  }
>  EXPORT_SYMBOL_GPL(vb2_ops_wait_finish);
>  
> +bool vb2_ops_set_unordered(struct vb2_queue *q)
> +{
> + return true;
> +}
> +EXPORT_SYMBOL_GPL(vb2_ops_set_unordered);

This should be called vb2_ops_is_unordered. The name after the vb2_ops_
prefix should match the op name (is_unordered).

I also would add this to videobuf2-core.c since there is nothing V4L2
specific about this.

> +
>  MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2");
>  MODULE_AUTHOR("Pawel Osciak , Marek Szyprowski");
>  MODULE_LICENSE("GPL");
> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
> index 5b6c541e4e1b..46a9e674f7e1 100644
> --- a/include/media/videobuf2-core.h
> +++ b/include/media/videobuf2-core.h
> @@ -370,6 +370,10 @@ struct vb2_buffer {
>   *   callback by calling vb2_buffer_done() with either
>   *   %VB2_BUF_STATE_DONE or %VB2_BUF_STATE_ERROR; may use
>   *   vb2_wait_for_all_buffers() function
> + * @is_unordered:tell if the queue is unordered, i.e. buffers can be
> + *   dequeued in a different order from how they were queued.
> + *   The default is assumed to be ordered and this function
> + *   only needs to be implemented for unordered queues.
>   * @buf_queue:   passes buffer vb to the driver; driver may start
>   *   hardware operation on this buffer; driver should give
>   *   the buffer back by calling vb2_buffer_done() function;
> @@ -393,6 +397,7 @@ struct vb2_ops {
>  
>   int (*start_streaming)(struct vb2_queue *q, unsigned int count);
>   void (*stop_streaming)(struct vb2_queue *q);
> + bool (*is_unordered)(struct vb2_queue *q);
>  
>   void (*buf_queue)(struct vb2_buffer *vb);
>  };
> @@ -566,6 +571,7 @@ struct vb2_queue {
>   u32 cnt_wait_finish;
>   u32 cnt_start_streaming;
>   u32 cnt_stop_streaming;
> + u32 cnt_is_unordered;
>  #endif
>  };
>  
> diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
> index 3d5e2d739f05..9de3c887c875 100644
> --- a/include/media/videobuf2-v4l2.h
> +++ b/include/media/videobuf2-v4l2.h
> @@ -291,4 +291,14 @@ void vb2_ops_wait_prepare(struct vb2_queue *vq);
>   */
>  void vb2_ops_wait_finish(struct vb2_queue *vq);
>  
> +/**
> + * vb2_ops_set_unordered - helper function to mark queue as unordered
> + *
> + * @vq: pointer to  vb2_queue
> + *
> + * This helper just return true to notify that the driver can't deal with

return -> returns

> + * ordered queues.
> + */
> +bool vb2_ops_set_unordered(struct vb2_queue *q);
> +
>  #endif /* _MEDIA_VIDEOBUF2_V4L2_H */
> 

Regards,

Hans


Re: [PATCH v8 11/13] [media] v4l: introduce the fences capability

2018-03-13 Thread Hans Verkuil
On 03/09/2018 09:49 AM, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> Drivers capable of using fences (vb2 drivers) should report the
> V4L2_CAP_FENCES to userspace, so add this flag to the uapi.
> 
> Signed-off-by: Gustavo Padovan 
> ---
>  Documentation/media/uapi/v4l/vidioc-querycap.rst | 3 +++
>  include/uapi/linux/videodev2.h   | 1 +
>  2 files changed, 4 insertions(+)
> 
> diff --git a/Documentation/media/uapi/v4l/vidioc-querycap.rst 
> b/Documentation/media/uapi/v4l/vidioc-querycap.rst
> index 66fb1b3d6e6e..414016065309 100644
> --- a/Documentation/media/uapi/v4l/vidioc-querycap.rst
> +++ b/Documentation/media/uapi/v4l/vidioc-querycap.rst
> @@ -254,6 +254,9 @@ specification the ioctl returns an ``EINVAL`` error code.
>  * - ``V4L2_CAP_TOUCH``
>- 0x1000
>- This is a touch device.
> +* - ``V4L2_CAP_FENCES``
> +  - 0x2000
> +  - The device support explicit synchronization.

support -> supports

>  * - ``V4L2_CAP_DEVICE_CAPS``
>- 0x8000
>- The driver fills the ``device_caps`` field. This capability can
> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index 2d424aebdd1e..db58204e346e 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -460,6 +460,7 @@ struct v4l2_capability {
>  #define V4L2_CAP_STREAMING  0x0400  /* streaming I/O ioctls 
> */
>  
>  #define V4L2_CAP_TOUCH  0x1000  /* Is a touch device */
> +#define V4L2_CAP_FENCES 0x2000  /* Supports explicit 
> synchronization */
>  
>  #define V4L2_CAP_DEVICE_CAPS0x8000  /* sets device 
> capabilities field */
>  
> 

Regards,

Hans


[PATCH v2 1/2] rcar-vin: allocate a scratch buffer at stream start

2018-03-13 Thread Niklas Söderlund
Before starting a capture, allocate a scratch buffer which can be used
by the driver to give to the hardware if no buffers are available from
userspace. The buffer is not used in this patch but prepares for future
refactoring where the scratch buffer can be used to avoid the need to
fallback on single capture mode if userspace can't queue buffers as fast
as the VIN driver consumes them.

Signed-off-by: Niklas Söderlund 
Reviewed-by: Jacopo Mondi 
Reviewed-by: Kieran Bingham 
---
 drivers/media/platform/rcar-vin/rcar-dma.c | 19 +++
 drivers/media/platform/rcar-vin/rcar-vin.h |  4 
 2 files changed, 23 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 23fdff7a7370842e..1f91b056188ebdb3 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -1076,6 +1076,17 @@ static int rvin_start_streaming(struct vb2_queue *vq, 
unsigned int count)
unsigned long flags;
int ret;
 
+   /* Allocate scratch buffer. */
+   vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage,
+ >scratch_phys, GFP_KERNEL);
+   if (!vin->scratch) {
+   spin_lock_irqsave(>qlock, flags);
+   return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
+   spin_unlock_irqrestore(>qlock, flags);
+   vin_err(vin, "Failed to allocate scratch buffer\n");
+   return -ENOMEM;
+   }
+
sd = vin_to_source(vin);
v4l2_subdev_call(sd, video, s_stream, 1);
 
@@ -1091,6 +1102,10 @@ static int rvin_start_streaming(struct vb2_queue *vq, 
unsigned int count)
 
spin_unlock_irqrestore(>qlock, flags);
 
+   if (ret)
+   dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
+ vin->scratch_phys);
+
return ret;
 }
 
@@ -1141,6 +1156,10 @@ static void rvin_stop_streaming(struct vb2_queue *vq)
 
/* disable interrupts */
rvin_disable_interrupts(vin);
+
+   /* Free scratch buffer. */
+   dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
+ vin->scratch_phys);
 }
 
 static const struct vb2_ops rvin_qops = {
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h 
b/drivers/media/platform/rcar-vin/rcar-vin.h
index 5382078143fb3869..00b405f78d0912c9 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -102,6 +102,8 @@ struct rvin_graph_entity {
  *
  * @lock:  protects @queue
  * @queue: vb2 buffers queue
+ * @scratch:   cpu address for scratch buffer
+ * @scratch_phys:  physical address of the scratch buffer
  *
  * @qlock: protects @queue_buf, @buf_list, @continuous, @sequence
  * @state
@@ -130,6 +132,8 @@ struct rvin_dev {
 
struct mutex lock;
struct vb2_queue queue;
+   void *scratch;
+   dma_addr_t scratch_phys;
 
spinlock_t qlock;
struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM];
-- 
2.16.2



[PATCH v2 0/2] rcar-vin: always run in continues mode

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

This series reworks the R-Car VIN driver to only run using its continues
capture mode. This improves performance a lot when userspace struggles
to keep up and queue buffers as fast as the VIN driver consumes them.
The solution to always be able to run in continues is to introduce a
scratch buffer inside the VIN driver which it can pad the hardware
capture buffer ring with if it have no buffer from userspace. Using this
scratch buffer allows the driver to not need to stop capturing when it
run out of buffers and then restart it once it have more buffers.

Patch 1/2 adds the allocation of the scratch buffer. And patch 2/2 drops 
the single capture mode in favor of always running in continues capture 
mode and the scratch buffer.

The series is based on top of the latest media-tree master branch and
can be fetched from.

git://git.ragnatech.se/linux v4l2/next/vin/mode-v2

It is tested on R-Car Koelsch Gen2 board using the onboard HDMI and CVBS
inputs. The test application v4l2-compliance pass for both inputs
without issues or warnings. A slight adaption of these patches to the
pending VIN Gen3 patches have been tested with great improvement in
capture speed for buffer strained situations and no regressions in the
vin-tests suite.

* Changes since v1
- Dropped first patch in series as it removed a correct check due to my 
  poor reading skills.
- Corrected spelling in commit messages and comments.
- Added review tags from Jacopo and Kieran, thanks!


Niklas Söderlund (2):
  rcar-vin: allocate a scratch buffer at stream start
  rcar-vin: use scratch buffer and always run in continuous mode

 drivers/media/platform/rcar-vin/rcar-dma.c | 206 ++---
 drivers/media/platform/rcar-vin/rcar-vin.h |  10 +-
 2 files changed, 75 insertions(+), 141 deletions(-)

-- 
2.16.2



Re: [PATCH v8 06/13] [media] cobalt: add .is_unordered() for cobalt

2018-03-13 Thread Hans Verkuil
On 03/09/2018 09:49 AM, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> The cobalt driver may reorder the capture buffers so we need to report
> it as such.
> 
> v2: - use vb2_ops_set_unordered() helper
> 
> Signed-off-by: Gustavo Padovan 
> ---
>  drivers/media/pci/cobalt/cobalt-v4l2.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c 
> b/drivers/media/pci/cobalt/cobalt-v4l2.c
> index e2a4c705d353..6b6611a0e190 100644
> --- a/drivers/media/pci/cobalt/cobalt-v4l2.c
> +++ b/drivers/media/pci/cobalt/cobalt-v4l2.c
> @@ -430,6 +430,7 @@ static const struct vb2_ops cobalt_qops = {
>   .stop_streaming = cobalt_stop_streaming,
>   .wait_prepare = vb2_ops_wait_prepare,
>   .wait_finish = vb2_ops_wait_finish,
> + .is_unordered = vb2_ops_set_unordered,
>  };

If you do this, then you should also set the UNORDERED format flag for
all formats used by cobalt.

Regards,

Hans

>  
>  /* V4L2 ioctls */
> 



Re: [PATCH v8 08/13] [media] vb2: add explicit fence user API

2018-03-13 Thread Hans Verkuil
On 03/09/2018 09:49 AM, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> Turn the reserved2 field into fence_fd that we will use to send
> an in-fence to the kernel or return an out-fence from the kernel to
> userspace.
> 
> Two new flags were added, V4L2_BUF_FLAG_IN_FENCE, that should be used
> when sending a fence to the kernel to be waited on, and
> V4L2_BUF_FLAG_OUT_FENCE, to ask the kernel to give back an out-fence.
> 
> v6:   - big improvement on doc (Hans Verkuil)
> 
> v5:
>   - keep using reserved2 field for cpia2
>   - set fence_fd to 0 for now, for compat with userspace(Mauro)
> 
> v4:
>   - make it a union with reserved2 and fence_fd (Hans Verkuil)
> 
> v3:
>   - make the out_fence refer to the current buffer (Hans Verkuil)
> 
> v2: add documentation
> 
> Signed-off-by: Gustavo Padovan 
> ---
>  Documentation/media/uapi/v4l/buffer.rst | 45 
> +++--
>  drivers/media/common/videobuf2/videobuf2-v4l2.c |  2 +-
>  drivers/media/v4l2-core/v4l2-compat-ioctl32.c   |  4 +--
>  include/uapi/linux/videodev2.h  |  7 +++-
>  4 files changed, 51 insertions(+), 7 deletions(-)
> 
> diff --git a/Documentation/media/uapi/v4l/buffer.rst 
> b/Documentation/media/uapi/v4l/buffer.rst
> index e2c85ddc990b..49273026740f 100644
> --- a/Documentation/media/uapi/v4l/buffer.rst
> +++ b/Documentation/media/uapi/v4l/buffer.rst
> @@ -301,10 +301,22 @@ struct v4l2_buffer
>   elements in the ``planes`` array. The driver will fill in the
>   actual number of valid elements in that array.
>  * - __u32
> -  - ``reserved2``
> +  - ``fence_fd``
>-
> -  - A place holder for future extensions. Drivers and applications
> - must set this to 0.
> +  - Used to communicate fences file descriptors from userspace to kernel

fences file descriptors -> a fence file descriptor

> + and vice-versa. On :ref:`VIDIOC_QBUF ` when sending
> + an in-fence for V4L2 to wait on, the ``V4L2_BUF_FLAG_IN_FENCE`` flag 
> must
> + be used and this field set to the fence file descriptor of the in-fence

Missing period at the end of this sentence.

> + If the in-fence is not valid ` VIDIOC_QBUF`` returns an error.

` -> ``

> +
> +To get an out-fence back from V4L2 the ``V4L2_BUF_FLAG_OUT_FENCE``
> + must be set, the kernel will return the out-fence file descriptor on

on -> in

> + this field. If it fails to create the out-fence ``VIDIOC_QBUF` returns

` -> ``

> +an error.
> +
> + In all other ioctls V4L2 sets this field to -1 if

In all other -> For all other buffer

> + ``V4L2_BUF_FLAG_IN_FENCE`` and/or ``V4L2_BUF_FLAG_OUT_FENCE`` are set,
> + otherwise this field is set to 0 for backward compatibility.
>  * - __u32
>- ``reserved``
>-
> @@ -648,6 +660,33 @@ Buffer Flags
>- Start Of Exposure. The buffer timestamp has been taken when the
>   exposure of the frame has begun. This is only valid for the
>   ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` buffer type.
> +* .. _`V4L2-BUF-FLAG-IN-FENCE`:
> +
> +  - ``V4L2_BUF_FLAG_IN_FENCE``
> +  - 0x0020
> +  - Ask V4L2 to wait on the fence passed in the ``fence_fd`` field. The
> + buffer won't be queued to the driver until the fence signals. The order
> + in which buffers are queued is guaranteed to be preserved, so any
> + buffers queued after this buffer will also be blocked until this fence
> + signals. This flag must be set before calling ``VIDIOC_QBUF``. For
> + other ioctls the driver just report the value of the flag.

report -> reports

> +
> +If the fence signals the flag is cleared and not reported anymore.
> + If the fence is not valid ``VIDIOC_QBUF`` returns an error.
> +
> +
> +* .. _`V4L2-BUF-FLAG-OUT-FENCE`:
> +
> +  - ``V4L2_BUF_FLAG_OUT_FENCE``
> +  - 0x0040
> +  - Request for a fence to be attached to the buffer. The driver will 
> fill
> + in the out-fence fd in the ``fence_fd`` field when :ref:`VIDIOC_QBUF
> + ` returns. This flag must be set before calling
> + ``VIDIOC_QBUF``. For other ioctls the driver just report the value of

report -> reports

> + the flag.
> +
> +If the creation of the  out-fence  fails ``VIDIOC_QBUF`` returns an

double spaces before and after 'out-fence'.

> + error.
>  
>  
>  
> diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
> b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> index 68291ba8632d..ad1e032c3bf5 100644
> --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
> +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> @@ -203,7 +203,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, 
> void *pb)
>   b->timestamp = ns_to_timeval(vb->timestamp);
>   b->timecode = vbuf->timecode;
>   b->sequence = vbuf->sequence;
> - b->reserved2 = 0;
> + b->fence_fd = 0;
>   b->reserved = 0;
>  

Re: [PATCH v8 07/13] [media] vb2: mark codec drivers as unordered

2018-03-13 Thread Hans Verkuil
On 03/09/2018 09:49 AM, Gustavo Padovan wrote:
> From: Gustavo Padovan 
> 
> In preparation to have full support to explicit fence we are
> marking codec as non-ordered preventively. It is easier and safer from an
> uAPI point of view to move from unordered to ordered than the opposite.

Same comment as for the cobalt driver: if you mark these drivers as
unordered, shouldn't you mark the compressed formats as UNORDERED
as well? Should we perhaps do this by default for compressed formats
(except MJPEG) in v4l2-ioctl.c? Thus requiring drivers to clear the
flag if they are actually ordered.

> 
> Signed-off-by: Gustavo Padovan 
> ---
>  drivers/media/platform/coda/coda-common.c  | 1 +
>  drivers/media/platform/exynos-gsc/gsc-m2m.c| 1 +
>  drivers/media/platform/exynos4-is/fimc-m2m.c   | 1 +
>  drivers/media/platform/m2m-deinterlace.c   | 1 +

This is a deinterlaced, so this should be ordered.

>  drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c| 1 +

JPEG is ordered.

>  drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c   | 1 +
>  drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 1 +
>  drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c | 1 +
>  drivers/media/platform/mx2_emmaprp.c   | 1 +

I believe this is also not a codec, so ordered,

>  drivers/media/platform/qcom/venus/vdec.c   | 1 +
>  drivers/media/platform/qcom/venus/venc.c   | 1 +
>  drivers/media/platform/rcar_fdp1.c | 1 +
>  drivers/media/platform/rcar_jpu.c  | 1 +

I don't think these two R-Car drivers are codecs, so these would be
ordered (the 2nd is a JPEG codec, not sure about the first one).

>  drivers/media/platform/rockchip/rga/rga-buf.c  | 1 +

Not a codec driver, this is ordered,

>  drivers/media/platform/s5p-g2d/g2d.c   | 1 +

Not sure about this one, I don't think it is a codec driver,

>  drivers/media/platform/s5p-jpeg/jpeg-core.c| 1 +

MJPEG, so ordered,

>  drivers/media/platform/s5p-mfc/s5p_mfc_dec.c   | 1 +
>  drivers/media/platform/s5p-mfc/s5p_mfc_enc.c   | 1 +
>  drivers/media/platform/sh_veu.c| 1 +

Not a codec, so ordered,

>  drivers/media/platform/sti/bdisp/bdisp-v4l2.c  | 1 +
>  drivers/media/platform/ti-vpe/vpe.c| 1 +
>  drivers/media/platform/vim2m.c | 1 +

Same for these three.

Regards,

Hans

>  22 files changed, 22 insertions(+)
> 
> diff --git a/drivers/media/platform/coda/coda-common.c 
> b/drivers/media/platform/coda/coda-common.c
> index 04e35d70ce2e..6deb29fe6eb7 100644
> --- a/drivers/media/platform/coda/coda-common.c
> +++ b/drivers/media/platform/coda/coda-common.c
> @@ -1649,6 +1649,7 @@ static const struct vb2_ops coda_qops = {
>   .stop_streaming = coda_stop_streaming,
>   .wait_prepare   = vb2_ops_wait_prepare,
>   .wait_finish= vb2_ops_wait_finish,
> + .is_unordered   = vb2_ops_set_unordered,
>  };
>  
>  static int coda_s_ctrl(struct v4l2_ctrl *ctrl)
> diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c 
> b/drivers/media/platform/exynos-gsc/gsc-m2m.c
> index e9ff27949a91..10c3e4659d38 100644
> --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c
> +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c
> @@ -286,6 +286,7 @@ static const struct vb2_ops gsc_m2m_qops = {
>   .wait_finish = vb2_ops_wait_finish,
>   .stop_streaming  = gsc_m2m_stop_streaming,
>   .start_streaming = gsc_m2m_start_streaming,
> + .is_unordered= vb2_ops_set_unordered,
>  };
>  
>  static int gsc_m2m_querycap(struct file *file, void *fh,
> diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c 
> b/drivers/media/platform/exynos4-is/fimc-m2m.c
> index a19f8b164a47..dfc487a582c0 100644
> --- a/drivers/media/platform/exynos4-is/fimc-m2m.c
> +++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
> @@ -227,6 +227,7 @@ static const struct vb2_ops fimc_qops = {
>   .wait_finish = vb2_ops_wait_finish,
>   .stop_streaming  = stop_streaming,
>   .start_streaming = start_streaming,
> + .is_unordered= vb2_ops_set_unordered,
>  };
>  
>  /*
> diff --git a/drivers/media/platform/m2m-deinterlace.c 
> b/drivers/media/platform/m2m-deinterlace.c
> index 1e4195144f39..35a0f45d2a51 100644
> --- a/drivers/media/platform/m2m-deinterlace.c
> +++ b/drivers/media/platform/m2m-deinterlace.c
> @@ -856,6 +856,7 @@ static const struct vb2_ops deinterlace_qops = {
>   .queue_setup = deinterlace_queue_setup,
>   .buf_prepare = deinterlace_buf_prepare,
>   .buf_queue   = deinterlace_buf_queue,
> + .is_unordered= vb2_ops_set_unordered,
>  };
>  
>  static int queue_init(void *priv, struct vb2_queue *src_vq,
> diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c 
> b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> index 226f90886484..34a4b5b2e1b5 100644
> --- 

cron job: media_tree daily build: ERRORS

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

Results of the daily build of media_tree:

date:   Wed Mar 14 05:00:10 CET 2018
media-tree git hash:e68854a2588a923b31eebce348f8020374843f8e
media_build git hash:   2a1900fddab68c7686e6b146ff91e02b32675fae
v4l-utils git hash: 14ce03c18ef67aa7a3d5781f015be855fd43839c
gcc version:i686-linux-gcc (GCC) 7.3.0
sparse version: v0.5.0-3994-g45eb2282
smatch version: v0.5.0-3994-g45eb2282
host hardware:  x86_64
host os:4.14.0-3-amd64

linux-git-arm-at91: OK
linux-git-arm-davinci: OK
linux-git-arm-multi: WARNINGS
linux-git-arm-pxa: OK
linux-git-arm-stm32: OK
linux-git-arm64: OK
linux-git-blackfin-bf561: OK
linux-git-i686: OK
linux-git-m32r: OK
linux-git-mips: OK
linux-git-powerpc64: OK
linux-git-sh: OK
linux-git-x86_64: OK
linux-2.6.36.4-i686: ERRORS
linux-2.6.36.4-x86_64: ERRORS
linux-2.6.37.6-i686: WARNINGS
linux-2.6.37.6-x86_64: WARNINGS
linux-2.6.38.8-i686: WARNINGS
linux-2.6.38.8-x86_64: WARNINGS
linux-2.6.39.4-i686: WARNINGS
linux-2.6.39.4-x86_64: WARNINGS
linux-3.0.60-i686: WARNINGS
linux-3.0.60-x86_64: WARNINGS
linux-3.1.10-i686: WARNINGS
linux-3.1.10-x86_64: WARNINGS
linux-3.2.98-i686: ERRORS
linux-3.2.98-x86_64: ERRORS
linux-3.3.8-i686: ERRORS
linux-3.3.8-x86_64: ERRORS
linux-3.4.27-i686: ERRORS
linux-3.4.27-x86_64: ERRORS
linux-3.5.7-i686: WARNINGS
linux-3.5.7-x86_64: WARNINGS
linux-3.6.11-i686: WARNINGS
linux-3.6.11-x86_64: WARNINGS
linux-3.7.4-i686: WARNINGS
linux-3.7.4-x86_64: WARNINGS
linux-3.8-i686: WARNINGS
linux-3.8-x86_64: WARNINGS
linux-3.9.2-i686: WARNINGS
linux-3.9.2-x86_64: WARNINGS
linux-3.10.1-i686: WARNINGS
linux-3.10.1-x86_64: WARNINGS
linux-3.11.1-i686: WARNINGS
linux-3.11.1-x86_64: WARNINGS
linux-3.12.67-i686: WARNINGS
linux-3.12.67-x86_64: WARNINGS
linux-3.13.11-i686: WARNINGS
linux-3.13.11-x86_64: WARNINGS
linux-3.14.9-i686: WARNINGS
linux-3.14.9-x86_64: WARNINGS
linux-3.15.2-i686: WARNINGS
linux-3.15.2-x86_64: WARNINGS
linux-3.16.53-i686: WARNINGS
linux-3.16.53-x86_64: WARNINGS
linux-3.17.8-i686: WARNINGS
linux-3.17.8-x86_64: WARNINGS
linux-3.18.93-i686: WARNINGS
linux-3.18.93-x86_64: WARNINGS
linux-3.19-i686: WARNINGS
linux-3.19-x86_64: WARNINGS
linux-4.0.9-i686: WARNINGS
linux-4.0.9-x86_64: WARNINGS
linux-4.1.49-i686: WARNINGS
linux-4.1.49-x86_64: WARNINGS
linux-4.2.8-i686: WARNINGS
linux-4.2.8-x86_64: WARNINGS
linux-4.3.6-i686: WARNINGS
linux-4.3.6-x86_64: WARNINGS
linux-4.4.115-i686: OK
linux-4.4.115-x86_64: OK
linux-4.5.7-i686: WARNINGS
linux-4.5.7-x86_64: WARNINGS
linux-4.6.7-i686: OK
linux-4.6.7-x86_64: WARNINGS
linux-4.7.5-i686: OK
linux-4.7.5-x86_64: WARNINGS
linux-4.8-i686: OK
linux-4.8-x86_64: WARNINGS
linux-4.9.80-i686: OK
linux-4.9.80-x86_64: OK
linux-4.10.14-i686: OK
linux-4.10.14-x86_64: WARNINGS
linux-4.11-i686: OK
linux-4.11-x86_64: WARNINGS
linux-4.12.1-i686: OK
linux-4.12.1-x86_64: WARNINGS
linux-4.13-i686: OK
linux-4.13-x86_64: OK
linux-4.14.17-i686: OK
linux-4.14.17-x86_64: OK
linux-4.15.2-i686: WARNINGS
linux-4.15.2-x86_64: WARNINGS
linux-4.16-rc1-i686: WARNINGS
linux-4.16-rc1-x86_64: WARNINGS
apps: WARNINGS
spec-git: OK
sparse: WARNINGS
smatch: OK

Detailed results are available here:

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

Full logs are available here:

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

The Media Infrastructure API from this daily build is here:

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


  1   2   >