Re: [ANN v2] Media sessions in Lyon in October: libcamera

2019-10-20 Thread Helen Koike
Hello,

On 10/20/19 5:13 PM, Ezequiel Garcia wrote:
> Hello Hans,
> 
> On Thu, 17 Oct 2019 at 13:16, Hans Verkuil  wrote:
>>
>> (Just updated the attendee list for this meeting, no other changes)
>>
>> Hi all,
>>
>> Since we have three separate half-day sessions for different topics I decided
>> to split the announcement for this in three emails as well, so these things
>> can be discussed in separate threads.
>>
>> All sessions are in room Terreaux VIP Lounge - Level 0.
>> There is a maximum of 15 people.
>>
>> The second session deals with libcamera and is on Wednesday morning
>> from 9:00 to 13:00.
>>
>> Attendees for this session:
>>
>> Nicolas Dufresne 
>> Tomasz Figa 
>> Ezequiel Garcia 
>> Dafna Hirschfeld 
> 
> I beliebe Dafna and I should not be on this list, and instead
> Helen Koike and Nicolas Dufresne would be attending.

Yes, I'm interested in attending the libcamera session.

Thanks
Helen

> 
> Thanks,
> Ezequiel
> 
>> Eugen Hristev 
>> Jacopo Mondi 
>> Laurent Pinchart 
>> Niklas Söderlund 
>> Dave Stevenson 
>> Hans Verkuil 
>>
>> That's 10 people.
>>
>> Planning to use libcamera, but willing to give up their seat if needed:
>>
>> Daniel Gomez 
>> Helen Koike 
>>
>> Just interested:
>>
>> Boris Brezillon 
>> Alexandre Courbot 
>>
>> If I missed someone, or you are on the list but won't attend after all, then
>> please let me know.
>>
>> Attendees: it is probably useful if you let us know whether you have to
>> join this meeting because you plan to use libcamera, or if you are 'just
>> interested'. After the libcamera presentation on Tuesday afternoon we
>> should know how many of the 'just interested' list can join.
>>
>> Agenda:
>>
>> TBD by Laurent.
>>
>> Regards,
>>
>> Hans


Re: [PATCH -next] media: vimc: Fix error return code in vimc_register_devices()

2019-10-08 Thread Helen Koike
Hi,

On 10/8/19 6:01 AM, Wei Yongjun wrote:
> Fix to return a negative error code from the error handling
> case instead of 0, as done elsewhere in this function.
> 
> Fixes: f13d5f361959 ("media: vimc: Collapse component structure into a single 
> monolithic driver")
> Signed-off-by: Wei Yongjun 

Acked-by: Helen Koike 

Thank you
Helen

> ---
>  drivers/media/platform/vimc/vimc-core.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-core.c 
> b/drivers/media/platform/vimc/vimc-core.c
> index 6e3e5c91ae39..2d20a7c10398 100644
> --- a/drivers/media/platform/vimc/vimc-core.c
> +++ b/drivers/media/platform/vimc/vimc-core.c
> @@ -202,8 +202,10 @@ static int vimc_register_devices(struct vimc_device 
> *vimc)
>   vimc->ent_devs = kmalloc_array(vimc->pipe_cfg->num_ents,
>  sizeof(*vimc->ent_devs),
>  GFP_KERNEL);
> - if (!vimc->ent_devs)
> + if (!vimc->ent_devs) {
> + ret = -ENOMEM;
>   goto err_v4l2_unregister;
> + }
>  
>   /* Invoke entity config hooks to initialize and register subdevs */
>   ret = vimc_add_subdevs(vimc);
> 
> 
> 


Re: [PATCH v2 5/5] media: vimc: remove the helper function vimc_ent_sd_unregister

2019-10-03 Thread Helen Koike



On 10/3/19 7:44 AM, Dafna Hirschfeld wrote:
> since this function only calls v4l2_device_unregister_subdev,
> it is pointless.
> 
> Signed-off-by: Dafna Hirschfeld 

Acked-by: Helen Koike 

> ---
>  drivers/media/platform/vimc/vimc-common.c  |  5 -
>  drivers/media/platform/vimc/vimc-common.h  | 12 
>  drivers/media/platform/vimc/vimc-debayer.c |  2 +-
>  drivers/media/platform/vimc/vimc-scaler.c  |  2 +-
>  drivers/media/platform/vimc/vimc-sensor.c  |  2 +-
>  5 files changed, 3 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-common.c 
> b/drivers/media/platform/vimc/vimc-common.c
> index 999bc353fb10..67b53dc1849d 100644
> --- a/drivers/media/platform/vimc/vimc-common.c
> +++ b/drivers/media/platform/vimc/vimc-common.c
> @@ -421,8 +421,3 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
>  }
>  EXPORT_SYMBOL_GPL(vimc_ent_sd_register);
>  
> -void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev 
> *sd)
> -{
> - v4l2_device_unregister_subdev(sd);
> -}
> -EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister);
> diff --git a/drivers/media/platform/vimc/vimc-common.h 
> b/drivers/media/platform/vimc/vimc-common.h
> index 698db7c07645..af5b1166dc1f 100644
> --- a/drivers/media/platform/vimc/vimc-common.h
> +++ b/drivers/media/platform/vimc/vimc-common.h
> @@ -251,18 +251,6 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
>const struct v4l2_subdev_internal_ops *sd_int_ops,
>const struct v4l2_subdev_ops *sd_ops);
>  
> -/**
> - * vimc_ent_sd_unregister - cleanup and unregister a subdev node
> - *
> - * @ved: the vimc_ent_device struct to be cleaned up
> - * @sd:  the v4l2_subdev struct to be unregistered
> - *
> - * Helper function cleanup and unregister the struct vimc_ent_device and 
> struct
> - * v4l2_subdev which represents a subdev node in the topology
> - */
> -void vimc_ent_sd_unregister(struct vimc_ent_device *ved,
> - struct v4l2_subdev *sd);
> -
>  /**
>   * vimc_link_validate - validates a media link
>   *
> diff --git a/drivers/media/platform/vimc/vimc-debayer.c 
> b/drivers/media/platform/vimc/vimc-debayer.c
> index e1bad6713cde..4e5316c671e0 100644
> --- a/drivers/media/platform/vimc/vimc-debayer.c
> +++ b/drivers/media/platform/vimc/vimc-debayer.c
> @@ -491,7 +491,7 @@ void vimc_deb_rm(struct vimc_device *vimc, struct 
> vimc_ent_device *ved)
>   struct vimc_deb_device *vdeb;
>  
>   vdeb = container_of(ved, struct vimc_deb_device, ved);
> - vimc_ent_sd_unregister(ved, &vdeb->sd);
> + v4l2_device_unregister_subdev(&vdeb->sd);
>  }
>  
>  struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
> diff --git a/drivers/media/platform/vimc/vimc-scaler.c 
> b/drivers/media/platform/vimc/vimc-scaler.c
> index 1982bc089af5..4fe2ba578652 100644
> --- a/drivers/media/platform/vimc/vimc-scaler.c
> +++ b/drivers/media/platform/vimc/vimc-scaler.c
> @@ -350,7 +350,7 @@ void vimc_sca_rm(struct vimc_device *vimc, struct 
> vimc_ent_device *ved)
>   struct vimc_sca_device *vsca;
>  
>   vsca = container_of(ved, struct vimc_sca_device, ved);
> - vimc_ent_sd_unregister(ved, &vsca->sd);
> + v4l2_device_unregister_subdev(&vsca->sd);
>  }
>  
>  struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,
> diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
> b/drivers/media/platform/vimc/vimc-sensor.c
> index 63fe024ccea5..14838362d871 100644
> --- a/drivers/media/platform/vimc/vimc-sensor.c
> +++ b/drivers/media/platform/vimc/vimc-sensor.c
> @@ -305,7 +305,7 @@ void vimc_sen_rm(struct vimc_device *vimc, struct 
> vimc_ent_device *ved)
>   struct vimc_sen_device *vsen;
>  
>   vsen = container_of(ved, struct vimc_sen_device, ved);
> - vimc_ent_sd_unregister(ved, &vsen->sd);
> + v4l2_device_unregister_subdev(&vsen->sd);
>  }
>  
>  /* Image Processing Controls */
> 


Re: [PATCH v2 3/5] media: vimc: sensor: register subdevice only after initialization

2019-10-03 Thread Helen Koike
Hi Dafna,

Could you just rename the title tags to "media: vimc: sen: " to follow the
model of the other commits?

Thanks
Helen

On 10/3/19 7:44 AM, Dafna Hirschfeld wrote:
> vimc_sen_add function first registers the subdevice and then
> calls tpg_alloc. If tpg_alloc fails it unregisters the subdevice
> and then frees vsen, this cause double free since the release
> callback that follows subdevice unregistration also frees vsen.
> 
> Signed-off-by: Dafna Hirschfeld 
> Acked-by: Helen Koike 
> ---
>  drivers/media/platform/vimc/vimc-sensor.c | 20 ++--
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
> b/drivers/media/platform/vimc/vimc-sensor.c
> index 46dc6a535abe..ee2306c08569 100644
> --- a/drivers/media/platform/vimc/vimc-sensor.c
> +++ b/drivers/media/platform/vimc/vimc-sensor.c
> @@ -358,6 +358,13 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device 
> *vimc,
>   goto err_free_vsen;
>   }
>  
> + /* Initialize the test pattern generator */
> + tpg_init(&vsen->tpg, vsen->mbus_format.width,
> +  vsen->mbus_format.height);
> + ret = tpg_alloc(&vsen->tpg, VIMC_FRAME_MAX_WIDTH);
> + if (ret)
> + goto err_free_hdl;
> +
>   /* Initialize ved and sd */
>   ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
>  vcfg_name,
> @@ -365,7 +372,7 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device 
> *vimc,
>  (const unsigned long[1]) 
> {MEDIA_PAD_FL_SOURCE},
>  &vimc_sen_int_ops, &vimc_sen_ops);
>   if (ret)
> - goto err_free_hdl;
> + goto err_free_tpg;
>  
>   vsen->ved.process_frame = vimc_sen_process_frame;
>   vsen->dev = &vimc->pdev.dev;
> @@ -373,17 +380,10 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device 
> *vimc,
>   /* Initialize the frame format */
>   vsen->mbus_format = fmt_default;
>  
> - /* Initialize the test pattern generator */
> - tpg_init(&vsen->tpg, vsen->mbus_format.width,
> -  vsen->mbus_format.height);
> - ret = tpg_alloc(&vsen->tpg, VIMC_FRAME_MAX_WIDTH);
> - if (ret)
> - goto err_unregister_ent_sd;
> -
>   return &vsen->ved;
>  
> -err_unregister_ent_sd:
> - vimc_ent_sd_unregister(&vsen->ved,  &vsen->sd);
> +err_free_tpg:
> + tpg_free(&vsen->tpg);
>  err_free_hdl:
>   v4l2_ctrl_handler_free(&vsen->hdl);
>  err_free_vsen:
> 


Re: [PATCH v2 2/5] media: vimc: cleanup code that assigns entity in entities array

2019-10-03 Thread Helen Koike



On 10/3/19 7:44 AM, Dafna Hirschfeld wrote:
> Since the add callback returns NULL on failure and the array
> is initialized to NULLs, there is no need for the intermediate
> assignment to local var.
> 
> Signed-off-by: Dafna Hirschfeld 

I would just rename the title to something like:
"media: vimc: remove unnecessary var when adding entities"

It makes clear what you are doing and where, what do you think?

With this:

Acked-by: Helen Koike 

> ---
>  drivers/media/platform/vimc/vimc-core.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-core.c 
> b/drivers/media/platform/vimc/vimc-core.c
> index b8add4087652..325f55d0d8b3 100644
> --- a/drivers/media/platform/vimc/vimc-core.c
> +++ b/drivers/media/platform/vimc/vimc-core.c
> @@ -160,19 +160,17 @@ static int vimc_create_links(struct vimc_device *vimc)
>  static int vimc_add_subdevs(struct vimc_device *vimc)
>  {
>   unsigned int i;
> - struct vimc_ent_device *ved;
>  
>   for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
>   dev_dbg(&vimc->pdev.dev, "new entity for %s\n",
>   vimc->pipe_cfg->ents[i].name);
> - ved = vimc->pipe_cfg->ents[i].add(vimc,
> + vimc->ent_devs[i] = vimc->pipe_cfg->ents[i].add(vimc,
>   vimc->pipe_cfg->ents[i].name);
> - if (!ved) {
> + if (!vimc->ent_devs[i]) {
>   dev_err(&vimc->pdev.dev, "add new entity for %s\n",
>   vimc->pipe_cfg->ents[i].name);
>   return -EINVAL;
>   }
> - vimc->ent_devs[i] = ved;
>   }
>   return 0;
>  }
> 


Re: [PATCH v2 1/5] media: vimc: initialize vim entity pointers to NULL

2019-10-03 Thread Helen Koike



On 10/3/19 7:44 AM, Dafna Hirschfeld wrote:
> since NULL value for vimc entity pointer indicates
> that entity creation failed and this is tested, the
> pointers should be initialized to NULL.
> 
> Signed-off-by: Dafna Hirschfeld 

Acked-by: Helen Koike 

> ---
>  drivers/media/platform/vimc/vimc-core.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-core.c 
> b/drivers/media/platform/vimc/vimc-core.c
> index 6e3e5c91ae39..b8add4087652 100644
> --- a/drivers/media/platform/vimc/vimc-core.c
> +++ b/drivers/media/platform/vimc/vimc-core.c
> @@ -199,9 +199,8 @@ static int vimc_register_devices(struct vimc_device *vimc)
>   }
>  
>   /* allocate ent_devs */
> - vimc->ent_devs = kmalloc_array(vimc->pipe_cfg->num_ents,
> -sizeof(*vimc->ent_devs),
> -GFP_KERNEL);
> + vimc->ent_devs = kcalloc(vimc->pipe_cfg->num_ents,
> +  sizeof(*vimc->ent_devs), GFP_KERNEL);
>   if (!vimc->ent_devs)
>   goto err_v4l2_unregister;
>  
> 


Re: [PATCH] media: vimc: embed the pads of entities in the entities' structs

2019-10-01 Thread Helen Koike
Hi Dafna,

Thanks for your patch, just some comments below.

On 10/1/19 2:07 PM, Dafna Hirschfeld wrote:
> since the pads array is of known small size, there is no reason to
> allocate it separately. Instead, it is embedded in the entity struct.
> This also conforms to the media controller doc:
> 'Most drivers will embed the pads array in a driver-specific structure,
> avoiding dynamic allocation.'

Just as a background information, It was allocated separately because the
initial idea was to be able to create multiple pads according to some
configuration. But this changed and your way is better.

> 
> Signed-off-by: Dafna Hirschfeld 
> ---
> This patch is rebased on top of the patchset
> 'media: vimc: bug fixes related to memory management' sent
> by me which is in turn rebased on top of v5 of the patchset
> 'media: vimc: Collapse component structure into a single
> monolithic driver' sent by 'Shuah Khan'
> 
>  drivers/media/platform/vimc/vimc-capture.c | 15 +++---
>  drivers/media/platform/vimc/vimc-common.c  | 13 ++---
>  drivers/media/platform/vimc/vimc-common.h  | 33 --
>  drivers/media/platform/vimc/vimc-debayer.c |  9 --
>  drivers/media/platform/vimc/vimc-scaler.c  |  8 --
>  drivers/media/platform/vimc/vimc-sensor.c  |  6 ++--
>  6 files changed, 26 insertions(+), 60 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index 5f353c20e605..c3488b5b738f 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -30,6 +30,7 @@ struct vimc_cap_device {
>   struct mutex lock;
>   u32 sequence;
>   struct vimc_stream stream;
> + struct media_pad pad[0];

You are declaring an array of size zero, I believe you meant struct media_pad 
pad[1], no?
In any case, why declare an array? You could just use struct media_pad pad.

>  };
>  
>  static const struct v4l2_pix_format fmt_default = {
> @@ -331,7 +332,6 @@ static void vimc_cap_release(struct video_device *vdev)
>   container_of(vdev, struct vimc_cap_device, vdev);
>  
>   media_entity_cleanup(vcap->ved.ent);
> - vimc_pads_cleanup(vcap->ved.pads);
>   kfree(vcap);
>  }
>  
> @@ -398,21 +398,14 @@ struct vimc_ent_device *vimc_cap_add(struct vimc_device 
> *vimc,
>   if (!vcap)
>   return NULL;
>  
> - /* Allocate the pads */
> - vcap->ved.pads =
> - vimc_pads_init(1, (const unsigned long[1]) {MEDIA_PAD_FL_SINK});
> - if (IS_ERR(vcap->ved.pads)) {
> - ret = PTR_ERR(vcap->ved.pads);
> - goto err_free_vcap;
> - }
> -
>   /* Initialize the media entity */
>   vcap->vdev.entity.name = vcfg_name;
>   vcap->vdev.entity.function = MEDIA_ENT_F_IO_V4L;
> + vcap->pad[0].flags = MEDIA_PAD_FL_SINK;
>   ret = media_entity_pads_init(&vcap->vdev.entity,
> -  1, vcap->ved.pads);
> +  1, vcap->pad);
>   if (ret)
> - goto err_clean_pads;
> + goto err_free_vcap;
>  
>   /* Initialize the lock */
>   mutex_init(&vcap->lock);
> @@ -481,8 +474,6 @@ struct vimc_ent_device *vimc_cap_add(struct vimc_device 
> *vimc,
>   vb2_queue_release(q);
>  err_clean_m_ent:
>   media_entity_cleanup(&vcap->vdev.entity);
> -err_clean_pads:
> - vimc_pads_cleanup(vcap->ved.pads);
>  err_free_vcap:
>   kfree(vcap);
>  
> diff --git a/drivers/media/platform/vimc/vimc-common.c 
> b/drivers/media/platform/vimc/vimc-common.c
> index 999bc353fb10..8eb8c7df36f5 100644
> --- a/drivers/media/platform/vimc/vimc-common.c
> +++ b/drivers/media/platform/vimc/vimc-common.c
> @@ -369,17 +369,12 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
>const char *const name,
>u32 function,
>u16 num_pads,
> -  const unsigned long *pads_flag,
> +  struct media_pad *pads,
>const struct v4l2_subdev_internal_ops *sd_int_ops,
>const struct v4l2_subdev_ops *sd_ops)
>  {
>   int ret;
>  
> - /* Allocate the pads. Should be released from the sd_int_op release */
> - ved->pads = vimc_pads_init(num_pads, pads_flag);
> - if (IS_ERR(ved->pads))
> - return PTR_ERR(ved->pads);
> -
>   /* Fill the vimc_ent_device struct */
>   ved->ent = &sd->entity;
>  
> @@ -398,9 +393,9 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
>   sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
>  
>   /* Initialize the media entity */
> - ret = media_entity_pads_init(&sd->entity, num_pads, ved->pads);
> + ret = media_entity_pads_init(&sd->entity, num_pads, pads);
>   if (ret)
> - goto err_clean_pads;
> + return ret;
>  
>   /* Register the subdev with the v4l2 and the media framework */
>   ret = v4l2_d

Re: [PATCH 1/3] media: vimc: initialize vim entity pointers to NULL

2019-10-01 Thread Helen Koike



On 10/1/19 2:25 PM, Andrzej Pietrasiewicz wrote:
> Hi Dafna, hi Helen,
> 
> W dniu 01.10.2019 o 19:19, Helen Koike pisze:
>> Hi Dafna,
>>
>> On 10/1/19 1:50 PM, Dafna Hirschfeld wrote:
>>> since NULL value for vimc entity pointer indicates
>>> that entity creation failed and this is tested, the
>>> pointers should be initialized to NULL.
>>
>> Nice catch :)
>>
>>>
>>> Signed-off-by: Dafna Hirschfeld 
>>> ---
>>>   drivers/media/platform/vimc/vimc-core.c | 8 +++-
>>>   1 file changed, 3 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/media/platform/vimc/vimc-core.c 
>>> b/drivers/media/platform/vimc/vimc-core.c
>>> index 6e3e5c91ae39..32a79e578b78 100644
>>> --- a/drivers/media/platform/vimc/vimc-core.c
>>> +++ b/drivers/media/platform/vimc/vimc-core.c
>>> @@ -160,19 +160,17 @@ static int vimc_create_links(struct vimc_device *vimc)
>>>   static int vimc_add_subdevs(struct vimc_device *vimc)
>>>   {
>>>   unsigned int i;
>>> -    struct vimc_ent_device *ved;
>>>     for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
>>>   dev_dbg(&vimc->pdev.dev, "new entity for %s\n",
>>>   vimc->pipe_cfg->ents[i].name);
>>> -    ved = vimc->pipe_cfg->ents[i].add(vimc,
>>> +    vimc->ent_devs[i] = vimc->pipe_cfg->ents[i].add(vimc,
>>>   vimc->pipe_cfg->ents[i].name);
>>> -    if (!ved) {
>>> +    if (!vimc->ent_devs[i]) {
>>>   dev_err(&vimc->pdev.dev, "add new entity for %s\n",
>>>   vimc->pipe_cfg->ents[i].name);
>>>   return -EINVAL;
>>>   }
>>> -    vimc->ent_devs[i] = ved;
>>>   }
>>>   return 0;
>>>   }
>>
>> I believe just the kcalloc bellow should fix the issue.
>> But if you want to do this cleanup anyway, I would suggest sending a 
>> separate patch for it.
>>
>>> @@ -199,7 +197,7 @@ static int vimc_register_devices(struct vimc_device 
>>> *vimc)
>>>   }
>>>     /* allocate ent_devs */
>>> -    vimc->ent_devs = kmalloc_array(vimc->pipe_cfg->num_ents,
>>> +    vimc->ent_devs = kcalloc(vimc->pipe_cfg->num_ents,
>>>  sizeof(*vimc->ent_devs),
>>>  GFP_KERNEL);
>>
>> Could you fix the alignment of the params here?
> 
> Isn't the above change (kmalloc_array() to kcalloc()) alone enough
> to ensure the promise from the patch title is fulfilled?

I fully agree. That is why I mentioned above in "I believe just the kcalloc 
bellow should fix the issue."
Sorry if I wasn't clear.

Thanks
Helen


> 
> In other words, why remove the "ved" local variable in vimc_add_subdevs()?
> 
> Andrzej


Re: [PATCH 3/3] media: vimc: move media_entity_cleanup to release callbacks

2019-10-01 Thread Helen Koike
Hi Dafna,

Thanks for your patch

On 10/1/19 1:50 PM, Dafna Hirschfeld wrote:
> according to the docs, this function must be called during
> the cleanup phase after unregistering the entity.
> 
> Signed-off-by: Dafna Hirschfeld 

Acked-by: Helen Koike 

I just have one note below.

> ---
>  drivers/media/platform/vimc/vimc-capture.c | 2 +-
>  drivers/media/platform/vimc/vimc-common.c  | 1 -
>  drivers/media/platform/vimc/vimc-debayer.c | 1 +
>  drivers/media/platform/vimc/vimc-scaler.c  | 1 +
>  drivers/media/platform/vimc/vimc-sensor.c  | 1 +
>  5 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index 602f80323031..5f353c20e605 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -330,6 +330,7 @@ static void vimc_cap_release(struct video_device *vdev)
>   struct vimc_cap_device *vcap =
>   container_of(vdev, struct vimc_cap_device, vdev);
>  
> + media_entity_cleanup(vcap->ved.ent);
>   vimc_pads_cleanup(vcap->ved.pads);
>   kfree(vcap);
>  }
> @@ -340,7 +341,6 @@ void vimc_cap_rm(struct vimc_device *vimc, struct 
> vimc_ent_device *ved)
>  
>   vcap = container_of(ved, struct vimc_cap_device, ved);
>   vb2_queue_release(&vcap->queue);
> - media_entity_cleanup(ved->ent);
>   video_unregister_device(&vcap->vdev);
>  }
>  
> diff --git a/drivers/media/platform/vimc/vimc-common.c 
> b/drivers/media/platform/vimc/vimc-common.c
> index a3120f4f7a90..999bc353fb10 100644
> --- a/drivers/media/platform/vimc/vimc-common.c
> +++ b/drivers/media/platform/vimc/vimc-common.c
> @@ -423,7 +423,6 @@ EXPORT_SYMBOL_GPL(vimc_ent_sd_register);
>  
>  void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev 
> *sd)

Could you get rid of this function as well?
There is no point in keeping it anymore, feel free to send in another patch.

Thanks
Helen

>  {
> - media_entity_cleanup(ved->ent);
>   v4l2_device_unregister_subdev(sd);
>  }
>  EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister);
> diff --git a/drivers/media/platform/vimc/vimc-debayer.c 
> b/drivers/media/platform/vimc/vimc-debayer.c
> index feac47d79449..e1bad6713cde 100644
> --- a/drivers/media/platform/vimc/vimc-debayer.c
> +++ b/drivers/media/platform/vimc/vimc-debayer.c
> @@ -477,6 +477,7 @@ static void vimc_deb_release(struct v4l2_subdev *sd)
>   struct vimc_deb_device *vdeb =
>   container_of(sd, struct vimc_deb_device, sd);
>  
> + media_entity_cleanup(vdeb->ved.ent);
>   vimc_pads_cleanup(vdeb->ved.pads);
>   kfree(vdeb);
>  }
> diff --git a/drivers/media/platform/vimc/vimc-scaler.c 
> b/drivers/media/platform/vimc/vimc-scaler.c
> index a6a3cc5be872..1982bc089af5 100644
> --- a/drivers/media/platform/vimc/vimc-scaler.c
> +++ b/drivers/media/platform/vimc/vimc-scaler.c
> @@ -336,6 +336,7 @@ static void vimc_sca_release(struct v4l2_subdev *sd)
>   struct vimc_sca_device *vsca =
>   container_of(sd, struct vimc_sca_device, sd);
>  
> + media_entity_cleanup(vsca->ved.ent);
>   vimc_pads_cleanup(vsca->ved.pads);
>   kfree(vsca);
>  }
> diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
> b/drivers/media/platform/vimc/vimc-sensor.c
> index ee2306c08569..63fe024ccea5 100644
> --- a/drivers/media/platform/vimc/vimc-sensor.c
> +++ b/drivers/media/platform/vimc/vimc-sensor.c
> @@ -291,6 +291,7 @@ static void vimc_sen_release(struct v4l2_subdev *sd)
>  
>   v4l2_ctrl_handler_free(&vsen->hdl);
>   tpg_free(&vsen->tpg);
> + media_entity_cleanup(vsen->ved.ent);
>   vimc_pads_cleanup(vsen->ved.pads);
>   kfree(vsen);
>  }
> 


Re: [PATCH 2/3] media: vimc: sensor: register subdevice only after initialization

2019-10-01 Thread Helen Koike



On 10/1/19 1:50 PM, Dafna Hirschfeld wrote:
> vimc_sen_add function first registers the subdevice and then
> calls tpg_alloc. If tpg_alloc fails it unregisters the subdevice
> and then frees vsen, this cause double free since the release
> callback that follows subdevice unregistration also frees vsen.
> 
> Signed-off-by: Dafna Hirschfeld 

Acked-by: Helen Koike 

> ---
>  drivers/media/platform/vimc/vimc-sensor.c | 20 ++--
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
> b/drivers/media/platform/vimc/vimc-sensor.c
> index 46dc6a535abe..ee2306c08569 100644
> --- a/drivers/media/platform/vimc/vimc-sensor.c
> +++ b/drivers/media/platform/vimc/vimc-sensor.c
> @@ -358,6 +358,13 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device 
> *vimc,
>   goto err_free_vsen;
>   }
>  
> + /* Initialize the test pattern generator */
> + tpg_init(&vsen->tpg, vsen->mbus_format.width,
> +  vsen->mbus_format.height);
> + ret = tpg_alloc(&vsen->tpg, VIMC_FRAME_MAX_WIDTH);
> + if (ret)
> + goto err_free_hdl;
> +
>   /* Initialize ved and sd */
>   ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
>  vcfg_name,
> @@ -365,7 +372,7 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device 
> *vimc,
>  (const unsigned long[1]) 
> {MEDIA_PAD_FL_SOURCE},
>  &vimc_sen_int_ops, &vimc_sen_ops);
>   if (ret)
> - goto err_free_hdl;
> + goto err_free_tpg;
>  
>   vsen->ved.process_frame = vimc_sen_process_frame;
>   vsen->dev = &vimc->pdev.dev;
> @@ -373,17 +380,10 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device 
> *vimc,
>   /* Initialize the frame format */
>   vsen->mbus_format = fmt_default;
>  
> - /* Initialize the test pattern generator */
> - tpg_init(&vsen->tpg, vsen->mbus_format.width,
> -  vsen->mbus_format.height);
> - ret = tpg_alloc(&vsen->tpg, VIMC_FRAME_MAX_WIDTH);
> - if (ret)
> - goto err_unregister_ent_sd;
> -
>   return &vsen->ved;
>  
> -err_unregister_ent_sd:
> - vimc_ent_sd_unregister(&vsen->ved,  &vsen->sd);
> +err_free_tpg:
> + tpg_free(&vsen->tpg);
>  err_free_hdl:
>   v4l2_ctrl_handler_free(&vsen->hdl);
>  err_free_vsen:
> 


Re: [PATCH 1/3] media: vimc: initialize vim entity pointers to NULL

2019-10-01 Thread Helen Koike
Hi Dafna,

On 10/1/19 1:50 PM, Dafna Hirschfeld wrote:
> since NULL value for vimc entity pointer indicates
> that entity creation failed and this is tested, the
> pointers should be initialized to NULL.

Nice catch :)

> 
> Signed-off-by: Dafna Hirschfeld 
> ---
>  drivers/media/platform/vimc/vimc-core.c | 8 +++-
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-core.c 
> b/drivers/media/platform/vimc/vimc-core.c
> index 6e3e5c91ae39..32a79e578b78 100644
> --- a/drivers/media/platform/vimc/vimc-core.c
> +++ b/drivers/media/platform/vimc/vimc-core.c
> @@ -160,19 +160,17 @@ static int vimc_create_links(struct vimc_device *vimc)
>  static int vimc_add_subdevs(struct vimc_device *vimc)
>  {
>   unsigned int i;
> - struct vimc_ent_device *ved;
>  
>   for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
>   dev_dbg(&vimc->pdev.dev, "new entity for %s\n",
>   vimc->pipe_cfg->ents[i].name);
> - ved = vimc->pipe_cfg->ents[i].add(vimc,
> + vimc->ent_devs[i] = vimc->pipe_cfg->ents[i].add(vimc,
>   vimc->pipe_cfg->ents[i].name);
> - if (!ved) {
> + if (!vimc->ent_devs[i]) {
>   dev_err(&vimc->pdev.dev, "add new entity for %s\n",
>   vimc->pipe_cfg->ents[i].name);
>   return -EINVAL;
>   }
> - vimc->ent_devs[i] = ved;
>   }
>   return 0;
>  }

I believe just the kcalloc bellow should fix the issue.
But if you want to do this cleanup anyway, I would suggest sending a separate 
patch for it.

> @@ -199,7 +197,7 @@ static int vimc_register_devices(struct vimc_device *vimc)
>   }
>  
>   /* allocate ent_devs */
> - vimc->ent_devs = kmalloc_array(vimc->pipe_cfg->num_ents,
> + vimc->ent_devs = kcalloc(vimc->pipe_cfg->num_ents,
>  sizeof(*vimc->ent_devs),
>  GFP_KERNEL);

Could you fix the alignment of the params here?

Thanks
Helen

>   if (!vimc->ent_devs)
> 


Re: [ANN] Media sessions in Lyon in October: codecs

2019-09-25 Thread Helen Koike



On 9/23/19 12:02 PM, Jacopo Mondi wrote:
> Hi Hans,
> 
> On Mon, Sep 23, 2019 at 04:12:55PM +0200, Hans Verkuil wrote:
>> Hi all,
>>
>> Since we have three separate half-day sessions for different topics I decided
>> to split the announcement for this in three emails as well, so these things
>> can be discussed in separate threads.
>>
>> All sessions are in room Terreaux VIP Lounge - Level 0.
>> There is a maximum of 15 people.
>>
>> The first session deals with the codec API and is on Tuesday morning from
>> 8:30 (tentative, might change) to 12:00 (we have to vacate the room at that
>> time).
>>
>> Confirmed attendees for this session:
>>
>> Boris Brezillon 
>> Alexandre Courbot 
>> Nicolas Dufresne 
>> Tomasz Figa 
>> Ezequiel Garcia 
>> Daniel Gomez 
>> Dafna Hirschfeld 
>> Eugen Hristev 
>> Paul Kocialkowski 
>> Helen Koike 
>> Michael Tretter 
>> Hans Verkuil 
>>
>> Tentative:
>>
>> Laurent Pinchart 
>> Jacopo Mondi 
>>
>> Jacopo, please confirm if you want to attend this session. I didn't find
>> an email with explicit confirmation, so it was probably done via irc. But 
>> since
>> this session is getting close to capacity I would prefer to keep attendance 
>> to
>> those are actually working with codecs (or will work with it in the near 
>> future).
> 
> I'm not really working on codecs, so if you're running almost at full
> capacity please feel free to re-assign my seat.

Same here, feel free to re-assign my seat.

Thanks,
Helen

> 
> If there are free seats I might flock in, but without contributing too
> much to the discussions :)
> 
> Thanks
>j
> 
>>
>> If I missed someone, or you are on the list but won't attend after all, then
>> please let me know.
>>
>>
>>
>> Agenda:
>>
>> - Status of any pending patches related to codec support.
>>
>> - Requirements of moving codec drivers out of staging.
>>
>> - Finalize the stateful encoder API. There are two pieces that need
>>   to be defined:
>>
>> 1) Setting the frame rate so bitrate control can make sense, since
>>they need to know this information. This is also relevant for the
>>stateless codec (and this may have to change on a per-frame basis
>>for stateless codecs!).
>>
>>This can either be implemented via ENUM_FRAMEINTERVALS for the coded
>>pixelformats and S_PARM support, or we just add a new control for this.
>>E.g. V4L2_CID_MPEG_VIDEO_FRAME_INTERVAL (or perhaps FRAME_RATE). If we
>>go for a control, then we need to consider the unit. We can use a
>>fraction as well. See this series that puts in the foundation for that:
>>https://patchwork.linuxtv.org/cover/58857/
>>
>>I am inclined to go with a control, since the semantics don't really
>>match ENUM_FRAMEINTERVALS/S_PARM. These ioctls still need to be supported
>>for legacy drivers. Open question: some drivers (mediatek, hva, coda)
>>require S_PARM(OUTPUT), some (venus) allow both S_PARM(CAPTURE) and
>>S_PARM(OUTPUT). I am inclined to allow both since this is not a CAPTURE
>>vs OUTPUT thing, it is global to both queues.
>>
>> 2) Interactions between OUTPUT and CAPTURE formats.
>>
>>The main problem is what to do if the capture sizeimage is too small
>>for the OUTPUT resolution when streaming starts.
>>
>>Proposal: width and height of S_FMT(OUTPUT) are used to
>>calculate a minimum sizeimage (app may request more). This is
>>driver-specific. (Is it? Or is this codec-specific?)
>>
>>V4L2_FMT_FLAG_FIXED_RESOLUTION is always set for codec formats
>>for the encoder (i.e. we don't support mid-stream resolution
>>changes for now) and V4L2_EVENT_SOURCE_CHANGE is not
>>supported. See https://patchwork.linuxtv.org/patch/56478/ for
>>the patch adding this flag.
>>
>>Of course, if we start to support mid-stream resolution
>>changes (or other changes that require a source change event),
>>then this flag should be dropped by the encoder driver and
>>documentation on how to handle the source change event should
>>be documented in the encoder spec. I prefer to postpone this
>>until we have an encoder than can actually do mid-stream
>>resolution changes.
>>
>>If sizeimage of the OUTPUT is too small for the CAPTURE
>>resolution and V4L2_EVENT_SOURCE_CHANGE is not supported,
>>then the second STREAMON (either CAPTURE or OUTPUT) will
>>return -ENOMEM since there is not enough memory to do the
>>encode.
>>
>>If V4L2_FMT_FLAG_FIXED_RESOLUTION is set (i.e. that should
>>be the case for all current encoders), then any bitrate controls
>>will be limited in range to what the current state (CAPTURE and
>>OUTPUT formats and frame rate) supports.
>>
>> - Stateless encoders?
>>
>> - Anything else? (I have a feeling I missed a codec-related topic, but
>>   I can't find it in my mailbox)
>>
>> Regards,
>>
>>  Hans


Re: [PATCH] media: vimc: Implement get/set selection

2019-09-25 Thread Helen Koike
+Hans +Shuah

Hi Guilherme and Danilo,

Thank you for the patch, please see my comments below.

On 9/9/19 1:08 AM, Guilherme Alcarde Gallo wrote:
> Add support for the scaler subdevice to respond VIDIOC_G_SELECTION and
> VIDIOC_S_SELECTION ioctls with the following targets:
> V4L2_SEL_TGT_COMPOSE_BOUNDS and V4L2_SEL_TGT_CROP.
> 
> * Added new const struct crop_rect_default to initialize subdev scaler
>   properly.
> * Make changes in sink pad format reflect the crop rectangle. E.g.
>   changing the frame format to a smaller size one can make the former
>   crop rectangle selects a non existing frame area. To solve this
>   situation the crop rectangle is clamped to the frame boundaries.
> * Clamp crop rectangle respecting the sink bounds during set_selection
>   ioctl.
> 
> Signed-off-by: Guilherme Alcarde Gallo 
> Co-developed-by: Danilo Figueiredo Rocha 
> Signed-off-by: Danilo Figueiredo Rocha 
> 
> ---
> 
> This patch is based on the monolithic vimc driver from the patchset
> named "Collapse vimc into single monolithic driver"
> https://patchwork.kernel.org/patch/11136201/
> 
> ---
> 
>  drivers/media/platform/vimc/vimc-scaler.c | 148 +++---
>  1 file changed, 133 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-scaler.c 
> b/drivers/media/platform/vimc/vimc-scaler.c
> index a5a0855ad9cd..b50d11e76a2b 100644
> --- a/drivers/media/platform/vimc/vimc-scaler.c
> +++ b/drivers/media/platform/vimc/vimc-scaler.c
> @@ -18,6 +18,9 @@ MODULE_PARM_DESC(sca_mult, " the image size multiplier");
>  
>  #define MAX_ZOOM 8
>  
> +#define VIMC_SCA_FMT_WIDTH_DEFAULT   640
> +#define VIMC_SCA_FMT_HEIGHT_DEFAULT  480
> +
>  struct vimc_sca_device {
>   struct vimc_ent_device ved;
>   struct v4l2_subdev sd;
> @@ -26,6 +29,7 @@ struct vimc_sca_device {
>* with the width and hight multiplied by mult
>*/
>   struct v4l2_mbus_framefmt sink_fmt;
> + struct v4l2_rect crop_rect;
>   /* Values calculated when the stream starts */
>   u8 *src_frame;
>   unsigned int src_line_size;
> @@ -33,22 +37,33 @@ struct vimc_sca_device {
>  };
>  
>  static const struct v4l2_mbus_framefmt sink_fmt_default = {
> - .width = 640,
> - .height = 480,
> + .width = VIMC_SCA_FMT_WIDTH_DEFAULT,
> + .height = VIMC_SCA_FMT_HEIGHT_DEFAULT,
>   .code = MEDIA_BUS_FMT_RGB888_1X24,
>   .field = V4L2_FIELD_NONE,
>   .colorspace = V4L2_COLORSPACE_DEFAULT,
>  };
>  
> +static const struct v4l2_rect crop_rect_default = {
> + .width = VIMC_SCA_FMT_WIDTH_DEFAULT,
> + .height = VIMC_SCA_FMT_HEIGHT_DEFAULT,
> + .top = 0,
> + .left = 0,
> +};
> +
>  static int vimc_sca_init_cfg(struct v4l2_subdev *sd,
>struct v4l2_subdev_pad_config *cfg)
>  {
>   struct v4l2_mbus_framefmt *mf;
> + struct v4l2_rect *r;
>   unsigned int i;
>  
>   mf = v4l2_subdev_get_try_format(sd, cfg, 0);
>   *mf = sink_fmt_default;
>  
> + r = v4l2_subdev_get_try_crop(sd, cfg, 0);
> + *r = crop_rect_default;
> +
>   for (i = 1; i < sd->entity.num_pads; i++) {
>   mf = v4l2_subdev_get_try_format(sd, cfg, i);
>   *mf = sink_fmt_default;
> @@ -107,16 +122,21 @@ static int vimc_sca_get_fmt(struct v4l2_subdev *sd,
>   struct v4l2_subdev_format *format)
>  {
>   struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
> + struct v4l2_rect *crop_rect;
>  
>   /* Get the current sink format */
> - format->format = (format->which == V4L2_SUBDEV_FORMAT_TRY) ?
> -  *v4l2_subdev_get_try_format(sd, cfg, 0) :
> -  vsca->sink_fmt;
> + if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> + format->format = *v4l2_subdev_get_try_format(sd, cfg, 0);
> + crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0);
> + } else {
> + format->format = vsca->sink_fmt;
> + crop_rect = &vsca->crop_rect;
> + }
>  
>   /* Scale the frame size for the source pad */
>   if (VIMC_IS_SRC(format->pad)) {
> - format->format.width = vsca->sink_fmt.width * sca_mult;
> - format->format.height = vsca->sink_fmt.height * sca_mult;
> + format->format.width = crop_rect->width * sca_mult;
> + format->format.height = crop_rect->height * sca_mult;
>   }
>  
>   return 0;
> @@ -148,6 +168,7 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd,
>  {
>   struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
>   struct v4l2_mbus_framefmt *sink_fmt;
> + struct v4l2_rect *crop_rect;
>  
>   if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
>   /* Do not change the format while stream is on */
> @@ -155,8 +176,10 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd,
>   return -EBUSY;
>  
>   sink_fmt = &vsca->sink_fmt;
> + crop_rect = &vsca->crop_rect;
>   } else {
> 

[PATCH] v4l2-ctl: add missing subdev usage in --help-all

2019-09-25 Thread Helen Koike
--help-all option was not displaying options from --help-subdev.
Add missing subdev_usage() in usage_all() to fix it.

Signed-off-by: Helen Koike 
---
 utils/v4l2-ctl/v4l2-ctl.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
index 77e0d369..aa4742c5 100644
--- a/utils/v4l2-ctl/v4l2-ctl.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
@@ -299,6 +299,7 @@ static void usage_all(void)
vbi_usage();
sdr_usage();
meta_usage();
+   subdev_usage();
selection_usage();
misc_usage();
streaming_usage();
-- 
2.22.0



Re: [ANN] Media sessions in Lyon in October: libcamera

2019-09-24 Thread Helen Koike
Hi,

On 9/23/19 3:21 PM, Daniel Gomez wrote:
> Hi Laurent, Hans:
> On Mon, 23 Sep 2019 at 20:16, Shuah Khan  wrote:
>>
>> On 9/23/19 9:57 AM, Laurent Pinchart wrote:
>>> Hello everybody,
>>>
>>> On Mon, Sep 23, 2019 at 04:03:54PM +0100, Kieran Bingham wrote:
>>>> On 23/09/2019 15:47, Nicolas Dufresne wrote:
>>>>> Le lundi 23 septembre 2019 à 16:21 +0200, Hans Verkuil a écrit :
>>>>>> Hi all,
>>>>>>
>>>>>> Since we have three separate half-day sessions for different topics I 
>>>>>> decided
>>>>>> to split the announcement for this in three emails as well, so these 
>>>>>> things
>>>>>> can be discussed in separate threads.
>>>>>>
>>>>>> All sessions are in room Terreaux VIP Lounge - Level 0.
>>>>>> There is a maximum of 15 people.
>>>>>>
>>>>>> The second session deals with libcamera and is on Wednesday morning
>>>>>> from 9:00 to 13:00.
>>>>>>
>>>>>> Attendees for this session:
>>>>>>
>>>>>> Kieran Bingham 
>>>>
>>>> Unfortunately I can no longer attend ELCE.
>>>>
>>>> (My second baby will be a bit too new for an extended stay away from home)
>>>>
>>>>>> Boris Brezillon 
>>>>>> Alexandre Courbot 
>>>>>> Tomasz Figa 
>>>>>> Ezequiel Garcia 
>>>>>> Daniel Gomez 
>>>>>> Dafna Hirschfeld 
>>>>>> Eugen Hristev 
>>>>>> Shuah Khan 
>>>>>> Helen Koike 
>>>>>> Jacopo Mondi 
>>>>>> Laurent Pinchart 
>>>>>> Niklas Söderlund 
>>>>>> Hans Verkuil 
>>>>>>
>>>>>> If I missed someone, or you are on the list but won't attend after all, 
>>>>>> then
>>>>>> please let me know.
>>>>>
>>>>> I would like to join this one to, as after ELCE I should have some time
>>>>> to spend on this. I understand thought hat this would make use reach
>>>>> the limit, let me know if there is any issues, I can spare my seat if
>>>>> needed.
>>>>
>>>> You now have my seat, and I've just made you a required attendee to go
>>>> in my place :-D
>>>
>>> Thank you for the offer Kieran.
>>>
>>> We're reaching the room capacity, and I know of several people who may
>>> attend ELCE and would be beneficial for the discussions. If anyone in
>>> the above list only has a general curiosity about libcamera but doesn't
>>> expect to really contribute to the discussions, and would consider
>>> giving their seat if required, could you please let me know ?
>>>
> I would like to attend if possible since we are going to work with libcamera
> but not sure how much I can contribute so, no problem to give my seat
> if necessary.

Same thing for me. I also would like to attend since I intend to work on 
libcamera,
more specifically in the Rockchip support part. But not sure how much I can 
contribute.

Helen

>>
>> Looks like I have a conflict with my talk for the an hour so towards the
>> end of this morning session. I might as well give up my seat so it can
>> be given to somebody that can attend the session in full.
>>
>> I am attending the afternoon session on Wednesday.
>>
>> thanks,
>> -- Shuah


Re: [PATCH 0/4] Enable Hantro G1 post-processor

2019-09-16 Thread Helen Koike
Hello,

On 9/12/19 8:35 AM, Ezequiel Garcia wrote:
> On Thu, 2019-09-12 at 14:52 +0900, Tomasz Figa wrote:
>> On Thu, Sep 12, 2019 at 4:49 AM Nicolas Dufresne  
>> wrote:
>>> Le mercredi 11 septembre 2019 à 09:27 +0100, Ezequiel Garcia a écrit :
 On Mon, 2019-09-09 at 16:07 +0900, Tomasz Figa wrote:
> Hi Ezequiel,
>
> On Wed, Sep 4, 2019 at 3:17 AM Ezequiel Garcia  
> wrote:
>> Hi all,
>>
>> This series enables the post-processor support available
>> on the Hantro G1 VPU. The post-processor block can be
>> pipelined with the decoder hardware, allowing to perform
>> operations such as color conversion, scaling, rotation,
>> cropping, among others.
>>
>> The decoder hardware needs its own set of NV12 buffers
>> (the native decoder format), and the post-processor is the
>> owner of the CAPTURE buffers. This allows the application
>> get processed (scaled, converted, etc) buffers, completely
>> transparently.
>>
>> This feature is implemented by exposing other CAPTURE pixel
>> formats to the application (ENUM_FMT). When the application
>> sets a pixel format other than NV12, the driver will enable
>> and use the post-processor transparently.
>
> I'll try to review the series a bit later, but a general comment here
> is that the userspace wouldn't have a way to distinguish between the
> native and post-processed formats. I'm pretty much sure that
> post-processing at least imposes some power penalty, so it would be
> good if the userspace could avoid it if unnecessary.
>

 Hm, that's true, good catch.

 So, it would be desirable to retain the current behavior of allowing
 the application to just set a different pixel format and get
 a post-processed frame, transparently.

 But at the same time, it would be nice if the application is somehow
 aware of the post-processing happening. Maybe we can expose a more
 accurate media controller topology, have applications enable
 the post-processing pipeline explicitly.
>>>
>>> How it works on the stateful side is that userspace set the encoding
>>> type (the codec), then passes a header (in our case, there will be
>>> parsed structures replacing this) first. The driver then configure
>>> capture format, giving a hint of the "default" or "native" format. This
>>> may or may not be sufficient, but it does work in giving userspace a
>>> hint.
>>
>> The bad side of that is that we can't handle more than 1 native format.
>>
>> For the most backwards-compatible behavior, sorting the results of
>> ENUM_FMT according to format preference would allow the applications
>> that choose the first format returned that works for them to choose
>> the best one.
>>
>> For a further improvement, an ENUM_FMT flag that tells the userspace
>> that a format is preferred could work.
>>
>> That said, modelling the pipeline appropriately using the media
>> controller is the idea I like the most, because it's the most
>> comprehensive solution. That would have to be well specified and
>> documented, though, and sounds like a long term effort.
>>

I was playing with vimc to emulate this topology.

What I would suggest is a topology like this:

Device topology
- entity 1: Decoder (2 pads, 3 links)
type V4L2 subdev subtype Unknown flags 0
pad0: Sink
<- "M2M Video Node":1 [ENABLED]
pad1: Source
-> "M2M Video Node":0 [ENABLED]
-> "PostProc":0 []

- entity 4: PostProc (2 pads, 2 links)
type V4L2 subdev subtype Unknown flags 0
pad0: Sink
<- "Decoder":1 []
pad1: Source
-> "M2M Video Node":0 []

- entity 7: M2M Video Node (2 pads, 3 links)
type Node subtype V4L flags 0
device node name /dev/video0
pad0: Sink
<- "Decoder":1 [ENABLED]
<- "PostProc":1 []
pad1: Source
-> "Decoder":0 [ENABLED]

Dot file:
-
digraph board {
rankdir=TB
n0001 [label="{{ 0} | Decoder\n | { 1}}", 
shape=Mrecord, style=filled, fillcolor=green]
n0001:port1 -> n0007
n0001:port1 -> n0004:port0 [style=dashed]
n0004 [label="{{ 0} | PostProc\n | { 1}}", 
shape=Mrecord, style=filled, fillcolor=green]
n0004:port1 -> n0007 [style=dashed]
n0007 [label="M2M Video Node\n/dev/video0", shape=box, 
style=filled, fillcolor=yellow]
n0007 -> n0001:port0
}


Also, as you mentioned in patch 4:

> On the YUV-to-RGB path, the post-processing pipeline
> allows to modify the image contrast, brigthness and saturation,
> so additional user controls are added to expose them.

So I think it would make sense to expose these controls in the post-processor 
subdev,
through a /dev/v4l-subdev0, this avoids having a dynamic set of controls in the 
video node
depending on th

Re: [PATCH] media: vimc: upon streaming, check that the pipeline starts with a source entity

2019-08-30 Thread Helen Koike
Hi Dafna,

Thanks for the patch. Just small comments below.

On 8/29/19 8:00 AM, Dafna Hirschfeld wrote:
> Userspace can disable links and create pipelines that
> do not start with a source entity. Trying to stream
> from such a pipeline should fail with -EPIPE
> currently this is not handled and cause kernel crash.
> 
> Signed-off-by: Dafna Hirschfeld 
> ---
> Hi,
> These are the commands to reproduce the crash:
> media-ctl -d0 -l "5:1->21:0[0]" -v
> v4l2-ctl -z platform:vimc -d "RGB/YUV Capture" -v width=1920,height=1440
> v4l2-ctl --stream-mmap --stream-count=100 -d /dev/video2
> 
> drivers/media/platform/vimc/vimc-streamer.c | 39 +++--
>  1 file changed, 28 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-streamer.c 
> b/drivers/media/platform/vimc/vimc-streamer.c
> index 048d770e498b..bfc7921c7a8b 100644
> --- a/drivers/media/platform/vimc/vimc-streamer.c
> +++ b/drivers/media/platform/vimc/vimc-streamer.c
> @@ -13,6 +13,19 @@
>  
>  #include "vimc-streamer.h"
>  
> +/**
> + * Check if the entity has only source pads
> + */

please add docs like the other functions in this file.

> +static bool vimc_is_source(struct media_entity *ent)
> +{
> + int i;

unsigned

Regards,
Helen

> +
> + for (i = 0; i < ent->num_pads; i++)
> + if (ent->pads[i].flags & MEDIA_PAD_FL_SINK)
> + return false;
> + return true;
> +}
> +
>  /**
>   * vimc_get_source_entity - get the entity connected with the first sink pad
>   *
> @@ -83,14 +96,12 @@ static int vimc_streamer_pipeline_init(struct vimc_stream 
> *stream,
>   struct media_entity *entity;
>   struct video_device *vdev;
>   struct v4l2_subdev *sd;
> - int ret = 0;
> + int ret = -EINVAL;
>  
>   stream->pipe_size = 0;
>   while (stream->pipe_size < VIMC_STREAMER_PIPELINE_MAX_SIZE) {
> - if (!ved) {
> - vimc_streamer_pipeline_terminate(stream);
> - return -EINVAL;
> - }
> + if (!ved)
> + break;
>   stream->ved_pipeline[stream->pipe_size++] = ved;
>  
>   if (is_media_entity_v4l2_subdev(ved->ent)) {
> @@ -99,15 +110,22 @@ static int vimc_streamer_pipeline_init(struct 
> vimc_stream *stream,
>   if (ret && ret != -ENOIOCTLCMD) {
>   pr_err("subdev_call error %s\n",
>  ved->ent->name);
> - vimc_streamer_pipeline_terminate(stream);
> - return ret;
> + break;
>   }
>   }
>  
>   entity = vimc_get_source_entity(ved->ent);
> - /* Check if the end of the pipeline was reached*/
> - if (!entity)
> + /* Check if the end of the pipeline was reached */
> + if (!entity) {
> + /* the first entity of the pipe should be source only */
> + if (!vimc_is_source(ved->ent)) {
> + pr_err("first entity in the pipe '%s' is not a 
> source\n",
> +ved->ent->name);
> + ret = -EPIPE;
> + break;
> + }
>   return 0;
> + }
>  
>   /* Get the next device in the pipeline */
>   if (is_media_entity_v4l2_subdev(entity)) {
> @@ -120,9 +138,8 @@ static int vimc_streamer_pipeline_init(struct vimc_stream 
> *stream,
>   ved = video_get_drvdata(vdev);
>   }
>   }
> -
>   vimc_streamer_pipeline_terminate(stream);
> - return -EINVAL;
> + return ret;
>  }
>  
>  /**
> 


Re: [PATCH 2/2] media: Don't hide any menu if "ancillary drivers autoselect" is enabled

2019-07-25 Thread Helen Koike



On 7/25/19 3:41 PM, Mauro Carvalho Chehab wrote:
> Em Fri, 26 Jul 2019 01:29:58 +0800
> Chen-Yu Tsai  escreveu:
> 
>> On Fri, Jul 26, 2019 at 1:06 AM Ezequiel Garcia  
>> wrote:
>>>
>>> On Thu, 2019-07-25 at 12:57 -0300, Mauro Carvalho Chehab wrote:  
 Em Mon, 15 Jul 2019 18:23:16 -0300
 Ezequiel Garcia  escreveu:
  
> Many users have been complaining about not being able to find
> certain menu options. One such example are camera sensor drivers
> (e.g IMX219, OV5645, etc) which are common on embedded platforms
> and not always ancillary devices.
>
> The problem with MEDIA_SUBDRV_AUTOSELECT seems to be related
> to the fact that it uses the "visible" kbuild syntax to hide
> entire group of drivers.
>
> This is not obvious and, as explained above, not always desired.
>
> To fix the problem, drop the "visible" and stop hiding any menu
> options. Users skilled enough to configure their kernel are expected
> to be skilled enough to know what (not) to configure anyway.
>
> Signed-off-by: Ezequiel Garcia 
> ---
>  drivers/media/dvb-frontends/Kconfig | 1 -
>  drivers/media/i2c/Kconfig   | 1 -
>  drivers/media/spi/Kconfig   | 1 -
>  drivers/media/tuners/Kconfig| 1 -
>  4 files changed, 4 deletions(-)
>
> diff --git a/drivers/media/dvb-frontends/Kconfig 
> b/drivers/media/dvb-frontends/Kconfig
> index dc43749177df..2d1fea3bf546 100644
> --- a/drivers/media/dvb-frontends/Kconfig
> +++ b/drivers/media/dvb-frontends/Kconfig
> @@ -1,5 +1,4 @@
>  menu "Customise DVB Frontends"
> -   visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST || EXPERT
>
>  comment "Multistandard (satellite) frontends"
> depends on DVB_CORE
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 79ce9ec6fc1b..475072bb67d6 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -23,7 +23,6 @@ config VIDEO_IR_I2C
>  #
>
>  menu "I2C Encoders, decoders, sensors and other helper chips"
> -   visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST || EXPERT  

 Hmm... Hans picked this patch, but IMO it doesn't make sense
 for PC consumer people to see the hundreds of extra options
 that making those menus visible will produce.

 This was added because in the past we had lots of issues with
 people desktop/laptop settings with all those things enabled.

 In any case, if the desktop/laptop user is smart enough to
 go though it, he can simply disable MEDIA_SUBDRV_AUTOSELECT and
 manually select what he wants, so I really miss the point of
 making those stuff always visible.

 Now, from this patch's comments, it seems that you want this
 to be visible if CONFIG_EMBEDDED. So, I won't complain if you
 replace the changes on this patch to:

   menu "foo"
   visible if !MEDIA_SUBDRV_AUTOSELECT || !EMBEDDED || COMPILE_TEST 
 || EXPERT

 In other words, for the normal guy that just wants to build the
 latest media stuff for his PC camera or TV device to work, he won't
 need to dig into hundreds of things that won't make any difference
 if he enables, except for making the Kernel bigger.
  
>>>
>>> Well, I think the real value of MEDIA_SUBDRV_AUTOSELECT is the 
>>> autoselection,
>>> not the hidden part. I'm really missing to see what hiding anything gives 
>>> you.
>>>
>>> In other words, this option gets useful when driver authors select ancillary
>>> drivers such as:
>>>
>>> config VIDEO_USBVISION
>>> tristate "USB video devices based on Nogatech NT1003/1004/1005"
>>> depends on I2C && VIDEO_V4L2
>>> select VIDEO_TUNER
>>> select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
>>>
>>> What's so confusing about having these drivers visible? Compared to the
>>> rest of the zillion menu options, what's more confusing about seeing these?
>>>
>>> Now, while I would agree with EMBEDDED, the problem with that is that
>>> many "embedded" platforms don't enable EMBEDDED. So, it's not that useful.
>>>
>>> Finally, let me give an example of why hiding the menus is so bad.
>>> Normally, to enable a symbol, we use the search tool.
>>>
>>> Now, when MEDIA_SUBDRV_AUTOSELECT=y, the search tool will _not_ take you
>>> there and there's no indication why.  
>>
>> As someone who has done so in the past year, I agree it's confusing.
>> I had to dig through the Kconfig files to figure out which knobs to
>> turn to get the OV5640 option out. The description says "auto-selecting",

I had this same problem.

> 
> Well, the text and/or the help message can be changed, if it is not
> clear enough, but this option was added because we had too many issues
> with users trying to build drivers for their devices without being
> able to do that, because selecting thousands of devices is something
> t

Re: [PATCH 3/3] vimc: Join pipeline if one already exists

2019-07-09 Thread Helen Koike
Hi Niklas,

Thanks for the patch (and sorry for my late reply).

On 5/17/19 10:07 PM, Niklas Söderlund wrote:
> A sensor which is running is already part of a pipeline and trying to
> start a new pipeline is not possible. This prevents two capture devices
> connected to the same sensor from running at the same time.
> 
> Instead of failing to start the second capture device allow it to join
> the already running pipeline by looking it up at the sensor. This allows
> two (or more) capture devices to independently be started and stopped
> while still being connected to the same sensor.
> 
> Signed-off-by: Niklas Söderlund 
> ---
>  drivers/media/platform/vimc/vimc-capture.c | 35 +-
>  1 file changed, 34 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index e7d0fc2228a6f0c1..f9eb1e327e311b4a 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -264,16 +264,49 @@ static void vimc_cap_return_all_buffers(struct 
> vimc_cap_device *vcap,
>   spin_unlock(&vcap->qlock);
>  }
>  
> +static struct media_entity *vimc_cap_get_sensor(struct vimc_cap_device *vcap)
> +{
> + struct media_entity *entity = &vcap->vdev.entity;
> + struct media_device *mdev = entity->graph_obj.mdev;
> + struct media_graph graph;
> +
> + mutex_lock(&mdev->graph_mutex);
> + if (media_graph_walk_init(&graph, mdev)) {
> + mutex_unlock(&mdev->graph_mutex);
> + return NULL;
> + }
> +
> + media_graph_walk_start(&graph, entity);
> +
> + while ((entity = media_graph_walk_next(&graph)))
> + if (entity->function == MEDIA_ENT_F_CAM_SENSOR)
> + break;

I was wondering if it should search up to the sensor, or if it could just 
search the first entity with a pipe object, what do you think?
Like this it should work with an output device instead of a sensor.

Regards,
Helen

> +
> + mutex_unlock(&mdev->graph_mutex);
> +
> + media_graph_walk_cleanup(&graph);
> +
> + return entity;
> +}
> +
>  static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
>  {
>   struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
>   struct media_entity *entity = &vcap->vdev.entity;
> + struct media_pipeline *pipe = NULL;
> + struct media_entity *sensorent;
>   int ret;
>  
>   vcap->sequence = 0;
>  
>   /* Start the media pipeline */
> - ret = media_pipeline_start(entity, &vcap->stream.pipe);
> + sensorent = vimc_cap_get_sensor(vcap);
> + if (sensorent && sensorent->pipe)
> + pipe = sensorent->pipe;
> + else
> + pipe = &vcap->stream.pipe;
> +
> + ret = media_pipeline_start(entity, pipe);
>   if (ret) {
>   vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
>   return ret;
> 


Re: Linux 5.2 - vimc streaming fails with format error

2019-07-08 Thread Helen Koike
Hi Shuah,

On 7/2/19 10:44 PM, shuah wrote:
> On 5/23/19 9:07 AM, shuah wrote:
>> Hi Hans and Helen,
>>
>> vimc streaming fails on Linux 5.2-rc1
>>
>> vimc: format doesn't match in link Scaler->RGB/YUV Capture
>>
>> You can reproduce this easily with v4l2-ctl
>>
>> Streaming works fine on Linux 5.1
>>
>> I narrowed it to the following commit.
>> commit b6c61a6c37317efd7327199bfe24770af3d7e799
>> Author: Helen Fornazier 
>> Date:   Wed Mar 13 14:29:37 2019 -0400
>>
>>  media: vimc: propagate pixel format in the stream
>>
>>
>> Please take a look.
>>
>> thanks,
>> -- Shuah
>>
> 
> Hi Hans and Helen,
> 
> Is there trick to being able to run v4l2-ctl --stream-mmap on vimc
> 
> I am seeing
> 
> VIDIOC_STREAMON returned -1 (Broken pipe)
> 
> since 5.2 and narrowed it to the above commit.
> 
> I am working on vimc life-time problem and unable test my patches
> because of this commit on 5.2
> 
> thanks,
> -- Shuah


Thanks you for working on this and sorry for my late reply.

The media topology requires configuration from userspace, otherwise 
configuration
between the media entities won't match and you'll get a Broken Pipe (this is 
expected).

I'll update libcamera to properly configure it, but meanwhile you should
be able to configure with the following commands:

media-ctl -d platform:vimc -V '"Sensor A":0[fmt:SBGGR8_1X8/640x480]'
media-ctl -d platform:vimc -V '"Debayer A":0[fmt:SBGGR8_1X8/640x480]'
media-ctl -d platform:vimc -V '"Sensor B":0[fmt:SBGGR8_1X8/640x480]'
media-ctl -d platform:vimc -V '"Debayer B":0[fmt:SBGGR8_1X8/640x480]'
v4l2-ctl -z platform:vimc -d "RGB/YUV Capture" -v width=1920,height=1440
v4l2-ctl -z platform:vimc -d "Raw Capture 0" -v pixelformat=BA81
v4l2-ctl -z platform:vimc -d "Raw Capture 1" -v pixelformat=BA81

I hope this helps.

Thanks again,
Helen


Re: [PATCH v5 12/14] media: vimc: sca: Add support for multiplanar formats

2019-04-26 Thread Helen Koike



On 4/26/19 4:51 PM, André Almeida wrote:
> Change the scaling functions in order to scale planes. This change makes
> easier to support multiplanar pixel formats.
> 
> Signed-off-by: André Almeida 

Acked-by: Helen Koike 

> ---
> Changes in v5:
> - Remove bpp from vimc_sca_device
> - Changes where bpp var is declared at `vimc_sca_scale_pix`
> 
> Changes in v4:
> - Rename `frame_size` to `plane_size`
> - Correct `unsigned int ret` to `int ret`
> - Remove label `free_planes` from else scope
> - Change type of `width` and `heigth` to `unsigned int`
> - Rename and move var declarations on `vimc_sca_fill_src_frame`
> - Change `comp_planes` to `mem_planes` 
> - Remove `v4l2_format_info()` unnecessary call
> 
> Change in v3:
> - Adapt to new vimc_frame
> 
> Changes in v2:
> - Move the TODO comment to vimc-capture
> - Reuse and share the code to free the memory of planes with a goto
> - Fix comment block style 
>  drivers/media/platform/vimc/vimc-scaler.c | 113 +-
>  1 file changed, 69 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-scaler.c 
> b/drivers/media/platform/vimc/vimc-scaler.c
> index f655b8312dc9..71b16ad80bc8 100644
> --- a/drivers/media/platform/vimc/vimc-scaler.c
> +++ b/drivers/media/platform/vimc/vimc-scaler.c
> @@ -39,6 +39,9 @@ static const u32 vimc_sca_supported_pixfmt[] = {
>   V4L2_PIX_FMT_BGR24,
>   V4L2_PIX_FMT_RGB24,
>   V4L2_PIX_FMT_ARGB32,
> + V4L2_PIX_FMT_YUV420,
> + V4L2_PIX_FMT_YUV420M,
> + V4L2_PIX_FMT_NV12M,
>  };
>  
>  struct vimc_sca_device {
> @@ -51,8 +54,7 @@ struct vimc_sca_device {
>   struct v4l2_mbus_framefmt sink_fmt;
>   /* Values calculated when the stream starts */
>   struct vimc_frame src_frame;
> - unsigned int src_line_size;
> - unsigned int bpp;
> + unsigned int src_line_size[TPG_MAX_PLANES];
>  };
>  
>  static const struct v4l2_mbus_framefmt sink_fmt_default = {
> @@ -207,11 +209,12 @@ static const struct v4l2_subdev_pad_ops 
> vimc_sca_pad_ops = {
>  static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable)
>  {
>   struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
> + unsigned int i;
> + int ret = 0;
>  
>   if (enable) {
>   u32 pixelformat = vsca->ved.stream->producer_pixfmt;
> - const struct v4l2_format_info *pix_info;
> - unsigned int frame_size;
> + unsigned int plane_size;
>  
>   if (!vimc_sca_is_pixfmt_supported(pixelformat)) {
>   dev_err(vsca->dev, "pixfmt (0x%08x) is not supported\n",
> @@ -219,34 +222,44 @@ static int vimc_sca_s_stream(struct v4l2_subdev *sd, 
> int enable)
>   return -EINVAL;
>   }
>  
> - /* Save the bytes per pixel of the sink */
> - pix_info = v4l2_format_info(pixelformat);
> - vsca->bpp = pix_info->bpp[0];
> -
> - /* Calculate the width in bytes of the src frame */
> - vsca->src_line_size = vsca->sink_fmt.width *
> -   sca_mult * vsca->bpp;
> -
> - /* Calculate the frame size of the source pad */
> - frame_size = vsca->src_line_size * vsca->sink_fmt.height *
> -  sca_mult;
> + vimc_fill_frame(&vsca->src_frame, pixelformat,
> + vsca->sink_fmt.width, vsca->sink_fmt.height);
> +
> + for (i = 0; i < vsca->src_frame.fmt.num_planes; i++) {
> + /* Calculate the width in bytes of the src frame */
> + vsca->src_line_size[i] =
> + vsca->src_frame.fmt.plane_fmt[i].bytesperline *
> + sca_mult;
> +
> + /* Calculate the size of the nth-plane of source pad */
> + plane_size = vsca->src_frame.fmt.plane_fmt[i].sizeimage
> + * sca_mult * sca_mult;
> +
> + /**
> +  * Allocate the frame buffer. Use vmalloc to be able to
> +  * allocate a large amount of memory
> +  */
> + vsca->src_frame.plane_addr[i] = vmalloc(plane_size);
> + if (!vsca->src_frame.plane_addr[i]) {
> + ret = -ENOMEM;
> + goto free_planes;
> + }
> + vsca->src_frame.fmt.plane_fmt[i].sizeimage = plane_size;
> + }
>  
> - /* Allocate the frame

Re: [PATCH v4 13/14] media: vimc: cap: Add support for multiplanar formats

2019-04-26 Thread Helen Koike



On 4/25/19 10:22 PM, André Almeida wrote:
> Adapt vimc-capture to support multiplanar formats, copying
> each plane to the correct buffer.
> 
> Signed-off-by: André Almeida 

Acked-by: Helen Koike 

> ---
> Change in v4:
> - Move variables to inside the for loop
> - Change `plane_size` type from `unsigned int` to `size_t`
> 
> Change in v3:
> - Adapt to new vimc_frame
> 
> Change in v2: none
> 
>  drivers/media/platform/vimc/vimc-capture.c | 16 ++--
>  1 file changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index d9dae5b3a0bf..932d622d56ca 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -523,7 +523,7 @@ static struct vimc_frame *vimc_cap_process_frame(struct 
> vimc_ent_device *ved,
>   struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
>   ved);
>   struct vimc_cap_buffer *vimc_buf;
> - void *vbuf;
> + unsigned int i;
>  
>   spin_lock(&vcap->qlock);
>  
> @@ -545,13 +545,17 @@ static struct vimc_frame *vimc_cap_process_frame(struct 
> vimc_ent_device *ved,
>   vimc_buf->vb2.sequence = vcap->sequence++;
>   vimc_buf->vb2.field = vcap->format.fmt.pix.field;
>  
> - vbuf = vb2_plane_vaddr(&vimc_buf->vb2.vb2_buf, 0);
> + /* For each plane, copy the pixels */
> + for (i = 0; i < vimc_buf->vb2.vb2_buf.num_planes; i++) {
> + void *vbuf = vb2_plane_vaddr(&vimc_buf->vb2.vb2_buf, i);
> + size_t plane_size = frame->fmt.plane_fmt[i].sizeimage;
> +
> + memcpy(vbuf, frame->plane_addr[i], plane_size);
>  
> - memcpy(vbuf, frame->plane_addr[0], vcap->format.fmt.pix.sizeimage);
> + /* Set it as ready */
> + vb2_set_plane_payload(&vimc_buf->vb2.vb2_buf, i, plane_size);
> + }
>  
> - /* Set it as ready */
> - vb2_set_plane_payload(&vimc_buf->vb2.vb2_buf, 0,
> -   vcap->format.fmt.pix.sizeimage);
>   vb2_buffer_done(&vimc_buf->vb2.vb2_buf, VB2_BUF_STATE_DONE);
>   return NULL;
>  }
> 


Re: [PATCH v4 12/14] media: vimc: sca: Add support for multiplanar formats

2019-04-26 Thread Helen Koike



On 4/25/19 10:22 PM, André Almeida wrote:
> Change the scaling functions in order to scale planes. This change makes
> easier to support multiplanar pixel formats.
> 
> Signed-off-by: André Almeida 
> ---
> Changes in v4:
> - Rename `frame_size` to `plane_size`
> - Correct `unsigned int ret` to `int ret`
> - Remove label `free_planes` from else scope
> - Change type of `width` and `heigth` to `unsigned int`
> - Rename and move var declarations on `vimc_sca_fill_src_frame`
> - Change `comp_planes` to `mem_planes` 
> - Remove `v4l2_format_info()` unnecessary call
> 
> Change in v3:
> - Adapt to new vimc_frame
> 
> Changes in v2:
> - Move the TODO comment to vimc-capture
> - Reuse and share the code to free the memory of planes with a goto
> - Fix comment block style 
> 
>  drivers/media/platform/vimc/vimc-scaler.c | 117 ++
>  1 file changed, 74 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-scaler.c 
> b/drivers/media/platform/vimc/vimc-scaler.c
> index f655b8312dc9..a49870c9cbf1 100644
> --- a/drivers/media/platform/vimc/vimc-scaler.c
> +++ b/drivers/media/platform/vimc/vimc-scaler.c
> @@ -39,6 +39,9 @@ static const u32 vimc_sca_supported_pixfmt[] = {
>   V4L2_PIX_FMT_BGR24,
>   V4L2_PIX_FMT_RGB24,
>   V4L2_PIX_FMT_ARGB32,
> + V4L2_PIX_FMT_YUV420,
> + V4L2_PIX_FMT_YUV420M,
> + V4L2_PIX_FMT_NV12M,
>  };
>  
>  struct vimc_sca_device {
> @@ -51,8 +54,8 @@ struct vimc_sca_device {
>   struct v4l2_mbus_framefmt sink_fmt;
>   /* Values calculated when the stream starts */
>   struct vimc_frame src_frame;
> - unsigned int src_line_size;
> - unsigned int bpp;
> + unsigned int src_line_size[TPG_MAX_PLANES];
> + unsigned int bpp[TPG_MAX_PLANES];

Do you think we could get rid of this bpp variable here as we have it
inside vimc_frame struct ?

Helen

>  };
>  
>  static const struct v4l2_mbus_framefmt sink_fmt_default = {
> @@ -207,11 +210,12 @@ static const struct v4l2_subdev_pad_ops 
> vimc_sca_pad_ops = {
>  static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable)
>  {
>   struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
> + unsigned int i;
> + int ret = 0;
>  
>   if (enable) {
>   u32 pixelformat = vsca->ved.stream->producer_pixfmt;
> - const struct v4l2_format_info *pix_info;
> - unsigned int frame_size;
> + unsigned int plane_size;
>  
>   if (!vimc_sca_is_pixfmt_supported(pixelformat)) {
>   dev_err(vsca->dev, "pixfmt (0x%08x) is not supported\n",
> @@ -219,34 +223,47 @@ static int vimc_sca_s_stream(struct v4l2_subdev *sd, 
> int enable)
>   return -EINVAL;
>   }
>  
> - /* Save the bytes per pixel of the sink */
> - pix_info = v4l2_format_info(pixelformat);
> - vsca->bpp = pix_info->bpp[0];
> -
> - /* Calculate the width in bytes of the src frame */
> - vsca->src_line_size = vsca->sink_fmt.width *
> -   sca_mult * vsca->bpp;
> -
> - /* Calculate the frame size of the source pad */
> - frame_size = vsca->src_line_size * vsca->sink_fmt.height *
> -  sca_mult;
> + vimc_fill_frame(&vsca->src_frame, pixelformat,
> + vsca->sink_fmt.width, vsca->sink_fmt.height);
> +
> + for (i = 0; i < vsca->src_frame.fmt.num_planes; i++) {
> + /* Save the bytes per pixel of the sink */
> + vsca->bpp[i] = vsca->src_frame.fmt_info->bpp[i];
> +
> + /* Calculate the width in bytes of the src frame */
> + vsca->src_line_size[i] =
> + vsca->src_frame.fmt.plane_fmt[i].bytesperline *
> + sca_mult;
> +
> + /* Calculate the size of the nth-plane of source pad */
> + plane_size = vsca->src_frame.fmt.plane_fmt[i].sizeimage
> + * sca_mult * sca_mult;
> +
> + /**
> +  * Allocate the frame buffer. Use vmalloc to be able to
> +  * allocate a large amount of memory
> +  */
> + vsca->src_frame.plane_addr[i] = vmalloc(plane_size);
> + if (!vsca->src_frame.plane_addr[i]) {
> + ret = -ENOMEM;
> + goto free_planes;
> + }
> + vsca->src_frame.fmt.plane_fmt[i].sizeimage = plane_size;
> + }
>  
> - /* Allocate the frame buffer. Use vmalloc to be able to
> -  * allocate a large amount of memory
> -  */
> - vsca->src_frame.plane_addr[0] = vmalloc(frame_size);
> - if (!vsca->src_frame.plane_addr[0])
> - return -ENOMEM;

Re: [PATCH v4 14/14] media: vimc: Create multiplanar parameter

2019-04-26 Thread Helen Koike



On 4/25/19 10:22 PM, André Almeida wrote:
> Create multiplanar kernel module parameter to define if the driver is
> running in single planar or in multiplanar mode. Define the device
> capabilities according to the multiplanar kernel parameter. A device can't
> support both CAP_VIDEO_CAPTURE and CAP_VIDEO_CAPTURE_MPLANAR at the
> same time.
> 
> Signed-off-by: André Almeida 

Acked-by: Helen Koike 

> ---
> Change in v4:
> - Split commit with "Add handler for multiplanar fmt ioctls" 
> 
> Change in v3:
> - Squash commit with "Add handler for multiplanar fmt ioctls" 
> - Remove functions that only did the `IS_MULTIPLANAR(vcap)` check
> - Assign ioctls according to device capabilities
> 
> Changes in v2:
> - Squash commits to create multiplanar module parameter and to define
> the device capabilities
> - Move the creation of the multiplanar parameter to the end of
> history, so it's only added when all required changes are applied
> 
>  drivers/media/platform/vimc/vimc-capture.c | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index 932d622d56ca..c5959b8e21f7 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -28,6 +28,10 @@
>  
>  #define VIMC_CAP_DRV_NAME "vimc-capture"
>  
> +static unsigned int multiplanar;
> +module_param(multiplanar, uint, );
> +MODULE_PARM_DESC(multiplanar, "0 (default) creates a single planar device, 1 
> creates a multiplanar device.");
> +
>  /* Checks if the device supports multiplanar capture */
>  #define IS_MULTIPLANAR(vcap) \
>   (vcap->vdev.device_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE)
> @@ -597,7 +601,9 @@ static int vimc_cap_comp_bind(struct device *comp, struct 
> device *master,
>  
>   /* Initialize the vb2 queue */
>   q = &vcap->queue;
> - q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> + q->type = multiplanar ?
> + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
> + V4L2_BUF_TYPE_VIDEO_CAPTURE;
>   q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_USERPTR;
>   q->drv_priv = vcap;
>   q->buf_struct_size = sizeof(struct vimc_cap_buffer);
> @@ -627,7 +633,9 @@ static int vimc_cap_comp_bind(struct device *comp, struct 
> device *master,
>  
>   /* Initialize the video_device struct */
>   vdev = &vcap->vdev;
> - vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
> + vdev->device_caps = (multiplanar ?
> + V4L2_CAP_VIDEO_CAPTURE_MPLANE :
> + V4L2_CAP_VIDEO_CAPTURE) | V4L2_CAP_STREAMING;
>   vdev->entity.ops = &vimc_cap_mops;
>   vdev->release = vimc_cap_release;
>   vdev->fops = &vimc_cap_fops;
> 


Re: [PATCH v4 10/14] media: vimc: Add and use new struct vimc_frame

2019-04-26 Thread Helen Koike



On 4/25/19 10:22 PM, André Almeida wrote:
> Struct vimc_frame is intended to hold metadata about a frame,
> such as memory address of a plane, number of planes and size
> of each plane, to better integrated with the multiplanar operations.
> The struct can be also used with singleplanar formats, making the
> implementation of frame manipulation generic for both type of
> formats.
> 
> vimc_fill_frame function fills a vimc_frame structure given a
> pixelformat, height and width. This is done once to avoid recalculations
> and provide enough information to subdevices work with
> the frame.
> 
> Change the return and argument type of process_frame from void* to
> vimc_frame*. Change the frame in subdevices structs from u8* to vimc_frame.
> 
> Signed-off-by: André Almeida 

Acked-by: Helen Koike 

> ---
> Changes in v4: 
> - Remove unused parameter `bool multiplanar`
> 
> Changes in v3:
> - Refactor vimc_frame struct, now it have fewer fields with the same
> content
> - Refactor vimc_fill_frame to be more simple
> 
> Change in v2:
> - Fix alignment issues
> 
>  drivers/media/platform/vimc/vimc-capture.c  |  6 +--
>  drivers/media/platform/vimc/vimc-common.c   |  8 
>  drivers/media/platform/vimc/vimc-common.h   | 41 +++--
>  drivers/media/platform/vimc/vimc-debayer.c  | 33 +
>  drivers/media/platform/vimc/vimc-scaler.c   | 25 +++--
>  drivers/media/platform/vimc/vimc-sensor.c   | 18 -
>  drivers/media/platform/vimc/vimc-streamer.c |  2 +-
>  7 files changed, 89 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index 0439a5a008e8..d9dae5b3a0bf 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -517,8 +517,8 @@ static void vimc_cap_comp_unbind(struct device *comp, 
> struct device *master,
>   video_unregister_device(&vcap->vdev);
>  }
>  
> -static void *vimc_cap_process_frame(struct vimc_ent_device *ved,
> - const void *frame)
> +static struct vimc_frame *vimc_cap_process_frame(struct vimc_ent_device *ved,
> +  const struct vimc_frame *frame)
>  {
>   struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
>   ved);
> @@ -547,7 +547,7 @@ static void *vimc_cap_process_frame(struct 
> vimc_ent_device *ved,
>  
>   vbuf = vb2_plane_vaddr(&vimc_buf->vb2.vb2_buf, 0);
>  
> - memcpy(vbuf, frame, vcap->format.fmt.pix.sizeimage);
> + memcpy(vbuf, frame->plane_addr[0], vcap->format.fmt.pix.sizeimage);
>  
>   /* Set it as ready */
>   vb2_set_plane_payload(&vimc_buf->vb2.vb2_buf, 0,
> diff --git a/drivers/media/platform/vimc/vimc-common.c 
> b/drivers/media/platform/vimc/vimc-common.c
> index fad7c7c6de93..9bd163ae326c 100644
> --- a/drivers/media/platform/vimc/vimc-common.c
> +++ b/drivers/media/platform/vimc/vimc-common.c
> @@ -380,6 +380,14 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
>  }
>  EXPORT_SYMBOL_GPL(vimc_ent_sd_register);
>  
> +void vimc_fill_frame(struct vimc_frame *frame, u32 pixelformat, u32 width,
> +  u32 height)
> +{
> + frame->fmt_info = v4l2_format_info(pixelformat);
> + v4l2_fill_pixfmt_mp(&frame->fmt, pixelformat, width, height);
> +}
> +EXPORT_SYMBOL_GPL(vimc_fill_frame);
> +
>  void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev 
> *sd)
>  {
>   media_entity_cleanup(ved->ent);
> diff --git a/drivers/media/platform/vimc/vimc-common.h 
> b/drivers/media/platform/vimc/vimc-common.h
> index 142ddfa69b3d..ab5eccc95af4 100644
> --- a/drivers/media/platform/vimc/vimc-common.h
> +++ b/drivers/media/platform/vimc/vimc-common.h
> @@ -21,6 +21,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "vimc-streamer.h"
>  
> @@ -79,6 +80,25 @@ struct vimc_platform_data {
>   char entity_name[32];
>  };
>  
> +/**
> + * struct vimc_frame - metadata about frame components
> + *
> + * @plane_addr:  pointer to kernel address of the plane
> + * @fmt: pixel format attributes
> + * @fmt_info:pointer to a struct with pixel format metadata
> + *
> + * This struct helps subdevices to get information about the frame on
> + * multiplanar formats. If a singleplanar format is used, only the first
> + * index of the array is used and num_planes is set to 1, so the
> + * implementation is generic and the code will work for both form

Re: [PATCH v4 11/14] media: vimc: sen: Add support for multiplanar formats

2019-04-26 Thread Helen Koike



On 4/25/19 10:22 PM, André Almeida wrote:
> This commit adapts vimc-sensor to handle multiplanar pixel formats,
> adapting the memory allocation and TPG configuration.
> 
> Signed-off-by: André Almeida 

Acked-by: Helen Koike 

> ---
> Changes in v4:
> - Correct `unsigned int ret` to `int ret`
> - Remove label `free_planes` from else scope
> 
> Changes in v3:
> - Adapt to new vimc_frame
> 
> Changes in v2:
> - Fix alignment issues
> - Remove unnecessary variable assignment
> - Reuse and share the code to free the memory of planes with a goto
> 
>  drivers/media/platform/vimc/vimc-sensor.c | 53 +--
>  1 file changed, 31 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
> b/drivers/media/platform/vimc/vimc-sensor.c
> index 3495a3f3dd60..5432fb852137 100644
> --- a/drivers/media/platform/vimc/vimc-sensor.c
> +++ b/drivers/media/platform/vimc/vimc-sensor.c
> @@ -97,16 +97,17 @@ static int vimc_sen_get_fmt(struct v4l2_subdev *sd,
>  static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
>  {
>   u32 pixelformat = vsen->ved.stream->producer_pixfmt;
> - const struct v4l2_format_info *pix_info;
> -
> - pix_info = v4l2_format_info(pixelformat);
> + unsigned int i;
>  
>   tpg_reset_source(&vsen->tpg, vsen->mbus_format.width,
>vsen->mbus_format.height, vsen->mbus_format.field);
> - tpg_s_bytesperline(&vsen->tpg, 0,
> -vsen->mbus_format.width * pix_info->bpp[0]);
>   tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height);
>   tpg_s_fourcc(&vsen->tpg, pixelformat);
> +
> + for (i = 0; i < tpg_g_planes(&vsen->tpg); i++)
> + tpg_s_bytesperline(&vsen->tpg, i,
> +vsen->frame.fmt.plane_fmt[i].bytesperline);
> +
>   /* TODO: add support for V4L2_FIELD_ALTERNATE */
>   tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false);
>   tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace);
> @@ -182,8 +183,12 @@ static struct vimc_frame *vimc_sen_process_frame(struct 
> vimc_ent_device *ved,
>  {
>   struct vimc_sen_device *vsen = container_of(ved, struct vimc_sen_device,
>   ved);
> + unsigned int i;
> +
> + for (i = 0; i < tpg_g_planes(&vsen->tpg); i++)
> + tpg_fill_plane_buffer(&vsen->tpg, 0, i,
> +   vsen->frame.plane_addr[i]);
>  
> - tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame.plane_addr[0]);
>   return &vsen->frame;
>  }
>  
> @@ -191,36 +196,40 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, 
> int enable)
>  {
>   struct vimc_sen_device *vsen =
>   container_of(sd, struct vimc_sen_device, sd);
> + unsigned int i;
> + int ret = 0;
>  
>   if (enable) {
> - u32 pixelformat = vsen->ved.stream->producer_pixfmt;
> - const struct v4l2_format_info *pix_info;
> - unsigned int frame_size;
> -
>   /* Calculate the frame size */
> - pix_info = v4l2_format_info(pixelformat);
> - frame_size = vsen->mbus_format.width * pix_info->bpp[0] *
> -  vsen->mbus_format.height;
> -
> + vimc_fill_frame(&vsen->frame, vsen->ved.stream->producer_pixfmt,
> + vsen->mbus_format.width,
> + vsen->mbus_format.height);
>   /*
>* Allocate the frame buffer. Use vmalloc to be able to
>* allocate a large amount of memory
>*/
> - vsen->frame.plane_addr[0] = vmalloc(frame_size);
> - if (!vsen->frame.plane_addr[0])
> - return -ENOMEM;
> + for (i = 0; i < vsen->frame.fmt.num_planes; i++) {
> + vsen->frame.plane_addr[i] =
> + vmalloc(vsen->frame.fmt.plane_fmt[i].sizeimage);
> + if (!vsen->frame.plane_addr[i]) {
> + ret = -ENOMEM;
> + goto free_planes;
> + }
> + }
>  
>   /* configure the test pattern generator */
>   vimc_sen_tpg_s_format(vsen);
>  
> - } else {
> -
> - vfree(vsen->frame.plane_addr[0]);
> - vsen->frame.plane_addr[0] = NULL;
>   return 0;
>   }
>  
> - return 0;
> +free_planes:
> + for (i = 0; i < vsen->frame.fmt.num_planes; i++) {
> + vfree(vsen->frame.plane_addr[i]);
> + vsen->frame.plane_addr[i] = NULL;
> + }
> +
> + return ret;
>  }
>  
>  static const struct v4l2_subdev_core_ops vimc_sen_core_ops = {
> 


Re: [PATCH v4 08/14] media: vimc: cap: Add multiplanar default format

2019-04-26 Thread Helen Koike



On 4/25/19 10:22 PM, André Almeida wrote:
> vimc already have a default single planar format.
> Add a multiplanar default pixel format to perform those
> same actions. Change where the default pixelformat is set to make sure
> that the vcap is with the right capabilities.
> 
> Signed-off-by: André Almeida 

Acked-by: Helen Koike 

> ---
> Change in v4: none
> 
> Changes in v3:
> - Fix typo on commit message
> - Add `_sp` to single planar default format
> - Modify identation
> 
> Change in v2:
> - Move here the default format is set to verify if the device have a
> multiplanar capability before assign the default format
> 
>  drivers/media/platform/vimc/vimc-capture.c | 42 --
>  1 file changed, 32 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index a7dafc601033..60e888a3f588 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -95,7 +95,7 @@ struct vimc_cap_device {
>   struct vimc_stream stream;
>  };
>  
> -static const struct v4l2_format fmt_default = {
> +static const struct v4l2_format fmt_default_sp = {
>   .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
>   .fmt.pix.width = 640,
>   .fmt.pix.height = 480,
> @@ -104,6 +104,15 @@ static const struct v4l2_format fmt_default = {
>   .fmt.pix.colorspace = V4L2_COLORSPACE_DEFAULT,
>  };
>  
> +static const struct v4l2_format fmt_default_mp = {
> + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
> + .fmt.pix_mp.width = 640,
> + .fmt.pix_mp.height = 480,
> + .fmt.pix_mp.pixelformat = V4L2_PIX_FMT_YVU420M,
> + .fmt.pix_mp.field = V4L2_FIELD_NONE,
> + .fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT,
> +};
> +
>  struct vimc_cap_buffer {
>   /*
>* struct vb2_v4l2_buffer must be the first element
> @@ -152,6 +161,7 @@ static int vimc_cap_try_fmt_vid_cap_mp(struct file *file, 
> void *priv,
>  struct v4l2_format *f)
>  {
>   struct v4l2_pix_format_mplane *format = &f->fmt.pix_mp;
> + struct vimc_cap_device *vcap = video_drvdata(file);
>  
>   format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH,
>   VIMC_FRAME_MAX_WIDTH) & ~1;
> @@ -161,13 +171,15 @@ static int vimc_cap_try_fmt_vid_cap_mp(struct file 
> *file, void *priv,
>   vimc_colorimetry_clamp(format);
>  
>   if (format->field == V4L2_FIELD_ANY)
> - format->field = fmt_default.fmt.pix.field;
> + format->field = fmt_default_sp.fmt.pix.field;
>  
>   /* TODO: Add support for custom bytesperline values */
>  
>   /* Don't accept a pixelformat that is not on the table */
>   if (!v4l2_format_info(format->pixelformat))
> - format->pixelformat = fmt_default.fmt.pix.pixelformat;
> + format->pixelformat = IS_MULTIPLANAR(vcap) ?
> + fmt_default_mp.fmt.pix_mp.pixelformat :
> + fmt_default_sp.fmt.pix.pixelformat;
>  
>   return v4l2_fill_pixfmt_mp(format, format->pixelformat,
>  format->width, format->height);
> @@ -572,13 +584,6 @@ static int vimc_cap_comp_bind(struct device *comp, 
> struct device *master,
>   INIT_LIST_HEAD(&vcap->buf_list);
>   spin_lock_init(&vcap->qlock);
>  
> - /* Set default frame format */
> - vcap->format = fmt_default;
> - v4l2_fill_pixfmt(&vcap->format.fmt.pix,
> -  vcap->format.fmt.pix.pixelformat,
> -  vcap->format.fmt.pix.width,
> -  vcap->format.fmt.pix.height);
> -
>   /* Fill the vimc_ent_device struct */
>   vcap->ved.ent = &vcap->vdev.entity;
>   vcap->ved.process_frame = vimc_cap_process_frame;
> @@ -616,6 +621,23 @@ static int vimc_cap_comp_bind(struct device *comp, 
> struct device *master,
>   strscpy(vdev->name, pdata->entity_name, sizeof(vdev->name));
>   video_set_drvdata(vdev, &vcap->ved);
>  
> + dev_dbg(vcap->dev, "vimc-capture is in %s mode",
> + IS_MULTIPLANAR(vcap) ? "multiplanar" : "singleplanar");
> +
> + if (IS_MULTIPLANAR(vcap)) {
> + vcap->format = fmt_default_mp;
> + v4l2_fill_pixfmt_mp(&vcap->format.fmt.pix_mp,
> + vcap->format.fmt.pix_mp.pixelformat,
> + vcap->format.fmt.pix_mp.width,
> + vcap->fo

Re: [PATCH v4 06/14] media: vimc: cap: Add handler for multiplanar fmt ioctls

2019-04-26 Thread Helen Koike



On 4/25/19 10:22 PM, André Almeida wrote:
> Add functions to handle multiplanar format ioctls, calling
> the generic format ioctls functions when possible.
> 
> Signed-off-by: André Almeida 

Acked-by: Helen Koike 

> ---
> Change in v4:
> - Split from multiplanar parameter commit
> - Use `IS_MULTIPLANAR` instead of `multiplanar`
> - Move "Functions to handle..." to commit 5
> 
> Change in v3:
> - Remove functions that only did the `IS_MULTIPLANAR(vcap)` check
> - Squash with multiplanar parameter commit
> 
> Change in v2:
> - Fix alignment
> 
>  drivers/media/platform/vimc/vimc-capture.c | 63 +++---
>  1 file changed, 57 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index fa0d75eb06e8..652d3d08bc50 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -211,6 +211,44 @@ static int vimc_cap_s_fmt_vid_cap_sp(struct file *file, 
> void *priv,
>   return 0;
>  }
>  
> +/*
> + * VIDIOC handlers for multi-planar formats
> + */
> +static int vimc_cap_s_fmt_vid_cap_mp(struct file *file, void *priv,
> +  struct v4l2_format *f)
> +{
> + struct vimc_cap_device *vcap = video_drvdata(file);
> + int ret;
> +
> + /* Do not change the format while stream is on */
> + if (vb2_is_busy(&vcap->queue))
> + return -EBUSY;
> +
> + ret = vimc_cap_try_fmt_vid_cap_mp(file, priv, f);
> + if (ret)
> + return ret;
> +
> + dev_dbg(vcap->dev, "%s: format update: "
> + "old:%dx%d (0x%x, %d, %d, %d, %d) "
> + "new:%dx%d (0x%x, %d, %d, %d, %d)\n", vcap->vdev.name,
> + /* old */
> + vcap->format.fmt.pix_mp.width, vcap->format.fmt.pix_mp.height,
> + vcap->format.fmt.pix_mp.pixelformat,
> + vcap->format.fmt.pix_mp.colorspace,
> + vcap->format.fmt.pix_mp.quantization,
> + vcap->format.fmt.pix_mp.xfer_func,
> + vcap->format.fmt.pix_mp.ycbcr_enc,
> + /* new */
> + f->fmt.pix_mp.width, f->fmt.pix_mp.height,
> + f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.colorspace,
> + f->fmt.pix_mp.quantization, f->fmt.pix_mp.xfer_func,
> + f->fmt.pix_mp.ycbcr_enc);
> +
> + vcap->format = *f;
> +
> + return 0;
> +}
> +
>  static bool vimc_cap_is_pixfmt_supported(u32 pixelformat)
>  {
>   unsigned int i;
> @@ -251,13 +289,9 @@ static const struct v4l2_file_operations vimc_cap_fops = 
> {
>   .mmap   = vb2_fop_mmap,
>  };
>  
> -static const struct v4l2_ioctl_ops vimc_cap_ioctl_ops = {
> +static struct v4l2_ioctl_ops vimc_cap_ioctl_ops = {
>   .vidioc_querycap = vimc_cap_querycap,
>  
> - .vidioc_g_fmt_vid_cap = vimc_cap_g_fmt_vid_cap,
> - .vidioc_s_fmt_vid_cap = vimc_cap_s_fmt_vid_cap_sp,
> - .vidioc_try_fmt_vid_cap = vimc_cap_try_fmt_vid_cap_sp,
> - .vidioc_enum_fmt_vid_cap = vimc_cap_enum_fmt_vid_cap,
>   .vidioc_enum_framesizes = vimc_cap_enum_framesizes,
>  
>   .vidioc_reqbufs = vb2_ioctl_reqbufs,
> @@ -455,6 +489,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct 
> device *master,
>  {
>   struct v4l2_device *v4l2_dev = master_data;
>   struct vimc_platform_data *pdata = comp->platform_data;
> + struct v4l2_ioctl_ops *ioctl_ops = &vimc_cap_ioctl_ops;
>   struct vimc_cap_device *vcap;
>   struct video_device *vdev;
>   struct vb2_queue *q;
> @@ -527,7 +562,23 @@ static int vimc_cap_comp_bind(struct device *comp, 
> struct device *master,
>   vdev->entity.ops = &vimc_cap_mops;
>   vdev->release = vimc_cap_release;
>   vdev->fops = &vimc_cap_fops;
> - vdev->ioctl_ops = &vimc_cap_ioctl_ops;
> +
> + if (IS_MULTIPLANAR(vcap)) {
> + ioctl_ops->vidioc_g_fmt_vid_cap_mplane = vimc_cap_g_fmt_vid_cap;
> + ioctl_ops->vidioc_s_fmt_vid_cap_mplane =
> + vimc_cap_s_fmt_vid_cap_mp;
> + ioctl_ops->vidioc_try_fmt_vid_cap_mplane =
> + vimc_cap_try_fmt_vid_cap_mp;
> + ioctl_ops->vidioc_enum_fmt_vid_cap_mplane =
> + vimc_cap_enum_fmt_vid_cap;
> + } else {
> + ioctl_ops->vidioc_g_fmt_vid_cap = vimc_cap_g_fmt_vid_cap;
> + ioctl_ops->vidioc_s_fmt_vid_cap = vimc_cap_s_fmt_vid_cap_sp;
> + ioctl_ops->vidioc_try_fmt_vid_cap = vimc_cap_try_fmt_vid_cap_sp;
> + ioctl_ops->vidioc_enum_fmt_vid_cap = vimc_cap_enum_fmt_vid_cap;
> + }
> +
> + vdev->ioctl_ops = ioctl_ops;
>   vdev->lock = &vcap->lock;
>   vdev->queue = q;
>   vdev->v4l2_dev = v4l2_dev;
> 


Re: [PATCH v4 04/14] media: Move sp2mp functions to v4l2-common

2019-04-26 Thread Helen Koike



On 4/25/19 10:22 PM, André Almeida wrote:
> Move sp2mp functions from vivid code to v4l2-common as it will be reused
> by vimc driver for multiplanar support.
> 
> Signed-off-by: André Almeida 

Acked-by: Helen Koike 

> ---
> Changes in v4: none
> 
> Changes in v3:
> - Change commit order
> - Reword comments
> 
> Changes in v2:
> - Fix indentation
> - Change the style of comments. Functions now have a shorter title and a
> better description bellow
> 
>  drivers/media/platform/vivid/vivid-vid-cap.c  |  6 +-
>  .../media/platform/vivid/vivid-vid-common.c   | 59 --
>  .../media/platform/vivid/vivid-vid-common.h   |  9 ---
>  drivers/media/platform/vivid/vivid-vid-out.c  |  6 +-
>  drivers/media/v4l2-core/v4l2-common.c | 62 +++
>  include/media/v4l2-common.h   | 37 +++
>  6 files changed, 105 insertions(+), 74 deletions(-)
> 
> diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c 
> b/drivers/media/platform/vivid/vivid-vid-cap.c
> index 530ac8decb25..208f1094b998 100644
> --- a/drivers/media/platform/vivid/vivid-vid-cap.c
> +++ b/drivers/media/platform/vivid/vivid-vid-cap.c
> @@ -815,7 +815,7 @@ int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
>  
>   if (dev->multiplanar)
>   return -ENOTTY;
> - return fmt_sp2mp_func(file, priv, f, vivid_g_fmt_vid_cap);
> + return v4l2_fmt_sp2mp_func(file, priv, f, vivid_g_fmt_vid_cap);
>  }
>  
>  int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
> @@ -825,7 +825,7 @@ int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
>  
>   if (dev->multiplanar)
>   return -ENOTTY;
> - return fmt_sp2mp_func(file, priv, f, vivid_try_fmt_vid_cap);
> + return v4l2_fmt_sp2mp_func(file, priv, f, vivid_try_fmt_vid_cap);
>  }
>  
>  int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
> @@ -835,7 +835,7 @@ int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
>  
>   if (dev->multiplanar)
>   return -ENOTTY;
> - return fmt_sp2mp_func(file, priv, f, vivid_s_fmt_vid_cap);
> + return v4l2_fmt_sp2mp_func(file, priv, f, vivid_s_fmt_vid_cap);
>  }
>  
>  int vivid_vid_cap_g_selection(struct file *file, void *priv,
> diff --git a/drivers/media/platform/vivid/vivid-vid-common.c 
> b/drivers/media/platform/vivid/vivid-vid-common.c
> index 74b83bcc6119..3dd3a05d2e67 100644
> --- a/drivers/media/platform/vivid/vivid-vid-common.c
> +++ b/drivers/media/platform/vivid/vivid-vid-common.c
> @@ -674,65 +674,6 @@ void vivid_send_source_change(struct vivid_dev *dev, 
> unsigned type)
>   }
>  }
>  
> -/*
> - * Conversion function that converts a single-planar format to a
> - * single-plane multiplanar format.
> - */
> -void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt)
> -{
> - struct v4l2_pix_format_mplane *mp = &mp_fmt->fmt.pix_mp;
> - struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
> - const struct v4l2_pix_format *pix = &sp_fmt->fmt.pix;
> - bool is_out = sp_fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT;
> -
> - memset(mp->reserved, 0, sizeof(mp->reserved));
> - mp_fmt->type = is_out ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
> -V4L2_CAP_VIDEO_CAPTURE_MPLANE;
> - mp->width = pix->width;
> - mp->height = pix->height;
> - mp->pixelformat = pix->pixelformat;
> - mp->field = pix->field;
> - mp->colorspace = pix->colorspace;
> - mp->xfer_func = pix->xfer_func;
> - /* Also copies hsv_enc */
> - mp->ycbcr_enc = pix->ycbcr_enc;
> - mp->quantization = pix->quantization;
> - mp->num_planes = 1;
> - mp->flags = pix->flags;
> - ppix->sizeimage = pix->sizeimage;
> - ppix->bytesperline = pix->bytesperline;
> - memset(ppix->reserved, 0, sizeof(ppix->reserved));
> -}
> -
> -int fmt_sp2mp_func(struct file *file, void *priv,
> - struct v4l2_format *f, fmtfunc func)
> -{
> - struct v4l2_format fmt;
> - struct v4l2_pix_format_mplane *mp = &fmt.fmt.pix_mp;
> - struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
> - struct v4l2_pix_format *pix = &f->fmt.pix;
> - int ret;
> -
> - /* Converts to a mplane format */
> - fmt_sp2mp(f, &fmt);
> - /* Passes it to the generic mplane format function */
> - ret = func(file, priv, &fmt);
> - /* Copies back the mplane data to the single plane format */
> - pix->width = mp->width;
> - pix->height = mp->height;
> - pix->pixelformat = mp-&

Re: [PATCH v4 05/14] media: vimc: cap: refactor singleplanar as a subset of multiplanar

2019-04-26 Thread Helen Koike



On 4/25/19 10:22 PM, André Almeida wrote:
> Since multiplanar is a superset of single planar formats, instead of
> having different implementations for them, treat all formats as
> multiplanar. If we need to work with single planar formats, convert them to
> multiplanar (with num_planes = 1), re-use the multiplanar code, and
> transform them back to single planar. This is implemented with
> v4l2_fmt_sp2mp_func().
> 
> Signed-off-by: André Almeida 

Acked-by: Helen Koike 

> ---
> Changes in v4:
> - Add comment that was in wrong commit
> - Check the return of try_fmt function
> 
> Changes in v3:
> - Commit title renamed
> - Get rid of `if (IS_MULTIPLANAR(vcap))` checks and functions to do this
> check
> 
> Changes in v2:
> - Make more clear that the generic function _vimc_cap_try_fmt_vid_cap_mp
> expects a multiplanar format as input 
>  drivers/media/platform/vimc/vimc-capture.c | 57 ++
>  1 file changed, 36 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index ae703c52d3f8..fa0d75eb06e8 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -118,6 +118,9 @@ static void vimc_cap_get_format(struct vimc_ent_device 
> *ved,
>   *fmt = vcap->format.fmt.pix;
>  }
>  
> +/*
> + * Functions to handle both single- and multi-planar VIDIOC FMT
> + */
>  static int vimc_cap_g_fmt_vid_cap(struct file *file, void *priv,
> struct v4l2_format *f)
>  {
> @@ -128,10 +131,10 @@ static int vimc_cap_g_fmt_vid_cap(struct file *file, 
> void *priv,
>   return 0;
>  }
>  
> -static int vimc_cap_try_fmt_vid_cap(struct file *file, void *priv,
> - struct v4l2_format *f)
> +static int vimc_cap_try_fmt_vid_cap_mp(struct file *file, void *priv,
> +struct v4l2_format *f)
>  {
> - struct v4l2_pix_format *format = &f->fmt.pix;
> + struct v4l2_pix_format_mplane *format = &f->fmt.pix_mp;
>  
>   format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH,
>   VIMC_FRAME_MAX_WIDTH) & ~1;
> @@ -149,20 +152,43 @@ static int vimc_cap_try_fmt_vid_cap(struct file *file, 
> void *priv,
>   if (!v4l2_format_info(format->pixelformat))
>   format->pixelformat = fmt_default.fmt.pix.pixelformat;
>  
> - return v4l2_fill_pixfmt(format, format->pixelformat,
> - format->width, format->height);
> + return v4l2_fill_pixfmt_mp(format, format->pixelformat,
> +format->width, format->height);
>  }
>  
> -static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
> -   struct v4l2_format *f)
> +static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv,
> +  struct v4l2_fmtdesc *f)
> +{
> + if (f->index >= ARRAY_SIZE(vimc_cap_supported_pixfmt))
> + return -EINVAL;
> +
> + f->pixelformat = vimc_cap_supported_pixfmt[f->index];
> +
> + return 0;
> +}
> +
> +/*
> + * VIDIOC FMT handlers for single-planar
> + */
> +static int vimc_cap_try_fmt_vid_cap_sp(struct file *file, void *priv,
> +struct v4l2_format *f)
> +{
> + return v4l2_fmt_sp2mp_func(file, priv, f, vimc_cap_try_fmt_vid_cap_mp);
> +}
> +
> +static int vimc_cap_s_fmt_vid_cap_sp(struct file *file, void *priv,
> +  struct v4l2_format *f)
>  {
>   struct vimc_cap_device *vcap = video_drvdata(file);
> + int ret;
>  
>   /* Do not change the format while stream is on */
>   if (vb2_is_busy(&vcap->queue))
>   return -EBUSY;
>  
> - vimc_cap_try_fmt_vid_cap(file, priv, f);
> + ret = v4l2_fmt_sp2mp_func(file, priv, f, vimc_cap_try_fmt_vid_cap_mp);
> + if (ret)
> + return ret;
>  
>   dev_dbg(vcap->dev, "%s: format update: "
>   "old:%dx%d (0x%x, %d, %d, %d, %d) "
> @@ -185,17 +211,6 @@ static int vimc_cap_s_fmt_vid_cap(struct file *file, 
> void *priv,
>   return 0;
>  }
>  
> -static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv,
> -  struct v4l2_fmtdesc *f)
> -{
> - if (f->index >= ARRAY_SIZE(vimc_cap_supported_pixfmt))
> - return -EINVAL;
> -
> - f->pixelformat = vimc_cap_supported_pixfmt[f->index];
> -
> - return 0;
> -}
> -
>  static b

Re: [PATCH v3 14/14] media: vimc: Create multiplanar parameter and ioctls

2019-04-24 Thread Helen Koike



On 4/24/19 8:03 PM, André Almeida wrote:
> Hello Helen,
> 
> Thanks for your review!
> 
> On 4/24/19 6:32 PM, Helen Koike wrote:
>> Hi André,
>>
>> Thanks for the patch, please see my comments below.
>>
>> On 4/24/19 10:56 AM, André Almeida wrote:
>>> Create multiplanar kernel module parameter to define if the driver is
>>> running in single planar or in multiplanar mode. Define the device
>>> capabilities and format ioctls according to the multiplanar kernel
>>> parameter. A device can't support both CAP_VIDEO_CAPTURE and
>>> CAP_VIDEO_CAPTURE_MPLANAR at the same time. Add functions to handle
>>> multiplanar format ioctls, calling the generic format ioctls functions
>>> when possible.>
>>> Signed-off-by: André Almeida 
>>> ---
>>> Change in v3:
>>> - Squash commit with "Add handler for multiplanar fmt ioctls" 
>> Was there any reason to squash those? Could you please unsquash it?
>> so we can have one commit with the handlers and the last one adding the
>> kernel parameter?
> 
> It was because if I add those functions to the code, it would give the
> warning of function defined but not used. I only use the multiplanar
> format ioctls when the multiplanar variable exists.
> 
>>> - Remove functions that only did the `IS_MULTIPLANAR(vcap)` check
>>> - Assign ioctls according to device capabilities
>>>
>>> Changes in v2:
>>> - Squash commits to create multiplanar module parameter and to define
>>> the device capabilities
>>> - Move the creation of the multiplanar parameter to the end of
>>> history, so it's only added when all required changes are applied
>>>
>>>  drivers/media/platform/vimc/vimc-capture.c | 78 +++---
>>>  1 file changed, 70 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
>>> b/drivers/media/platform/vimc/vimc-capture.c
>>> index 2592ea982ff8..27caf14ddf43 100644
>>> --- a/drivers/media/platform/vimc/vimc-capture.c
>>> +++ b/drivers/media/platform/vimc/vimc-capture.c
>>> @@ -28,6 +28,10 @@
>>>  
>>>  #define VIMC_CAP_DRV_NAME "vimc-capture"
>>>  
>>> +static unsigned int multiplanar;
>>> +module_param(multiplanar, uint, );
>>> +MODULE_PARM_DESC(multiplanar, "0 (default) creates a single planar device, 
>>> 1 creates a multiplanar device.");
>>> +
>>>  /* Checks if the device supports multiplanar capture */
>>>  #define IS_MULTIPLANAR(vcap) \
>>> (vcap->vdev.device_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE)
>>> @@ -144,6 +148,10 @@ static void vimc_cap_get_format(struct vimc_ent_device 
>>> *ved,
>>> *fmt = vcap->format.fmt.pix;
>>>  }
>>>  
>>> +/*
>>> + * Functions to handle both single- and multi-planar VIDIOC FMT
>>> + */
>>> +
>> This comment could be added in commit 5 (where the  single format
>> comment was added)
>>
>>>  static int vimc_cap_g_fmt_vid_cap(struct file *file, void *priv,
>>>   struct v4l2_format *f)
>>>  {
>>> @@ -247,6 +255,41 @@ static int vimc_cap_s_fmt_vid_cap_sp(struct file 
>>> *file, void *priv,
>>> return 0;
>>>  }
>>>  
>>> +/*
>>> + * VIDIOC handlers for multi-planar formats
>>> + */
>>> +static int vimc_cap_s_fmt_vid_cap_mp(struct file *file, void *priv,
>>> +struct v4l2_format *f)
>>> +{
>>> +   struct vimc_cap_device *vcap = video_drvdata(file);
>>> +
>>> +   /* Do not change the format while stream is on */
>>> +   if (vb2_is_busy(&vcap->queue))
>>> +   return -EBUSY;
>>> +
>>> +   vimc_cap_try_fmt_vid_cap_mp(file, priv, f);
>> I know the original code wasn't checking for errors in this func, you
>> could add a check here it would be great.
> What kind of error checking? Checking if the try format was successful?

The return code of the function.

>>
>>> +
>>> +   dev_dbg(vcap->dev, "%s: format update: "
>>> +   "old:%dx%d (0x%x, %d, %d, %d, %d) "
>>> +   "new:%dx%d (0x%x, %d, %d, %d, %d)\n", vcap->vdev.name,
>>> +   /* old */
>>> +   vcap->format.fmt.pix_mp.width, vcap->format.fmt.pix_mp.height,
>>> +   vcap->format.fmt.pix_mp.pixelformat,
>>> +   vc

Re: [PATCH v3 05/14] media: vimc: cap: refactor singleplanar as a subset of multiplanar

2019-04-24 Thread Helen Koike



On 4/24/19 10:56 AM, André Almeida wrote:
> Since multiplanar is a superset of single planar formats, instead of
> having different implementations for them, treat all formats as
> multiplanar. If we need to work with single planar formats, convert them to
> multiplanar (with num_planes = 1), re-use the multiplanar code, and
> transform them back to single planar. This is implemented with
> v4l2_fmt_sp2mp_func().
> 
> Signed-off-by: André Almeida 
> ---
> Changes in v3:
> - Commit title renamed
> - Get rid of `if (IS_MULTIPLANAR(vcap))` checks and functions to do this
> check
> 
> Changes in v2:
> - Make more clear that the generic function _vimc_cap_try_fmt_vid_cap_mp
> expects a multiplanar format as input 
> 
>  drivers/media/platform/vimc/vimc-capture.c | 51 +-
>  1 file changed, 30 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index ae703c52d3f8..fbe51004aba8 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -128,10 +128,10 @@ static int vimc_cap_g_fmt_vid_cap(struct file *file, 
> void *priv,
>   return 0;
>  }
>  
> -static int vimc_cap_try_fmt_vid_cap(struct file *file, void *priv,
> - struct v4l2_format *f)
> +static int vimc_cap_try_fmt_vid_cap_mp(struct file *file, void *priv,
> +struct v4l2_format *f)
>  {
> - struct v4l2_pix_format *format = &f->fmt.pix;
> + struct v4l2_pix_format_mplane *format = &f->fmt.pix_mp;
>  
>   format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH,
>   VIMC_FRAME_MAX_WIDTH) & ~1;
> @@ -149,12 +149,32 @@ static int vimc_cap_try_fmt_vid_cap(struct file *file, 
> void *priv,
>   if (!v4l2_format_info(format->pixelformat))
>   format->pixelformat = fmt_default.fmt.pix.pixelformat;
>  
> - return v4l2_fill_pixfmt(format, format->pixelformat,
> - format->width, format->height);
> + return v4l2_fill_pixfmt_mp(format, format->pixelformat,
> +format->width, format->height);
>  }
>  
> -static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
> -   struct v4l2_format *f)
> +static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv,
> +  struct v4l2_fmtdesc *f)
> +{
> + if (f->index >= ARRAY_SIZE(vimc_cap_supported_pixfmt))
> + return -EINVAL;
> +
> + f->pixelformat = vimc_cap_supported_pixfmt[f->index];
> +
> + return 0;
> +}
> +
> +/*
> + * VIDIOC FMT handlers for single-planar
> + */
> +static int vimc_cap_try_fmt_vid_cap_sp(struct file *file, void *priv,
> +struct v4l2_format *f)
> +{
> + return v4l2_fmt_sp2mp_func(file, priv, f, vimc_cap_try_fmt_vid_cap_mp);
> +}
> +
> +static int vimc_cap_s_fmt_vid_cap_sp(struct file *file, void *priv,
> +  struct v4l2_format *f)
>  {
>   struct vimc_cap_device *vcap = video_drvdata(file);
>  
> @@ -162,7 +182,7 @@ static int vimc_cap_s_fmt_vid_cap(struct file *file, void 
> *priv,
>   if (vb2_is_busy(&vcap->queue))
>   return -EBUSY;
>  
> - vimc_cap_try_fmt_vid_cap(file, priv, f);
> + v4l2_fmt_sp2mp_func(file, priv, f, vimc_cap_try_fmt_vid_cap_mp);

I know the original code wasn't checking for errors in this func, but if
you could add a check here it would be great.

Helen

>  
>   dev_dbg(vcap->dev, "%s: format update: "
>   "old:%dx%d (0x%x, %d, %d, %d, %d) "
> @@ -185,17 +205,6 @@ static int vimc_cap_s_fmt_vid_cap(struct file *file, 
> void *priv,
>   return 0;
>  }
>  
> -static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv,
> -  struct v4l2_fmtdesc *f)
> -{
> - if (f->index >= ARRAY_SIZE(vimc_cap_supported_pixfmt))
> - return -EINVAL;
> -
> - f->pixelformat = vimc_cap_supported_pixfmt[f->index];
> -
> - return 0;
> -}
> -
>  static bool vimc_cap_is_pixfmt_supported(u32 pixelformat)
>  {
>   unsigned int i;
> @@ -240,8 +249,8 @@ static const struct v4l2_ioctl_ops vimc_cap_ioctl_ops = {
>   .vidioc_querycap = vimc_cap_querycap,
>  
>   .vidioc_g_fmt_vid_cap = vimc_cap_g_fmt_vid_cap,
> - .vidioc_s_fmt_vid_cap = vimc_cap_s_fmt_vid_cap,
> - .vidioc_try_fmt_vid_cap = vimc_cap_try_fmt_vid_cap,
> + .vidioc_s_fmt_vid_cap = vimc_cap_s_fmt_vid_cap_sp,
> + .vidioc_try_fmt_vid_cap = vimc_cap_try_fmt_vid_cap_sp,
>   .vidioc_enum_fmt_vid_cap = vimc_cap_enum_fmt_vid_cap,
>   .vidioc_enum_framesizes = vimc_cap_enum_framesizes,
>  
> 


Re: [PATCH v3 14/14] media: vimc: Create multiplanar parameter and ioctls

2019-04-24 Thread Helen Koike
Hi André,

Thanks for the patch, please see my comments below.

On 4/24/19 10:56 AM, André Almeida wrote:
> Create multiplanar kernel module parameter to define if the driver is
> running in single planar or in multiplanar mode. Define the device
> capabilities and format ioctls according to the multiplanar kernel
> parameter. A device can't support both CAP_VIDEO_CAPTURE and
> CAP_VIDEO_CAPTURE_MPLANAR at the same time. Add functions to handle
> multiplanar format ioctls, calling the generic format ioctls functions
> when possible.>
> Signed-off-by: André Almeida 
> ---
> Change in v3:
> - Squash commit with "Add handler for multiplanar fmt ioctls" 

Was there any reason to squash those? Could you please unsquash it?
so we can have one commit with the handlers and the last one adding the
kernel parameter?

> - Remove functions that only did the `IS_MULTIPLANAR(vcap)` check
> - Assign ioctls according to device capabilities
> 
> Changes in v2:
> - Squash commits to create multiplanar module parameter and to define
> the device capabilities
> - Move the creation of the multiplanar parameter to the end of
> history, so it's only added when all required changes are applied
> 
>  drivers/media/platform/vimc/vimc-capture.c | 78 +++---
>  1 file changed, 70 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index 2592ea982ff8..27caf14ddf43 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -28,6 +28,10 @@
>  
>  #define VIMC_CAP_DRV_NAME "vimc-capture"
>  
> +static unsigned int multiplanar;
> +module_param(multiplanar, uint, );
> +MODULE_PARM_DESC(multiplanar, "0 (default) creates a single planar device, 1 
> creates a multiplanar device.");
> +
>  /* Checks if the device supports multiplanar capture */
>  #define IS_MULTIPLANAR(vcap) \
>   (vcap->vdev.device_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE)
> @@ -144,6 +148,10 @@ static void vimc_cap_get_format(struct vimc_ent_device 
> *ved,
>   *fmt = vcap->format.fmt.pix;
>  }
>  
> +/*
> + * Functions to handle both single- and multi-planar VIDIOC FMT
> + */
> +

This comment could be added in commit 5 (where the  single format
comment was added)

>  static int vimc_cap_g_fmt_vid_cap(struct file *file, void *priv,
> struct v4l2_format *f)
>  {
> @@ -247,6 +255,41 @@ static int vimc_cap_s_fmt_vid_cap_sp(struct file *file, 
> void *priv,
>   return 0;
>  }
>  
> +/*
> + * VIDIOC handlers for multi-planar formats
> + */
> +static int vimc_cap_s_fmt_vid_cap_mp(struct file *file, void *priv,
> +  struct v4l2_format *f)
> +{
> + struct vimc_cap_device *vcap = video_drvdata(file);
> +
> + /* Do not change the format while stream is on */
> + if (vb2_is_busy(&vcap->queue))
> + return -EBUSY;
> +
> + vimc_cap_try_fmt_vid_cap_mp(file, priv, f);

I know the original code wasn't checking for errors in this func, you
could add a check here it would be great.

> +
> + dev_dbg(vcap->dev, "%s: format update: "
> + "old:%dx%d (0x%x, %d, %d, %d, %d) "
> + "new:%dx%d (0x%x, %d, %d, %d, %d)\n", vcap->vdev.name,
> + /* old */
> + vcap->format.fmt.pix_mp.width, vcap->format.fmt.pix_mp.height,
> + vcap->format.fmt.pix_mp.pixelformat,
> + vcap->format.fmt.pix_mp.colorspace,
> + vcap->format.fmt.pix_mp.quantization,
> + vcap->format.fmt.pix_mp.xfer_func,
> + vcap->format.fmt.pix_mp.ycbcr_enc,
> + /* new */
> + f->fmt.pix_mp.width, f->fmt.pix_mp.height,
> + f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.colorspace,
> + f->fmt.pix_mp.quantization, f->fmt.pix_mp.xfer_func,
> + f->fmt.pix_mp.ycbcr_enc);
> +
> + vcap->format = *f;
> +
> + return 0;
> +}
> +
>  static bool vimc_cap_is_pixfmt_supported(u32 pixelformat)
>  {
>   unsigned int i;
> @@ -257,6 +300,7 @@ static bool vimc_cap_is_pixfmt_supported(u32 pixelformat)
>   return false;
>  }
>  
> +
>  static int vimc_cap_enum_framesizes(struct file *file, void *fh,
>   struct v4l2_frmsizeenum *fsize)
>  {
> @@ -287,13 +331,9 @@ static const struct v4l2_file_operations vimc_cap_fops = 
> {
>   .mmap   = vb2_fop_mmap,
>  };
>  
> -static const struct v4l2_ioctl_ops vimc_cap_ioctl_ops = {
> +static struct v4l2_ioctl_ops vimc_cap_ioctl_ops = {
>   .vidioc_querycap = vimc_cap_querycap,
>  
> - .vidioc_g_fmt_vid_cap = vimc_cap_g_fmt_vid_cap,
> - .vidioc_s_fmt_vid_cap = vimc_cap_s_fmt_vid_cap_sp,
> - .vidioc_try_fmt_vid_cap = vimc_cap_try_fmt_vid_cap_sp,
> - .vidioc_enum_fmt_vid_cap = vimc_cap_enum_fmt_vid_cap,
>   .vidioc_enum_framesizes = vimc_cap_enum_framesizes,
>  
>   .vidioc_reqbufs = vb2_ioctl_reqbufs,
> @@ -529,6 +569,7 @@

Re: [PATCH v3 13/14] media: vimc: cap: Add support for multiplanar formats

2019-04-24 Thread Helen Koike
Hi André,

On 4/24/19 10:56 AM, André Almeida wrote:
> Adapt vimc-capture to support multiplanar formats, copying
> each plane to the correct buffer.
> 
> Signed-off-by: André Almeida 
> ---
> Change in v3:
> - Adapt to new vimc_frame
> 
> Change in v2: none
> 
>  drivers/media/platform/vimc/vimc-capture.c | 16 +++-
>  1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index d5b72c858af7..2592ea982ff8 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -485,6 +485,8 @@ static struct vimc_frame *vimc_cap_process_frame(struct 
> vimc_ent_device *ved,
>   struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
>   ved);
>   struct vimc_cap_buffer *vimc_buf;
> + unsigned long plane_size;
> + unsigned int i;
>   void *vbuf;
>  
>   spin_lock(&vcap->qlock);
> @@ -507,13 +509,17 @@ static struct vimc_frame *vimc_cap_process_frame(struct 
> vimc_ent_device *ved,
>   vimc_buf->vb2.sequence = vcap->sequence++;
>   vimc_buf->vb2.field = vcap->format.fmt.pix.field;
>  
> - vbuf = vb2_plane_vaddr(&vimc_buf->vb2.vb2_buf, 0);
> + /* For each plane, copy the pixels */
> + for (i = 0; i < vimc_buf->vb2.vb2_buf.num_planes; i++) {
> + vbuf = vb2_plane_vaddr(&vimc_buf->vb2.vb2_buf, i);
> + plane_size = frame->fmt.plane_fmt[i].sizeimage;

I think you should keep the same type, frame->fmt.plane_fmt[i].sizeimage
is __u32.

Helen

> +
> + memcpy(vbuf, frame->plane_addr[i], plane_size);>
> - memcpy(vbuf, frame->plane_addr[0], vcap->format.fmt.pix.sizeimage);
> + /* Set it as ready */
> + vb2_set_plane_payload(&vimc_buf->vb2.vb2_buf, i, plane_size);
> + }
>  
> - /* Set it as ready */
> - vb2_set_plane_payload(&vimc_buf->vb2.vb2_buf, 0,
> -   vcap->format.fmt.pix.sizeimage);
>   vb2_buffer_done(&vimc_buf->vb2.vb2_buf, VB2_BUF_STATE_DONE);
>   return NULL;
>  }
> 


Re: [PATCH v3 12/14] media: vimc: sca: Add support for multiplanar formats

2019-04-24 Thread Helen Koike
Hi André,

Thanks for the patch, please see my comments below.

On 4/24/19 10:56 AM, André Almeida wrote:
> Change the scaling functions in order to scale planes. This change makes
> easier to support multiplanar pixel formats.
> 
> Signed-off-by: André Almeida 
> ---
> Change in v3:
> - Adapt to new vimc_frame
> 
> Changes in v2:
> - Move the TODO comment to vimc-capture
> - Reuse and share the code to free the memory of planes with a goto
> - Fix comment block style 
> 
>  drivers/media/platform/vimc/vimc-scaler.c | 113 ++
>  1 file changed, 72 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-scaler.c 
> b/drivers/media/platform/vimc/vimc-scaler.c
> index f655b8312dc9..17c37076ff4e 100644
> --- a/drivers/media/platform/vimc/vimc-scaler.c
> +++ b/drivers/media/platform/vimc/vimc-scaler.c
> @@ -39,6 +39,9 @@ static const u32 vimc_sca_supported_pixfmt[] = {
>   V4L2_PIX_FMT_BGR24,
>   V4L2_PIX_FMT_RGB24,
>   V4L2_PIX_FMT_ARGB32,
> + V4L2_PIX_FMT_YUV420,
> + V4L2_PIX_FMT_YUV420M,
> + V4L2_PIX_FMT_NV12M,
>  };
>  
>  struct vimc_sca_device {
> @@ -51,8 +54,8 @@ struct vimc_sca_device {
>   struct v4l2_mbus_framefmt sink_fmt;
>   /* Values calculated when the stream starts */
>   struct vimc_frame src_frame;
> - unsigned int src_line_size;
> - unsigned int bpp;
> + unsigned int src_line_size[TPG_MAX_PLANES];
> + unsigned int bpp[TPG_MAX_PLANES];
>  };
>  
>  static const struct v4l2_mbus_framefmt sink_fmt_default = {
> @@ -207,10 +210,10 @@ static const struct v4l2_subdev_pad_ops 
> vimc_sca_pad_ops = {
>  static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable)
>  {
>   struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
> + unsigned int i, ret = 0;

int ret

>  
>   if (enable) {
>   u32 pixelformat = vsca->ved.stream->producer_pixfmt;
> - const struct v4l2_format_info *pix_info;
>   unsigned int frame_size;
>  
>   if (!vimc_sca_is_pixfmt_supported(pixelformat)) {
> @@ -219,34 +222,47 @@ static int vimc_sca_s_stream(struct v4l2_subdev *sd, 
> int enable)
>   return -EINVAL;
>   }
>  
> - /* Save the bytes per pixel of the sink */
> - pix_info = v4l2_format_info(pixelformat);
> - vsca->bpp = pix_info->bpp[0];
> -
> - /* Calculate the width in bytes of the src frame */
> - vsca->src_line_size = vsca->sink_fmt.width *
> -   sca_mult * vsca->bpp;
> -
> - /* Calculate the frame size of the source pad */
> - frame_size = vsca->src_line_size * vsca->sink_fmt.height *
> -  sca_mult;
> -
> - /* Allocate the frame buffer. Use vmalloc to be able to
> -  * allocate a large amount of memory
> -  */
> - vsca->src_frame.plane_addr[0] = vmalloc(frame_size);
> - if (!vsca->src_frame.plane_addr[0])
> - return -ENOMEM;
> + vimc_fill_frame(&vsca->src_frame, pixelformat,
> + vsca->sink_fmt.width, vsca->sink_fmt.height,
> + vsca->ved.stream->multiplanar);
> +
> + for (i = 0; i < vsca->src_frame.fmt.num_planes; i++) {
> + /* Save the bytes per pixel of the sink */
> + vsca->bpp[i] = vsca->src_frame.fmt_info->bpp[i];
> +
> + /* Calculate the width in bytes of the src frame */
> + vsca->src_line_size[i] =
> + vsca->src_frame.fmt.plane_fmt[i].bytesperline *
> + sca_mult;
> +
> + /* Calculate the frame size of the source pad */
> + frame_size = vsca->src_frame.fmt.plane_fmt[i].sizeimage
> + * sca_mult * sca_mult;
> +
> + /**
> +  * Allocate the frame buffer. Use vmalloc to be able to
> +  * allocate a large amount of memory
> +  */
> + vsca->src_frame.plane_addr[i] = vmalloc(frame_size);
> + if (!vsca->src_frame.plane_addr[i]) {
> + ret = -ENOMEM;
> + goto free_planes;
> + }
> + vsca->src_frame.fmt.plane_fmt[i].sizeimage = frame_size;
> + }
>  
>   } else {
>   if (!vsca->src_frame.plane_addr[0])
>   return 0;
>  
> - vfree(vsca->src_frame.plane_addr[0]);
> - vsca->src_frame.plane_addr[0] = NULL;
> +free_planes:

please, prefer to have goto labels in the end and outside and if/else
statement.

> + for (i = 0; i < vsca->src_frame.fmt.num_planes; i++) {
> + vfree(vsca->src_frame.plane_addr[i]);
> + vsca

Re: [PATCH v3 11/14] media: vimc: sen: Add support for multiplanar formats

2019-04-24 Thread Helen Koike
Hi André,

On 4/24/19 10:56 AM, André Almeida wrote:
> This commit adapts vimc-sensor to handle multiplanar pixel formats,
> adapting the memory allocation and TPG configuration.
> 
> Signed-off-by: André Almeida 
> ---
> Changes in v3:
> - Adapt to new vimc_frame
> 
> Changes in v2:
> - Fix alignment issues
> - Remove unnecessary variable assignment
> - Reuse and share the code to free the memory of planes with a goto
> 
>  drivers/media/platform/vimc/vimc-sensor.c | 52 +--
>  1 file changed, 30 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
> b/drivers/media/platform/vimc/vimc-sensor.c
> index 3495a3f3dd60..d933a1db309c 100644
> --- a/drivers/media/platform/vimc/vimc-sensor.c
> +++ b/drivers/media/platform/vimc/vimc-sensor.c
> @@ -97,16 +97,17 @@ static int vimc_sen_get_fmt(struct v4l2_subdev *sd,
>  static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
>  {
>   u32 pixelformat = vsen->ved.stream->producer_pixfmt;
> - const struct v4l2_format_info *pix_info;
> -
> - pix_info = v4l2_format_info(pixelformat);
> + unsigned int i;
>  
>   tpg_reset_source(&vsen->tpg, vsen->mbus_format.width,
>vsen->mbus_format.height, vsen->mbus_format.field);
> - tpg_s_bytesperline(&vsen->tpg, 0,
> -vsen->mbus_format.width * pix_info->bpp[0]);
>   tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height);
>   tpg_s_fourcc(&vsen->tpg, pixelformat);
> +
> + for (i = 0; i < tpg_g_planes(&vsen->tpg); i++)
> + tpg_s_bytesperline(&vsen->tpg, i,
> +vsen->frame.fmt.plane_fmt[i].bytesperline);
> +
>   /* TODO: add support for V4L2_FIELD_ALTERNATE */
>   tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false);
>   tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace);
> @@ -182,8 +183,12 @@ static struct vimc_frame *vimc_sen_process_frame(struct 
> vimc_ent_device *ved,
>  {
>   struct vimc_sen_device *vsen = container_of(ved, struct vimc_sen_device,
>   ved);
> + unsigned int i;
> +
> + for (i = 0; i < tpg_g_planes(&vsen->tpg); i++)
> + tpg_fill_plane_buffer(&vsen->tpg, 0, i,
> +   vsen->frame.plane_addr[i]);
>  
> - tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame.plane_addr[0]);
>   return &vsen->frame;
>  }
>  
> @@ -191,36 +196,39 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, 
> int enable)
>  {
>   struct vimc_sen_device *vsen =
>   container_of(sd, struct vimc_sen_device, sd);
> + unsigned int i, ret = 0;

ret should be int, not unsigned int, this also applies to other patches.

>  
>   if (enable) {
> - u32 pixelformat = vsen->ved.stream->producer_pixfmt;
> - const struct v4l2_format_info *pix_info;
> - unsigned int frame_size;
> -
>   /* Calculate the frame size */
> - pix_info = v4l2_format_info(pixelformat);
> - frame_size = vsen->mbus_format.width * pix_info->bpp[0] *
> -  vsen->mbus_format.height;
> -
> + vimc_fill_frame(&vsen->frame, vsen->ved.stream->producer_pixfmt,
> + vsen->mbus_format.width,
> + vsen->mbus_format.height,
> + vsen->ved.stream->multiplanar);
>   /*
>* Allocate the frame buffer. Use vmalloc to be able to
>* allocate a large amount of memory
>*/
> - vsen->frame.plane_addr[0] = vmalloc(frame_size);
> - if (!vsen->frame.plane_addr[0])
> - return -ENOMEM;
> + for (i = 0; i < vsen->frame.fmt.num_planes; i++) {
> + vsen->frame.plane_addr[i] =
> + vmalloc(vsen->frame.fmt.plane_fmt[i].sizeimage);
> + if (!vsen->frame.plane_addr[i]) {
> + ret = -ENOMEM;
> + goto free_planes;
> + }
> + }
>  
>   /* configure the test pattern generator */
>   vimc_sen_tpg_s_format(vsen);
>  
>   } else {
> -
> - vfree(vsen->frame.plane_addr[0]);
> - vsen->frame.plane_addr[0] = NULL;
> - return 0;
> +free_planes:

Hmm, its a bit weird to have a goto going inside an else statement.
It would be better if you remove the else statement, and add a return 0
in the end of the if statement.
This also applies to other patches.

Helen

> + for (i = 0; i < vsen->frame.fmt.num_planes; i++) {
> + vfree(vsen->frame.plane_addr[i]);
> + vsen->frame.plane_addr[i] = NULL;
> + }
>   }
>  
> - return 0;
> + return ret;
>  }
>  
>  static const struct v4l2_subdev_core_ops vimc_sen_co

Re: [PATCH v3 10/14] media: vimc: Add and use new struct vimc_frame

2019-04-24 Thread Helen Koike
Hi André

On 4/24/19 10:56 AM, André Almeida wrote:
> Struct vimc_frame is intended to hold metadata about a frame,
> such as memory address of a plane, number of planes and size
> of each plane, to better integrated with the multiplanar operations.
> The struct can be also used with singleplanar formats, making the
> implementation of frame manipulation generic for both type of
> formats.
> 
> vimc_fill_frame function fills a vimc_frame structure given a
> pixelformat, height and width. This is done once to avoid recalculations
> and provide enough information to subdevices work with
> the frame.
> 
> Change the return and argument type of process_frame from void* to
> vimc_frame*. Change the frame in subdevices structs from u8* to vimc_frame.
> 
> Signed-off-by: André Almeida 
> ---
> Changes in v3:
> - Refactor vimc_frame struct, now it have fewer fields with the same
> content
> - Refactor vimc_fill_frame to be more simple
> 
> Change in v2:
> - Fix alignment issues
> 
>  drivers/media/platform/vimc/vimc-capture.c  |  6 +--
>  drivers/media/platform/vimc/vimc-common.c   |  8 
>  drivers/media/platform/vimc/vimc-common.h   | 43 +++--
>  drivers/media/platform/vimc/vimc-debayer.c  | 34 
>  drivers/media/platform/vimc/vimc-scaler.c   | 25 ++--
>  drivers/media/platform/vimc/vimc-sensor.c   | 18 -
>  drivers/media/platform/vimc/vimc-streamer.c |  2 +-
>  7 files changed, 92 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index e1805cf0140d..d5b72c858af7 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -479,8 +479,8 @@ static void vimc_cap_comp_unbind(struct device *comp, 
> struct device *master,
>   video_unregister_device(&vcap->vdev);
>  }
>  
> -static void *vimc_cap_process_frame(struct vimc_ent_device *ved,
> - const void *frame)
> +static struct vimc_frame *vimc_cap_process_frame(struct vimc_ent_device *ved,
> +  const struct vimc_frame *frame)
>  {
>   struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
>   ved);
> @@ -509,7 +509,7 @@ static void *vimc_cap_process_frame(struct 
> vimc_ent_device *ved,
>  
>   vbuf = vb2_plane_vaddr(&vimc_buf->vb2.vb2_buf, 0);
>  
> - memcpy(vbuf, frame, vcap->format.fmt.pix.sizeimage);
> + memcpy(vbuf, frame->plane_addr[0], vcap->format.fmt.pix.sizeimage);
>  
>   /* Set it as ready */
>   vb2_set_plane_payload(&vimc_buf->vb2.vb2_buf, 0,
> diff --git a/drivers/media/platform/vimc/vimc-common.c 
> b/drivers/media/platform/vimc/vimc-common.c
> index fad7c7c6de93..2418626f513d 100644
> --- a/drivers/media/platform/vimc/vimc-common.c
> +++ b/drivers/media/platform/vimc/vimc-common.c
> @@ -380,6 +380,14 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
>  }
>  EXPORT_SYMBOL_GPL(vimc_ent_sd_register);
>  
> +void vimc_fill_frame(struct vimc_frame *frame, u32 pixelformat, u32 width,
> +  u32 height, bool multiplanar)

multiplanar arguments seems unused :)

Helen

> +{
> + frame->fmt_info = v4l2_format_info(pixelformat);
> + v4l2_fill_pixfmt_mp(&frame->fmt, pixelformat, width, height);
> +}
> +EXPORT_SYMBOL_GPL(vimc_fill_frame);
> +
>  void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev 
> *sd)
>  {
>   media_entity_cleanup(ved->ent);
> diff --git a/drivers/media/platform/vimc/vimc-common.h 
> b/drivers/media/platform/vimc/vimc-common.h
> index 142ddfa69b3d..8b4f07a20266 100644
> --- a/drivers/media/platform/vimc/vimc-common.h
> +++ b/drivers/media/platform/vimc/vimc-common.h
> @@ -21,6 +21,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "vimc-streamer.h"
>  
> @@ -79,6 +80,25 @@ struct vimc_platform_data {
>   char entity_name[32];
>  };
>  
> +/**
> + * struct vimc_frame - metadata about frame components
> + *
> + * @plane_addr:  pointer to kernel address of the plane
> + * @fmt: pixel format attributes
> + * @fmt_info:pointer to a struct with pixel format metadata
> + *
> + * This struct helps subdevices to get information about the frame on
> + * multiplanar formats. If a singleplanar format is used, only the first
> + * index of the array is used and num_planes is set to 1, so the
> + * implementation is generic and the code will work for both formats.
> + */
> +
> +struct vimc_frame {
> + u8 *plane_addr[TPG_MAX_PLANES];
> + struct v4l2_pix_format_mplane fmt;
> + const struct v4l2_format_info *fmt_info;
> +};
> +
>  /**
>   * struct vimc_ent_device - core struct that represents a node in the 
> topology
>   *
> @@ -101,10 +121,10 @@ struct vimc_ent_device {
>   struct media_entity *ent;
>   struct media_pad *pads;
>   struct vimc_stream *stre

Re: [PATCH v3 09/14] media: vimc: Propagate multiplanar state in the stream

2019-04-24 Thread Helen Koike
Hi André, thanks for the patch.

On 4/24/19 10:56 AM, André Almeida wrote:
> Add a multiplanar flag in vimc_stream in order to propagate the
> state (singleplanar/multiplanar) to subdevices at the stream.

This shouldn't be required as you are using multiplanar only between the
subdevices :)

Helen

> 
> Signed-off-by: André Almeida 
> ---
> Change in v3:
> - Use ternary operator to get code more simple
> 
> Change in v2:
> - New commit
> 
>  drivers/media/platform/vimc/vimc-capture.c  | 4 +++-
>  drivers/media/platform/vimc/vimc-streamer.h | 3 +++
>  2 files changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index 415dbab63ec5..e1805cf0140d 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -337,7 +337,9 @@ static int vimc_cap_start_streaming(struct vb2_queue *vq, 
> unsigned int count)
>   return ret;
>   }
>  
> - vcap->stream.producer_pixfmt = IS_MULTIPLANAR(vcap) ?
> + vcap->stream.multiplanar = IS_MULTIPLANAR(vcap);
> +
> + vcap->stream.producer_pixfmt = vcap->stream.multiplanar ?
>   vcap->format.fmt.pix_mp.pixelformat :
>   vcap->format.fmt.pix.pixelformat;
>  
> diff --git a/drivers/media/platform/vimc/vimc-streamer.h 
> b/drivers/media/platform/vimc/vimc-streamer.h
> index 2b3667408794..4878e0b72ea7 100644
> --- a/drivers/media/platform/vimc/vimc-streamer.h
> +++ b/drivers/media/platform/vimc/vimc-streamer.h
> @@ -25,6 +25,8 @@
>   * processed in the pipeline.
>   * @pipe_size:   size of @ved_pipeline
>   * @kthread: thread that generates the frames of the stream.
> + * @multiplanar: sets if the stream is running in multiplanar or
> + * singleplanar format mode
>   * @producer_pixfmt: the pixel format requested from the pipeline. This must
>   * be set just before calling vimc_streamer_s_stream(ent, 1). This value is
>   * propagated up to the source of the base image (usually a sensor node) and
> @@ -40,6 +42,7 @@ struct vimc_stream {
>   struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE];
>   unsigned int pipe_size;
>   struct task_struct *kthread;
> + bool multiplanar;
>   u32 producer_pixfmt;
>  };
>  
> 


[PATCH 7/8] media: vimc: stream: init/terminate the first entity

2019-03-06 Thread Helen Koike
The s_stream callback was not being called for the first entity in the
stream pipeline array.
Instead of verifying the type of the node (video or subdevice) and
calling s_stream from the second entity in the pipeline, do this process
for all the entities in the pipeline for consistency.

The previous code was not a problem because the first entity is a video
device and not a subdevice, but this patch prepares vimc to allow
setting some configuration in the entity before calling s_stream.

Signed-off-by: Helen Koike 
---

 drivers/media/platform/vimc/vimc-streamer.c | 25 -
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-streamer.c 
b/drivers/media/platform/vimc/vimc-streamer.c
index b7c1fdef5f0d..5a3bda62fbc8 100644
--- a/drivers/media/platform/vimc/vimc-streamer.c
+++ b/drivers/media/platform/vimc/vimc-streamer.c
@@ -46,19 +46,18 @@ static struct media_entity *vimc_get_source_entity(struct 
media_entity *ent)
  */
 static void vimc_streamer_pipeline_terminate(struct vimc_stream *stream)
 {
-   struct media_entity *entity;
+   struct vimc_ent_device *ved;
struct v4l2_subdev *sd;
 
while (stream->pipe_size) {
stream->pipe_size--;
-   entity = stream->ved_pipeline[stream->pipe_size]->ent;
-   entity = vimc_get_source_entity(entity);
+   ved = stream->ved_pipeline[stream->pipe_size];
stream->ved_pipeline[stream->pipe_size] = NULL;
 
-   if (!is_media_entity_v4l2_subdev(entity))
+   if (!is_media_entity_v4l2_subdev(ved->ent))
continue;
 
-   sd = media_entity_to_v4l2_subdev(entity);
+   sd = media_entity_to_v4l2_subdev(ved->ent);
v4l2_subdev_call(sd, video, s_stream, 0);
}
 }
@@ -89,18 +88,24 @@ static int vimc_streamer_pipeline_init(struct vimc_stream 
*stream,
}
stream->ved_pipeline[stream->pipe_size++] = ved;
 
+   if (is_media_entity_v4l2_subdev(ved->ent)) {
+   sd = media_entity_to_v4l2_subdev(ved->ent);
+   ret = v4l2_subdev_call(sd, video, s_stream, 1);
+   if (ret && ret != -ENOIOCTLCMD) {
+   pr_err("subdev_call error %s\n", 
ved->ent->name);
+   vimc_streamer_pipeline_terminate(stream);
+   return ret;
+   }
+   }
+
entity = vimc_get_source_entity(ved->ent);
/* Check if the end of the pipeline was reached*/
if (!entity)
return 0;
 
+   /* Get the next device in the pipeline */
if (is_media_entity_v4l2_subdev(entity)) {
sd = media_entity_to_v4l2_subdev(entity);
-   ret = v4l2_subdev_call(sd, video, s_stream, 1);
-   if (ret && ret != -ENOIOCTLCMD) {
-   vimc_streamer_pipeline_terminate(stream);
-   return ret;
-   }
ved = v4l2_get_subdevdata(sd);
} else {
vdev = container_of(entity,
-- 
2.20.1



[PATCH 8/8] media: vimc: propagate pixel format in the stream

2019-03-06 Thread Helen Koike
Media bus codes were being mapped to pixelformats, which causes a
limitation on vimc because not all pixelformats can be mapped to media
bus codes.
Also, media bus codes are an internal configuration from the device.
Userspace only assures media bus codes matches between pads and expects
the image in a given pixelformat. So we can allow almost any media bus
format to be configured between pads, except for debayer that expects a
media bus code of type bayer in the sink pad.

Signed-off-by: Helen Koike 

---

 drivers/media/platform/vimc/vimc-capture.c  |  76 +++--
 drivers/media/platform/vimc/vimc-common.c   | 307 
 drivers/media/platform/vimc/vimc-common.h   |  13 +
 drivers/media/platform/vimc/vimc-debayer.c  |  78 +++--
 drivers/media/platform/vimc/vimc-scaler.c   |  60 ++--
 drivers/media/platform/vimc/vimc-sensor.c   |  48 +--
 drivers/media/platform/vimc/vimc-streamer.c |   2 +
 drivers/media/platform/vimc/vimc-streamer.h |   6 +
 8 files changed, 281 insertions(+), 309 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-capture.c 
b/drivers/media/platform/vimc/vimc-capture.c
index e976a9d6b460..6377974879d7 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -28,6 +28,32 @@
 
 #define VIMC_CAP_DRV_NAME "vimc-capture"
 
+static const u32 vimc_cap_supported_pixftm[] = {
+   V4L2_PIX_FMT_BGR24,
+   V4L2_PIX_FMT_RGB24,
+   V4L2_PIX_FMT_ARGB32,
+   V4L2_PIX_FMT_SBGGR8,
+   V4L2_PIX_FMT_SGBRG8,
+   V4L2_PIX_FMT_SGRBG8,
+   V4L2_PIX_FMT_SRGGB8,
+   V4L2_PIX_FMT_SBGGR10,
+   V4L2_PIX_FMT_SGBRG10,
+   V4L2_PIX_FMT_SGRBG10,
+   V4L2_PIX_FMT_SRGGB10,
+   V4L2_PIX_FMT_SBGGR10ALAW8,
+   V4L2_PIX_FMT_SGBRG10ALAW8,
+   V4L2_PIX_FMT_SGRBG10ALAW8,
+   V4L2_PIX_FMT_SRGGB10ALAW8,
+   V4L2_PIX_FMT_SBGGR10DPCM8,
+   V4L2_PIX_FMT_SGBRG10DPCM8,
+   V4L2_PIX_FMT_SGRBG10DPCM8,
+   V4L2_PIX_FMT_SRGGB10DPCM8,
+   V4L2_PIX_FMT_SBGGR12,
+   V4L2_PIX_FMT_SGBRG12,
+   V4L2_PIX_FMT_SGRBG12,
+   V4L2_PIX_FMT_SRGGB12,
+};
+
 struct vimc_cap_device {
struct vimc_ent_device ved;
struct video_device vdev;
@@ -101,29 +127,25 @@ static int vimc_cap_try_fmt_vid_cap(struct file *file, 
void *priv,
struct v4l2_format *f)
 {
struct v4l2_pix_format *format = &f->fmt.pix;
-   const struct vimc_pix_map *vpix;
 
format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH,
VIMC_FRAME_MAX_WIDTH) & ~1;
format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT,
 VIMC_FRAME_MAX_HEIGHT) & ~1;
 
-   /* Don't accept a pixelformat that is not on the table */
-   vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
-   if (!vpix) {
-   format->pixelformat = fmt_default.pixelformat;
-   vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
-   }
-   /* TODO: Add support for custom bytesperline values */
-   format->bytesperline = format->width * vpix->bpp;
-   format->sizeimage = format->bytesperline * format->height;
+   vimc_colorimetry_clamp(format);
 
if (format->field == V4L2_FIELD_ANY)
format->field = fmt_default.field;
 
-   vimc_colorimetry_clamp(format);
+   /* TODO: Add support for custom bytesperline values */
 
-   return 0;
+   /* Don't accept a pixelformat that is not on the table */
+   if (!v4l2_format_info(format->pixelformat))
+   format->pixelformat = fmt_default.pixelformat;
+
+   return v4l2_fill_pixfmt(format, format->pixelformat,
+   format->width, format->height);
 }
 
 static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
@@ -159,27 +181,31 @@ static int vimc_cap_s_fmt_vid_cap(struct file *file, void 
*priv,
 static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv,
 struct v4l2_fmtdesc *f)
 {
-   const struct vimc_pix_map *vpix = vimc_pix_map_by_index(f->index);
-
-   if (!vpix)
+   if (f->index >= ARRAY_SIZE(vimc_cap_supported_pixftm))
return -EINVAL;
 
-   f->pixelformat = vpix->pixelformat;
+   f->pixelformat = vimc_cap_supported_pixftm[f->index];
 
return 0;
 }
 
+static bool vimc_cap_is_pixfmt_supported(u32 pixelformat)
+{
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(vimc_cap_supported_pixftm); i++)
+   if (vimc_cap_supported_pixftm[i] == pixelformat)
+   return true;
+   return false;
+}
+
 static int vimc_cap_enum_framesizes(struct file *file, void *fh,
struct v4l2_frmsizeenum *fsize)
 {
-   const struct vimc_pix_map *vpix;
-
 

[PATCH 5/8] media: vimc: stream: cleanup frame field from struct vimc_stream

2019-03-06 Thread Helen Koike
There is no need to have the frame field in the vimc_stream struct.

Signed-off-by: Helen Koike 
---

 drivers/media/platform/vimc/vimc-streamer.c | 10 --
 drivers/media/platform/vimc/vimc-streamer.h |  1 -
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-streamer.c 
b/drivers/media/platform/vimc/vimc-streamer.c
index 392754c18046..b7c1fdef5f0d 100644
--- a/drivers/media/platform/vimc/vimc-streamer.c
+++ b/drivers/media/platform/vimc/vimc-streamer.c
@@ -117,6 +117,7 @@ static int vimc_streamer_pipeline_init(struct vimc_stream 
*stream,
 static int vimc_streamer_thread(void *data)
 {
struct vimc_stream *stream = data;
+   u8 *frame = NULL;
int i;
 
set_freezable();
@@ -127,12 +128,9 @@ static int vimc_streamer_thread(void *data)
break;
 
for (i = stream->pipe_size - 1; i >= 0; i--) {
-   stream->frame = stream->ved_pipeline[i]->process_frame(
-   stream->ved_pipeline[i],
-   stream->frame);
-   if (!stream->frame)
-   break;
-   if (IS_ERR(stream->frame))
+   frame = stream->ved_pipeline[i]->process_frame(
+   stream->ved_pipeline[i], frame);
+   if (!frame || IS_ERR(frame))
break;
}
//wait for 60hz
diff --git a/drivers/media/platform/vimc/vimc-streamer.h 
b/drivers/media/platform/vimc/vimc-streamer.h
index 752af2e2d5a2..dc1d0be431cb 100644
--- a/drivers/media/platform/vimc/vimc-streamer.h
+++ b/drivers/media/platform/vimc/vimc-streamer.h
@@ -19,7 +19,6 @@ struct vimc_stream {
struct media_pipeline pipe;
struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE];
unsigned int pipe_size;
-   u8 *frame;
struct task_struct *kthread;
 };
 
-- 
2.20.1



[PATCH 6/8] media: vimc: stream: add docs to struct vimc_stream

2019-03-06 Thread Helen Koike
Add missing documentation for struct vimc_stream

Signed-off-by: Helen Koike 
---

 drivers/media/platform/vimc/vimc-streamer.h | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/media/platform/vimc/vimc-streamer.h 
b/drivers/media/platform/vimc/vimc-streamer.h
index dc1d0be431cb..a7c5ac5ace4f 100644
--- a/drivers/media/platform/vimc/vimc-streamer.h
+++ b/drivers/media/platform/vimc/vimc-streamer.h
@@ -15,6 +15,21 @@
 
 #define VIMC_STREAMER_PIPELINE_MAX_SIZE 16
 
+/**
+ * struct vimc_stream - struct that represents a stream in the pipeline
+ *
+ * @pipe:  the media pipeline object associated with this stream
+ * @ved_pipeline:  array containing all the entities participating in the
+ * stream. The order is from a video device (usually a capture device) where
+ * stream_on was called, to the entity generating the first base image to be
+ * processed in the pipeline.
+ * @pipe_size: size of @ved_pipeline
+ * @kthread:   thread that generates the frames of the stream.
+ *
+ * When the user call stream_on in a video device, struct vimc_stream is
+ * used to keep track of all entities and subdevices that generates and
+ * process frames for the stream.
+ */
 struct vimc_stream {
struct media_pipeline pipe;
struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE];
-- 
2.20.1



[PATCH 4/8] media: v4l2-common: add bayer formats in v4l2_format_info

2019-03-06 Thread Helen Koike
Add bayer format information in struct v4l2_format_info table.

Signed-off-by: Helen Koike 
---

 drivers/media/v4l2-core/v4l2-common.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-common.c 
b/drivers/media/v4l2-core/v4l2-common.c
index 11a16bb3efda..779e44d6db43 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -517,6 +517,28 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
{ .format = V4L2_PIX_FMT_NV21M,   .mem_planes = 2, .comp_planes 
= 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
{ .format = V4L2_PIX_FMT_NV16M,   .mem_planes = 2, .comp_planes 
= 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
{ .format = V4L2_PIX_FMT_NV61M,   .mem_planes = 2, .comp_planes 
= 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
+
+   /* Bayer RGB formats */
+   { .format = V4L2_PIX_FMT_SBGGR8,.mem_planes = 1, 
.comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SGBRG8,.mem_planes = 1, 
.comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SGRBG8,.mem_planes = 1, 
.comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SRGGB8,.mem_planes = 1, 
.comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SBGGR10,   .mem_planes = 1, 
.comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SGBRG10,   .mem_planes = 1, 
.comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SGRBG10,   .mem_planes = 1, 
.comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SRGGB10,   .mem_planes = 1, 
.comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SBGGR10ALAW8,  .mem_planes = 1, 
.comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SGBRG10ALAW8,  .mem_planes = 1, 
.comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SGRBG10ALAW8,  .mem_planes = 1, 
.comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SRGGB10ALAW8,  .mem_planes = 1, 
.comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SBGGR10DPCM8,  .mem_planes = 1, 
.comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SGBRG10DPCM8,  .mem_planes = 1, 
.comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SGRBG10DPCM8,  .mem_planes = 1, 
.comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SRGGB10DPCM8,  .mem_planes = 1, 
.comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SBGGR12,   .mem_planes = 1, 
.comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SGBRG12,   .mem_planes = 1, 
.comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SGRBG12,   .mem_planes = 1, 
.comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+   { .format = V4L2_PIX_FMT_SRGGB12,   .mem_planes = 1, 
.comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
};
unsigned int i;
 
-- 
2.20.1



[PATCH 3/8] media: vimc: cap: fix step width/height in enum framesize

2019-03-06 Thread Helen Koike
The type V4L2_FRMSIZE_TYPE_CONTINUOUS expects a step of 1.
This fixes v4l2-compliance test error:

fail: v4l2-test-formats.cpp(184): invalid step_width/height for 
continuous framesize
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: FAIL

Signed-off-by: Helen Koike 
---

 drivers/media/platform/vimc/vimc-capture.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-capture.c 
b/drivers/media/platform/vimc/vimc-capture.c
index 3d433361d297..e976a9d6b460 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -187,8 +187,8 @@ static int vimc_cap_enum_framesizes(struct file *file, void 
*fh,
fsize->stepwise.max_width = VIMC_FRAME_MAX_WIDTH;
fsize->stepwise.min_height = VIMC_FRAME_MIN_HEIGHT;
fsize->stepwise.max_height = VIMC_FRAME_MAX_HEIGHT;
-   fsize->stepwise.step_width = 2;
-   fsize->stepwise.step_height = 2;
+   fsize->stepwise.step_width = 1;
+   fsize->stepwise.step_height = 1;
 
return 0;
 }
-- 
2.20.1



[PATCH 1/8] media: vimc: deb: fix default sink bayer format

2019-03-06 Thread Helen Koike
The format of the sink pad should be a bayer mbus format.

This fixes a kernel NULL pointer dereference error that was caused when
the stream starts because the configured format was not found in the
pixelmap table.

Reported-by: Hans Verkuil 
Signed-off-by: Helen Koike 
---

 drivers/media/platform/vimc/vimc-debayer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/vimc/vimc-debayer.c 
b/drivers/media/platform/vimc/vimc-debayer.c
index eaed4233ad1b..20826f209731 100644
--- a/drivers/media/platform/vimc/vimc-debayer.c
+++ b/drivers/media/platform/vimc/vimc-debayer.c
@@ -66,7 +66,7 @@ struct vimc_deb_device {
 static const struct v4l2_mbus_framefmt sink_fmt_default = {
.width = 640,
.height = 480,
-   .code = MEDIA_BUS_FMT_RGB888_1X24,
+   .code = MEDIA_BUS_FMT_SRGGB8_1X8,
.field = V4L2_FIELD_NONE,
.colorspace = V4L2_COLORSPACE_DEFAULT,
 };
-- 
2.20.1



[PATCH 2/8] media: vimc: stream: fix thread state before sleep

2019-03-06 Thread Helen Koike
The state TASK_UNINTERRUPTIBLE should be set just before
schedule_timeout() call, so it knows the sleep mode it should enter.
There is no point in setting TASK_UNINTERRUPTIBLE at the initialization
of the thread as schedule_timeout() will set the state back to
TASK_RUNNING.

This fixes a warning in __might_sleep() call, as it's expecting the
task to be in TASK_RUNNING state just before changing the state to
a sleeping state.

Reported-by: Hans Verkuil 
Signed-off-by: Helen Koike 
---

 drivers/media/platform/vimc/vimc-streamer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/vimc/vimc-streamer.c 
b/drivers/media/platform/vimc/vimc-streamer.c
index fcc897fb247b..392754c18046 100644
--- a/drivers/media/platform/vimc/vimc-streamer.c
+++ b/drivers/media/platform/vimc/vimc-streamer.c
@@ -120,7 +120,6 @@ static int vimc_streamer_thread(void *data)
int i;
 
set_freezable();
-   set_current_state(TASK_UNINTERRUPTIBLE);
 
for (;;) {
try_to_freeze();
@@ -137,6 +136,7 @@ static int vimc_streamer_thread(void *data)
break;
}
//wait for 60hz
+   set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ / 60);
}
 
-- 
2.20.1



[PATCH 0/8] media: vimc: remove media bus code limitation

2019-03-06 Thread Helen Koike
Hello,

This patch series has several vimc fixes (that I am sending in the same
series only for convenience, let me know if you prefer them to be
sent separately from the series).

The last commit removes the vimc_pix_map_list[] that was mapping
pixelformats with media bus formats, but it turns out they are not
1-to-1 equivalent and it is really painful to add other formats.
Also, for the userspace, media bus formats don't really matter as long
as they match between links. So this patch allows any media bus format
to be configured independently of the final expected pixelformat.

The series depends on
"[PATCH] media: Introduce helpers to fill pixel format structs "

Thanks,
Helen


Helen Koike (8):
  media: vimc: deb: fix default sink bayer format
  media: vimc: stream: fix thread state before sleep
  media: vimc: cap: fix step width/height in enum framesize
  media: v4l2-common: add bayer formats in v4l2_format_info
  media: vimc: stream: cleanup frame field from struct vimc_stream
  media: vimc: stream: add docs to struct vimc_stream
  media: vimc: stream: init/terminate the first entity
  media: vimc: propagate pixel format in the stream

 drivers/media/platform/vimc/vimc-capture.c  |  80 +++--
 drivers/media/platform/vimc/vimc-common.c   | 307 
 drivers/media/platform/vimc/vimc-common.h   |  13 +
 drivers/media/platform/vimc/vimc-debayer.c  |  80 +++--
 drivers/media/platform/vimc/vimc-scaler.c   |  60 ++--
 drivers/media/platform/vimc/vimc-sensor.c   |  48 +--
 drivers/media/platform/vimc/vimc-streamer.c |  39 +--
 drivers/media/platform/vimc/vimc-streamer.h |  22 +-
 drivers/media/v4l2-core/v4l2-common.c   |  22 ++
 9 files changed, 341 insertions(+), 330 deletions(-)

-- 
2.20.1



Re: [PATCH] vimc: add USERPTR support

2019-02-07 Thread Helen Koike
Hi Hans,

Sorry about my delay.

On 1/14/19 3:05 PM, Hans Verkuil wrote:
> On 1/14/19 6:04 PM, Helen Koike wrote:
>> Hi Hans,
>>
>> Thanks for the patch.
>>
>> On 1/14/19 12:58 PM, Hans Verkuil wrote:
>>> Add VB2_USERPTR to the vimc capture device.
>>>
>>> Signed-off-by: Hans Verkuil 

Acked-by: Helen Koike 

>>> ---
>>> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
>>> b/drivers/media/platform/vimc/vimc-capture.c
>>> index 3f7e9ed56633..35c730f484a7 100644
>>> --- a/drivers/media/platform/vimc/vimc-capture.c
>>> +++ b/drivers/media/platform/vimc/vimc-capture.c
>>> @@ -431,7 +431,7 @@ static int vimc_cap_comp_bind(struct device *comp, 
>>> struct device *master,
>>> /* Initialize the vb2 queue */
>>> q = &vcap->queue;
>>> q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
>>> -   q->io_modes = VB2_MMAP | VB2_DMABUF;
>>> +   q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_USERPTR;
>>> q->drv_priv = vcap;
>>> q->buf_struct_size = sizeof(struct vimc_cap_buffer);
>>> q->ops = &vimc_cap_qops;
>>>
>>
>> I remember at the time I was having some issues regarding userptr, I
>> just want to make a few tests first.
> 
> Make sure you update to the latest v4l-utils first: there was a 
> v4l2-compliance bug
> that caused an incorrect FAIL for vimc.

Indeed, seems to be working with latest v4l-utils.

> 
> Regards,
> 
>   Hans
> 

Thanks
Helen


Re: [PATCH] vimc: fill in bus_info in media_device_info

2019-02-07 Thread Helen Koike



On 1/30/19 11:43 AM, Hans Verkuil wrote:
> It is good practice to fill in bus_info.
> 
> Also just use 'platform:vimc' when filling in the bus_info in querycap:
> the bus_info has nothing to do with the video device name.
> 
> Signed-off-by: Hans Verkuil 

Acked-by: Helen Koike 

Thanks
Helen

> ---
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index aaeddf24b042..550aa426ae5e 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -69,12 +69,10 @@ struct vimc_cap_buffer {
>  static int vimc_cap_querycap(struct file *file, void *priv,
>struct v4l2_capability *cap)
>  {
> - struct vimc_cap_device *vcap = video_drvdata(file);
> -
>   strscpy(cap->driver, VIMC_PDEV_NAME, sizeof(cap->driver));
>   strscpy(cap->card, KBUILD_MODNAME, sizeof(cap->card));
>   snprintf(cap->bus_info, sizeof(cap->bus_info),
> -  "platform:%s", vcap->vdev.v4l2_dev->name);
> +  "platform:%s", VIMC_PDEV_NAME);
> 
>   return 0;
>  }
> diff --git a/drivers/media/platform/vimc/vimc-core.c 
> b/drivers/media/platform/vimc/vimc-core.c
> index bf19f1f9795e..c2fdf3ea67ed 100644
> --- a/drivers/media/platform/vimc/vimc-core.c
> +++ b/drivers/media/platform/vimc/vimc-core.c
> @@ -318,6 +318,8 @@ static int vimc_probe(struct platform_device *pdev)
>   /* Initialize media device */
>   strscpy(vimc->mdev.model, VIMC_MDEV_MODEL_NAME,
>   sizeof(vimc->mdev.model));
> + snprintf(vimc->mdev.bus_info, sizeof(vimc->mdev.bus_info),
> +  "platform:%s", VIMC_PDEV_NAME);
>   vimc->mdev.dev = &pdev->dev;
>   media_device_init(&vimc->mdev);
> 


Re: [PATCH v4] media: vimc: Add vimc-streamer for stream control

2019-01-22 Thread Helen Koike
Hi Lucas,

On 1/21/19 11:05 PM, Lucas A. M. Magalhaes wrote:
> Add a linear pipeline logic for the stream control. It's created by
> walking backwards on the entity graph. When the stream starts it will
> simply loop through the pipeline calling the respective process_frame
> function of each entity.
> 
> Fixes: f2fe89061d797 ("vimc: Virtual Media Controller core, capture
> and sensor")
> Cc: sta...@vger.kernel.org # for v4.20
> Signed-off-by: Lucas A. M. Magalhães 

lgtm, thanks for the patch.

Acked-by: Helen Koike 

Regards,
Helen

> ---
> 
> The actual approach for streaming frames on vimc uses a recursive
> logic[1]. This algorithm may cause problems as the stack usage
> increases a with the topology. For the actual topology almost 1Kb of
> stack is used if compiled with KASAN on a 64bit architecture. However
> the topology is fixed and hard-coded on vimc-core[2]. So it's a
> controlled situation if used as is.
> 
> [1]
> The stream starts on vim-sensor's thread
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-sensor.c#n204
> It proceeds calling successively vimc_propagate_frame
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-common.c#n210
> Then processes_frame on the next entity
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-scaler.c#n349
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-debayer.c#n483
> This goes until the loop ends on a vimc-capture device
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-capture.c#n358
> 
> [2]https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-core.c#n80
> 
> Thanks the review Helen. I've made the change you pointed out. There was 
> really
> a bug for single entity pipelines.
> 
> Changed from v3:
> * Fix vimc_streamer_pipeline_init and vimc_streamer_pipeline_terminate for a
> single entity pipeline.
> * Remove unnecessary checks and comments.
> * Alignment and style.
> 
>  drivers/media/platform/vimc/Makefile|   3 +-
>  drivers/media/platform/vimc/vimc-capture.c  |  18 +-
>  drivers/media/platform/vimc/vimc-common.c   |  35 
>  drivers/media/platform/vimc/vimc-common.h   |  15 +-
>  drivers/media/platform/vimc/vimc-debayer.c  |  26 +--
>  drivers/media/platform/vimc/vimc-scaler.c   |  28 +--
>  drivers/media/platform/vimc/vimc-sensor.c   |  56 ++
>  drivers/media/platform/vimc/vimc-streamer.c | 188 
>  drivers/media/platform/vimc/vimc-streamer.h |  38 
>  9 files changed, 260 insertions(+), 147 deletions(-)
>  create mode 100644 drivers/media/platform/vimc/vimc-streamer.c
>  create mode 100644 drivers/media/platform/vimc/vimc-streamer.h
> 
> diff --git a/drivers/media/platform/vimc/Makefile 
> b/drivers/media/platform/vimc/Makefile
> index 4b2e3de7856e..c4fc8e7d365a 100644
> --- a/drivers/media/platform/vimc/Makefile
> +++ b/drivers/media/platform/vimc/Makefile
> @@ -5,6 +5,7 @@ vimc_common-objs := vimc-common.o
>  vimc_debayer-objs := vimc-debayer.o
>  vimc_scaler-objs := vimc-scaler.o
>  vimc_sensor-objs := vimc-sensor.o
> +vimc_streamer-objs := vimc-streamer.o
>  
>  obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc_capture.o vimc_common.o 
> vimc-debayer.o \
> - vimc_scaler.o vimc_sensor.o
> + vimc_scaler.o vimc_sensor.o vimc_streamer.o
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index aaeddf24b042..93837d9eecd2 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -24,6 +24,7 @@
>  #include 
>  
>  #include "vimc-common.h"
> +#include "vimc-streamer.h"
>  
>  #define VIMC_CAP_DRV_NAME "vimc-capture"
>  
> @@ -44,7 +45,7 @@ struct vimc_cap_device {
>   spinlock_t qlock;
>   struct mutex lock;
>   u32 sequence;
> - struct media_pipeline pipe;
> + struct vimc_stream stream;
>  };
>  
>  static const struct v4l2_pix_format fmt_default = {
> @@ -248,14 +249,13 @@ static int vimc_cap_start_streaming(struct vb2_queue 
> *vq, unsigned int count)
>   vcap->sequence = 0;
>  
>   /* Start the media pipeline */
> - ret = media_pipeline_start(entity, &vcap->pipe);
> + ret = media_pipeline_start(entity, &vcap->stream.pipe);
>   if (ret) {
>   vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
>   return ret;
>   }
>  
> - /* Enable streaming from the pipe */
> - ret = vimc_pipeline_s_stream(&vcap->vdev.entity, 1)

Re: [PATCH v3] media: vimc: Add vimc-streamer for stream control

2019-01-18 Thread Helen Koike



On 1/17/19 8:15 PM, Lucas A. M. Magalhaes wrote:
> Add a linear pipeline logic for the stream control. It's created by
> walking backwards on the entity graph. When the stream starts it will
> simply loop through the pipeline calling the respective process_frame
> function of each entity.
> 
> Fixes: f2fe89061d797 ("vimc: Virtual Media Controller core, capture
> and sensor")
> Cc: sta...@vger.kernel.org # for v4.20
> Signed-off-by: Lucas A. M. Magalhães 
> ---
> 
> The actual approach for streaming frames on vimc uses a recursive
> logic[1]. This algorithm may cause problems as the stack usage
> increases a with the topology. For the actual topology almost 1Kb of
> stack is used if compiled with KASAN on a 64bit architecture. However
> the topology is fixed and hard-coded on vimc-core[2]. So it's a
> controlled situation if used as is.
> 
> [1]
> The stream starts on vim-sensor's thread
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-sensor.c#n204
> It proceeds calling successively vimc_propagate_frame
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-common.c#n210
> Then processes_frame on the next entity
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-scaler.c#n349
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-debayer.c#n483
> This goes until the loop ends on a vimc-capture device
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-capture.c#n358
> 
> [2]https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-core.c#n80
> 
> Change since v2:
> - Fix checks on vimc_streamer_pipeline_init.
> 
>  drivers/media/platform/vimc/Makefile|   3 +-
>  drivers/media/platform/vimc/vimc-capture.c  |  18 +-
>  drivers/media/platform/vimc/vimc-common.c   |  35 
>  drivers/media/platform/vimc/vimc-common.h   |  15 +-
>  drivers/media/platform/vimc/vimc-debayer.c  |  26 +--
>  drivers/media/platform/vimc/vimc-scaler.c   |  28 +--
>  drivers/media/platform/vimc/vimc-sensor.c   |  56 ++
>  drivers/media/platform/vimc/vimc-streamer.c | 198 
>  drivers/media/platform/vimc/vimc-streamer.h |  38 
>  9 files changed, 270 insertions(+), 147 deletions(-)
>  create mode 100644 drivers/media/platform/vimc/vimc-streamer.c
>  create mode 100644 drivers/media/platform/vimc/vimc-streamer.h
> 
> diff --git a/drivers/media/platform/vimc/Makefile 
> b/drivers/media/platform/vimc/Makefile
> index 4b2e3de7856e..c4fc8e7d365a 100644
> --- a/drivers/media/platform/vimc/Makefile
> +++ b/drivers/media/platform/vimc/Makefile
> @@ -5,6 +5,7 @@ vimc_common-objs := vimc-common.o
>  vimc_debayer-objs := vimc-debayer.o
>  vimc_scaler-objs := vimc-scaler.o
>  vimc_sensor-objs := vimc-sensor.o
> +vimc_streamer-objs := vimc-streamer.o
>  
>  obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc_capture.o vimc_common.o 
> vimc-debayer.o \
> - vimc_scaler.o vimc_sensor.o
> + vimc_scaler.o vimc_sensor.o vimc_streamer.o
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index 3f7e9ed56633..80d7515ec420 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -24,6 +24,7 @@
>  #include 
>  
>  #include "vimc-common.h"
> +#include "vimc-streamer.h"
>  
>  #define VIMC_CAP_DRV_NAME "vimc-capture"
>  
> @@ -44,7 +45,7 @@ struct vimc_cap_device {
>   spinlock_t qlock;
>   struct mutex lock;
>   u32 sequence;
> - struct media_pipeline pipe;
> + struct vimc_stream stream;
>  };
>  
>  static const struct v4l2_pix_format fmt_default = {
> @@ -248,14 +249,13 @@ static int vimc_cap_start_streaming(struct vb2_queue 
> *vq, unsigned int count)
>   vcap->sequence = 0;
>  
>   /* Start the media pipeline */
> - ret = media_pipeline_start(entity, &vcap->pipe);
> + ret = media_pipeline_start(entity, &vcap->stream.pipe);
>   if (ret) {
>   vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
>   return ret;
>   }
>  
> - /* Enable streaming from the pipe */
> - ret = vimc_pipeline_s_stream(&vcap->vdev.entity, 1);
> + ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1);
>   if (ret) {
>   media_pipeline_stop(entity);
>   vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
> @@ -273,8 +273,7 @@ static void vimc_cap_stop_streaming(struct vb2_queue *vq)
>  {
>   struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
>  
> - /* Disable streaming from the pipe */
> - vimc_pipeline_s_stream(&vcap->vdev.entity, 0);
> + vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 0);
>  
>   /* Stop the media pipeline */
>   media_pipeline_stop(&vcap->vdev.entity);
> @@ -355,8 +354,8 @@ static void vimc_cap_comp_unbind(struct device *comp, 
> struct device *master,
>   kfree(vcap);
>  }
>

Re: [PATCH v2] media: vimc: Add vimc-streamer for stream control

2019-01-15 Thread Helen Koike
Hi Lucas,

Thank you for this patch, please see my comments below.

On 1/14/19 10:19 PM, Lucas A. M. Magalhaes wrote:
> Add a linear pipeline logic for the stream control. It's created by
> walking backwards on the entity graph. When the stream starts it will
> simply loop through the pipeline calling the respective process_frame
> function of each entity.
> 
> Fixes: f2fe89061d797 ("vimc: Virtual Media Controller core, capture
> and sensor")
> Cc: sta...@vger.kernel.org # for v4.20
> Signed-off-by: Lucas A. M. Magalhães 
> ---
> 
> The actual approach for streaming frames on vimc uses a recursive
> logic[1]. This algorithm may cause problems as the stack usage
> increases a with the topology. For the actual topology almost 1Kb of
> stack is used if compiled with KASAN on a 64bit architecture. However
> the topology is fixed and hard-coded on vimc-core[2]. So it's a
> controlled situation if used as is.
> 
> [1]
> The stream starts on vim-sensor's thread
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-sensor.c#n204
> It proceeds calling successively vimc_propagate_frame
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-common.c#n210
> Then processes_frame on the next entity
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-scaler.c#n349
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-debayer.c#n483
> This goes until the loop ends on a vimc-capture device
> https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-capture.c#n358
> 
> [2]https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-core.c#n80
> 
>  drivers/media/platform/vimc/Makefile|   3 +-
>  drivers/media/platform/vimc/vimc-capture.c  |  18 +-
>  drivers/media/platform/vimc/vimc-common.c   |  35 
>  drivers/media/platform/vimc/vimc-common.h   |  15 +-
>  drivers/media/platform/vimc/vimc-debayer.c  |  26 +--
>  drivers/media/platform/vimc/vimc-scaler.c   |  28 +--
>  drivers/media/platform/vimc/vimc-sensor.c   |  56 ++
>  drivers/media/platform/vimc/vimc-streamer.c | 197 
>  drivers/media/platform/vimc/vimc-streamer.h |  38 
>  9 files changed, 269 insertions(+), 147 deletions(-)
>  create mode 100644 drivers/media/platform/vimc/vimc-streamer.c
>  create mode 100644 drivers/media/platform/vimc/vimc-streamer.h
> 
> diff --git a/drivers/media/platform/vimc/Makefile 
> b/drivers/media/platform/vimc/Makefile
> index 4b2e3de7856e..c4fc8e7d365a 100644
> --- a/drivers/media/platform/vimc/Makefile
> +++ b/drivers/media/platform/vimc/Makefile
> @@ -5,6 +5,7 @@ vimc_common-objs := vimc-common.o
>  vimc_debayer-objs := vimc-debayer.o
>  vimc_scaler-objs := vimc-scaler.o
>  vimc_sensor-objs := vimc-sensor.o
> +vimc_streamer-objs := vimc-streamer.o
>  
>  obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc_capture.o vimc_common.o 
> vimc-debayer.o \
> - vimc_scaler.o vimc_sensor.o
> + vimc_scaler.o vimc_sensor.o vimc_streamer.o
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index 3f7e9ed56633..80d7515ec420 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -24,6 +24,7 @@
>  #include 
>  
>  #include "vimc-common.h"
> +#include "vimc-streamer.h"
>  
>  #define VIMC_CAP_DRV_NAME "vimc-capture"
>  
> @@ -44,7 +45,7 @@ struct vimc_cap_device {
>   spinlock_t qlock;
>   struct mutex lock;
>   u32 sequence;
> - struct media_pipeline pipe;
> + struct vimc_stream stream;
>  };
>  
>  static const struct v4l2_pix_format fmt_default = {
> @@ -248,14 +249,13 @@ static int vimc_cap_start_streaming(struct vb2_queue 
> *vq, unsigned int count)
>   vcap->sequence = 0;
>  
>   /* Start the media pipeline */
> - ret = media_pipeline_start(entity, &vcap->pipe);
> + ret = media_pipeline_start(entity, &vcap->stream.pipe);
>   if (ret) {
>   vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
>   return ret;
>   }
>  
> - /* Enable streaming from the pipe */
> - ret = vimc_pipeline_s_stream(&vcap->vdev.entity, 1);
> + ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1);
>   if (ret) {
>   media_pipeline_stop(entity);
>   vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
> @@ -273,8 +273,7 @@ static void vimc_cap_stop_streaming(struct vb2_queue *vq)
>  {
>   struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
>  
> - /* Disable streaming from the pipe */
> - vimc_pipeline_s_stream(&vcap->vdev.entity, 0);
> + vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 0);
>  
>   /* Stop the media pipeline */
>   media_pipeline_stop(&vcap->vdev.entity);
> @@ -355,8 +354,8 @@ static void vimc_cap_comp_unbind(struct device *comp, 
> struct device *master,
>   kfree(vcap);
>  }
>  

Re: [PATCH] vimc: add USERPTR support

2019-01-14 Thread Helen Koike
Hi Hans,

Thanks for the patch.

On 1/14/19 12:58 PM, Hans Verkuil wrote:
> Add VB2_USERPTR to the vimc capture device.
> 
> Signed-off-by: Hans Verkuil 
> ---
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index 3f7e9ed56633..35c730f484a7 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -431,7 +431,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct 
> device *master,
>   /* Initialize the vb2 queue */
>   q = &vcap->queue;
>   q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> - q->io_modes = VB2_MMAP | VB2_DMABUF;
> + q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_USERPTR;
>   q->drv_priv = vcap;
>   q->buf_struct_size = sizeof(struct vimc_cap_buffer);
>   q->ops = &vimc_cap_qops;
> 

I remember at the time I was having some issues regarding userptr, I
just want to make a few tests first.

Regards,
Helen


Re: vimc kernel warning and kernel oops

2019-01-14 Thread Helen Koike
Hi Hans

On 1/11/19 1:25 PM, Hans Verkuil wrote:
> Hi Helen,
> 
> I've started work to fix the last compliance failures with vimc so that
> vimc can be used in regression tests.
> 
> But I found a kernel warning and a kernel oops using vimc from our master 
> tree.
> 
> To test, load vimc, then run:
> 
> v4l2-ctl -d2 -v width=1920,height=1440
> v4l2-ctl -d2 --stream-mmap
> 
> This is the first kernel warning:
> 
> [  671.799450] [ cut here ]
> [  671.799471] do not call blocking ops when !TASK_RUNNING; state=2 set at 
> [<50c41bbb>] vimc_sen_tpg_thread+0x0/0x110 [vimc_sensor]
> [  671.799487] WARNING: CPU: 5 PID: 31428 at kernel/sched/core.c:6099 
> __might_sleep+0x63/0x70
> [  671.799492] Modules linked in: vimc_scaler vimc_sensor v4l2_tpg 
> vimc_capture videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 vimc_debayer 
> videobuf2_common vimc_common vimc videodev media
> vmw_vsock_vmci_transport vmw_balloon vmwgfx ttm vmw_vmci button [last 
> unloaded: media]
> [  671.799515] CPU: 5 PID: 31428 Comm: vimc vimc.0-sen Not tainted 
> 5.0.0-rc1-test-nl #23
> [  671.799518] Hardware name: VMware, Inc. VMware Virtual Platform/440BX 
> Desktop Reference Platform, BIOS 6.00 04/13/2018
> [  671.799522] RIP: 0010:__might_sleep+0x63/0x70
> [  671.799526] Code: 5b 5d 41 5c e9 3e ff ff ff 48 8b 90 f0 20 00 00 48 8b 70 
> 10 48 c7 c7 98 79 30 82 c6 05 91 fb 5b 01 01 48 89 d1 e8 14 91 fd ff <0f> 0b 
> eb ca 66 0f 1f 84 00 00 00 00 00 55 53 48 83
> ec 08 65 48 8b
> [  671.799529] RSP: 0018:c90016457ec8 EFLAGS: 00010282
> [  671.799532] RAX:  RBX: a00ec398 RCX: 
> 
> [  671.799535] RDX: 0007 RSI: 8232b345 RDI: 
> 
> [  671.799537] RBP: 0039 R08:  R09: 
> 
> [  671.799540] R10: 7e7cfc77 R11: c90016457d70 R12: 
> 
> [  671.799542] R13: 88842afc4168 R14: 88842afc4000 R15: 
> a00eb0e0
> [  671.799545] FS:  () GS:88842ed4() 
> knlGS:
> [  671.799585] CS:  0010 DS:  ES:  CR0: 80050033
> [  671.799587] CR2: 56027a051cc0 CR3: 0004136ec000 CR4: 
> 003406e0
> [  671.799615] Call Trace:
> [  671.799624]  vimc_sen_tpg_thread+0x72/0x110 [vimc_sensor]
> [  671.799632]  kthread+0x113/0x130
> [  671.799637]  ? kthread_create_on_node+0x60/0x60
> [  671.799645]  ret_from_fork+0x22/0x40
> [  671.799653] ---[ end trace 9048b36dd38333b9 ]---
> 
> The cause is that set_current_state(TASK_UNINTERRUPTIBLE); is called too 
> early,
> it should be called just before the schedule_timeout().
> 
> The kernel oops follows the warning:
> 
> [  671.800597] BUG: unable to handle kernel NULL pointer dereference at 
> 0004
> [  671.800600] #PF error: [normal kernel read fault]
> [  671.800602] PGD 0 P4D 0
> [  671.800606] Oops:  [#1] PREEMPT SMP
> [  671.800609] CPU: 5 PID: 31428 Comm: vimc vimc.0-sen Tainted: GW
>  5.0.0-rc1-test-nl #23
> [  671.800610] Hardware name: VMware, Inc. VMware Virtual Platform/440BX 
> Desktop Reference Platform, BIOS 6.00 04/13/2018
> [  671.800615] RIP: 0010:vimc_deb_process_frame+0x14b/0x2b0 [vimc_debayer]
> [  671.800617] Code: 4c 24 08 41 89 f0 48 8d 1c 12 8d 4e ff 45 0f af c4 48 89 
> 5c 24 10 48 89 4c 24 18 48 8b 4c 24 08 89 fa 83 e2 01 48 03 54 24 10 <44> 8b 
> 4c 91 04 44 89 c1 4a 8d 6c 8c 38 44 8b 55 00
> 85 f6 74 32 48
> [  671.800619] RSP: 0018:c90016457e38 EFLAGS: 00010246
> [  671.800622] RAX:  RBX:  RCX: 
> 
> [  671.800623] RDX:  RSI: 0003 RDI: 
> 
> [  671.800625] RBP: 888422331b40 R08:  R09: 
> 0001
> [  671.800628] R10: 01df R11: 0001 R12: 
> 
> [  671.800630] R13:  R14: 0280 R15: 
> 88842a465800
> [  671.800632] FS:  () GS:88842ed4() 
> knlGS:
> [  671.800635] CS:  0010 DS:  ES:  CR0: 80050033
> [  671.800637] CR2: 0004 CR3: 0004136ec000 CR4: 
> 003406e0
> [  671.800641] Call Trace:
> [  671.800647]  ? vimc_sen_enum_mbus_code+0x30/0x30 [vimc_sensor]
> [  671.800651]  vimc_propagate_frame+0x8f/0xa0 [vimc_common]
> [  671.800655]  vimc_sen_tpg_thread+0xcb/0x110 [vimc_sensor]
> [  671.800660]  kthread+0x113/0x130
> [  671.800663]  ? kthread_create_on_node+0x60/0x60
> [  671.800667]  ret_from_fork+0x22/0x40
> [  671.800671] Modules linked in: vimc_scaler vimc_sensor v4l2_tpg 
> vimc_capture videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 vimc_debayer 
> videobuf2_common vimc_common vimc videodev media
> vmw_vsock_vmci_transport vmw_balloon vmwgfx ttm vmw_vmci button [last 
> unloaded: media]
> [  671.800681] CR2: 0004
> [  671.800685] ---[ end trace 9048b36dd38333ba ]---
> 
> The reason for this is that in vimc_

Re: [PATCH v4] media: vicodec: add support for CROP and COMPOSE selection

2018-12-26 Thread Helen Koike
Hi Dafna,

Thanks for the patch, just a few comments, mostly regarding coding
style, I'll let Hans review the major logic.

On 12/23/18 6:36 PM, Dafna Hirschfeld wrote:
> Add support for the selection api for the crop and compose targets.
> The driver rounds up the coded width and height such that
> all planes dimensions are multiple of 8.
> 
> Signed-off-by: Dafna Hirschfeld 
> ---
> Changes from v3:
> In v3 mistakenly renamed some stride variables in codec-fwht.c
> to coded_width which should actually be kept named stride
> 
>  drivers/media/platform/vicodec/codec-fwht.c   |  66 
>  drivers/media/platform/vicodec/codec-fwht.h   |  15 +-
>  .../media/platform/vicodec/codec-v4l2-fwht.c  |  36 ++---
>  .../media/platform/vicodec/codec-v4l2-fwht.h  |   6 +-
>  drivers/media/platform/vicodec/vicodec-core.c | 146 ++
>  5 files changed, 187 insertions(+), 82 deletions(-)
> 
> diff --git a/drivers/media/platform/vicodec/codec-fwht.c 
> b/drivers/media/platform/vicodec/codec-fwht.c
> index a6fd0477633b..530a5bceb2b9 100644
> --- a/drivers/media/platform/vicodec/codec-fwht.c
> +++ b/drivers/media/platform/vicodec/codec-fwht.c
> @@ -11,6 +11,7 @@
>  
>  #include 
>  #include "codec-fwht.h"
> +#include 

Please add linux/kernel.h just after linux/string.h

>  
>  /*
>   * Note: bit 0 of the header must always be 0. Otherwise it cannot
> @@ -659,7 +660,7 @@ static void add_deltas(s16 *deltas, const u8 *ref, int 
> stride)
>  }
>  
>  static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max,
> - struct fwht_cframe *cf, u32 height, u32 width,
> + struct fwht_cframe *cf, u32 height, u32 width, u32 
> coded_width,

over 80 chars

>   unsigned int input_step,
>   bool is_intra, bool next_is_intra)
>  {
> @@ -671,7 +672,11 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 
> **rlco, __be16 *rlco_max,
>   unsigned int last_size = 0;
>   unsigned int i, j;
>  
> + width = round_up(width, 8);
> + height = round_up(height, 8);
> +
>   for (j = 0; j < height / 8; j++) {
> + input = input_start + j * 8 * coded_width * input_step;
>   for (i = 0; i < width / 8; i++) {
>   /* intra code, first frame is always intra coded. */
>   int blocktype = IBLOCK;
> @@ -679,9 +684,9 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 
> **rlco, __be16 *rlco_max,
>  
>   if (!is_intra)
>   blocktype = decide_blocktype(input, refp,
> - deltablock, width, input_step);
> + deltablock, coded_width, input_step);
>   if (blocktype == IBLOCK) {
> - fwht(input, cf->coeffs, width, input_step, 1);
> + fwht(input, cf->coeffs, coded_width, 
> input_step, 1);

over 80 chars

I think there are other places with line over 80 chars, checkpatch
should show you the other places.

This is not a strict rule, but I would try to follow it unless you
really think it is much easier to read otherwise.

>   quantize_intra(cf->coeffs, cf->de_coeffs,
>  cf->i_frame_qp);
>   } else {
> @@ -722,7 +727,6 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 
> **rlco, __be16 *rlco_max,
>   }
>   last_size = size;
>   }
> - input += width * 7 * input_step;
>   }
>  
>  exit_loop:
> @@ -747,29 +751,31 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 
> **rlco, __be16 *rlco_max,
>  u32 fwht_encode_frame(struct fwht_raw_frame *frm,
> struct fwht_raw_frame *ref_frm,
> struct fwht_cframe *cf,
> -   bool is_intra, bool next_is_intra)
> +   bool is_intra, bool next_is_intra,
> +   unsigned int width, unsigned int height)
>  {
> - unsigned int size = frm->height * frm->width;
> + unsigned int size = height * width;
>   __be16 *rlco = cf->rlc_data;
>   __be16 *rlco_max;
>   u32 encoding;
>  
>   rlco_max = rlco + size / 2 - 256;
>   encoding = encode_plane(frm->luma, ref_frm->luma, &rlco, rlco_max, cf,
> - frm->height, frm->width,
> + height, width, frm->coded_width,
>   frm->luma_alpha_step, is_intra, next_is_intra);
>   if (encoding & FWHT_FRAME_UNENCODED)
>   encoding |= FWHT_LUMA_UNENCODED;
>   encoding &= ~FWHT_FRAME_UNENCODED;
>  
>   if (frm->components_num >= 3) {
> - u32 chroma_h = frm->height / frm->height_div;
> - u32 chroma_w = frm->width / frm->width_div;
> + u32 chroma_h = height / frm->height_div;
> + u32 chroma_w = width / frm->width

Re: [Lkcamp][PATCH] media: vimc: Add vimc-streamer for stream control

2018-12-15 Thread Helen Koike
Hi Lucas,

Thank you for your patch, just some small comments below.

On 12/15/18 2:46 PM, Lucas A. M. Magalhães wrote:
> The previous code pipeline used the stack to walk on the graph and
> process a frame. Basically the vimc-sensor entity starts a thread that
> generates the frames and calls the propagate_process function to send
> this frame to each entity linked with a sink pad. The propagate_process
> will call the process_frame of the entities which will call the
> propagate_frame for each one of it's sink pad. This cycle will continue
> until it reaches a vimc-capture entity that will finally return and
> unstack.
> 
> This solution had many problems:
>   * It was a little bit slow
>   * It was susceptible to a stack overflow as it made indiscriminate
> use of the stack.
>   * It doesn't allow frame rate control
>   * It was complex to understand
>   * It doesn't allow pipeline control
> 
> This commit proposes an alternative way to control vimc streams by
> having a streamer object. This object will create a linear pipeline
> walking backwards on the graph. When the stream starts it will simply
> loop through the pipeline calling the respective process_frame function
> for each entity on the pipeline.
> 
> This solution has some premises which are true for now:
>   * Two paths can never be enabled and streaming at the same time.
>   * There is no entity streaming frames to two source pads at the same
> time.
>   * There is no entity receiving frames from two sink pads at the same
> time.
> 
> Signed-off-by: Lucas A. M. Magalhães 

I won't comment on the commit message, as Mauro already sent a good review.

> ---
> Hi,
> 
> This patch introduces a streamer controller library for the vimc
> driver. It's a step towards a optimized mode I've been discussing with
> Helen.
> I plan to pass a tpg struct through the pipeline. This tpg struct
> will be configured in each entity and the capture will generate the
> frames with the correct format at the end of the pipeline.
> 
> Thanks,
> Lucas
> 
>  drivers/media/platform/vimc/Makefile|   3 +-
>  drivers/media/platform/vimc/vimc-capture.c  |  18 +-
>  drivers/media/platform/vimc/vimc-common.c   |  50 ++
>  drivers/media/platform/vimc/vimc-common.h   |  15 +-
>  drivers/media/platform/vimc/vimc-debayer.c  |  26 +--
>  drivers/media/platform/vimc/vimc-scaler.c   |  28 +---
>  drivers/media/platform/vimc/vimc-sensor.c   |  56 ++-
>  drivers/media/platform/vimc/vimc-streamer.c | 176 
>  drivers/media/platform/vimc/vimc-streamer.h |  38 +
>  9 files changed, 268 insertions(+), 142 deletions(-)
>  create mode 100644 drivers/media/platform/vimc/vimc-streamer.c
>  create mode 100644 drivers/media/platform/vimc/vimc-streamer.h
> 
> diff --git a/drivers/media/platform/vimc/Makefile 
> b/drivers/media/platform/vimc/Makefile
> index 4b2e3de7856e..c4fc8e7d365a 100644
> --- a/drivers/media/platform/vimc/Makefile
> +++ b/drivers/media/platform/vimc/Makefile
> @@ -5,6 +5,7 @@ vimc_common-objs := vimc-common.o
>  vimc_debayer-objs := vimc-debayer.o
>  vimc_scaler-objs := vimc-scaler.o
>  vimc_sensor-objs := vimc-sensor.o
> +vimc_streamer-objs := vimc-streamer.o
>  
>  obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc_capture.o vimc_common.o 
> vimc-debayer.o \
> - vimc_scaler.o vimc_sensor.o
> + vimc_scaler.o vimc_sensor.o vimc_streamer.o
> diff --git a/drivers/media/platform/vimc/vimc-capture.c 
> b/drivers/media/platform/vimc/vimc-capture.c
> index 3f7e9ed56633..80d7515ec420 100644
> --- a/drivers/media/platform/vimc/vimc-capture.c
> +++ b/drivers/media/platform/vimc/vimc-capture.c
> @@ -24,6 +24,7 @@
>  #include 
>  
>  #include "vimc-common.h"
> +#include "vimc-streamer.h"
>  
>  #define VIMC_CAP_DRV_NAME "vimc-capture"
>  
> @@ -44,7 +45,7 @@ struct vimc_cap_device {
>   spinlock_t qlock;
>   struct mutex lock;
>   u32 sequence;
> - struct media_pipeline pipe;
> + struct vimc_stream stream;
>  };
>  
>  static const struct v4l2_pix_format fmt_default = {
> @@ -248,14 +249,13 @@ static int vimc_cap_start_streaming(struct vb2_queue 
> *vq, unsigned int count)
>   vcap->sequence = 0;
>  
>   /* Start the media pipeline */
> - ret = media_pipeline_start(entity, &vcap->pipe);
> + ret = media_pipeline_start(entity, &vcap->stream.pipe);
>   if (ret) {
>   vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
>   return ret;
>   }
>  
> - /* Enable streaming from the pipe */
> - ret = vimc_pipeline_s_stream(&vcap->vdev.entity, 1);
> + ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1);
>   if (ret) {
>   media_pipeline_stop(entity);
>   vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
> @@ -273,8 +273,7 @@ static void vimc_cap_stop_streaming(struct vb2_queue *vq)
>  {
>   struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
>  
> - /* Disable streaming f

Re: [Lkcamp][PATCH] media: vimc: Add vimc-streamer for stream control

2018-12-15 Thread Helen Koike
Hi Mauro,

On 12/15/18 4:01 PM, Mauro Carvalho Chehab wrote:
> Hi Lucas,
> 
> 
> Em Sat, 15 Dec 2018 14:46:31 -0200
> Lucas A. M. Magalhães  escreveu:
> 
>> The previous code pipeline used the stack to walk on the graph and
>> process a frame. Basically the vimc-sensor entity starts a thread that
>> generates the frames and calls the propagate_process function to send
>> this frame to each entity linked with a sink pad. The propagate_process
>> will call the process_frame of the entities which will call the
>> propagate_frame for each one of it's sink pad. This cycle will continue
>> until it reaches a vimc-capture entity that will finally return and
>> unstack.
> 
> I didn't review the code yet, but I have a few comments about the
> way you're describing this patch.
> 
> When you mention about a "previous code pipeline". Well, by adding it
> at the main body of the patch description, reviewers should expect
> that you're mentioning an implementation that already reached upstream.
> 
> I suspect that this is not the case here, as I don't think we merged
> any recursive algorithm using the stack, as this is something that
> we shouldn't do at Kernelspace, as a 4K stack is usually not OK
> with recursive algorithms.
> 
> So, it seems that this entire patch description (as-is) is bogus[1].
> 
> [1] if this is not the case and a recursive approach was indeed
> sneaked into the Kernel, this is a bug. So, you should really
> use the "Fixes:" meta-tag indicating what changeset this patch is
> fixing, and a "Cc: sta...@vger.kernel.org", in order to hint
> stable maintainers that this require backports.

Just fyi, this is not the case, the current implementation in mainline
is bogus indeed (implemented by me when I was starting kernel
development, sorry about that and thanks Lucas for sending a fix). Not
only when propagating the frame [1] but also when activating the
pipeline [2].

But in any case this should be better written in the commit message.


[1]
Every entity calls vimc_propagate_frame()
https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-debayer.c#n506
That calls the process_frame() of each entity directly connected, that
calls vimc_propagate_frame() again:
https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-common.c#n237

[2]
.s_stream is calling the .s_stream of the subdevices directly connected
https://git.linuxtv.org/media_tree.git/tree/drivers/media/platform/vimc/vimc-debayer.c#n355


I was actually wondering if this is worthy in sending this to stable, as
this implementation is not a real problem, because the topology in vimc
is hardcoded and limited, and according to:
https://www.kernel.org/doc/Documentation/process/stable-kernel-rules.rst
"It must fix a real bug that bothers people"

So as the topology is fixed (in the current implementation), the max
number of nested calls is 4 (in the sensor->debayer->scaler->capture
path), this doesn't triggers any bug to users. But this will be a
problem once we have the configfs API in vimc.

You could say that if your memory is low, this can be a problem in the
current implementation, but then your system won't have memory for any 4
nested function calls anyway (which I think the kernel wouldn't work at
all).

Mauro, with that said, do you still think we should send this to stable?

Thanks
Helen

> 
> Please notice that the patch description will be stored forever
> at the git tree. Mentioning something that were never merged
> (and that, years from now people will hardly remember, and will
> have lots of trouble to seek as you didn't even mentioned any
> ML archive with the past solution) shouldn't be done.
> 
> So, you should rewrite the entire patch description explaining
> what the current approach took by this patch does. Then, in order
> to make easier for reviewers to compare with a previous implementation,
> you can add a "---" line and then a description about why this approach
> is better than the first version, e. g. something like:
> 
>   [PATCH v2] media: vimc: Add vimc-streamer for stream control
> 
>   Add a logic that will create a linear pipeline walking 
>   backwards on the graph. When the stream starts it will simply
>   loop through the pipeline calling the respective process_frame
>   function for each entity on the pipeline.
> 
>   Signed-off-by: Your Name 
> 
>   ---
> 
>   v2: The previous approach were to use a recursive function that
>   it was using the stack to walk on the graph and
>   process a frame. Basically the vimc-sensor entity starts a thread that
>   generates the frames and calls the propagate_process function to send
>   this frame to each entity linked with a sink pad. The propagate_process
>   will call the process_frame of the entities which will call the
>   propagate_frame for each one of it's sink pad. This cycle will continue
>   until it reaches a vimc-capture entity that will finally return and
>

Re: [PATCH] media: vimc: add configfs API to configure the topology

2018-12-10 Thread Helen Koike
Hi Hans,

On 12/10/18 9:31 AM, Hans Verkuil wrote:
> On 12/7/18 7:22 PM, Helen Koike wrote:
>> Add API to allow userspace to create any type of topology in vimc using
>> basic system calls such as mkdir/rmdir/read/write.
>>
>> Signed-off-by: Helen Koike 
>>
>> ---
>> Hi,
>>
>> This patch introduces the configufs API for configuring the topology in
>> vimc while it removes the hardcoded topology, so now, when you load the
>> module you need to create a device (no device will appear in your system
>> by default) using mkdir/rmdir/write/read.
>> Please see documentation in the patch.
>> I was thinking in adding a device by default, but if I do it in
>> configfs, userspace won't be able to delete the device (which might not
>> be a problem), as I need to create it as a "default" group in configfs,
>> or I can just not expose the default device in the configfs.
>> What do you think?
> 
> I don't like the idea of having a special default device.
> 
> So I think the way this patch does it is fine.

ok, nice.

> 
>>
>> Thanks
>> Helen
>>
>>  Documentation/media/v4l-drivers/vimc.rst| 172 +
>>  drivers/media/platform/vimc/Kconfig |   7 +-
>>  drivers/media/platform/vimc/Makefile|   7 +-
>>  drivers/media/platform/vimc/vimc-capture.c  |  46 +-
>>  drivers/media/platform/vimc/vimc-common.h   |  58 +-
>>  drivers/media/platform/vimc/vimc-configfs.c | 665 
>>  drivers/media/platform/vimc/vimc-configfs.h |  30 +
>>  drivers/media/platform/vimc/vimc-core.c | 283 ++---
>>  drivers/media/platform/vimc/vimc-core.h |  17 +
>>  drivers/media/platform/vimc/vimc-debayer.c  |  51 +-
>>  drivers/media/platform/vimc/vimc-scaler.c   |  49 +-
>>  drivers/media/platform/vimc/vimc-sensor.c   |  43 +-
>>  12 files changed, 1153 insertions(+), 275 deletions(-)
>>  create mode 100644 Documentation/media/v4l-drivers/vimc.rst
>>  create mode 100644 drivers/media/platform/vimc/vimc-configfs.c
>>  create mode 100644 drivers/media/platform/vimc/vimc-configfs.h
>>  create mode 100644 drivers/media/platform/vimc/vimc-core.h
>>
>> diff --git a/Documentation/media/v4l-drivers/vimc.rst 
>> b/Documentation/media/v4l-drivers/vimc.rst
>> new file mode 100644
>> index ..28d3b02c7d30
>> --- /dev/null
>> +++ b/Documentation/media/v4l-drivers/vimc.rst
>> @@ -0,0 +1,172 @@
>> +The Virtual Media Controller Driver (vimc)
>> +=
>> +
>> +This driver emulates video4linux hardware of varios media topologies. It 
>> exposes
> 
> varios -> various

ops, sorry about so many spelling mistakes, I'll pay more attention on
this next time.

> 
>> +media devices through /dev/mediaX notes, video capture devices through
> 
> notes -> nodes
> 
>> +/dev/videoX and sub-devices through /dev/v4l-subdevX.
> 
> I'd add 'nodes' after videoX and v4l-subdevX as well.
> 
>> +
>> +A subdevice can be a sensor, a debayer or a scaler.
>> +
>> +To configure a media device of a given topology, a ConfigFS API is provided.
>> +
>> +
>> +Configuring the driver through ConfigFS (Experimental)
>> +--
>> +
>> +.. note::
>> +This API is not finished yet and might change in the future.
>> +
>> +Mount configfs:
>> +::
>> +$ mkdir /configfs
>> +$ mount -t configfs none /configfs
>> +
>> +When loading the module, you see a folders name vimc
>> +::
>> +$ tree /configfs/
>> +/configfs/
>> +`-- vimc
>> +
>> +1) Creating a media device
>> +~~
>> +
>> +To create a media device just create a new folder under /configfs/vimc/
>> +
>> +Example:
>> +::
>> +$ mkdir /configfs/vimc/mdev
>> +$ tree /configfs/vimc/mdev
>> +/configfs/vimc/mdev/
>> +|-- entities/
>> +|-- hotplug
>> +`-- links/
>> +
>> +2 directories, 1 file
>> +
>> +2) Creating entities
>> +
>> +
>> +To create an entity in the media device's topology, just create a folder 
>> under
>> +/configfs/vimc//entities/ with the following format:
>> +
>> +:
>> +
>> +Where  is one of the following:
>> +::
>> +vimc-sensor
>> +vimc-scaler
>> +vimc-debayer
>> +vimc-capture
>> +
>> +Example:
>> +::
>> +$ mkdir /configfs/vimc/mdev/entities

Re: VIVID/VIMC and media fuzzing

2018-12-07 Thread Helen Koike
Hi Dmitry,

On 10/31/18 9:49 AM, Helen Koike wrote:
> Hi Dmitry,
> 
> On 10/31/18 7:46 AM, Hans Verkuil wrote:
>> On 10/30/2018 03:02 PM, Dmitry Vyukov wrote:
>>> Hello Helen and linux-media,
>>>
>>> I've attended your talk "Shifting Media App Development into High
>>> Gear" on OSS Summit last week and approached you with some questions
>>> if/how this can be used for kernel testing. Thanks, turn out to be a
>>> very useful talk!
> 
> Great, I am  glad it was useful :)
> 
>>>
>>> I am working on syzkaller/syzbot, continuous kernel fuzzing system:
>>> https://github.com/google/syzkaller
>>> https://github.com/google/syzkaller/blob/master/docs/syzbot.md
>>> https://syzkaller.appspot.com
>>>
>>> After simply enabling CONFIG_VIDEO_VIMC, CONFIG_VIDEO_VIM2M,
>>> CONFIG_VIDEO_VIVID, CONFIG_VIDEO_VICODEC syzbot has found 8 bugs in
>>> media subsystem in just 24 hours:
>>>
>>> KASAN: use-after-free Read in vb2_mmap
>>> https://groups.google.com/forum/#!msg/syzkaller-bugs/XGGH69jMWQ0/S8vfxgEmCgAJ
>>>
>>> KASAN: use-after-free Write in __vb2_cleanup_fileio
>>> https://groups.google.com/forum/#!msg/syzkaller-bugs/qKKhsZVPo3o/P6AB2of2CQAJ
>>>
>>> WARNING in __vb2_queue_cancel
>>> https://groups.google.com/forum/#!msg/syzkaller-bugs/S29GU_NtfPY/ZvAz8UDtCQAJ
>>>
>>> divide error in vivid_vid_cap_s_dv_timings
>>> https://groups.google.com/forum/#!msg/syzkaller-bugs/GwF5zGBCfyg/wnuWmW_sCQAJ
>>
>> Should be fixed by https://patchwork.linuxtv.org/patch/52641/
>>
>>>
>>> KASAN: use-after-free Read in wake_up_if_idle
>>> https://groups.google.com/forum/#!msg/syzkaller-bugs/aBWb_yV1kiI/sWQO63fkCQAJ
>>>
>>> KASAN: use-after-free Read in __vb2_perform_fileio
>>> https://groups.google.com/forum/#!msg/syzkaller-bugs/MdFCZHz0LUQ/qSK_bFbcCQAJ
>>>
>>> INFO: task hung in vivid_stop_generating_vid_cap
>>> https://groups.google.com/forum/#!msg/syzkaller-bugs/F_KFW6PVyTA/wTBeHLfTCQAJ
>>>
>>> KASAN: null-ptr-deref Write in kthread_stop
>>> https://groups.google.com/forum/#!msg/syzkaller-bugs/u0AGnYvSlf4/fUiyfA_TCQAJ
>>
>> These last two should be fixed by https://patchwork.linuxtv.org/patch/52640/
>>
>> Haven't figured out the others yet (hope to get back to that next week).
>>
>>>
>>> Based on this I think if we put more effort into media fuzzing, it
>>> will be able to find dozens more.
>>
>> Yeah, this is good stuff. Thank you for setting this up.
> 
> Agreed, Dmitry thank you for doing this.
> 
>>
>>>
>>> syzkaller needs descriptions of kernel interfaces to efficiently cover
>>> a subsystem. For example, see:
>>> https://github.com/google/syzkaller/blob/master/sys/linux/uinput.txt
>>> Hopefully you can read it without much explanation, it basically
>>> states that there is that node in /dev and here are ioctls and other
>>> syscalls that are relevant for this device and here are types of
>>> arguments and layout of involved data structures.
>>>
>>> Turned we actually have such descriptions for /dev/video* and 
>>> /dev/v4l-subdev*:
>>> https://github.com/google/syzkaller/blob/master/sys/linux/video4linux.txt
>>> But we don't have anything for /dev/media*, fuzzer merely knows that
>>> it can open the device:
>>> https://github.com/google/syzkaller/blob/12b38f22c18c6109a5cc1c0238d015eef121b9b7/sys/linux/sys.txt#L479
>>> and then it will just blindly execute completely random workload on
>>> it, e.g. most likely it won't be able to come up with a proper complex
>>> structure layout for some ioctls. And I am actually not completely
>>> sure about completeness and coverage of video4linux.txt descriptions
>>> too as they were contributed by somebody interested in android
>>> testing.
>>
>> A quick look suggests that it is based on the 4.9 videodev2.h, which ain't
>> too bad. There are some differences between the 4.20 videodev2.h and the
>> 4.9, but not too many.
>>
>>>
>>> I wonder if somebody knowledgeable in /dev/media interface be willing
>>> to contribute additional descriptions?
>>
>> We'll have to wait for 4.20-rc1 to be released since there are important
>> additions to the media API. I can probably come up with something, I'm
>> just not sure when I get around to it. Ping me in three weeks time if you
>> haven't heard from me.
>>
>>

[PATCH] media: vimc: add configfs API to configure the topology

2018-12-07 Thread Helen Koike
Add API to allow userspace to create any type of topology in vimc using
basic system calls such as mkdir/rmdir/read/write.

Signed-off-by: Helen Koike 

---
Hi,

This patch introduces the configufs API for configuring the topology in
vimc while it removes the hardcoded topology, so now, when you load the
module you need to create a device (no device will appear in your system
by default) using mkdir/rmdir/write/read.
Please see documentation in the patch.
I was thinking in adding a device by default, but if I do it in
configfs, userspace won't be able to delete the device (which might not
be a problem), as I need to create it as a "default" group in configfs,
or I can just not expose the default device in the configfs.
What do you think?

Thanks
Helen

 Documentation/media/v4l-drivers/vimc.rst| 172 +
 drivers/media/platform/vimc/Kconfig |   7 +-
 drivers/media/platform/vimc/Makefile|   7 +-
 drivers/media/platform/vimc/vimc-capture.c  |  46 +-
 drivers/media/platform/vimc/vimc-common.h   |  58 +-
 drivers/media/platform/vimc/vimc-configfs.c | 665 
 drivers/media/platform/vimc/vimc-configfs.h |  30 +
 drivers/media/platform/vimc/vimc-core.c | 283 ++---
 drivers/media/platform/vimc/vimc-core.h |  17 +
 drivers/media/platform/vimc/vimc-debayer.c  |  51 +-
 drivers/media/platform/vimc/vimc-scaler.c   |  49 +-
 drivers/media/platform/vimc/vimc-sensor.c   |  43 +-
 12 files changed, 1153 insertions(+), 275 deletions(-)
 create mode 100644 Documentation/media/v4l-drivers/vimc.rst
 create mode 100644 drivers/media/platform/vimc/vimc-configfs.c
 create mode 100644 drivers/media/platform/vimc/vimc-configfs.h
 create mode 100644 drivers/media/platform/vimc/vimc-core.h

diff --git a/Documentation/media/v4l-drivers/vimc.rst 
b/Documentation/media/v4l-drivers/vimc.rst
new file mode 100644
index ..28d3b02c7d30
--- /dev/null
+++ b/Documentation/media/v4l-drivers/vimc.rst
@@ -0,0 +1,172 @@
+The Virtual Media Controller Driver (vimc)
+=
+
+This driver emulates video4linux hardware of varios media topologies. It 
exposes
+media devices through /dev/mediaX notes, video capture devices through
+/dev/videoX and sub-devices through /dev/v4l-subdevX.
+
+A subdevice can be a sensor, a debayer or a scaler.
+
+To configure a media device of a given topology, a ConfigFS API is provided.
+
+
+Configuring the driver through ConfigFS (Experimental)
+--
+
+.. note::
+This API is not finished yet and might change in the future.
+
+Mount configfs:
+::
+   $ mkdir /configfs
+   $ mount -t configfs none /configfs
+
+When loading the module, you see a folders name vimc
+::
+   $ tree /configfs/
+   /configfs/
+   `-- vimc
+
+1) Creating a media device
+~~
+
+To create a media device just create a new folder under /configfs/vimc/
+
+Example:
+::
+   $ mkdir /configfs/vimc/mdev
+   $ tree /configfs/vimc/mdev
+   /configfs/vimc/mdev/
+   |-- entities/
+   |-- hotplug
+   `-- links/
+
+   2 directories, 1 file
+
+2) Creating entities
+
+
+To create an entity in the media device's topology, just create a folder under
+/configfs/vimc//entities/ with the following format:
+
+   :
+
+Where  is one of the following:
+::
+   vimc-sensor
+   vimc-scaler
+   vimc-debayer
+   vimc-capture
+
+Example:
+::
+   $ mkdir /configfs/vimc/mdev/entities/vimc-sensor:my-sensor
+   $ mkdir /configfs/vimc/mdev/entities/vimc-capture:my-capture
+   $ tree /configfs/
+   /configfs/
+   `-- vimc/
+   `-- mdev/
+   |-- entities/
+   |   |-- vimc-capture:my-capture/
+   |   |   `-- pad:sink:0/
+   |   `-- vimc-sensor:my-sensor/
+   |   `-- pad:source:0/
+   |-- hotplug
+   `-- links/
+
+   8 directories, 1 file
+
+3) Creating links
+~
+
+To create links between two entities in the topology, just create a folder 
under
+/configfs/vimc//links/ with the following format:
+
+   ":"
+
+Example:
+::
+   $ mkdir "/configfs/vimc/mdev/links/my-sensor:0->my-capture:0"
+   $ tree /configfs
+   /configfs/
+   `-- vimc/
+   `-- mdev/
+   |-- entities/
+   |   |-- vimc-capture:my-capture/
+   |   |   `-- pad:sink:0/
+   |   `-- vimc-sensor:my-sensor/
+   |   `-- pad:source:0/
+   |-- hotplug
+   `-- links/
+   `-- my-sensor:0->my-capture:0/
+   `-- flags
+
+   9 directories, 2 files
+
+Change the attributes of the link by writing in the file
+"/configfs/vimc//links//flags"
+
+Flag values are defined in :ref:`include/uapi/linux/media.h `
+( seek for ``MEDIA_LNK_FL_*``)
+
+1 - Ena

[PATCH] media: vimc: fix start stream when link is disabled

2018-12-07 Thread Helen Koike
If link is disabled, media_entity_remote_pad returns NULL, causing a
NULL pointer deference.
Ignore links that are not enabled instead.

Signed-off-by: Helen Koike 

---

 drivers/media/platform/vimc/vimc-common.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/platform/vimc/vimc-common.c 
b/drivers/media/platform/vimc/vimc-common.c
index dee1b9dfc4f6..867e24dbd6b5 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -276,6 +276,8 @@ int vimc_pipeline_s_stream(struct media_entity *ent, int 
enable)
 
/* Start the stream in the subdevice direct connected */
pad = media_entity_remote_pad(&ent->pads[i]);
+   if (!pad)
+   continue;
 
if (!is_media_entity_v4l2_subdev(pad->entity))
return -EINVAL;
-- 
2.19.1



Re: [PATCH 2/2] media: vimc: constify structures stored in fields of v4l2_subdev_ops structure

2018-11-01 Thread Helen Koike
Hi Julia,

Thanks, I had missed that one.

On 10/27/18 10:49 AM, Julia Lawall wrote:
> The fields of a v4l2_subdev_ops structure are all const, so the
> structures that are stored there and are not used elsewhere can be
> const as well.
> 
> Done with the help of Coccinelle.
> 
> Signed-off-by: Julia Lawall 

Acked-by: Helen Koike 

> 
> ---
>  drivers/media/platform/vimc/vimc-sensor.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
> b/drivers/media/platform/vimc/vimc-sensor.c
> index edf4c85ae63d..32ca9c6172b1 100644
> --- a/drivers/media/platform/vimc/vimc-sensor.c
> +++ b/drivers/media/platform/vimc/vimc-sensor.c
> @@ -286,7 +286,7 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int 
> enable)
>   return 0;
>  }
>  
> -static struct v4l2_subdev_core_ops vimc_sen_core_ops = {
> +static const struct v4l2_subdev_core_ops vimc_sen_core_ops = {
>   .log_status = v4l2_ctrl_subdev_log_status,
>   .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
>   .unsubscribe_event = v4l2_event_subdev_unsubscribe,
> 


Re: VIVID/VIMC and media fuzzing

2018-10-31 Thread Helen Koike
Hi Dmitry,

On 10/31/18 7:46 AM, Hans Verkuil wrote:
> On 10/30/2018 03:02 PM, Dmitry Vyukov wrote:
>> Hello Helen and linux-media,
>>
>> I've attended your talk "Shifting Media App Development into High
>> Gear" on OSS Summit last week and approached you with some questions
>> if/how this can be used for kernel testing. Thanks, turn out to be a
>> very useful talk!

Great, I am  glad it was useful :)

>>
>> I am working on syzkaller/syzbot, continuous kernel fuzzing system:
>> https://github.com/google/syzkaller
>> https://github.com/google/syzkaller/blob/master/docs/syzbot.md
>> https://syzkaller.appspot.com
>>
>> After simply enabling CONFIG_VIDEO_VIMC, CONFIG_VIDEO_VIM2M,
>> CONFIG_VIDEO_VIVID, CONFIG_VIDEO_VICODEC syzbot has found 8 bugs in
>> media subsystem in just 24 hours:
>>
>> KASAN: use-after-free Read in vb2_mmap
>> https://groups.google.com/forum/#!msg/syzkaller-bugs/XGGH69jMWQ0/S8vfxgEmCgAJ
>>
>> KASAN: use-after-free Write in __vb2_cleanup_fileio
>> https://groups.google.com/forum/#!msg/syzkaller-bugs/qKKhsZVPo3o/P6AB2of2CQAJ
>>
>> WARNING in __vb2_queue_cancel
>> https://groups.google.com/forum/#!msg/syzkaller-bugs/S29GU_NtfPY/ZvAz8UDtCQAJ
>>
>> divide error in vivid_vid_cap_s_dv_timings
>> https://groups.google.com/forum/#!msg/syzkaller-bugs/GwF5zGBCfyg/wnuWmW_sCQAJ
> 
> Should be fixed by https://patchwork.linuxtv.org/patch/52641/
> 
>>
>> KASAN: use-after-free Read in wake_up_if_idle
>> https://groups.google.com/forum/#!msg/syzkaller-bugs/aBWb_yV1kiI/sWQO63fkCQAJ
>>
>> KASAN: use-after-free Read in __vb2_perform_fileio
>> https://groups.google.com/forum/#!msg/syzkaller-bugs/MdFCZHz0LUQ/qSK_bFbcCQAJ
>>
>> INFO: task hung in vivid_stop_generating_vid_cap
>> https://groups.google.com/forum/#!msg/syzkaller-bugs/F_KFW6PVyTA/wTBeHLfTCQAJ
>>
>> KASAN: null-ptr-deref Write in kthread_stop
>> https://groups.google.com/forum/#!msg/syzkaller-bugs/u0AGnYvSlf4/fUiyfA_TCQAJ
> 
> These last two should be fixed by https://patchwork.linuxtv.org/patch/52640/
> 
> Haven't figured out the others yet (hope to get back to that next week).
> 
>>
>> Based on this I think if we put more effort into media fuzzing, it
>> will be able to find dozens more.
> 
> Yeah, this is good stuff. Thank you for setting this up.

Agreed, Dmitry thank you for doing this.

> 
>>
>> syzkaller needs descriptions of kernel interfaces to efficiently cover
>> a subsystem. For example, see:
>> https://github.com/google/syzkaller/blob/master/sys/linux/uinput.txt
>> Hopefully you can read it without much explanation, it basically
>> states that there is that node in /dev and here are ioctls and other
>> syscalls that are relevant for this device and here are types of
>> arguments and layout of involved data structures.
>>
>> Turned we actually have such descriptions for /dev/video* and 
>> /dev/v4l-subdev*:
>> https://github.com/google/syzkaller/blob/master/sys/linux/video4linux.txt
>> But we don't have anything for /dev/media*, fuzzer merely knows that
>> it can open the device:
>> https://github.com/google/syzkaller/blob/12b38f22c18c6109a5cc1c0238d015eef121b9b7/sys/linux/sys.txt#L479
>> and then it will just blindly execute completely random workload on
>> it, e.g. most likely it won't be able to come up with a proper complex
>> structure layout for some ioctls. And I am actually not completely
>> sure about completeness and coverage of video4linux.txt descriptions
>> too as they were contributed by somebody interested in android
>> testing.
> 
> A quick look suggests that it is based on the 4.9 videodev2.h, which ain't
> too bad. There are some differences between the 4.20 videodev2.h and the
> 4.9, but not too many.
> 
>>
>> I wonder if somebody knowledgeable in /dev/media interface be willing
>> to contribute additional descriptions?
> 
> We'll have to wait for 4.20-rc1 to be released since there are important
> additions to the media API. I can probably come up with something, I'm
> just not sure when I get around to it. Ping me in three weeks time if you
> haven't heard from me.
> 
>>
>> We also have code coverage reports with the coverage fuzzer achieved
>> so far. Here in the Cover column:
>> https://syzkaller.appspot.com/#managers
>> e.g. this one (but note this is a ~80MB html file):
>> https://storage.googleapis.com/syzkaller/cover/ci-upstream-kasan-gce-root.html
>> This can be used to assess e.g. v4l coverage. But I don't know what's
>> coverable in general from syscalls and what's coverable via the stub
>> drivers in particular. So some expertise from media developers would
>> be helpful too.
> 
> The four virtual drivers should give pretty decent coverage of the core
> code. Are you able to test with a 32-bit syzkaller application on a 64-bit
> kernel as well? That way the compat32 code is tested.
> 
>>
>> Do I understand it correctly that when a process opens /dev/video* or
>> /dev/media* it gets a private instance of the device? In particular,
>> if several processes test this in parallel, will they collide? Or they
>> 

Re: [PATCH] media: vivid: Improve timestamping

2018-10-09 Thread Helen Koike
Hi Gabriel,

Thanks for your patch.

On 10/9/18 9:49 PM, Gabriel Francisco Mandaji wrote:
> Simulate a more precise timestamp by calculating it based on the
> current framerate.
> 
> Signed-off-by: Gabriel Francisco Mandaji 
> ---
>  drivers/media/platform/vivid/vivid-core.h|  1 +
>  drivers/media/platform/vivid/vivid-kthread-cap.c | 24 
> 
>  2 files changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/platform/vivid/vivid-core.h 
> b/drivers/media/platform/vivid/vivid-core.h
> index cd4c823..cbdadd8 100644
> --- a/drivers/media/platform/vivid/vivid-core.h
> +++ b/drivers/media/platform/vivid/vivid-core.h
> @@ -384,6 +384,7 @@ struct vivid_dev {
>   /* thread for generating video capture stream */
>   struct task_struct  *kthread_vid_cap;
>   unsigned long   jiffies_vid_cap;
> + u64 cap_stream_start;
>   u32 cap_seq_offset;
>   u32 cap_seq_count;
>   boolcap_seq_resync;
> diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c 
> b/drivers/media/platform/vivid/vivid-kthread-cap.c
> index f06003b..0793b15 100644
> --- a/drivers/media/platform/vivid/vivid-kthread-cap.c
> +++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
> @@ -416,6 +416,7 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct 
> vivid_buffer *buf)
>   char str[100];
>   s32 gain;
>   bool is_loop = false;
> + u64 soe_time = 0;
>  
>   if (dev->loop_video && dev->can_loop_video &&
>   ((vivid_is_svid_cap(dev) &&
> @@ -426,11 +427,11 @@ static void vivid_fillbuff(struct vivid_dev *dev, 
> struct vivid_buffer *buf)
>  
>   buf->vb.sequence = dev->vid_cap_seq_count;
>   /*
> -  * Take the timestamp now if the timestamp source is set to
> -  * "Start of Exposure".
> +  * Store the current time to calculate the delta if source is set to
> +  * "End of Frame".
>*/
> - if (dev->tstamp_src_is_soe)
> - buf->vb.vb2_buf.timestamp = ktime_get_ns();
> + if (!dev->tstamp_src_is_soe)
> + soe_time = ktime_get_ns();
>   if (dev->field_cap == V4L2_FIELD_ALTERNATE) {
>   /*
>* 60 Hz standards start with the bottom field, 50 Hz standards
> @@ -556,12 +557,18 @@ static void vivid_fillbuff(struct vivid_dev *dev, 
> struct vivid_buffer *buf)
>   }
>  
>   /*
> -  * If "End of Frame" is specified at the timestamp source, then take
> -  * the timestamp now.
> +  * If "End of Frame", then calculate the "exposition time" and add
> +  * it to the timestamp.
>*/
>   if (!dev->tstamp_src_is_soe)
> - buf->vb.vb2_buf.timestamp = ktime_get_ns();
> - buf->vb.vb2_buf.timestamp += dev->time_wrap_offset;
> + soe_time = ktime_get_ns() - soe_time;

If I understand correctly, soe_time here is the elapsed time (the delta
between the beginning of the frame and the end of it), so I thing naming
it etime or frame_time or delta_time would be clearer, because soe
stands for "start of exposure" and doesn't seem to be the right meaning.

> + buf->vb.vb2_buf.timestamp = dev->timeperframe_vid_cap.numerator *
> + 10 /
> + dev->timeperframe_vid_cap.denominator *
> + dev->vid_cap_seq_count +
> + dev->cap_stream_start +
> + soe_time +
> + dev->time_wrap_offset;

Could you move the dev->vid_cap_seq_count to the top? I got confused if
it was multiplying only the denominator, I think moving to the top makes
it clearer (or add parenthesis).

>  }
>  
>  /*
> @@ -759,6 +766,7 @@ static int vivid_thread_vid_cap(void *data)
>   dev->cap_seq_count = 0;
>   dev->cap_seq_resync = false;
>   dev->jiffies_vid_cap = jiffies;
> + dev->cap_stream_start = ktime_get_ns();
>  
>   for (;;) {
>   try_to_freeze();
> 

Thanks
Helen


Re: [PATCH vicodec] media: pvrusb2: replace `printk` with `pr_*`

2018-10-07 Thread Helen Koike
Hi Dafna,

Thanks for you patch.

On 10/6/18 4:21 PM, Dafna Hirschfeld wrote:
> Replace calls to `printk` with the appropriate `pr_*`
> macro.
> 
> Signed-off-by: Dafna Hirschfeld 
> ---
>  drivers/media/usb/pvrusb2/pvrusb2-hdw.c  |  8 
>  drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c | 14 ++
>  drivers/media/usb/pvrusb2/pvrusb2-main.c |  4 ++--
>  drivers/media/usb/pvrusb2/pvrusb2-v4l2.c |  4 ++--

Could you also update drivers/media/usb/pvrusb2/pvrusb2-debug.h please?
So we can get rid of all the printk in this driver.

>  4 files changed, 14 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c 
> b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
> index a8519da0020b..7702285c1519 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
> @@ -3293,12 +3293,12 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
>   int nr = pvr2_hdw_get_unit_number(hdw);
>   LOCK_TAKE(hdw->big_lock);
>   do {
> - printk(KERN_INFO "pvrusb2: =  START STATUS CARD 
> #%d  =\n", nr);
> + pr_info("pvrusb2: =  START STATUS CARD #%d  
> =\n", nr);
>   v4l2_device_call_all(&hdw->v4l2_dev, 0, core, log_status);
>   pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
>   cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
>   pvr2_hdw_state_log_state(hdw);
> - printk(KERN_INFO "pvrusb2: ==  END STATUS CARD 
> #%d  ==\n", nr);
> + pr_info("pvrusb2: ==  END STATUS CARD #%d  
> ==\n", nr);
>   } while (0);
>   LOCK_GIVE(hdw->big_lock);
>  }
> @@ -4851,7 +4851,7 @@ static void pvr2_hdw_state_log_state(struct pvr2_hdw 
> *hdw)
>   for (idx = 0; ; idx++) {
>   ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf));
>   if (!ccnt) break;
> - printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf);
> + pr_info("%s %.*s\n", hdw->name, ccnt, buf);
>   }
>   ccnt = pvr2_hdw_report_clients(hdw, buf, sizeof(buf));
>   if (ccnt >= sizeof(buf))
> @@ -4863,7 +4863,7 @@ static void pvr2_hdw_state_log_state(struct pvr2_hdw 
> *hdw)
>   while ((lcnt + ucnt < ccnt) && (buf[lcnt + ucnt] != '\n')) {
>   lcnt++;
>   }
> - printk(KERN_INFO "%s %.*s\n", hdw->name, lcnt, buf + ucnt);
> + pr_info("%s %.*s\n", hdw->name, lcnt, buf + ucnt);
>   ucnt += lcnt + 1;
>   }
>  }> diff --git a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
> index ec7d32759e39..06c7e875fa0f 100644
> --- a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
> +++ b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
> @@ -478,8 +478,7 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
>   unsigned int idx,offs,cnt;
>   for (idx = 0; idx < num; idx++) {
>   cnt = msgs[idx].len;
> - printk(KERN_INFO
> -"pvrusb2 i2c xfer %u/%u: addr=0x%x len=%d %s",
> + pr_info("pvrusb2 i2c xfer %u/%u: addr=0x%x len=%d %s",
>  idx+1,num,
>  msgs[idx].addr,
>  cnt,
> @@ -501,8 +500,7 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
>   printk(KERN_CONT "\n");
>   }
>   if (!num) {
> - printk(KERN_INFO
> -"pvrusb2 i2c xfer null transfer result=%d\n",
> + pr_info("pvrusb2 i2c xfer null transfer result=%d\n",
>  ret);
>   }
>   }
> @@ -542,14 +540,14 @@ static int do_i2c_probe(struct pvr2_hdw *hdw, int addr)
>  static void do_i2c_scan(struct pvr2_hdw *hdw)
>  {
>   int i;
> - printk(KERN_INFO "%s: i2c scan beginning\n", hdw->name);
> + pr_info("%s: i2c scan beginning\n", hdw->name);
>   for (i = 0; i < 128; i++) {
>   if (do_i2c_probe(hdw, i)) {
> - printk(KERN_INFO "%s: i2c scan: found device @ 0x%x\n",
> + pr_info("%s: i2c scan: found device @ 0x%x\n",
>  hdw->name, i);
>   }
>   }
> - printk(KERN_INFO "%s: i2c scan done.\n", hdw->name);
> + pr_info("%s: i2c scan done.\n", hdw->name);
>  }
>  
>  static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
> @@ -612,7 +610,7 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
>  
>   /* However, deal with various special cases for 24xxx hardware. */
>   if (ir_mode[hdw->unit_number] == 0) {
> - printk(KERN_INFO "%s: IR disabled\n",hdw->name);
> + pr_info("%s: IR disabled\n", hdw->name);
>   hdw->i2c_func[0x18] = i2c_black_hole;
> 

Re: [ANN] Draft Agenda for the media summit on Thursday Oct 25th in Edinburgh

2018-09-26 Thread Helen Koike
Hi Hans and Mauro,


On 9/24/18 11:42 AM, Hans Verkuil wrote:
> Hi all,
> 
> We are organizing a media mini-summit on Thursday October 25th in
> Edinburgh, Edinburgh International Conference Centre.
> 
> If you plan to attend, please let Mauro know. It is open for all, but
> we have a limited number of seats.

I believe I also I selected attendance when registering for the
conference. Please add my name too.

> 
> Name of the room for the summit: TBD
> 
> Currently known attendees (please add/remove names as needed):
> 
> Sakari Ailus 
> Mauro Carvalho Chehab 
> Ezequiel Garcia 
> Michael Ira Krufky 
> Laurent Pinchart 
> Ricardo Ribalda Delgado 
> Hans Verkuil 
> Sean Young 
> 
> Agenda (First draft!)
> =
> 
> General remarks: the given start/end times for the various topics are
> approximate since it is always hard to predict how long a discussion will 
> take.
> If people are attending other summits and those conflict with specific media
> topics they want to be part of, then let me know and we can rearrange the
> schedule to (hopefully) accommodate that.
> 
> 9:00-9:15: Introduction (Hans Verkuil)
> 
> 9:15-9:30: Status of the HDMI CEC kernel support (Hans Verkuil)
>   Give a quick overview of the status: what has been merged, what is
>   still pending, what is under development.
> 
> 9:30-9:45: Save/restore controls from MTD (Ricardo Ribalda Delgado)
>   Industrial/Scientific sensors usually come with very extensive
>   calibration information such as: per column gain, list of dead
>   pixels, temperature sensor offset... etc
> 
>   We are saving that information on an flash device that is located
>   by the sensor.
> 
>   Show how we are integrating that calibration flash with v4l2-ctrl.
>   And if this feature is useful for someone else and upstream it.
> 
> 9:45-11:00: Complex Cameras (Mauro Carvalho Chehab)
>   I expect that we could have something to discuss there about complex
>   cameras. So, I'd reserve a 50 mins slot for it.
> 
>   The idea is to discuss about the undergoing work with complex camera
>   development is happening.
> 
>   As we're working to merge request API, another topic for discussion
>   is how to add support for requests on it (or on a separate but related
>   library).
> 
> 11:00-11:15: Break
> 
> 11:15-12:00: Automated Testing (Ezequiel Garcia)
>   There is a lot of discussion going on around testing,
>   so it's a good opportunity for us to talk about our
>   current testing infrastructure.
> 
>   We are already doing a good job with v4l2-compliance.
>   Can we do more?
> 
> Lunch
> 
> 13:30-14:30: Stateless Codec userspace (Hans Verkuil)
>   Support for stateless codecs and Request API should be merged for
>   4.20, and the next step is to discuss how to organize the userspace
>   support.
> 
>   Hopefully by the time the media summit starts we'll have some better
>   ideas of what we want in this area.
> 
> 14:30-15:15: Which ioctls should be replaced with better versions? (Hans 
> Verkuil)
>   Some parts of the V4L2 API are awkward to use and I think it would be
>   a good idea to look at possible candidates for that.
> 
>   Examples are the ioctls that use struct v4l2_buffer: the multiplanar 
> support is
>   really horrible, and writing code to support both single and 
> multiplanar is hard.
>   We are also running out of fields and the timeval isn't y2038 compliant.
> 
>   A proof-of-concept is here:
> 
>   
> https://git.linuxtv.org/hverkuil/media_tree.git/commit/?h=v4l2-buffer&id=a95549df06d9900f3559afdbb9da06bd4b22d1f3
> 
>   It's a bit old, but it gives a good impression of what I have in mind.
> 
>   Another candidate is 
> VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL/VIDIOC_ENUM_FRAMEINTERVALS:
>   expressing frame intervals as a fraction is really awkward and so is 
> the fact
>   that the subdev and 'normal' ioctls are not the same.
> 
>   Discuss what possible other ioctls are candidates for a refresh.
> 
> 15:15-15:30: Break
> 
> 15:30-16:00: Discuss the media development process
>   Since we are all here, discuss any issues there may be with the media
>   subsystem development process. Anything to improve?
> 
> 16:00-16:15: Wrap up
>   Create action items (and who will take care of them) if needed.
>   Summarize and conclude the day.
> 
> End of the day: Key Signing Party
> 
> Regards,
> 
>   Hans
> 

Thanks
Helen


Re: Question regarding optimizing pipeline in Vimc

2018-08-29 Thread Helen Koike



On 8/22/18 3:49 AM, Hans Verkuil wrote:
> On 08/22/2018 05:35 AM, Helen Koike wrote:
>> Hello,
>>
>> One of the discussions we had when developing Vimc, was regarding
>> optimizing image generation.
>> The ideia was to generate the images directly in the capture instead
>> of propagating through the pipeline (to make things faster).
>> But my question is: if this optimization is on, and if there is a
>> greyscaler filter in the middle of the pipeline, do you expect to see
>> a grey image with this optimization?
> 
> Yes.
> 
>> Or if we just generate a dummy
>> image (with the right size format) at the end of the pipeline, would
>> it be ok? (I am asking because it doesn't sound that simple to
>> propagate the image transformation made by each entity in the pipe)
> 
> No, that would not be OK.
> 
> My basic idea was that you use a TPG state structure that contains the
> desired output: the sensor starts with e.g. 720p using some bayer pixelformat,
> the debayer module replaces the pixelformat with e.g. PIX_FMT_RGB32, a
> grayscale filter replaces it with PI_FMT_GREY, and that's what the TPG for the
> video device eventually will use to generate the video.
> 
> This assumes of course that all the vimc blocks only do operations that can
> be handled by the TPG. Depending on what the blocks will do the TPG might need
> to be extended if a feature is missing.
> 
> Regards,
> 
>   Hans
> 
>> Or do you have any other thing in mind?
>>
>> Thanks
>> Helen
>>
> 

Thanks Hans,

We'll be working on that soon.

Helen


Question regarding optimizing pipeline in Vimc

2018-08-21 Thread Helen Koike
Hello,

One of the discussions we had when developing Vimc, was regarding
optimizing image generation.
The ideia was to generate the images directly in the capture instead
of propagating through the pipeline (to make things faster).
But my question is: if this optimization is on, and if there is a
greyscaler filter in the middle of the pipeline, do you expect to see
a grey image with this optimization? Or if we just generate a dummy
image (with the right size format) at the end of the pipeline, would
it be ok? (I am asking because it doesn't sound that simple to
propagate the image transformation made by each entity in the pipe)
Or do you have any other thing in mind?

Thanks
Helen


Re: [PATCH] vimc: use correct subdev functions

2018-03-01 Thread Helen Koike

Hi Hans,

On 02/07/2018 03:06 PM, Hans Verkuil wrote:

Instead of calling everything a MEDIA_ENT_F_ATV_DECODER, pick the
correct functions for these blocks.


Nice, thanks for the patch



Signed-off-by: Hans Verkuil 



Acked-by: Helen Koike 


---
diff --git a/drivers/media/platform/vimc/vimc-debayer.c 
b/drivers/media/platform/vimc/vimc-debayer.c
index 4d663e89d33f..6e10b63ba9ec 100644
--- a/drivers/media/platform/vimc/vimc-debayer.c
+++ b/drivers/media/platform/vimc/vimc-debayer.c
@@ -533,7 +533,7 @@ static int vimc_deb_comp_bind(struct device *comp, struct 
device *master,
/* Initialize ved and sd */
ret = vimc_ent_sd_register(&vdeb->ved, &vdeb->sd, v4l2_dev,
   pdata->entity_name,
-  MEDIA_ENT_F_ATV_DECODER, 2,
+  MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,
   (const unsigned long[2]) {MEDIA_PAD_FL_SINK,
   MEDIA_PAD_FL_SOURCE},
   &vimc_deb_ops);
diff --git a/drivers/media/platform/vimc/vimc-scaler.c 
b/drivers/media/platform/vimc/vimc-scaler.c
index e1602e0bc230..e583ec7a91da 100644
--- a/drivers/media/platform/vimc/vimc-scaler.c
+++ b/drivers/media/platform/vimc/vimc-scaler.c
@@ -395,7 +395,7 @@ static int vimc_sca_comp_bind(struct device *comp, struct 
device *master,
/* Initialize ved and sd */
ret = vimc_ent_sd_register(&vsca->ved, &vsca->sd, v4l2_dev,
   pdata->entity_name,
-  MEDIA_ENT_F_ATV_DECODER, 2,
+  MEDIA_ENT_F_PROC_VIDEO_SCALER, 2,
   (const unsigned long[2]) {MEDIA_PAD_FL_SINK,
   MEDIA_PAD_FL_SOURCE},
   &vimc_sca_ops);
diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
b/drivers/media/platform/vimc/vimc-sensor.c
index 457e211514c6..7d9fa9ccdb0e 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -378,7 +378,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct 
device *master,
/* Initialize ved and sd */
ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
   pdata->entity_name,
-  MEDIA_ENT_F_ATV_DECODER, 1,
+  MEDIA_ENT_F_CAM_SENSOR, 1,
   (const unsigned long[1]) 
{MEDIA_PAD_FL_SOURCE},
   &vimc_sen_ops);
if (ret)



Re: [PATCH] v4l2-subdev: without controls return -ENOTTY

2018-03-01 Thread Helen Koike

Hi Hans

On 02/02/2018 11:05 AM, Hans Verkuil wrote:

If the subdev did not define any controls, then return -ENOTTY if
userspace attempts to call these ioctls.

The control framework functions will return -EINVAL, not -ENOTTY if
vfh->ctrl_handler is NULL.

Several of these framework functions are also called directly from
drivers, so I don't want to change the error code there.


Right, I see, thanks for the patch



Found with vimc and v4l2-compliance.

Signed-off-by: Hans Verkuil 


Acked-by: Helen Koike 


---
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c 
b/drivers/media/v4l2-core/v4l2-subdev.c
index 43fefa73e0a3..be7a19272614 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -187,27 +187,43 @@ static long subdev_do_ioctl(struct file *file, unsigned 
int cmd, void *arg)

switch (cmd) {
case VIDIOC_QUERYCTRL:
+   if (!vfh->ctrl_handler)
+   return -ENOTTY;
return v4l2_queryctrl(vfh->ctrl_handler, arg);

case VIDIOC_QUERY_EXT_CTRL:
+   if (!vfh->ctrl_handler)
+   return -ENOTTY;
return v4l2_query_ext_ctrl(vfh->ctrl_handler, arg);

case VIDIOC_QUERYMENU:
+   if (!vfh->ctrl_handler)
+   return -ENOTTY;
return v4l2_querymenu(vfh->ctrl_handler, arg);

case VIDIOC_G_CTRL:
+   if (!vfh->ctrl_handler)
+   return -ENOTTY;
return v4l2_g_ctrl(vfh->ctrl_handler, arg);

case VIDIOC_S_CTRL:
+   if (!vfh->ctrl_handler)
+   return -ENOTTY;
return v4l2_s_ctrl(vfh, vfh->ctrl_handler, arg);

case VIDIOC_G_EXT_CTRLS:
+   if (!vfh->ctrl_handler)
+   return -ENOTTY;
return v4l2_g_ext_ctrls(vfh->ctrl_handler, arg);

case VIDIOC_S_EXT_CTRLS:
+   if (!vfh->ctrl_handler)
+   return -ENOTTY;
return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, arg);

case VIDIOC_TRY_EXT_CTRLS:
+   if (!vfh->ctrl_handler)
+   return -ENOTTY;
return v4l2_try_ext_ctrls(vfh->ctrl_handler, arg);

case VIDIOC_DQEVENT:



Re: [PATCH] vimc: fix control event handling

2018-03-01 Thread Helen Koike

Hi Hans,

Thanks for the patch

On 02/02/2018 11:00 AM, Hans Verkuil wrote:

The sensor subdev didn't handle control events. Add support for this.
Found with v4l2-compliance.

Signed-off-by: Hans Verkuil 


Acked-by: Helen Koike 


---
diff --git a/drivers/media/platform/vimc/vimc-common.c 
b/drivers/media/platform/vimc/vimc-common.c
index 9d63c84a9876..617415c224fe 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -434,7 +434,9 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
v4l2_set_subdevdata(sd, ved);

/* Expose this subdev to user space */
-   sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
+   sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+   if (sd->ctrl_handler)
+   sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS;

/* Initialize the media entity */
ret = media_entity_pads_init(&sd->entity, num_pads, ved->pads);
diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
b/drivers/media/platform/vimc/vimc-sensor.c
index 457e211514c6..54184cd9e0ff 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -23,6 +23,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 

@@ -284,11 +285,18 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int 
enable)
return 0;
  }

+static struct v4l2_subdev_core_ops vimc_sen_core_ops = {
+   .log_status = v4l2_ctrl_subdev_log_status,
+   .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+   .unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
  static const struct v4l2_subdev_video_ops vimc_sen_video_ops = {
.s_stream = vimc_sen_s_stream,
  };

  static const struct v4l2_subdev_ops vimc_sen_ops = {
+   .core = &vimc_sen_core_ops,
.pad = &vimc_sen_pad_ops,
.video = &vimc_sen_video_ops,
  };



Re: [PATCH] vimc: add test_pattern and h/vflip controls to the sensor

2017-11-06 Thread Helen Koike
Hi Hans,

On 2017-11-06 08:19 AM, Hans Verkuil wrote:
> Hi Helen,
> 
> On 09/27/2017 08:30 PM, Helen Koike wrote:
>> Hi Hans,
>>
>> Thanks for your patch and sorry for my late reply.
> 
> Sorry for my late reply to your reply :-)
> 
>> Please see my comments and questions below
>>
>> On 2017-07-28 07:23 AM, Hans Verkuil wrote:
>>> Add support for the test_pattern control and the h/vflip controls.
>>>
>>> This makes it possible to switch to more interesting test patterns and to
>>> test control handling in v4l-subdevs.
>>>
>>> There are more tpg-related controls that can be added, but this is a good
>>> start.
>>>
>>> Signed-off-by: Hans Verkuil 
>>> ---
>>> diff --git a/drivers/media/platform/vimc/vimc-common.h 
>>> b/drivers/media/platform/vimc/vimc-common.h
>>> index dca528a316e7..2e9981b18166 100644
>>> --- a/drivers/media/platform/vimc/vimc-common.h
>>> +++ b/drivers/media/platform/vimc/vimc-common.h
>>> @@ -22,6 +22,11 @@
>>>  #include 
>>>  #include 
>>>
>>> +/* VIMC-specific controls */
>>> +#define VIMC_CID_VIMC_BASE (0x00f0 | 0xf000)
>>> +#define VIMC_CID_VIMC_CLASS(0x00f0 | 1)
>>
>> Why this values, shouldn't we use a derivative from
>> V4L2_CID_PRIVATE_BASE for custom controls? Or can we use random values?
> 
> The values are taken from vivid which uses the same scheme. These controls
> deal with how the virtual driver emulates things, and I prefer not to make
> these control IDs part of the public API so we can be a bit more flexible in
> the future. It's a design choice which worked well for vivid.
> 
>>
>>> +#define VIMC_CID_TEST_PATTERN  (VIMC_CID_VIMC_BASE + 0)
>>> +
>>>  #define VIMC_FRAME_MAX_WIDTH 4096
>>>  #define VIMC_FRAME_MAX_HEIGHT 2160
>>>  #define VIMC_FRAME_MIN_WIDTH 16
>>> diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
>>> b/drivers/media/platform/vimc/vimc-sensor.c
>>> index 615c2b18dcfc..532097566b27 100644
>>> --- a/drivers/media/platform/vimc/vimc-sensor.c
>>> +++ b/drivers/media/platform/vimc/vimc-sensor.c
>>> @@ -22,6 +22,7 @@
>>>  #include 
>>>  #include 
>>>  #include 
>>> +#include 
>>>  #include 
>>>  #include 
>>>
>>> @@ -38,6 +39,7 @@ struct vimc_sen_device {
>>> u8 *frame;
>>> /* The active format */
>>> struct v4l2_mbus_framefmt mbus_format;
>>> +   struct v4l2_ctrl_handler hdl;
>>>  };
>>>
>>>  static const struct v4l2_mbus_framefmt fmt_default = {
>>> @@ -291,6 +293,31 @@ static const struct v4l2_subdev_ops vimc_sen_ops = {
>>> .video = &vimc_sen_video_ops,
>>>  };
>>>
>>> +static int vimc_sen_s_ctrl(struct v4l2_ctrl *ctrl)
>>> +{
>>> +   struct vimc_sen_device *vsen =
>>> +   container_of(ctrl->handler, struct vimc_sen_device, hdl);
>>> +
>>> +   switch (ctrl->id) {
>>> +   case VIMC_CID_TEST_PATTERN:
>>> +   tpg_s_pattern(&vsen->tpg, ctrl->val);
>>> +   break;
>>> +   case V4L2_CID_HFLIP:
>>> +   tpg_s_hflip(&vsen->tpg, ctrl->val);
>>> +   break;
>>> +   case V4L2_CID_VFLIP:
>>> +   tpg_s_vflip(&vsen->tpg, ctrl->val);
>>> +   break;
>>> +   default:
>>> +   return -EINVAL;
>>> +   }
>>> +   return 0;
>>> +}
>>> +
>>> +static const struct v4l2_ctrl_ops vimc_sen_ctrl_ops = {
>>> +   .s_ctrl = vimc_sen_s_ctrl,
>>> +};
>>> +
>>>  static void vimc_sen_comp_unbind(struct device *comp, struct device 
>>> *master,
>>>  void *master_data)
>>>  {
>>> @@ -299,10 +326,29 @@ static void vimc_sen_comp_unbind(struct device *comp, 
>>> struct device *master,
>>> container_of(ved, struct vimc_sen_device, ved);
>>>
>>> vimc_ent_sd_unregister(ved, &vsen->sd);
>>> +   v4l2_ctrl_handler_free(&vsen->hdl);
>>> tpg_free(&vsen->tpg);
>>> kfree(vsen);
>>>  }
>>>
>>> +/* Image Processing Controls */
>>> +static const struct v4l2_ctrl_config vimc_sen_ctrl_class = {
>>> +   .ops = &vimc_sen_ctrl_ops,
>>> +   .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
>>
>&

Re: [PATCH] [media] vimc: Fix return value check in vimc_add_subdevs()

2017-10-11 Thread Helen Koike
Hello,


On 2017-10-11 08:16 AM, Wei Yongjun wrote:
> In case of error, the function platform_device_register_data() returns
> ERR_PTR() and never returns NULL. The NULL test in the return value check
> should be replaced with IS_ERR().
> 
> Signed-off-by: Wei Yongjun 
> ---
>  drivers/media/platform/vimc/vimc-core.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/vimc/vimc-core.c 
> b/drivers/media/platform/vimc/vimc-core.c
> index 51c0eee..fe088a9 100644
> --- a/drivers/media/platform/vimc/vimc-core.c
> +++ b/drivers/media/platform/vimc/vimc-core.c
> @@ -267,11 +267,12 @@ static struct component_match *vimc_add_subdevs(struct 
> vimc_device *vimc)
>   PLATFORM_DEVID_AUTO,
>   &pdata,
>   sizeof(pdata));
> - if (!vimc->subdevs[i]) {
> + if (IS_ERR(vimc->subdevs[i])) {
> + match = ERR_CAST(vimc->subdevs[i]);
>   while (--i >= 0)
>   platform_device_unregister(vimc->subdevs[i]);
>  
> - return ERR_PTR(-ENOMEM);
> + return match;
>   }
>  
>   component_match_add(&vimc->pdev.dev, &match, vimc_comp_compare,
> 
> 
> 

Nice catch, thanks, looks good to me

Acked-by: Helen Koike 


Re: [media] vimc: API proposal, configuring the topology from user space

2017-09-27 Thread Helen Koike
Hi Hans,

Thanks for your review.

On 2017-07-28 10:39 AM, Hans Verkuil wrote:
> Hi Helen,
> 
> Finally after way too long I found some time to review this. See my comments
> below.
> 
> On 04/11/2017 12:53 AM, Helen Koike wrote:
>>
>> Hi,
>>
>> Continuing the discussion about the API of the vimc driver, I made some 
>> changes
>> based on the previous comments, please see below and let me know your 
>> opinion about it.
>>
>> Helen
>>
>> /***
>> Configfs considerations:
>> /
>> Informal definitions:
>>  subsystem: the root driver folder in user space (/configfs/vimc)
>>  item: aka a folder in user space
>>  attributes: aka files in the folder
>>  group: aka a folder that can contain subfolders (parent and child 
>> relation)
>>  default group: aka a subfolder that is created automatically when the 
>> "parent" folder is created
>>  it is not considered a child in terms of rmdir
>>
>> * Performing rmdir in a group will fail if it contain children that are 
>> not default groups, i.e, if the
>> folder contain subfolders that are default group, then it can be removed 
>> with rmdir, if the
>> subfolders were created with mkdir, then rmdir in the parent will fail.
>>
>> * Configfs has the notion of committable item but it is not implemented 
>> yet. A committable item is an item
>> that can be in one of two parent folders called: live and pending. The 
>> idea is to create and modify the item
>> in the pending directory and then to move the item through a rename to 
>> the live directory where
>> it can't be modified. This seems to be a nice feature for vimc, but as 
>> it is not available yet the
>> proposal below won't be based on this.
>>
>> * Groups can be dynamically created/destroyed by the driver whenever it 
>> wants. Afaik attributes can only
>> be created when the group or item is created and symlinks can only be 
>> create from user space, i.e, the
>> driver don't know how to create/destroy attributes or symlinks in anytime.
>>
>> /***
>> The API:
>> /
>>
>> In short, a topology like this one: http://goo.gl/Y7eUfu
>> Would look like this filesystem tree: https://goo.gl/mEOmOf
> 
> This mentions 'Yellow' lines, but since you dropped symlinks these no
> longer exist. You probably need to update the legend.
> 

Yes, thanks for noticing, I'll update when including it in the docs of
the API.

>>
>> v3 core changes:
>> - I removed the use of symlinks as I wans't able to see how to do it nicely.
>> - I use the names of the folders created by user space to retrieve 
>> information at mkdir time
>> - hotplug file in each entity
>> - hotplug file in each device
>> - reset file in each device
>>
>> * The /configfs/vimc subsystem
>> empty when the driver is loaded
> 
> I'm not sure about that. I think it would make sense that vimc when loaded
> would make one instance, unless otherwise told via a module option.

I don't think it really matters, the instance would be in unplugged
state anyway and it would need to be configured, but sure, we can add a
n_devs param as you proposed, no problem.

> 
> Something like this (taken from vivid):
> 
> parm:   n_devs: number of driver instances to create (uint)
> 
> By default this is 1, but can also be 0, 2, 3, etc.
> 
>>
>> * Create a device
>> Userspace can create a new vimc device with:
>>
>>  $ mkdir /configfs/vimc/any_name
>>  Example:
>>  $ mkdir /configfs/vimc/vimc0
>>  $ ls -l /configfs/vimc/vimc0
>>  hotplug
>>  reset
>>  entities/
>>  links/
>>
>> entities/ and links/ folder are default groups, thus they don't prevent 
>> rmdir vimc0/, but
>> rmdir will fail if it has any child inside entities/ or links/.
>> hotplug is used to plug and unplug the device, it can read "plugged" or 
>> "unplugged" and user can
>> write "plug" or "unplug" to change its state.
> 
> I would also support writing "plugged" and "unplugged". I.e. support both 
> variants.
> 

So it matches the values that you can read from the file, thanks for
this suggestion.

>> Changing hotplug state will never fail as the configfs tree will always 
>> be in a valid state.
>> reset is used to easily destroy all the topology without the need to 
>> wal

Re: [PATCH] vimc: add test_pattern and h/vflip controls to the sensor

2017-09-27 Thread Helen Koike
Hi Hans,

Thanks for your patch and sorry for my late reply.
Please see my comments and questions below

On 2017-07-28 07:23 AM, Hans Verkuil wrote:
> Add support for the test_pattern control and the h/vflip controls.
> 
> This makes it possible to switch to more interesting test patterns and to
> test control handling in v4l-subdevs.
> 
> There are more tpg-related controls that can be added, but this is a good
> start.
> 
> Signed-off-by: Hans Verkuil 
> ---
> diff --git a/drivers/media/platform/vimc/vimc-common.h 
> b/drivers/media/platform/vimc/vimc-common.h
> index dca528a316e7..2e9981b18166 100644
> --- a/drivers/media/platform/vimc/vimc-common.h
> +++ b/drivers/media/platform/vimc/vimc-common.h
> @@ -22,6 +22,11 @@
>  #include 
>  #include 
> 
> +/* VIMC-specific controls */
> +#define VIMC_CID_VIMC_BASE   (0x00f0 | 0xf000)
> +#define VIMC_CID_VIMC_CLASS  (0x00f0 | 1)

Why this values, shouldn't we use a derivative from
V4L2_CID_PRIVATE_BASE for custom controls? Or can we use random values?

> +#define VIMC_CID_TEST_PATTERN(VIMC_CID_VIMC_BASE + 0)
> +
>  #define VIMC_FRAME_MAX_WIDTH 4096
>  #define VIMC_FRAME_MAX_HEIGHT 2160
>  #define VIMC_FRAME_MIN_WIDTH 16
> diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
> b/drivers/media/platform/vimc/vimc-sensor.c
> index 615c2b18dcfc..532097566b27 100644
> --- a/drivers/media/platform/vimc/vimc-sensor.c
> +++ b/drivers/media/platform/vimc/vimc-sensor.c
> @@ -22,6 +22,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
> 
> @@ -38,6 +39,7 @@ struct vimc_sen_device {
>   u8 *frame;
>   /* The active format */
>   struct v4l2_mbus_framefmt mbus_format;
> + struct v4l2_ctrl_handler hdl;
>  };
> 
>  static const struct v4l2_mbus_framefmt fmt_default = {
> @@ -291,6 +293,31 @@ static const struct v4l2_subdev_ops vimc_sen_ops = {
>   .video = &vimc_sen_video_ops,
>  };
> 
> +static int vimc_sen_s_ctrl(struct v4l2_ctrl *ctrl)
> +{
> + struct vimc_sen_device *vsen =
> + container_of(ctrl->handler, struct vimc_sen_device, hdl);
> +
> + switch (ctrl->id) {
> + case VIMC_CID_TEST_PATTERN:
> + tpg_s_pattern(&vsen->tpg, ctrl->val);
> + break;
> + case V4L2_CID_HFLIP:
> + tpg_s_hflip(&vsen->tpg, ctrl->val);
> + break;
> + case V4L2_CID_VFLIP:
> + tpg_s_vflip(&vsen->tpg, ctrl->val);
> + break;
> + default:
> + return -EINVAL;
> + }
> + return 0;
> +}
> +
> +static const struct v4l2_ctrl_ops vimc_sen_ctrl_ops = {
> + .s_ctrl = vimc_sen_s_ctrl,
> +};
> +
>  static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
>void *master_data)
>  {
> @@ -299,10 +326,29 @@ static void vimc_sen_comp_unbind(struct device *comp, 
> struct device *master,
>   container_of(ved, struct vimc_sen_device, ved);
> 
>   vimc_ent_sd_unregister(ved, &vsen->sd);
> + v4l2_ctrl_handler_free(&vsen->hdl);
>   tpg_free(&vsen->tpg);
>   kfree(vsen);
>  }
> 
> +/* Image Processing Controls */
> +static const struct v4l2_ctrl_config vimc_sen_ctrl_class = {
> + .ops = &vimc_sen_ctrl_ops,
> + .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,

I was wondering if it is really necessary to specify the ops and flags
in the class, as this is seems to me a meta control for the other
controls to be grouped in a class.

> + .id = VIMC_CID_VIMC_CLASS,
> + .name = "VIMC Controls",
> + .type = V4L2_CTRL_TYPE_CTRL_CLASS,
> +};
> +
> +static const struct v4l2_ctrl_config vimc_sen_ctrl_test_pattern = {
> + .ops = &vimc_sen_ctrl_ops,
> + .id = VIMC_CID_TEST_PATTERN,
> + .name = "Test Pattern",
> + .type = V4L2_CTRL_TYPE_MENU,
> + .max = TPG_PAT_NOISE,
> + .qmenu = tpg_pattern_strings,
> +};
> +
>  static int vimc_sen_comp_bind(struct device *comp, struct device *master,
> void *master_data)
>  {
> @@ -316,6 +362,20 @@ static int vimc_sen_comp_bind(struct device *comp, 
> struct device *master,
>   if (!vsen)
>   return -ENOMEM;
> 
> + v4l2_ctrl_handler_init(&vsen->hdl, 4);
> +
> + v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_class, NULL);
> + v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_test_pattern, NULL);
> + v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
> + V4L2_CID_VFLIP, 0, 1, 1, 0);
> + v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
> + V4L2_CID_HFLIP, 0, 1, 1, 0);

Shouldn't we test the return values of the above functions? Or maybe not
because we should know what we are doing and this doesn't depend on the
user space.

> + vsen->sd.ctrl_handler = &vsen->hdl;
> + if (vsen->hdl.error) {
> + ret = vsen->hdl.error;
> + goto err_free_vsen;
> + }
> +
>   /* Initialize ved and sd */
>   ret 

Re: [PATCH] [media] vimc: set id_table for platform drivers

2017-07-14 Thread Helen Koike

Hi,

Thanks for the patch

On 2017-07-14 05:58 AM, Javier Martinez Canillas wrote:

The vimc platform drivers define a platform device ID table but these
are not set to the .id_table field in the platform driver structure.

So the platform device ID table is only used to fill the aliases in
the module but are not used for matching (works because the platform
subsystem fallbacks to the driver's name if no .id_table is set).

But this also means that the platform device ID table isn't used if
the driver is built-in, which leads to the following build warning:

This causes the following build warnings when the driver is built-in:

drivers/media/platform/vimc//vimc-capture.c:528:40: warning: 
‘vimc_cap_driver_ids’ defined but not used [-Wunused-const-variable=]
  static const struct platform_device_id vimc_cap_driver_ids[] = {
 ^~~
drivers/media/platform/vimc//vimc-debayer.c:588:40: warning: 
‘vimc_deb_driver_ids’ defined but not used [-Wunused-const-variable=]
  static const struct platform_device_id vimc_deb_driver_ids[] = {
 ^~~
drivers/media/platform/vimc//vimc-scaler.c:442:40: warning: 
‘vimc_sca_driver_ids’ defined but not used [-Wunused-const-variable=]
  static const struct platform_device_id vimc_sca_driver_ids[] = {
 ^~~
drivers/media/platform/vimc//vimc-sensor.c:376:40: warning: 
‘vimc_sen_driver_ids’ defined but not used [-Wunused-const-variable=]
  static const struct platform_device_id vimc_sen_driver_ids[] = {
 ^~~

Reported-by: Mauro Carvalho Chehab 
Suggested-by: Sakari Ailus 
Signed-off-by: Javier Martinez Canillas 


Seems good to me.

Reviewed-by: Helen Koike 



---

  drivers/media/platform/vimc/vimc-capture.c | 15 ---
  drivers/media/platform/vimc/vimc-debayer.c | 15 ---
  drivers/media/platform/vimc/vimc-scaler.c  | 15 ---
  drivers/media/platform/vimc/vimc-sensor.c  | 15 ---
  4 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-capture.c 
b/drivers/media/platform/vimc/vimc-capture.c
index 14cb32e21130..88a1e5670c72 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -517,21 +517,22 @@ static int vimc_cap_remove(struct platform_device *pdev)
return 0;
  }
  
+static const struct platform_device_id vimc_cap_driver_ids[] = {

+   {
+   .name   = VIMC_CAP_DRV_NAME,
+   },
+   { }
+};
+
  static struct platform_driver vimc_cap_pdrv = {
.probe  = vimc_cap_probe,
.remove = vimc_cap_remove,
+   .id_table   = vimc_cap_driver_ids,
.driver = {
.name   = VIMC_CAP_DRV_NAME,
},
  };
  
-static const struct platform_device_id vimc_cap_driver_ids[] = {

-   {
-   .name   = VIMC_CAP_DRV_NAME,
-   },
-   { }
-};
-
  module_platform_driver(vimc_cap_pdrv);
  
  MODULE_DEVICE_TABLE(platform, vimc_cap_driver_ids);

diff --git a/drivers/media/platform/vimc/vimc-debayer.c 
b/drivers/media/platform/vimc/vimc-debayer.c
index 35b15bd4d61d..033a131f67af 100644
--- a/drivers/media/platform/vimc/vimc-debayer.c
+++ b/drivers/media/platform/vimc/vimc-debayer.c
@@ -577,21 +577,22 @@ static int vimc_deb_remove(struct platform_device *pdev)
return 0;
  }
  
+static const struct platform_device_id vimc_deb_driver_ids[] = {

+   {
+   .name   = VIMC_DEB_DRV_NAME,
+   },
+   { }
+};
+
  static struct platform_driver vimc_deb_pdrv = {
.probe  = vimc_deb_probe,
.remove = vimc_deb_remove,
+   .id_table   = vimc_deb_driver_ids,
.driver = {
.name   = VIMC_DEB_DRV_NAME,
},
  };
  
-static const struct platform_device_id vimc_deb_driver_ids[] = {

-   {
-   .name   = VIMC_DEB_DRV_NAME,
-   },
-   { }
-};
-
  module_platform_driver(vimc_deb_pdrv);
  
  MODULE_DEVICE_TABLE(platform, vimc_deb_driver_ids);

diff --git a/drivers/media/platform/vimc/vimc-scaler.c 
b/drivers/media/platform/vimc/vimc-scaler.c
index fe77505d2679..0a3e086e12f3 100644
--- a/drivers/media/platform/vimc/vimc-scaler.c
+++ b/drivers/media/platform/vimc/vimc-scaler.c
@@ -431,21 +431,22 @@ static int vimc_sca_remove(struct platform_device *pdev)
return 0;
  }
  
+static const struct platform_device_id vimc_sca_driver_ids[] = {

+   {
+   .name   = VIMC_SCA_DRV_NAME,
+   },
+   { }
+};
+
  static struct platform_driver vimc_sca_pdrv = {
.probe  = vimc_sca_probe,
.remove = vimc_sca_remove,
+   .id_table   = vimc_sca_driver_ids,
.driver = {
.name   = VIMC_SC

Re: [PATCH v2] [media] v4l2: add V4L2_CAP_IO_MC

2017-06-19 Thread Helen Koike

Hi Hans,

Thanks for reviewing this

On 2017-06-19 08:15 AM, Hans Verkuil wrote:

On 06/14/2017 06:50 AM, Helen Koike wrote:

Add V4L2_CAP_IO_MC to be used in struct v4l2_capability to indicate that
input and output are controlled by the Media Controller instead of V4L2
API.
When this flag is set, ioctls for get, set and enum input and outputs
are automatically enabled and programmed to call helper function.

Signed-off-by: Helen Koike 

---

Changes in v2::
- replace the type by capability
- erase V4L2_INPUT_TYPE_DEFAULT
- also consider output
- plug helpers in the ops automatically so drivers doesn't need
to set it by hand
- update docs
- commit message and title
---
  Documentation/media/uapi/v4l/vidioc-querycap.rst |  3 +
  Documentation/media/videodev2.h.rst.exceptions   |  1 +
  drivers/media/v4l2-core/v4l2-dev.c   | 35 +++--
  drivers/media/v4l2-core/v4l2-ioctl.c | 91
++--
  include/uapi/linux/videodev2.h   |  2 +
  5 files changed, 120 insertions(+), 12 deletions(-)

diff --git a/Documentation/media/uapi/v4l/vidioc-querycap.rst
b/Documentation/media/uapi/v4l/vidioc-querycap.rst
index 12e0d9a..2bd1223 100644
--- a/Documentation/media/uapi/v4l/vidioc-querycap.rst
+++ b/Documentation/media/uapi/v4l/vidioc-querycap.rst
@@ -252,6 +252,9 @@ specification the ioctl returns an ``EINVAL``
error code.
  * - ``V4L2_CAP_TOUCH``
- 0x1000
- This is a touch device.
+* - ``V4L2_CAP_IO_MC``
+  - 0x2000
+  - This device has its inputs and outputs controller by the
Media Controller


controller -> controlled


Sorry, I'll remember to use a spell checker next time



But I would rephrase this a bit:

- The inputs and/or outputs of this device are controlled by the
Media Controller
  (see: ).



Sure, much better.
In this document, almost all the flags start with "The device 
supports..." or "The device has...", I was thinking to do something similar.



  * - ``V4L2_CAP_DEVICE_CAPS``
- 0x8000
- The driver fills the ``device_caps`` field. This capability can
diff --git a/Documentation/media/videodev2.h.rst.exceptions
b/Documentation/media/videodev2.h.rst.exceptions
index a5cb0a8..0b48cd0 100644
--- a/Documentation/media/videodev2.h.rst.exceptions
+++ b/Documentation/media/videodev2.h.rst.exceptions
@@ -159,6 +159,7 @@ replace define V4L2_CAP_ASYNCIO device-capabilities
  replace define V4L2_CAP_STREAMING device-capabilities
  replace define V4L2_CAP_DEVICE_CAPS device-capabilities
  replace define V4L2_CAP_TOUCH device-capabilities
+replace define V4L2_CAP_IO_MC device-capabilities
# V4L2 pix flags
  replace define V4L2_PIX_FMT_PRIV_MAGIC :c:type:`v4l2_pix_format`
diff --git a/drivers/media/v4l2-core/v4l2-dev.c
b/drivers/media/v4l2-core/v4l2-dev.c
index c647ba6..0f272fe 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -688,22 +688,34 @@ static void determine_valid_ioctls(struct
video_device *vdev)
  SET_VALID_IOCTL(ops, VIDIOC_G_STD, vidioc_g_std);
  if (is_rx) {
  SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd);
-SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input);
-SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input);
-SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input);
  SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDIO, vidioc_enumaudio);
  SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio);
  SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio);
  SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS,
vidioc_query_dv_timings);
  SET_VALID_IOCTL(ops, VIDIOC_S_EDID, vidioc_s_edid);
+if (vdev->device_caps & V4L2_CAP_IO_MC) {
+set_bit(_IOC_NR(VIDIOC_ENUMINPUT), valid_ioctls);
+set_bit(_IOC_NR(VIDIOC_G_INPUT), valid_ioctls);
+set_bit(_IOC_NR(VIDIOC_S_INPUT), valid_ioctls);
+} else {
+SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT,
vidioc_enum_input);
+SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input);
+SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input);
+}
  }
  if (is_tx) {
-SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output);
-SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output);
-SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output);
  SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDOUT, vidioc_enumaudout);
  SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout);
  SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout);
+if (vdev->device_caps & V4L2_CAP_IO_MC) {
+set_bit(_IOC_NR(VIDIOC_ENUMOUTPUT), valid_ioctls);
+set_bit(_IOC_NR(VIDIOC_G_OUTPUT), valid_ioctls);
+   

[PATCH v5 04/12] [media] vimc: common: Add vimc_pipeline_s_stream helper

2017-06-19 Thread Helen Koike
Move the vimc_cap_pipeline_s_stream from the vimc-cap.c to vimc-common.c
as this core will be reused by other subdevices to activate the stream
in their directly connected nodes

Signed-off-by: Helen Koike 

---

Changes in v5: None
Changes in v4: None
Changes in v3:
[media] vimc: Add vimc_pipeline_s_stream in the core
- add it in vimc-common instead of vimc-core
- rename commit with "common" tag

Changes in v2:
[media] vimc: Add vimc_pipeline_s_stream in the core
- Use is_media_entity_v4l2_subdev instead of comparing with the old
entity->type
- Fix comments style
- add kernel-docs
- call s_stream across all sink pads


---
 drivers/media/platform/vimc/vimc-capture.c | 29 ++-
 drivers/media/platform/vimc/vimc-common.c  | 32 ++
 drivers/media/platform/vimc/vimc-common.h  | 11 ++
 3 files changed, 45 insertions(+), 27 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-capture.c 
b/drivers/media/platform/vimc/vimc-capture.c
index 9adb06d..93f6a09 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -132,31 +132,6 @@ static void vimc_cap_return_all_buffers(struct 
vimc_cap_device *vcap,
spin_unlock(&vcap->qlock);
 }
 
-static int vimc_cap_pipeline_s_stream(struct vimc_cap_device *vcap, int enable)
-{
-   struct v4l2_subdev *sd;
-   struct media_pad *pad;
-   int ret;
-
-   /* Start the stream in the subdevice direct connected */
-   pad = media_entity_remote_pad(&vcap->vdev.entity.pads[0]);
-
-   /*
-* if it is a raw node from vimc-core, there is nothing to activate
-* TODO: remove this when there are no more raw nodes in the
-* core and return error instead
-*/
-   if (pad->entity->obj_type == MEDIA_ENTITY_TYPE_BASE)
-   return 0;
-
-   sd = media_entity_to_v4l2_subdev(pad->entity);
-   ret = v4l2_subdev_call(sd, video, s_stream, enable);
-   if (ret && ret != -ENOIOCTLCMD)
-   return ret;
-
-   return 0;
-}
-
 static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
@@ -173,7 +148,7 @@ static int vimc_cap_start_streaming(struct vb2_queue *vq, 
unsigned int count)
}
 
/* Enable streaming from the pipe */
-   ret = vimc_cap_pipeline_s_stream(vcap, 1);
+   ret = vimc_pipeline_s_stream(&vcap->vdev.entity, 1);
if (ret) {
media_pipeline_stop(entity);
vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
@@ -192,7 +167,7 @@ static void vimc_cap_stop_streaming(struct vb2_queue *vq)
struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
 
/* Disable streaming from the pipe */
-   vimc_cap_pipeline_s_stream(vcap, 0);
+   vimc_pipeline_s_stream(&vcap->vdev.entity, 0);
 
/* Stop the media pipeline */
media_pipeline_stop(&vcap->vdev.entity);
diff --git a/drivers/media/platform/vimc/vimc-common.c 
b/drivers/media/platform/vimc/vimc-common.c
index 3afbabd..f809a9d 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -220,6 +220,38 @@ struct media_pad *vimc_pads_init(u16 num_pads, const 
unsigned long *pads_flag)
return pads;
 }
 
+int vimc_pipeline_s_stream(struct media_entity *ent, int enable)
+{
+   struct v4l2_subdev *sd;
+   struct media_pad *pad;
+   unsigned int i;
+   int ret;
+
+   for (i = 0; i < ent->num_pads; i++) {
+   if (ent->pads[i].flags & MEDIA_PAD_FL_SOURCE)
+   continue;
+
+   /* Start the stream in the subdevice direct connected */
+   pad = media_entity_remote_pad(&ent->pads[i]);
+
+   /*
+* if this is a raw node from vimc-core, then there is
+* nothing to activate
+* TODO: remove this when there are no more raw nodes in the
+* core and return error instead
+*/
+   if (pad->entity->obj_type == MEDIA_ENTITY_TYPE_BASE)
+   continue;
+
+   sd = media_entity_to_v4l2_subdev(pad->entity);
+   ret = v4l2_subdev_call(sd, video, s_stream, enable);
+   if (ret && ret != -ENOIOCTLCMD)
+   return ret;
+   }
+
+   return 0;
+}
+
 static const struct media_entity_operations vimc_ent_sd_mops = {
.link_validate = v4l2_subdev_link_validate,
 };
diff --git a/drivers/media/platform/vimc/vimc-common.h 
b/drivers/media/platform/vimc/vimc-common.h
index 9ec361c..73e7e94 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -97,6 +97,17 @@ static inline void vimc_pads_cl

[PATCH v5 07/12] [media] vimc: sen: Support several image formats

2017-06-19 Thread Helen Koike
Allow user space to change the image format as the frame size, the
media bus pixel format, colorspace, quantization, field YCbCr encoding
and the transfer function

Signed-off-by: Helen Koike 

---

Changes in v5: None
Changes in v4:
[media] vimc: sen: Support several image formats
- use vimc_colorimetry_clamp macro
- replace V4L2_COLORSPACE_SRGB by V4L2_COLORSPACE_DEFAULT in the
default format struct

Changes in v3:
[media] vimc: sen: Support several image formats
- remove support for V4L2_FIELD_ALTERNATE (left as TODO for now)
- clamp image size to an even dimension for height and width
- set default values for colorimetry using _DEFAULT macro
- reset all values of colorimetry to _DEFAULT if user tries to
set an invalid colorspace

Changes in v2:
[media] vimc: sen: Support several image formats
- this is a new commit in the serie (the old one was splitted in two)
- add init_cfg to initialize try_fmt
- reorder code in vimc_sen_set_fmt
- allow user space to change all fields from struct v4l2_mbus_framefmt
  (e.g. colospace, quantization, field, xfer_func, ycbcr_enc)
- merge with patch for the enum_mbus_code and enum_frame_size
- change commit message
- add vimc_pix_map_by_index
- rename MIN/MAX macros
- check set_fmt default parameters for quantization, colorspace 
...media] vimc: sen: Support several image formats


---
 drivers/media/platform/vimc/vimc-common.c |   8 ++
 drivers/media/platform/vimc/vimc-common.h |  12 +++
 drivers/media/platform/vimc/vimc-sensor.c | 130 +++---
 3 files changed, 121 insertions(+), 29 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-common.c 
b/drivers/media/platform/vimc/vimc-common.c
index 6ad77fd..b698055 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -144,6 +144,14 @@ static const struct vimc_pix_map vimc_pix_map_list[] = {
},
 };
 
+const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i)
+{
+   if (i >= ARRAY_SIZE(vimc_pix_map_list))
+   return NULL;
+
+   return &vimc_pix_map_list[i];
+}
+
 const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
 {
unsigned int i;
diff --git a/drivers/media/platform/vimc/vimc-common.h 
b/drivers/media/platform/vimc/vimc-common.h
index 43483ee..fb3463c 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -22,6 +22,11 @@
 #include 
 #include 
 
+#define VIMC_FRAME_MAX_WIDTH 4096
+#define VIMC_FRAME_MAX_HEIGHT 2160
+#define VIMC_FRAME_MIN_WIDTH 16
+#define VIMC_FRAME_MIN_HEIGHT 16
+
 /**
  * struct vimc_colorimetry_clamp - Adjust colorimetry parameters
  *
@@ -139,6 +144,13 @@ static inline void vimc_pads_cleanup(struct media_pad 
*pads)
 int vimc_pipeline_s_stream(struct media_entity *ent, int enable);
 
 /**
+ * vimc_pix_map_by_index - get vimc_pix_map struct by its index
+ *
+ * @i: index of the vimc_pix_map struct in vimc_pix_map_list
+ */
+const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i);
+
+/**
  * vimc_pix_map_by_code - get vimc_pix_map struct by media bus code
  *
  * @code:  media bus format code defined by MEDIA_BUS_FMT_* macros
diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
b/drivers/media/platform/vimc/vimc-sensor.c
index 6386ac1..d4f9705 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -24,8 +24,6 @@
 
 #include "vimc-sensor.h"
 
-#define VIMC_SEN_FRAME_MAX_WIDTH 4096
-
 struct vimc_sen_device {
struct vimc_ent_device ved;
struct v4l2_subdev sd;
@@ -36,18 +34,39 @@ struct vimc_sen_device {
struct v4l2_mbus_framefmt mbus_format;
 };
 
+static const struct v4l2_mbus_framefmt fmt_default = {
+   .width = 640,
+   .height = 480,
+   .code = MEDIA_BUS_FMT_RGB888_1X24,
+   .field = V4L2_FIELD_NONE,
+   .colorspace = V4L2_COLORSPACE_DEFAULT,
+};
+
+static int vimc_sen_init_cfg(struct v4l2_subdev *sd,
+struct v4l2_subdev_pad_config *cfg)
+{
+   unsigned int i;
+
+   for (i = 0; i < sd->entity.num_pads; i++) {
+   struct v4l2_mbus_framefmt *mf;
+
+   mf = v4l2_subdev_get_try_format(sd, cfg, i);
+   *mf = fmt_default;
+   }
+
+   return 0;
+}
+
 static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
   struct v4l2_subdev_pad_config *cfg,
   struct v4l2_subdev_mbus_code_enum *code)
 {
-   struct vimc_sen_device *vsen =
-   container_of(sd, struct vimc_sen_device, sd);
+   const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index);
 
-   /* TODO: Add support for other codes */
-   if (code->index)
+   if (!vpix)
 

[PATCH v5 06/12] [media] vimc: common: Add vimc_colorimetry_clamp

2017-06-19 Thread Helen Koike
Colorimetry value will always be checked in the same way. Adding a
helper macro for that

Signed-off-by: Helen Koike 

---

Changes in v5: None
Changes in v4:
[media] vimc: common: Add vimc_colorimetry_clamp
- this is a new patch in the series

Changes in v3: None
Changes in v2: None


---
 drivers/media/platform/vimc/vimc-common.h | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/drivers/media/platform/vimc/vimc-common.h 
b/drivers/media/platform/vimc/vimc-common.h
index 60ebde2..43483ee 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -23,6 +23,32 @@
 #include 
 
 /**
+ * struct vimc_colorimetry_clamp - Adjust colorimetry parameters
+ *
+ * @fmt:   the pointer to struct v4l2_pix_format or
+ * struct v4l2_mbus_framefmt
+ *
+ * Entities must check if colorimetry given by the userspace is valid, if not
+ * then set them as DEFAULT
+ */
+#define vimc_colorimetry_clamp(fmt)\
+do {   \
+   if ((fmt)->colorspace == V4L2_COLORSPACE_DEFAULT\
+   || (fmt)->colorspace > V4L2_COLORSPACE_DCI_P3) {\
+   (fmt)->colorspace = V4L2_COLORSPACE_DEFAULT;\
+   (fmt)->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;  \
+   (fmt)->quantization = V4L2_QUANTIZATION_DEFAULT;\
+   (fmt)->xfer_func = V4L2_XFER_FUNC_DEFAULT;  \
+   }   \
+   if ((fmt)->ycbcr_enc > V4L2_YCBCR_ENC_SMPTE240M)\
+   (fmt)->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;  \
+   if ((fmt)->quantization > V4L2_QUANTIZATION_LIM_RANGE)  \
+   (fmt)->quantization = V4L2_QUANTIZATION_DEFAULT;\
+   if ((fmt)->xfer_func > V4L2_XFER_FUNC_SMPTE2084)\
+   (fmt)->xfer_func = V4L2_XFER_FUNC_DEFAULT;  \
+} while (0)
+
+/**
  * struct vimc_pix_map - maps media bus code with v4l2 pixel format
  *
  * @code:  media bus format code defined by MEDIA_BUS_FMT_* macros
-- 
2.7.4



[PATCH v5 01/12] [media] vimc: sen: Integrate the tpg on the sensor

2017-06-19 Thread Helen Koike
Initialize the test pattern generator on the sensor
Generate a colored bar image instead of a grey one

Signed-off-by: Helen Koike 

---

Changes in v5: None
Changes in v4: None
Changes in v3:
[media] vimc: sen: Integrate the tpg on the sensor
- Declare frame_size as a local variable
- Set tpg frame format before starting kthread
- s_stream(sd, 1): return 0 if stream is already enabled
- s_stream(sd, 0): return 0 if stream is already disabled
- s_stream: propagate error from kthread_stop
- coding style when calling tpg_s_bytesperline
- s/vimc_thread_sen/vimc_sen_tpg_thread
- fix multiline comment
- remove V4L2_FIELD_ALTERNATE from tpg_s_field
- remove V4L2_STD_PAL from tpg_fill_plane_buffer

Changes in v2:
[media] vimc: sen: Integrate the tpg on the sensor
- Fix include location
- Select V4L2_TPG in Kconfig
- configure tpg on streamon only
- rm BUG_ON
- coding style


---
 drivers/media/platform/vimc/Kconfig   |  1 +
 drivers/media/platform/vimc/vimc-sensor.c | 64 ---
 2 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/drivers/media/platform/vimc/Kconfig 
b/drivers/media/platform/vimc/Kconfig
index a18f635..71c9fe7 100644
--- a/drivers/media/platform/vimc/Kconfig
+++ b/drivers/media/platform/vimc/Kconfig
@@ -2,6 +2,7 @@ config VIDEO_VIMC
tristate "Virtual Media Controller Driver (VIMC)"
depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
select VIDEOBUF2_VMALLOC
+   select VIDEO_V4L2_TPG
default n
---help---
  Skeleton driver for Virtual Media Controller
diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
b/drivers/media/platform/vimc/vimc-sensor.c
index 591f6a4..2e83487 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -20,17 +20,20 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "vimc-sensor.h"
 
+#define VIMC_SEN_FRAME_MAX_WIDTH 4096
+
 struct vimc_sen_device {
struct vimc_ent_device ved;
struct v4l2_subdev sd;
+   struct tpg_data tpg;
struct task_struct *kthread_sen;
u8 *frame;
/* The active format */
struct v4l2_mbus_framefmt mbus_format;
-   int frame_size;
 };
 
 static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
@@ -84,6 +87,24 @@ static int vimc_sen_get_fmt(struct v4l2_subdev *sd,
return 0;
 }
 
+static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
+{
+   const struct vimc_pix_map *vpix =
+   vimc_pix_map_by_code(vsen->mbus_format.code);
+
+   tpg_reset_source(&vsen->tpg, vsen->mbus_format.width,
+vsen->mbus_format.height, vsen->mbus_format.field);
+   tpg_s_bytesperline(&vsen->tpg, 0, vsen->mbus_format.width * vpix->bpp);
+   tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height);
+   tpg_s_fourcc(&vsen->tpg, vpix->pixelformat);
+   /* TODO: add support for V4L2_FIELD_ALTERNATE */
+   tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false);
+   tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace);
+   tpg_s_ycbcr_enc(&vsen->tpg, vsen->mbus_format.ycbcr_enc);
+   tpg_s_quantization(&vsen->tpg, vsen->mbus_format.quantization);
+   tpg_s_xfer_func(&vsen->tpg, vsen->mbus_format.xfer_func);
+}
+
 static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
.enum_mbus_code = vimc_sen_enum_mbus_code,
.enum_frame_size= vimc_sen_enum_frame_size,
@@ -97,7 +118,7 @@ static const struct media_entity_operations vimc_sen_mops = {
.link_validate = v4l2_subdev_link_validate,
 };
 
-static int vimc_thread_sen(void *data)
+static int vimc_sen_tpg_thread(void *data)
 {
struct vimc_sen_device *vsen = data;
unsigned int i;
@@ -110,7 +131,7 @@ static int vimc_thread_sen(void *data)
if (kthread_should_stop())
break;
 
-   memset(vsen->frame, 100, vsen->frame_size);
+   tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame);
 
/* Send the frame to all source pads */
for (i = 0; i < vsen->sd.entity.num_pads; i++)
@@ -132,26 +153,31 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int 
enable)
 
if (enable) {
const struct vimc_pix_map *vpix;
+   unsigned int frame_size;
 
if (vsen->kthread_sen)
-   return -EINVAL;
+   /* tpg is already executing */
+   return 0;
 
/* Calculate the frame size */
vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
-   vsen->frame_s

[PATCH v5 08/12] [media] vimc: cap: Support several image formats

2017-06-19 Thread Helen Koike
Allow user space to change the image format as the frame size, the
pixel format, colorspace, quantization, field YCbCr encoding
and the transfer function

Signed-off-by: Helen Koike 

---

Changes in v5: None
Changes in v4:
[media] vimc: cap: Support several image formats
- add vimc_colorimetry_clamp macro
- replace V4L2_COLORSPACE_SRGB by V4L2_COLORSPACE_DEFAULT in the
default format struct

Changes in v3:
[media] vimc: cap: Support several image formats
- use *_DEFAULT macros for colorimetry in the default format
- clamp height and width of the image by an even value
- is user try to set colorspace to an invalid format, set all
colorimetry parameters to _DEFAULT
- remove V4L2_FMT_FLAG_COMPRESSED from vimc_cap_enum_fmt_vid_cap
- remove V4L2_BUF_TYPE_VIDEO_CAPTURE from vimc_cap_enum_fmt_vid_cap
- increase step_width and step_height to 2 instead of 1
- remove link validate function, use the one in vimc-common.c

Changes in v2:
[media] vimc: cap: Support several image formats
- this is a new commit in the serie (the old one was splitted in two)
- allow user space to change all fields from struct v4l2_pix_format
  (e.g. colospace, quantization, field, xfer_func, ycbcr_enc)
- link_validate and try_fmt: also checks colospace, quantization, 
field, xfer_func, ycbcr_enc
- add struct v4l2_pix_format fmt_default
- add enum_framesizes
- enum_fmt_vid_cap: enumerate all formats from vimc_pix_map_table
- add mode dev_dbg


---
 drivers/media/platform/vimc/vimc-capture.c | 117 +
 1 file changed, 101 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-capture.c 
b/drivers/media/platform/vimc/vimc-capture.c
index 5bdecd1..359f59e 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -40,6 +40,14 @@ struct vimc_cap_device {
struct media_pipeline pipe;
 };
 
+static const struct v4l2_pix_format fmt_default = {
+   .width = 640,
+   .height = 480,
+   .pixelformat = V4L2_PIX_FMT_RGB24,
+   .field = V4L2_FIELD_NONE,
+   .colorspace = V4L2_COLORSPACE_DEFAULT,
+};
+
 struct vimc_cap_buffer {
/*
 * struct vb2_v4l2_buffer must be the first element
@@ -73,7 +81,7 @@ static void vimc_cap_get_format(struct vimc_ent_device *ved,
*fmt = vcap->format;
 }
 
-static int vimc_cap_fmt_vid_cap(struct file *file, void *priv,
+static int vimc_cap_g_fmt_vid_cap(struct file *file, void *priv,
  struct v4l2_format *f)
 {
struct vimc_cap_device *vcap = video_drvdata(file);
@@ -83,16 +91,98 @@ static int vimc_cap_fmt_vid_cap(struct file *file, void 
*priv,
return 0;
 }
 
+static int vimc_cap_try_fmt_vid_cap(struct file *file, void *priv,
+   struct v4l2_format *f)
+{
+   struct v4l2_pix_format *format = &f->fmt.pix;
+   const struct vimc_pix_map *vpix;
+
+   format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH,
+   VIMC_FRAME_MAX_WIDTH) & ~1;
+   format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT,
+VIMC_FRAME_MAX_HEIGHT) & ~1;
+
+   /* Don't accept a pixelformat that is not on the table */
+   vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
+   if (!vpix) {
+   format->pixelformat = fmt_default.pixelformat;
+   vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
+   }
+   /* TODO: Add support for custom bytesperline values */
+   format->bytesperline = format->width * vpix->bpp;
+   format->sizeimage = format->bytesperline * format->height;
+
+   if (format->field == V4L2_FIELD_ANY)
+   format->field = fmt_default.field;
+
+   vimc_colorimetry_clamp(format);
+
+   return 0;
+}
+
+static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+   struct vimc_cap_device *vcap = video_drvdata(file);
+
+   /* Do not change the format while stream is on */
+   if (vb2_is_busy(&vcap->queue))
+   return -EBUSY;
+
+   vimc_cap_try_fmt_vid_cap(file, priv, f);
+
+   dev_dbg(vcap->vdev.v4l2_dev->dev, "%s: format update: "
+   "old:%dx%d (0x%x, %d, %d, %d, %d) "
+   "new:%dx%d (0x%x, %d, %d, %d, %d)\n", vcap->vdev.name,
+   /* old */
+   vcap->format.width, vcap->format.height,
+   vcap->format.pixelformat, vcap->format.colorspace,
+   vcap->format.quantization, vcap->format.xfer_func,
+   vcap->format.ycbcr_enc,
+   /* new */
+   f->f

[PATCH v5 02/12] [media] vimc: Move common code from the core

2017-06-19 Thread Helen Koike
Remove helper functions from vimc-core and add it in vimc-common to
clean up the core.

Signed-off-by: Helen Koike 

---

Changes in v5: None
Changes in v4: None
Changes in v3:
[media] vimc: Move common code from the core
- This is a new patch in the series

Changes in v2: None


---
 drivers/media/platform/vimc/Makefile   |   2 +-
 drivers/media/platform/vimc/vimc-capture.h |   2 +-
 drivers/media/platform/vimc/vimc-common.c  | 221 +
 .../platform/vimc/{vimc-core.h => vimc-common.h}   |   7 +-
 drivers/media/platform/vimc/vimc-core.c| 205 +--
 drivers/media/platform/vimc/vimc-sensor.h  |   2 +-
 6 files changed, 229 insertions(+), 210 deletions(-)
 create mode 100644 drivers/media/platform/vimc/vimc-common.c
 rename drivers/media/platform/vimc/{vimc-core.h => vimc-common.h} (96%)

diff --git a/drivers/media/platform/vimc/Makefile 
b/drivers/media/platform/vimc/Makefile
index c45195e..6b6ddf4 100644
--- a/drivers/media/platform/vimc/Makefile
+++ b/drivers/media/platform/vimc/Makefile
@@ -1,3 +1,3 @@
-vimc-objs := vimc-core.o vimc-capture.o vimc-sensor.o
+vimc-objs := vimc-core.o vimc-capture.o vimc-common.o vimc-sensor.o
 
 obj-$(CONFIG_VIDEO_VIMC) += vimc.o
diff --git a/drivers/media/platform/vimc/vimc-capture.h 
b/drivers/media/platform/vimc/vimc-capture.h
index 581a813..7e5c707 100644
--- a/drivers/media/platform/vimc/vimc-capture.h
+++ b/drivers/media/platform/vimc/vimc-capture.h
@@ -18,7 +18,7 @@
 #ifndef _VIMC_CAPTURE_H_
 #define _VIMC_CAPTURE_H_
 
-#include "vimc-core.h"
+#include "vimc-common.h"
 
 struct vimc_ent_device *vimc_cap_create(struct v4l2_device *v4l2_dev,
const char *const name,
diff --git a/drivers/media/platform/vimc/vimc-common.c 
b/drivers/media/platform/vimc/vimc-common.c
new file mode 100644
index 000..42f779a
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -0,0 +1,221 @@
+/*
+ * vimc-common.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015-2017 Helen Koike 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "vimc-common.h"
+
+static const struct vimc_pix_map vimc_pix_map_list[] = {
+   /* TODO: add all missing formats */
+
+   /* RGB formats */
+   {
+   .code = MEDIA_BUS_FMT_BGR888_1X24,
+   .pixelformat = V4L2_PIX_FMT_BGR24,
+   .bpp = 3,
+   },
+   {
+   .code = MEDIA_BUS_FMT_RGB888_1X24,
+   .pixelformat = V4L2_PIX_FMT_RGB24,
+   .bpp = 3,
+   },
+   {
+   .code = MEDIA_BUS_FMT_ARGB_1X32,
+   .pixelformat = V4L2_PIX_FMT_ARGB32,
+   .bpp = 4,
+   },
+
+   /* Bayer formats */
+   {
+   .code = MEDIA_BUS_FMT_SBGGR8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SBGGR8,
+   .bpp = 1,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SGBRG8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SGBRG8,
+   .bpp = 1,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SGRBG8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SGRBG8,
+   .bpp = 1,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SRGGB8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SRGGB8,
+   .bpp = 1,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SBGGR10_1X10,
+   .pixelformat = V4L2_PIX_FMT_SBGGR10,
+   .bpp = 2,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SGBRG10_1X10,
+   .pixelformat = V4L2_PIX_FMT_SGBRG10,
+   .bpp = 2,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SGRBG10_1X10,
+   .pixelformat = V4L2_PIX_FMT_SGRBG10,
+   .bpp = 2,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SRGGB10_1X10,
+   .pixelformat = V4L2_PIX_FMT_SRGGB10,
+   .bpp = 2,
+   },
+
+   /* 10bit raw bayer a-law compressed to 8 bits */
+   {
+   .code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
+   .bpp = 1,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
+   .bpp = 1,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SG

[PATCH v5 05/12] [media] vimc: common: Add vimc_link_validate

2017-06-19 Thread Helen Koike
All links will be checked in the same way. Adding a helper function for
that

Signed-off-by: Helen Koike 

---

Changes in v5: None
Changes in v4:
[media] vimc: common: Add vimc_link_validate
- remove vimc_fmt_pix_to_mbus(), replaced by
v4l2_fill_mbus_format()
- remove EXPORT_SYMBOL(vimc_link_validate), not necessary in
this patch, moved to submodules patch
- Fix multi-line comment style
- If colorspace is set to DEFAULT, then assume all the other
colorimetry parameters are also DEFAULT

Changes in v3:
[media] vimc: common: Add vimc_link_validate
- this is a new patch in the series

Changes in v2: None


---
 drivers/media/platform/vimc/vimc-capture.c |  78 +++
 drivers/media/platform/vimc/vimc-common.c  | 121 -
 drivers/media/platform/vimc/vimc-common.h  |  14 
 3 files changed, 145 insertions(+), 68 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-capture.c 
b/drivers/media/platform/vimc/vimc-capture.c
index 93f6a09..5bdecd1 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -64,6 +64,15 @@ static int vimc_cap_querycap(struct file *file, void *priv,
return 0;
 }
 
+static void vimc_cap_get_format(struct vimc_ent_device *ved,
+   struct v4l2_pix_format *fmt)
+{
+   struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
+   ved);
+
+   *fmt = vcap->format;
+}
+
 static int vimc_cap_fmt_vid_cap(struct file *file, void *priv,
  struct v4l2_format *f)
 {
@@ -231,74 +240,8 @@ static const struct vb2_ops vimc_cap_qops = {
.wait_finish= vb2_ops_wait_finish,
 };
 
-/*
- * NOTE: this function is a copy of v4l2_subdev_link_validate_get_format
- * maybe the v4l2 function should be public
- */
-static int vimc_cap_v4l2_subdev_link_validate_get_format(struct media_pad *pad,
-   struct v4l2_subdev_format *fmt)
-{
-   struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(pad->entity);
-
-   fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
-   fmt->pad = pad->index;
-
-   return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
-}
-
-static int vimc_cap_link_validate(struct media_link *link)
-{
-   struct v4l2_subdev_format source_fmt;
-   const struct vimc_pix_map *vpix;
-   struct vimc_cap_device *vcap = container_of(link->sink->entity,
-   struct vimc_cap_device,
-   vdev.entity);
-   struct v4l2_pix_format *sink_fmt = &vcap->format;
-   int ret;
-
-   /*
-* if it is a raw node from vimc-core, ignore the link for now
-* TODO: remove this when there are no more raw nodes in the
-* core and return error instead
-*/
-   if (link->source->entity->obj_type == MEDIA_ENTITY_TYPE_BASE)
-   return 0;
-
-   /* Get the the format of the subdev */
-   ret = vimc_cap_v4l2_subdev_link_validate_get_format(link->source,
-   &source_fmt);
-   if (ret)
-   return ret;
-
-   dev_dbg(vcap->vdev.v4l2_dev->dev,
-   "%s: link validate formats src:%dx%d %d sink:%dx%d %d\n",
-   vcap->vdev.name,
-   source_fmt.format.width, source_fmt.format.height,
-   source_fmt.format.code,
-   sink_fmt->width, sink_fmt->height,
-   sink_fmt->pixelformat);
-
-   /* The width, height and code must match. */
-   vpix = vimc_pix_map_by_pixelformat(sink_fmt->pixelformat);
-   if (source_fmt.format.width != sink_fmt->width
-   || source_fmt.format.height != sink_fmt->height
-   || vpix->code != source_fmt.format.code)
-   return -EPIPE;
-
-   /*
-* The field order must match, or the sink field order must be NONE
-* to support interlaced hardware connected to bridges that support
-* progressive formats only.
-*/
-   if (source_fmt.format.field != sink_fmt->field &&
-   sink_fmt->field != V4L2_FIELD_NONE)
-   return -EPIPE;
-
-   return 0;
-}
-
 static const struct media_entity_operations vimc_cap_mops = {
-   .link_validate  = vimc_cap_link_validate,
+   .link_validate  = vimc_link_validate,
 };
 
 static void vimc_cap_destroy(struct vimc_ent_device *ved)
@@ -434,6 +377,7 @@ struct vimc_ent_device *vimc_cap_create(struct v4l2_device 
*v4l2_dev,
vcap->ved.destroy = vimc_cap_destroy;
vcap->ved.ent = &vcap->vdev.entity;
vcap->ved.process_frame = vimc_cap_process_frame;
+   vcap->ved.vdev_get_form

[PATCH v5 09/12] [media] vimc: Subdevices as modules

2017-06-19 Thread Helen Koike
Change the core structure for adding subdevices in the topology.
Instead of calling the specific create function for each subdevice,
inject a child platform_device with the driver's name.
Each type of node in the topology (sensor, capture, debayer, scaler)
will register a platform_driver with the corresponding name through the
component subsystem.
Implementing a new subdevice type doesn't require vimc-core to be altered.

This facilitates future implementation of dynamic entities, where
hotpluging an entity in the topology is just a matter of
registering/unregistering a platform_device in the system.
It also facilitates other implementations of different nodes without
touching the core code and remove the need of a header file for each
type of node.

Signed-off-by: Helen Koike 

---

Changes in v5:
[media] vimc: Subdevices as modules
- Fix vimc_add_subdevs in rollback case. The loop variable can
be negative, remove 'unsigned' from the loop variable and fix
warning from smatch tool

Changes in v4:
[media] vimc: Subdevices as modules
- Rebase without [media] vimc: Optimize frame generation the through
pipe
- s/EXPORT_SYMBOL/EXPORT_SYMBOL_GPL
- add struct vimc_platform_data to pass the entity's name to the
sudmodule
- Fix comment about vimc-input (remove vimc-output comment)

Changes in v3:
[media] vimc: Subdevices as modules
- This is a new patch in the series

Changes in v2: None


---
 drivers/media/platform/vimc/Makefile   |   7 +-
 drivers/media/platform/vimc/vimc-capture.c |  99 ---
 drivers/media/platform/vimc/vimc-capture.h |  28 --
 drivers/media/platform/vimc/vimc-common.c  |  38 +--
 drivers/media/platform/vimc/vimc-common.h  |  29 ++-
 drivers/media/platform/vimc/vimc-core.c| 405 +++--
 drivers/media/platform/vimc/vimc-sensor.c  |  93 +--
 drivers/media/platform/vimc/vimc-sensor.h  |  28 --
 8 files changed, 339 insertions(+), 388 deletions(-)
 delete mode 100644 drivers/media/platform/vimc/vimc-capture.h
 delete mode 100644 drivers/media/platform/vimc/vimc-sensor.h

diff --git a/drivers/media/platform/vimc/Makefile 
b/drivers/media/platform/vimc/Makefile
index 6b6ddf4..0e5d5ce 100644
--- a/drivers/media/platform/vimc/Makefile
+++ b/drivers/media/platform/vimc/Makefile
@@ -1,3 +1,6 @@
-vimc-objs := vimc-core.o vimc-capture.o vimc-common.o vimc-sensor.o
+vimc-objs := vimc-core.o
+vimc_capture-objs := vimc-capture.o
+vimc_common-objs := vimc-common.o
+vimc_sensor-objs := vimc-sensor.o
 
-obj-$(CONFIG_VIDEO_VIMC) += vimc.o
+obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc_capture.o vimc_common.o vimc_sensor.o
diff --git a/drivers/media/platform/vimc/vimc-capture.c 
b/drivers/media/platform/vimc/vimc-capture.c
index 359f59e..14cb32e 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -15,15 +15,21 @@
  *
  */
 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
 
-#include "vimc-capture.h"
+#include "vimc-common.h"
+
+#define VIMC_CAP_DRV_NAME "vimc-capture"
 
 struct vimc_cap_device {
struct vimc_ent_device ved;
struct video_device vdev;
+   struct device *dev;
struct v4l2_pix_format format;
struct vb2_queue queue;
struct list_head buf_list;
@@ -131,7 +137,7 @@ static int vimc_cap_s_fmt_vid_cap(struct file *file, void 
*priv,
 
vimc_cap_try_fmt_vid_cap(file, priv, f);
 
-   dev_dbg(vcap->vdev.v4l2_dev->dev, "%s: format update: "
+   dev_dbg(vcap->dev, "%s: format update: "
"old:%dx%d (0x%x, %d, %d, %d, %d) "
"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vcap->vdev.name,
/* old */
@@ -309,8 +315,7 @@ static int vimc_cap_buffer_prepare(struct vb2_buffer *vb)
unsigned long size = vcap->format.sizeimage;
 
if (vb2_plane_size(vb, 0) < size) {
-   dev_err(vcap->vdev.v4l2_dev->dev,
-   "%s: buffer too small (%lu < %lu)\n",
+   dev_err(vcap->dev, "%s: buffer too small (%lu < %lu)\n",
vcap->vdev.name, vb2_plane_size(vb, 0), size);
return -EINVAL;
}
@@ -335,8 +340,10 @@ static const struct media_entity_operations vimc_cap_mops 
= {
.link_validate  = vimc_link_validate,
 };
 
-static void vimc_cap_destroy(struct vimc_ent_device *ved)
+static void vimc_cap_comp_unbind(struct device *comp, struct device *master,
+void *master_data)
 {
+   struct vimc_ent_device *ved = dev_get_drvdata(comp);
struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
ved);
 
@@ -385,42 +392,35 @@ static void vimc_cap_process_frame(struct vimc_ent_device

[PATCH v5 10/12] [media] vimc: deb: Add debayer filter

2017-06-19 Thread Helen Koike
Implement the debayer filter and integrate it with the core

Signed-off-by: Helen Koike 

---

Changes in v5:
[media] vimc: deb: Add debayer filter
- delare vimc_deb_video_ops as static, remove sparse warning

Changes in v4:
[media] vimc: deb: Add debayer filter
- Rebase without [media] vimc: Optimize frame generation through
pipe
- use vimc_colorimetry_clamp
- replace V4L2_COLORSPACE_SRGB by V4L2_COLORSPACE_DEFAULT in the
default format struct
- use struct vimc_platform_data to retrieve the entity's name

Changes in v3:
[media] vimc: deb: Add debayer filter
- Declare frame_size as a local variable
- s_stream(sd, 1): return 0 if stream is already enabled
- s_stream(sd, 0): return 0 if stream is already disabled
- s_stream: add ret variable to propagate return errors
- structure code to be a module, use platform_driver and component 
system
- fix multiline comment
- s/thought/through
- s/RGB/RGB888
- clamp height and width of the image by an even value
- if user try to set colorspace to an invalid format, set all
colorimetry parameters to _DEFAULT
- uset _DEFAULT for colorimetry in the default format

Changes in v2:
[media] vimc: deb: Add debayer filter
- Using MEDIA_ENT_F_ATV_DECODER in function
- remove v4l2_dev and dev from vimc_deb_device struct
- src fmt propagates from the sink
- coding style
- remove redundant else if statements
- check end of enum and remove BUG_ON
- enum frame size with min and max values
- set/try fmt
- remove unecessary include freezer.h
- check pad types on create
- return EBUSY when trying to set the format while stream is on
- remove vsd struct
- add IS_SRC and IS_SINK macros
- add deb_mean_win_size as a parameter of the module
- check set_fmt default parameters for quantization, colorspace ...
- add more dev_dbg


---
 drivers/media/platform/vimc/Makefile   |   4 +-
 drivers/media/platform/vimc/vimc-common.h  |   2 +
 drivers/media/platform/vimc/vimc-debayer.c | 601 +
 3 files changed, 606 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/vimc/vimc-debayer.c

diff --git a/drivers/media/platform/vimc/Makefile 
b/drivers/media/platform/vimc/Makefile
index 0e5d5ce..4fba8ef 100644
--- a/drivers/media/platform/vimc/Makefile
+++ b/drivers/media/platform/vimc/Makefile
@@ -1,6 +1,8 @@
 vimc-objs := vimc-core.o
 vimc_capture-objs := vimc-capture.o
 vimc_common-objs := vimc-common.o
+vimc_debayer-objs := vimc-debayer.o
 vimc_sensor-objs := vimc-sensor.o
 
-obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc_capture.o vimc_common.o vimc_sensor.o
+obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc_capture.o vimc_common.o vimc-debayer.o 
\
+   vimc_sensor.o
diff --git a/drivers/media/platform/vimc/vimc-common.h 
b/drivers/media/platform/vimc/vimc-common.h
index a9c1cfd..25ba752 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -27,6 +27,8 @@
 #define VIMC_FRAME_MIN_WIDTH 16
 #define VIMC_FRAME_MIN_HEIGHT 16
 
+#define VIMC_FRAME_INDEX(lin, col, width, bpp) ((lin * width + col) * bpp)
+
 /**
  * struct vimc_colorimetry_clamp - Adjust colorimetry parameters
  *
diff --git a/drivers/media/platform/vimc/vimc-debayer.c 
b/drivers/media/platform/vimc/vimc-debayer.c
new file mode 100644
index 000..35b15bd
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-debayer.c
@@ -0,0 +1,601 @@
+/*
+ * vimc-debayer.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015-2017 Helen Koike 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "vimc-common.h"
+
+#define VIMC_DEB_DRV_NAME "vimc-debayer"
+
+static unsigned int deb_mean_win_size = 3;
+module_param(deb_mean_win_size, uint, );
+MODULE_PARM_DESC(deb_mean_win_size, " the window size to calculate the mean.\n"
+   "NOTE: the window size need to be an odd number, as the main pixel "
+   "stays in the center of the window, otherwise the next odd number "
+   "is considered");
+
+#define IS_SINK(pad) (!pad)
+#define IS_SRC(pad)  (pad)
+
+enum vimc_deb_rgb_colors {
+   VIMC_DEB_RED = 0,
+   VIMC_DEB_GREEN = 1,
+   VIM

[PATCH v5 11/12] [media] vimc: sca: Add scaler

2017-06-19 Thread Helen Koike
Implement scaler and integrated with the core

Signed-off-by: Helen Koike 

---

Changes in v5:
[media] vimc: sca: Add scaler
- declare vimc_sca_video_ops as static, remove sparse warning

Changes in v4:
[media] vimc: sca: Add scaler
- use vimc_colorimetry_clamp
- replace V4L2_COLORSPACE_SRGB by V4L2_COLORSPACE_DEFAULT in the
default format struct
- use struct vimc_platform_data to retrieve the entity's name

Changes in v3:
[media] vimc: sca: Add scaler
- Declare frame_size as a local variable
- s_stream(sd, 1): return 0 if stream is already enabled
- s_stream(sd, 0): return 0 if stream is already disabled
- s_stream: add ret variable to propagate return errors
- structure code to be a module, use platform_driver and component 
system
- s/thought/through
- clamp height and width of the image by an even value
- if user try to set colorspace to an invalid format, set all
colorimetry parameters to _DEFAULT
- uset _DEFAULT for colorimetry in the default format

Changes in v2:
[media] vimc: sca: Add scaler
- Add function MEDIA_ENT_F_IO_V4L
- remove v4l2_dev and dev
- s/sink_mbus_fmt/sink_fmt
- remove BUG_ON, remove redundant if else, rewrite TODO, check end of 
enum
- rm src_width/height, enum fsize with min and max values
- set/try fmt
- remove unecessary include freezer.h
- core: add bayer boolean in pixel table
- coding style
- fix bug in enum frame size
- check pad types on create
- return EBUSY when trying to set the format while stream is on
- remove vsd struct
- add IS_SRC and IS_SINK macros
- add sca_mult as a parameter of the module
- check set_fmt default parameters for quantization, colorspace ...
- add more dev_dbg


---
 drivers/media/platform/vimc/Makefile  |   3 +-
 drivers/media/platform/vimc/vimc-common.c |  27 ++
 drivers/media/platform/vimc/vimc-common.h |   1 +
 drivers/media/platform/vimc/vimc-scaler.c | 455 ++
 4 files changed, 485 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/vimc/vimc-scaler.c

diff --git a/drivers/media/platform/vimc/Makefile 
b/drivers/media/platform/vimc/Makefile
index 4fba8ef..68c5d98 100644
--- a/drivers/media/platform/vimc/Makefile
+++ b/drivers/media/platform/vimc/Makefile
@@ -2,7 +2,8 @@ vimc-objs := vimc-core.o
 vimc_capture-objs := vimc-capture.o
 vimc_common-objs := vimc-common.o
 vimc_debayer-objs := vimc-debayer.o
+vimc_scaler-objs := vimc-scaler.o
 vimc_sensor-objs := vimc-sensor.o
 
 obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc_capture.o vimc_common.o vimc-debayer.o 
\
-   vimc_sensor.o
+   vimc_scaler.o vimc_sensor.o
diff --git a/drivers/media/platform/vimc/vimc-common.c 
b/drivers/media/platform/vimc/vimc-common.c
index da7f2b7..9d63c84 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -20,6 +20,10 @@
 
 #include "vimc-common.h"
 
+/*
+ * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code
+ * in the scaler)
+ */
 static const struct vimc_pix_map vimc_pix_map_list[] = {
/* TODO: add all missing formats */
 
@@ -28,16 +32,19 @@ static const struct vimc_pix_map vimc_pix_map_list[] = {
.code = MEDIA_BUS_FMT_BGR888_1X24,
.pixelformat = V4L2_PIX_FMT_BGR24,
.bpp = 3,
+   .bayer = false,
},
{
.code = MEDIA_BUS_FMT_RGB888_1X24,
.pixelformat = V4L2_PIX_FMT_RGB24,
.bpp = 3,
+   .bayer = false,
},
{
.code = MEDIA_BUS_FMT_ARGB_1X32,
.pixelformat = V4L2_PIX_FMT_ARGB32,
.bpp = 4,
+   .bayer = false,
},
 
/* Bayer formats */
@@ -45,41 +52,49 @@ static const struct vimc_pix_map vimc_pix_map_list[] = {
.code = MEDIA_BUS_FMT_SBGGR8_1X8,
.pixelformat = V4L2_PIX_FMT_SBGGR8,
.bpp = 1,
+   .bayer = true,
},
{
.code = MEDIA_BUS_FMT_SGBRG8_1X8,
.pixelformat = V4L2_PIX_FMT_SGBRG8,
.bpp = 1,
+   .bayer = true,
},
{
.code = MEDIA_BUS_FMT_SGRBG8_1X8,
.pixelformat = V4L2_PIX_FMT_SGRBG8,
.bpp = 1,
+   .bayer = true,
},
{
.code = MEDIA_BUS_FMT_SRGGB8_1X8,
.pixelformat = V4L2_PIX_FMT_SRGGB8,
.bpp = 1,
+   .bayer = true,
},
{
.code = MEDIA_BUS_FMT_SBGGR10_1X10,
.pixelformat = V4L2_PIX_FMT_SBGGR10,
.bpp = 2,
+ 

[PATCH v5 12/12] [media] vimc: sen: Declare vimc_sen_video_ops as static

2017-06-19 Thread Helen Koike
Declare vimc_sen_video_ops as static, remove warning from sparse tool

Signed-off-by: Helen Koike 

---

Changes in v5:
[media] vimc: sen: Declare vimc_sen_video_ops as static
- This is a new patch in the series

Changes in v4: None
Changes in v3: None
Changes in v2: None


---
 drivers/media/platform/vimc/vimc-sensor.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
b/drivers/media/platform/vimc/vimc-sensor.c
index 5ea7b08..ebdbbe8 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -282,7 +282,7 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int 
enable)
return 0;
 }
 
-struct v4l2_subdev_video_ops vimc_sen_video_ops = {
+static struct v4l2_subdev_video_ops vimc_sen_video_ops = {
.s_stream = vimc_sen_s_stream,
 };
 
-- 
2.7.4



[PATCH v5 03/12] [media] vimc: common: Add vimc_ent_sd_* helper

2017-06-19 Thread Helen Koike
As all the subdevices in the topology will be initialized in the same
way, to avoid code repetition the vimc_ent_sd_{register, unregister}
helper functions were created

Signed-off-by: Helen Koike 

---

Changes in v5: None
Changes in v4: None
Changes in v3:
[media] vimc: common: Add vimc_ent_sd_* helper
- add it in vimc-common.c instead in vimc-core.c
- fix vimc_ent_sd_register, use function parameter to assign
sd->entity.function instead of using a fixed value
- rename commit to add the "common" tag

Changes in v2:
[media] vimc: Add vimc_ent_sd_* helper functions
- Comments in vimc_ent_sd_init
- Update vimc_ent_sd_init with upstream code as media_entity_pads_init
(instead of media_entity_init), entity->function intead of entity->type
- Add missing vimc_pads_cleanup in vimc_ent_sd_cleanup
- remove subdevice v4l2_dev and dev fields
- change unregister order in vimc_ent_sd_cleanup
- rename vimc_ent_sd_{init,cleanup} to vimc_ent_sd_{register,unregister}
- remove struct vimc_ent_subdevice, use ved and sd directly
- don't impose struct vimc_sen_device to declare ved and sd struct first
- add kernel docs


---
 drivers/media/platform/vimc/vimc-common.c | 66 +++
 drivers/media/platform/vimc/vimc-common.h | 39 ++
 drivers/media/platform/vimc/vimc-sensor.c | 58 +--
 3 files changed, 114 insertions(+), 49 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-common.c 
b/drivers/media/platform/vimc/vimc-common.c
index 42f779a..3afbabd 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -219,3 +219,69 @@ struct media_pad *vimc_pads_init(u16 num_pads, const 
unsigned long *pads_flag)
 
return pads;
 }
+
+static const struct media_entity_operations vimc_ent_sd_mops = {
+   .link_validate = v4l2_subdev_link_validate,
+};
+
+int vimc_ent_sd_register(struct vimc_ent_device *ved,
+struct v4l2_subdev *sd,
+struct v4l2_device *v4l2_dev,
+const char *const name,
+u32 function,
+u16 num_pads,
+const unsigned long *pads_flag,
+const struct v4l2_subdev_ops *sd_ops,
+void (*sd_destroy)(struct vimc_ent_device *))
+{
+   int ret;
+
+   /* Allocate the pads */
+   ved->pads = vimc_pads_init(num_pads, pads_flag);
+   if (IS_ERR(ved->pads))
+   return PTR_ERR(ved->pads);
+
+   /* Fill the vimc_ent_device struct */
+   ved->destroy = sd_destroy;
+   ved->ent = &sd->entity;
+
+   /* Initialize the subdev */
+   v4l2_subdev_init(sd, sd_ops);
+   sd->entity.function = function;
+   sd->entity.ops = &vimc_ent_sd_mops;
+   sd->owner = THIS_MODULE;
+   strlcpy(sd->name, name, sizeof(sd->name));
+   v4l2_set_subdevdata(sd, ved);
+
+   /* Expose this subdev to user space */
+   sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+   /* Initialize the media entity */
+   ret = media_entity_pads_init(&sd->entity, num_pads, ved->pads);
+   if (ret)
+   goto err_clean_pads;
+
+   /* Register the subdev with the v4l2 and the media framework */
+   ret = v4l2_device_register_subdev(v4l2_dev, sd);
+   if (ret) {
+   dev_err(v4l2_dev->dev,
+   "%s: subdev register failed (err=%d)\n",
+   name, ret);
+   goto err_clean_m_ent;
+   }
+
+   return 0;
+
+err_clean_m_ent:
+   media_entity_cleanup(&sd->entity);
+err_clean_pads:
+   vimc_pads_cleanup(ved->pads);
+   return ret;
+}
+
+void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev 
*sd)
+{
+   v4l2_device_unregister_subdev(sd);
+   media_entity_cleanup(ved->ent);
+   vimc_pads_cleanup(ved->pads);
+}
diff --git a/drivers/media/platform/vimc/vimc-common.h 
b/drivers/media/platform/vimc/vimc-common.h
index 00d3da4..9ec361c 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -110,4 +110,43 @@ const struct vimc_pix_map *vimc_pix_map_by_code(u32 code);
  */
 const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat);
 
+/**
+ * vimc_ent_sd_register - initialize and register a subdev node
+ *
+ * @ved:   the vimc_ent_device struct to be initialize
+ * @sd:the v4l2_subdev struct to be initialize and registered
+ * @v4l2_dev:  the v4l2 device to register the v4l2_subdev
+ * @name:  name of the sub-device. Please notice that the name must be
+ * unique.
+ * @function:  media entity function defined by MEDIA_ENT_F_* macros
+ * @num_pads:  number of pad

[PATCH v5 00/12] [media]: vimc: Virtual Media Control VPU's

2017-06-19 Thread Helen Koike
t
- remove unecessary include freezer.h
- core: add bayer boolean in pixel table
- coding style
- fix bug in enum frame size
- check pad types on create
- return EBUSY when trying to set the format while stream is on
- remove vsd struct
- add IS_SRC and IS_SINK macros
- add sca_mult as a parameter of the module
- check set_fmt default parameters for quantization, colorspace ...
- add more dev_dbg

Helen Koike (12):
  [media] vimc: sen: Integrate the tpg on the sensor
  [media] vimc: Move common code from the core
  [media] vimc: common: Add vimc_ent_sd_* helper
  [media] vimc: common: Add vimc_pipeline_s_stream helper
  [media] vimc: common: Add vimc_link_validate
  [media] vimc: common: Add vimc_colorimetry_clamp
  [media] vimc: sen: Support several image formats
  [media] vimc: cap: Support several image formats
  [media] vimc: Subdevices as modules
  [media] vimc: deb: Add debayer filter
  [media] vimc: sca: Add scaler
  [media] vimc: sen: Declare vimc_sen_video_ops as static

 drivers/media/platform/vimc/Kconfig|   1 +
 drivers/media/platform/vimc/Makefile   |  10 +-
 drivers/media/platform/vimc/vimc-capture.c | 321 ---
 drivers/media/platform/vimc/vimc-capture.h |  28 --
 drivers/media/platform/vimc/vimc-common.c  | 473 ++
 drivers/media/platform/vimc/vimc-common.h  | 229 +++
 drivers/media/platform/vimc/vimc-core.c| 610 -
 drivers/media/platform/vimc/vimc-core.h| 112 --
 drivers/media/platform/vimc/vimc-debayer.c | 601 
 drivers/media/platform/vimc/vimc-scaler.c  | 455 +
 drivers/media/platform/vimc/vimc-sensor.c  | 321 ++-
 drivers/media/platform/vimc/vimc-sensor.h  |  28 --
 12 files changed, 2325 insertions(+), 864 deletions(-)
 delete mode 100644 drivers/media/platform/vimc/vimc-capture.h
 create mode 100644 drivers/media/platform/vimc/vimc-common.c
 create mode 100644 drivers/media/platform/vimc/vimc-common.h
 delete mode 100644 drivers/media/platform/vimc/vimc-core.h
 create mode 100644 drivers/media/platform/vimc/vimc-debayer.c
 create mode 100644 drivers/media/platform/vimc/vimc-scaler.c
 delete mode 100644 drivers/media/platform/vimc/vimc-sensor.h

-- 
2.7.4



[PATCH v2] [media] v4l2: add V4L2_CAP_IO_MC

2017-06-13 Thread Helen Koike
Add V4L2_CAP_IO_MC to be used in struct v4l2_capability to indicate that
input and output are controlled by the Media Controller instead of V4L2
API.
When this flag is set, ioctls for get, set and enum input and outputs
are automatically enabled and programmed to call helper function.

Signed-off-by: Helen Koike 

---

Changes in v2::
- replace the type by capability
- erase V4L2_INPUT_TYPE_DEFAULT
- also consider output
- plug helpers in the ops automatically so drivers doesn't need
to set it by hand
- update docs
- commit message and title
---
 Documentation/media/uapi/v4l/vidioc-querycap.rst |  3 +
 Documentation/media/videodev2.h.rst.exceptions   |  1 +
 drivers/media/v4l2-core/v4l2-dev.c   | 35 +++--
 drivers/media/v4l2-core/v4l2-ioctl.c | 91 ++--
 include/uapi/linux/videodev2.h   |  2 +
 5 files changed, 120 insertions(+), 12 deletions(-)

diff --git a/Documentation/media/uapi/v4l/vidioc-querycap.rst 
b/Documentation/media/uapi/v4l/vidioc-querycap.rst
index 12e0d9a..2bd1223 100644
--- a/Documentation/media/uapi/v4l/vidioc-querycap.rst
+++ b/Documentation/media/uapi/v4l/vidioc-querycap.rst
@@ -252,6 +252,9 @@ specification the ioctl returns an ``EINVAL`` error code.
 * - ``V4L2_CAP_TOUCH``
   - 0x1000
   - This is a touch device.
+* - ``V4L2_CAP_IO_MC``
+  - 0x2000
+  - This device has its inputs and outputs controller by the Media 
Controller
 * - ``V4L2_CAP_DEVICE_CAPS``
   - 0x8000
   - The driver fills the ``device_caps`` field. This capability can
diff --git a/Documentation/media/videodev2.h.rst.exceptions 
b/Documentation/media/videodev2.h.rst.exceptions
index a5cb0a8..0b48cd0 100644
--- a/Documentation/media/videodev2.h.rst.exceptions
+++ b/Documentation/media/videodev2.h.rst.exceptions
@@ -159,6 +159,7 @@ replace define V4L2_CAP_ASYNCIO device-capabilities
 replace define V4L2_CAP_STREAMING device-capabilities
 replace define V4L2_CAP_DEVICE_CAPS device-capabilities
 replace define V4L2_CAP_TOUCH device-capabilities
+replace define V4L2_CAP_IO_MC device-capabilities
 
 # V4L2 pix flags
 replace define V4L2_PIX_FMT_PRIV_MAGIC :c:type:`v4l2_pix_format`
diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index c647ba6..0f272fe 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -688,22 +688,34 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_G_STD, vidioc_g_std);
if (is_rx) {
SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd);
-   SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, 
vidioc_enum_input);
-   SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input);
-   SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input);
SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDIO, 
vidioc_enumaudio);
SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio);
SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio);
SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, 
vidioc_query_dv_timings);
SET_VALID_IOCTL(ops, VIDIOC_S_EDID, vidioc_s_edid);
+   if (vdev->device_caps & V4L2_CAP_IO_MC) {
+   set_bit(_IOC_NR(VIDIOC_ENUMINPUT), 
valid_ioctls);
+   set_bit(_IOC_NR(VIDIOC_G_INPUT), valid_ioctls);
+   set_bit(_IOC_NR(VIDIOC_S_INPUT), valid_ioctls);
+   } else {
+   SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, 
vidioc_enum_input);
+   SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, 
vidioc_g_input);
+   SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, 
vidioc_s_input);
+   }
}
if (is_tx) {
-   SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, 
vidioc_enum_output);
-   SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output);
-   SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output);
SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDOUT, 
vidioc_enumaudout);
SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout);
SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout);
+   if (vdev->device_caps & V4L2_CAP_IO_MC) {
+   set_bit(_IOC_NR(VIDIOC_ENUMOUTPUT), 
valid_ioctls);
+   set_bit(_IOC_NR(VIDIOC_G_OUTPUT), valid_ioctls);
+   set_bit(_IOC_NR(VIDIOC_S_OUTPUT), valid_ioctls);
+   } else {
+   SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, 

[PATCH v4 01/11] [media] vimc: sen: Integrate the tpg on the sensor

2017-06-13 Thread Helen Koike
Initialize the test pattern generator on the sensor
Generate a colored bar image instead of a grey one

Signed-off-by: Helen Koike 

---

Changes in v4: None
Changes in v3:
[media] vimc: sen: Integrate the tpg on the sensor
- Declare frame_size as a local variable
- Set tpg frame format before starting kthread
- s_stream(sd, 1): return 0 if stream is already enabled
- s_stream(sd, 0): return 0 if stream is already disabled
- s_stream: propagate error from kthread_stop
- coding style when calling tpg_s_bytesperline
- s/vimc_thread_sen/vimc_sen_tpg_thread
- fix multiline comment
- remove V4L2_FIELD_ALTERNATE from tpg_s_field
- remove V4L2_STD_PAL from tpg_fill_plane_buffer

Changes in v2:
[media] vimc: sen: Integrate the tpg on the sensor
- Fix include location
- Select V4L2_TPG in Kconfig
- configure tpg on streamon only
- rm BUG_ON
- coding style


---
 drivers/media/platform/vimc/Kconfig   |  1 +
 drivers/media/platform/vimc/vimc-sensor.c | 64 ---
 2 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/drivers/media/platform/vimc/Kconfig 
b/drivers/media/platform/vimc/Kconfig
index a18f635..71c9fe7 100644
--- a/drivers/media/platform/vimc/Kconfig
+++ b/drivers/media/platform/vimc/Kconfig
@@ -2,6 +2,7 @@ config VIDEO_VIMC
tristate "Virtual Media Controller Driver (VIMC)"
depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
select VIDEOBUF2_VMALLOC
+   select VIDEO_V4L2_TPG
default n
---help---
  Skeleton driver for Virtual Media Controller
diff --git a/drivers/media/platform/vimc/vimc-sensor.c 
b/drivers/media/platform/vimc/vimc-sensor.c
index 591f6a4..2e83487 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -20,17 +20,20 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "vimc-sensor.h"
 
+#define VIMC_SEN_FRAME_MAX_WIDTH 4096
+
 struct vimc_sen_device {
struct vimc_ent_device ved;
struct v4l2_subdev sd;
+   struct tpg_data tpg;
struct task_struct *kthread_sen;
u8 *frame;
/* The active format */
struct v4l2_mbus_framefmt mbus_format;
-   int frame_size;
 };
 
 static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
@@ -84,6 +87,24 @@ static int vimc_sen_get_fmt(struct v4l2_subdev *sd,
return 0;
 }
 
+static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
+{
+   const struct vimc_pix_map *vpix =
+   vimc_pix_map_by_code(vsen->mbus_format.code);
+
+   tpg_reset_source(&vsen->tpg, vsen->mbus_format.width,
+vsen->mbus_format.height, vsen->mbus_format.field);
+   tpg_s_bytesperline(&vsen->tpg, 0, vsen->mbus_format.width * vpix->bpp);
+   tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height);
+   tpg_s_fourcc(&vsen->tpg, vpix->pixelformat);
+   /* TODO: add support for V4L2_FIELD_ALTERNATE */
+   tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false);
+   tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace);
+   tpg_s_ycbcr_enc(&vsen->tpg, vsen->mbus_format.ycbcr_enc);
+   tpg_s_quantization(&vsen->tpg, vsen->mbus_format.quantization);
+   tpg_s_xfer_func(&vsen->tpg, vsen->mbus_format.xfer_func);
+}
+
 static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
.enum_mbus_code = vimc_sen_enum_mbus_code,
.enum_frame_size= vimc_sen_enum_frame_size,
@@ -97,7 +118,7 @@ static const struct media_entity_operations vimc_sen_mops = {
.link_validate = v4l2_subdev_link_validate,
 };
 
-static int vimc_thread_sen(void *data)
+static int vimc_sen_tpg_thread(void *data)
 {
struct vimc_sen_device *vsen = data;
unsigned int i;
@@ -110,7 +131,7 @@ static int vimc_thread_sen(void *data)
if (kthread_should_stop())
break;
 
-   memset(vsen->frame, 100, vsen->frame_size);
+   tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame);
 
/* Send the frame to all source pads */
for (i = 0; i < vsen->sd.entity.num_pads; i++)
@@ -132,26 +153,31 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int 
enable)
 
if (enable) {
const struct vimc_pix_map *vpix;
+   unsigned int frame_size;
 
if (vsen->kthread_sen)
-   return -EINVAL;
+   /* tpg is already executing */
+   return 0;
 
/* Calculate the frame size */
vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
-   vsen->frame_s

[PATCH v4 02/11] [media] vimc: Move common code from the core

2017-06-13 Thread Helen Koike
Remove helper functions from vimc-core and add it in vimc-common to
clean up the core.

Signed-off-by: Helen Koike 

---

Changes in v4: None
Changes in v3:
[media] vimc: Move common code from the core
- This is a new patch in the series

Changes in v2: None


---
 drivers/media/platform/vimc/Makefile   |   2 +-
 drivers/media/platform/vimc/vimc-capture.h |   2 +-
 drivers/media/platform/vimc/vimc-common.c  | 221 +
 .../platform/vimc/{vimc-core.h => vimc-common.h}   |   7 +-
 drivers/media/platform/vimc/vimc-core.c| 205 +--
 drivers/media/platform/vimc/vimc-sensor.h  |   2 +-
 6 files changed, 229 insertions(+), 210 deletions(-)
 create mode 100644 drivers/media/platform/vimc/vimc-common.c
 rename drivers/media/platform/vimc/{vimc-core.h => vimc-common.h} (96%)

diff --git a/drivers/media/platform/vimc/Makefile 
b/drivers/media/platform/vimc/Makefile
index c45195e..6b6ddf4 100644
--- a/drivers/media/platform/vimc/Makefile
+++ b/drivers/media/platform/vimc/Makefile
@@ -1,3 +1,3 @@
-vimc-objs := vimc-core.o vimc-capture.o vimc-sensor.o
+vimc-objs := vimc-core.o vimc-capture.o vimc-common.o vimc-sensor.o
 
 obj-$(CONFIG_VIDEO_VIMC) += vimc.o
diff --git a/drivers/media/platform/vimc/vimc-capture.h 
b/drivers/media/platform/vimc/vimc-capture.h
index 581a813..7e5c707 100644
--- a/drivers/media/platform/vimc/vimc-capture.h
+++ b/drivers/media/platform/vimc/vimc-capture.h
@@ -18,7 +18,7 @@
 #ifndef _VIMC_CAPTURE_H_
 #define _VIMC_CAPTURE_H_
 
-#include "vimc-core.h"
+#include "vimc-common.h"
 
 struct vimc_ent_device *vimc_cap_create(struct v4l2_device *v4l2_dev,
const char *const name,
diff --git a/drivers/media/platform/vimc/vimc-common.c 
b/drivers/media/platform/vimc/vimc-common.c
new file mode 100644
index 000..42f779a
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -0,0 +1,221 @@
+/*
+ * vimc-common.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015-2017 Helen Koike 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "vimc-common.h"
+
+static const struct vimc_pix_map vimc_pix_map_list[] = {
+   /* TODO: add all missing formats */
+
+   /* RGB formats */
+   {
+   .code = MEDIA_BUS_FMT_BGR888_1X24,
+   .pixelformat = V4L2_PIX_FMT_BGR24,
+   .bpp = 3,
+   },
+   {
+   .code = MEDIA_BUS_FMT_RGB888_1X24,
+   .pixelformat = V4L2_PIX_FMT_RGB24,
+   .bpp = 3,
+   },
+   {
+   .code = MEDIA_BUS_FMT_ARGB_1X32,
+   .pixelformat = V4L2_PIX_FMT_ARGB32,
+   .bpp = 4,
+   },
+
+   /* Bayer formats */
+   {
+   .code = MEDIA_BUS_FMT_SBGGR8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SBGGR8,
+   .bpp = 1,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SGBRG8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SGBRG8,
+   .bpp = 1,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SGRBG8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SGRBG8,
+   .bpp = 1,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SRGGB8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SRGGB8,
+   .bpp = 1,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SBGGR10_1X10,
+   .pixelformat = V4L2_PIX_FMT_SBGGR10,
+   .bpp = 2,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SGBRG10_1X10,
+   .pixelformat = V4L2_PIX_FMT_SGBRG10,
+   .bpp = 2,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SGRBG10_1X10,
+   .pixelformat = V4L2_PIX_FMT_SGRBG10,
+   .bpp = 2,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SRGGB10_1X10,
+   .pixelformat = V4L2_PIX_FMT_SRGGB10,
+   .bpp = 2,
+   },
+
+   /* 10bit raw bayer a-law compressed to 8 bits */
+   {
+   .code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
+   .bpp = 1,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
+   .bpp = 1,
+   },
+   {
+   .code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
+   .pixelformat = V4L2_PIX_FMT_SG

[PATCH v4 03/11] [media] vimc: common: Add vimc_ent_sd_* helper

2017-06-13 Thread Helen Koike
As all the subdevices in the topology will be initialized in the same
way, to avoid code repetition the vimc_ent_sd_{register, unregister}
helper functions were created

Signed-off-by: Helen Koike 

---

Changes in v4: None
Changes in v3:
[media] vimc: common: Add vimc_ent_sd_* helper
- add it in vimc-common.c instead in vimc-core.c
- fix vimc_ent_sd_register, use function parameter to assign
sd->entity.function instead of using a fixed value
- rename commit to add the "common" tag

Changes in v2:
[media] vimc: Add vimc_ent_sd_* helper functions
- Comments in vimc_ent_sd_init
- Update vimc_ent_sd_init with upstream code as media_entity_pads_init
(instead of media_entity_init), entity->function intead of entity->type
- Add missing vimc_pads_cleanup in vimc_ent_sd_cleanup
- remove subdevice v4l2_dev and dev fields
- change unregister order in vimc_ent_sd_cleanup
- rename vimc_ent_sd_{init,cleanup} to vimc_ent_sd_{register,unregister}
- remove struct vimc_ent_subdevice, use ved and sd directly
- don't impose struct vimc_sen_device to declare ved and sd struct first
- add kernel docs


---
 drivers/media/platform/vimc/vimc-common.c | 66 +++
 drivers/media/platform/vimc/vimc-common.h | 39 ++
 drivers/media/platform/vimc/vimc-sensor.c | 58 +--
 3 files changed, 114 insertions(+), 49 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-common.c 
b/drivers/media/platform/vimc/vimc-common.c
index 42f779a..3afbabd 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -219,3 +219,69 @@ struct media_pad *vimc_pads_init(u16 num_pads, const 
unsigned long *pads_flag)
 
return pads;
 }
+
+static const struct media_entity_operations vimc_ent_sd_mops = {
+   .link_validate = v4l2_subdev_link_validate,
+};
+
+int vimc_ent_sd_register(struct vimc_ent_device *ved,
+struct v4l2_subdev *sd,
+struct v4l2_device *v4l2_dev,
+const char *const name,
+u32 function,
+u16 num_pads,
+const unsigned long *pads_flag,
+const struct v4l2_subdev_ops *sd_ops,
+void (*sd_destroy)(struct vimc_ent_device *))
+{
+   int ret;
+
+   /* Allocate the pads */
+   ved->pads = vimc_pads_init(num_pads, pads_flag);
+   if (IS_ERR(ved->pads))
+   return PTR_ERR(ved->pads);
+
+   /* Fill the vimc_ent_device struct */
+   ved->destroy = sd_destroy;
+   ved->ent = &sd->entity;
+
+   /* Initialize the subdev */
+   v4l2_subdev_init(sd, sd_ops);
+   sd->entity.function = function;
+   sd->entity.ops = &vimc_ent_sd_mops;
+   sd->owner = THIS_MODULE;
+   strlcpy(sd->name, name, sizeof(sd->name));
+   v4l2_set_subdevdata(sd, ved);
+
+   /* Expose this subdev to user space */
+   sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+   /* Initialize the media entity */
+   ret = media_entity_pads_init(&sd->entity, num_pads, ved->pads);
+   if (ret)
+   goto err_clean_pads;
+
+   /* Register the subdev with the v4l2 and the media framework */
+   ret = v4l2_device_register_subdev(v4l2_dev, sd);
+   if (ret) {
+   dev_err(v4l2_dev->dev,
+   "%s: subdev register failed (err=%d)\n",
+   name, ret);
+   goto err_clean_m_ent;
+   }
+
+   return 0;
+
+err_clean_m_ent:
+   media_entity_cleanup(&sd->entity);
+err_clean_pads:
+   vimc_pads_cleanup(ved->pads);
+   return ret;
+}
+
+void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev 
*sd)
+{
+   v4l2_device_unregister_subdev(sd);
+   media_entity_cleanup(ved->ent);
+   vimc_pads_cleanup(ved->pads);
+}
diff --git a/drivers/media/platform/vimc/vimc-common.h 
b/drivers/media/platform/vimc/vimc-common.h
index 00d3da4..9ec361c 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -110,4 +110,43 @@ const struct vimc_pix_map *vimc_pix_map_by_code(u32 code);
  */
 const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat);
 
+/**
+ * vimc_ent_sd_register - initialize and register a subdev node
+ *
+ * @ved:   the vimc_ent_device struct to be initialize
+ * @sd:the v4l2_subdev struct to be initialize and registered
+ * @v4l2_dev:  the v4l2 device to register the v4l2_subdev
+ * @name:  name of the sub-device. Please notice that the name must be
+ * unique.
+ * @function:  media entity function defined by MEDIA_ENT_F_* macros
+ * @num_pads:  number of pads to initialize
+

[PATCH v4 04/11] [media] vimc: common: Add vimc_pipeline_s_stream helper

2017-06-13 Thread Helen Koike
Move the vimc_cap_pipeline_s_stream from the vimc-cap.c to vimc-common.c
as this core will be reused by other subdevices to activate the stream
in their directly connected nodes

Signed-off-by: Helen Koike 

---

Changes in v4: None
Changes in v3:
[media] vimc: Add vimc_pipeline_s_stream in the core
- add it in vimc-common instead of vimc-core
- rename commit with "common" tag

Changes in v2:
[media] vimc: Add vimc_pipeline_s_stream in the core
- Use is_media_entity_v4l2_subdev instead of comparing with the old
entity->type
- Fix comments style
- add kernel-docs
- call s_stream across all sink pads


---
 drivers/media/platform/vimc/vimc-capture.c | 29 ++-
 drivers/media/platform/vimc/vimc-common.c  | 32 ++
 drivers/media/platform/vimc/vimc-common.h  | 11 ++
 3 files changed, 45 insertions(+), 27 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-capture.c 
b/drivers/media/platform/vimc/vimc-capture.c
index 9adb06d..93f6a09 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -132,31 +132,6 @@ static void vimc_cap_return_all_buffers(struct 
vimc_cap_device *vcap,
spin_unlock(&vcap->qlock);
 }
 
-static int vimc_cap_pipeline_s_stream(struct vimc_cap_device *vcap, int enable)
-{
-   struct v4l2_subdev *sd;
-   struct media_pad *pad;
-   int ret;
-
-   /* Start the stream in the subdevice direct connected */
-   pad = media_entity_remote_pad(&vcap->vdev.entity.pads[0]);
-
-   /*
-* if it is a raw node from vimc-core, there is nothing to activate
-* TODO: remove this when there are no more raw nodes in the
-* core and return error instead
-*/
-   if (pad->entity->obj_type == MEDIA_ENTITY_TYPE_BASE)
-   return 0;
-
-   sd = media_entity_to_v4l2_subdev(pad->entity);
-   ret = v4l2_subdev_call(sd, video, s_stream, enable);
-   if (ret && ret != -ENOIOCTLCMD)
-   return ret;
-
-   return 0;
-}
-
 static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
@@ -173,7 +148,7 @@ static int vimc_cap_start_streaming(struct vb2_queue *vq, 
unsigned int count)
}
 
/* Enable streaming from the pipe */
-   ret = vimc_cap_pipeline_s_stream(vcap, 1);
+   ret = vimc_pipeline_s_stream(&vcap->vdev.entity, 1);
if (ret) {
media_pipeline_stop(entity);
vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
@@ -192,7 +167,7 @@ static void vimc_cap_stop_streaming(struct vb2_queue *vq)
struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
 
/* Disable streaming from the pipe */
-   vimc_cap_pipeline_s_stream(vcap, 0);
+   vimc_pipeline_s_stream(&vcap->vdev.entity, 0);
 
/* Stop the media pipeline */
media_pipeline_stop(&vcap->vdev.entity);
diff --git a/drivers/media/platform/vimc/vimc-common.c 
b/drivers/media/platform/vimc/vimc-common.c
index 3afbabd..f809a9d 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -220,6 +220,38 @@ struct media_pad *vimc_pads_init(u16 num_pads, const 
unsigned long *pads_flag)
return pads;
 }
 
+int vimc_pipeline_s_stream(struct media_entity *ent, int enable)
+{
+   struct v4l2_subdev *sd;
+   struct media_pad *pad;
+   unsigned int i;
+   int ret;
+
+   for (i = 0; i < ent->num_pads; i++) {
+   if (ent->pads[i].flags & MEDIA_PAD_FL_SOURCE)
+   continue;
+
+   /* Start the stream in the subdevice direct connected */
+   pad = media_entity_remote_pad(&ent->pads[i]);
+
+   /*
+* if this is a raw node from vimc-core, then there is
+* nothing to activate
+* TODO: remove this when there are no more raw nodes in the
+* core and return error instead
+*/
+   if (pad->entity->obj_type == MEDIA_ENTITY_TYPE_BASE)
+   continue;
+
+   sd = media_entity_to_v4l2_subdev(pad->entity);
+   ret = v4l2_subdev_call(sd, video, s_stream, enable);
+   if (ret && ret != -ENOIOCTLCMD)
+   return ret;
+   }
+
+   return 0;
+}
+
 static const struct media_entity_operations vimc_ent_sd_mops = {
.link_validate = v4l2_subdev_link_validate,
 };
diff --git a/drivers/media/platform/vimc/vimc-common.h 
b/drivers/media/platform/vimc/vimc-common.h
index 9ec361c..73e7e94 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -97,6 +97,17 @@ static inline void vimc_pads_cleanup(struct 

[PATCH v4 05/11] [media] vimc: common: Add vimc_link_validate

2017-06-13 Thread Helen Koike
All links will be checked in the same way. Adding a helper function for
that

Signed-off-by: Helen Koike 

---

Changes in v4:
[media] vimc: common: Add vimc_link_validate
- remove vimc_fmt_pix_to_mbus(), replaced by
v4l2_fill_mbus_format()
- remove EXPORT_SYMBOL(vimc_link_validate), not necessary in
this patch, moved to submodules patch
- Fix multi-line comment style
- If colorspace is set to DEFAULT, then assume all the other
colorimetry parameters are also DEFAULT

Changes in v3:
[media] vimc: common: Add vimc_link_validate
- this is a new patch in the series

Changes in v2: None


---
 drivers/media/platform/vimc/vimc-capture.c |  78 +++
 drivers/media/platform/vimc/vimc-common.c  | 121 -
 drivers/media/platform/vimc/vimc-common.h  |  14 
 3 files changed, 145 insertions(+), 68 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-capture.c 
b/drivers/media/platform/vimc/vimc-capture.c
index 93f6a09..5bdecd1 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -64,6 +64,15 @@ static int vimc_cap_querycap(struct file *file, void *priv,
return 0;
 }
 
+static void vimc_cap_get_format(struct vimc_ent_device *ved,
+   struct v4l2_pix_format *fmt)
+{
+   struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
+   ved);
+
+   *fmt = vcap->format;
+}
+
 static int vimc_cap_fmt_vid_cap(struct file *file, void *priv,
  struct v4l2_format *f)
 {
@@ -231,74 +240,8 @@ static const struct vb2_ops vimc_cap_qops = {
.wait_finish= vb2_ops_wait_finish,
 };
 
-/*
- * NOTE: this function is a copy of v4l2_subdev_link_validate_get_format
- * maybe the v4l2 function should be public
- */
-static int vimc_cap_v4l2_subdev_link_validate_get_format(struct media_pad *pad,
-   struct v4l2_subdev_format *fmt)
-{
-   struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(pad->entity);
-
-   fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
-   fmt->pad = pad->index;
-
-   return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
-}
-
-static int vimc_cap_link_validate(struct media_link *link)
-{
-   struct v4l2_subdev_format source_fmt;
-   const struct vimc_pix_map *vpix;
-   struct vimc_cap_device *vcap = container_of(link->sink->entity,
-   struct vimc_cap_device,
-   vdev.entity);
-   struct v4l2_pix_format *sink_fmt = &vcap->format;
-   int ret;
-
-   /*
-* if it is a raw node from vimc-core, ignore the link for now
-* TODO: remove this when there are no more raw nodes in the
-* core and return error instead
-*/
-   if (link->source->entity->obj_type == MEDIA_ENTITY_TYPE_BASE)
-   return 0;
-
-   /* Get the the format of the subdev */
-   ret = vimc_cap_v4l2_subdev_link_validate_get_format(link->source,
-   &source_fmt);
-   if (ret)
-   return ret;
-
-   dev_dbg(vcap->vdev.v4l2_dev->dev,
-   "%s: link validate formats src:%dx%d %d sink:%dx%d %d\n",
-   vcap->vdev.name,
-   source_fmt.format.width, source_fmt.format.height,
-   source_fmt.format.code,
-   sink_fmt->width, sink_fmt->height,
-   sink_fmt->pixelformat);
-
-   /* The width, height and code must match. */
-   vpix = vimc_pix_map_by_pixelformat(sink_fmt->pixelformat);
-   if (source_fmt.format.width != sink_fmt->width
-   || source_fmt.format.height != sink_fmt->height
-   || vpix->code != source_fmt.format.code)
-   return -EPIPE;
-
-   /*
-* The field order must match, or the sink field order must be NONE
-* to support interlaced hardware connected to bridges that support
-* progressive formats only.
-*/
-   if (source_fmt.format.field != sink_fmt->field &&
-   sink_fmt->field != V4L2_FIELD_NONE)
-   return -EPIPE;
-
-   return 0;
-}
-
 static const struct media_entity_operations vimc_cap_mops = {
-   .link_validate  = vimc_cap_link_validate,
+   .link_validate  = vimc_link_validate,
 };
 
 static void vimc_cap_destroy(struct vimc_ent_device *ved)
@@ -434,6 +377,7 @@ struct vimc_ent_device *vimc_cap_create(struct v4l2_device 
*v4l2_dev,
vcap->ved.destroy = vimc_cap_destroy;
vcap->ved.ent = &vcap->vdev.entity;
vcap->ved.process_frame = vimc_cap_process_frame;
+   vcap->ved.vdev_get_format = vimc_cap_

[PATCH v4 10/11] [media] vimc: deb: Add debayer filter

2017-06-13 Thread Helen Koike
Implement the debayer filter and integrate it with the core

Signed-off-by: Helen Koike 

---

Changes in v4:
[media] vimc: deb: Add debayer filter
- Rebase without [media] vimc: Optimize frame generation through
pipe
- use vimc_colorimetry_clamp
- replace V4L2_COLORSPACE_SRGB by V4L2_COLORSPACE_DEFAULT in the
default format struct
- use struct vimc_platform_data to retrieve the entity's name

Changes in v3:
[media] vimc: deb: Add debayer filter
- Declare frame_size as a local variable
- s_stream(sd, 1): return 0 if stream is already enabled
- s_stream(sd, 0): return 0 if stream is already disabled
- s_stream: add ret variable to propagate return errors
- structure code to be a module, use platform_driver and component 
system
- fix multiline comment
- s/thought/through
- s/RGB/RGB888
- clamp height and width of the image by an even value
- if user try to set colorspace to an invalid format, set all
colorimetry parameters to _DEFAULT
- uset _DEFAULT for colorimetry in the default format

Changes in v2:
[media] vimc: deb: Add debayer filter
- Using MEDIA_ENT_F_ATV_DECODER in function
- remove v4l2_dev and dev from vimc_deb_device struct
- src fmt propagates from the sink
- coding style
- remove redundant else if statements
- check end of enum and remove BUG_ON
- enum frame size with min and max values
- set/try fmt
- remove unecessary include freezer.h
- check pad types on create
- return EBUSY when trying to set the format while stream is on
- remove vsd struct
- add IS_SRC and IS_SINK macros
- add deb_mean_win_size as a parameter of the module
- check set_fmt default parameters for quantization, colorspace ...
- add more dev_dbg


---
 drivers/media/platform/vimc/Makefile   |   4 +-
 drivers/media/platform/vimc/vimc-common.h  |   2 +
 drivers/media/platform/vimc/vimc-debayer.c | 601 +
 3 files changed, 606 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/vimc/vimc-debayer.c

diff --git a/drivers/media/platform/vimc/Makefile 
b/drivers/media/platform/vimc/Makefile
index 0e5d5ce..4fba8ef 100644
--- a/drivers/media/platform/vimc/Makefile
+++ b/drivers/media/platform/vimc/Makefile
@@ -1,6 +1,8 @@
 vimc-objs := vimc-core.o
 vimc_capture-objs := vimc-capture.o
 vimc_common-objs := vimc-common.o
+vimc_debayer-objs := vimc-debayer.o
 vimc_sensor-objs := vimc-sensor.o
 
-obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc_capture.o vimc_common.o vimc_sensor.o
+obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc_capture.o vimc_common.o vimc-debayer.o 
\
+   vimc_sensor.o
diff --git a/drivers/media/platform/vimc/vimc-common.h 
b/drivers/media/platform/vimc/vimc-common.h
index a9c1cfd..25ba752 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -27,6 +27,8 @@
 #define VIMC_FRAME_MIN_WIDTH 16
 #define VIMC_FRAME_MIN_HEIGHT 16
 
+#define VIMC_FRAME_INDEX(lin, col, width, bpp) ((lin * width + col) * bpp)
+
 /**
  * struct vimc_colorimetry_clamp - Adjust colorimetry parameters
  *
diff --git a/drivers/media/platform/vimc/vimc-debayer.c 
b/drivers/media/platform/vimc/vimc-debayer.c
new file mode 100644
index 000..e23a5b9
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-debayer.c
@@ -0,0 +1,601 @@
+/*
+ * vimc-debayer.c Virtual Media Controller Driver
+ *
+ * Copyright (C) 2015-2017 Helen Koike 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "vimc-common.h"
+
+#define VIMC_DEB_DRV_NAME "vimc-debayer"
+
+static unsigned int deb_mean_win_size = 3;
+module_param(deb_mean_win_size, uint, );
+MODULE_PARM_DESC(deb_mean_win_size, " the window size to calculate the mean.\n"
+   "NOTE: the window size need to be an odd number, as the main pixel "
+   "stays in the center of the window, otherwise the next odd number "
+   "is considered");
+
+#define IS_SINK(pad) (!pad)
+#define IS_SRC(pad)  (pad)
+
+enum vimc_deb_rgb_colors {
+   VIMC_DEB_RED = 0,
+   VIMC_DEB_GREEN = 1,
+   VIMC_DEB_BLUE = 2,
+};
+
+struct vimc_deb_pix_map {
+   u32 code;
+   enum vimc_deb_rgb_colors order[2][2];
+

[PATCH v4 11/11] [media] vimc: sca: Add scaler

2017-06-13 Thread Helen Koike
Implement scaler and integrated with the core

Signed-off-by: Helen Koike 

---

Changes in v4:
[media] vimc: sca: Add scaler
- use vimc_colorimetry_clamp
- replace V4L2_COLORSPACE_SRGB by V4L2_COLORSPACE_DEFAULT in the
default format struct
- use struct vimc_platform_data to retrieve the entity's name

Changes in v3:
[media] vimc: sca: Add scaler
- Declare frame_size as a local variable
- s_stream(sd, 1): return 0 if stream is already enabled
- s_stream(sd, 0): return 0 if stream is already disabled
- s_stream: add ret variable to propagate return errors
- structure code to be a module, use platform_driver and component 
system
- s/thought/through
- clamp height and width of the image by an even value
- if user try to set colorspace to an invalid format, set all
colorimetry parameters to _DEFAULT
- uset _DEFAULT for colorimetry in the default format

Changes in v2:
[media] vimc: sca: Add scaler
- Add function MEDIA_ENT_F_IO_V4L
- remove v4l2_dev and dev
- s/sink_mbus_fmt/sink_fmt
- remove BUG_ON, remove redundant if else, rewrite TODO, check end of 
enum
- rm src_width/height, enum fsize with min and max values
- set/try fmt
- remove unecessary include freezer.h
- core: add bayer boolean in pixel table
- coding style
- fix bug in enum frame size
- check pad types on create
- return EBUSY when trying to set the format while stream is on
- remove vsd struct
- add IS_SRC and IS_SINK macros
- add sca_mult as a parameter of the module
- check set_fmt default parameters for quantization, colorspace ...
- add more dev_dbg


---
 drivers/media/platform/vimc/Makefile  |   3 +-
 drivers/media/platform/vimc/vimc-common.c |  27 ++
 drivers/media/platform/vimc/vimc-common.h |   1 +
 drivers/media/platform/vimc/vimc-scaler.c | 455 ++
 4 files changed, 485 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/vimc/vimc-scaler.c

diff --git a/drivers/media/platform/vimc/Makefile 
b/drivers/media/platform/vimc/Makefile
index 4fba8ef..68c5d98 100644
--- a/drivers/media/platform/vimc/Makefile
+++ b/drivers/media/platform/vimc/Makefile
@@ -2,7 +2,8 @@ vimc-objs := vimc-core.o
 vimc_capture-objs := vimc-capture.o
 vimc_common-objs := vimc-common.o
 vimc_debayer-objs := vimc-debayer.o
+vimc_scaler-objs := vimc-scaler.o
 vimc_sensor-objs := vimc-sensor.o
 
 obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc_capture.o vimc_common.o vimc-debayer.o 
\
-   vimc_sensor.o
+   vimc_scaler.o vimc_sensor.o
diff --git a/drivers/media/platform/vimc/vimc-common.c 
b/drivers/media/platform/vimc/vimc-common.c
index da7f2b7..9d63c84 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -20,6 +20,10 @@
 
 #include "vimc-common.h"
 
+/*
+ * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code
+ * in the scaler)
+ */
 static const struct vimc_pix_map vimc_pix_map_list[] = {
/* TODO: add all missing formats */
 
@@ -28,16 +32,19 @@ static const struct vimc_pix_map vimc_pix_map_list[] = {
.code = MEDIA_BUS_FMT_BGR888_1X24,
.pixelformat = V4L2_PIX_FMT_BGR24,
.bpp = 3,
+   .bayer = false,
},
{
.code = MEDIA_BUS_FMT_RGB888_1X24,
.pixelformat = V4L2_PIX_FMT_RGB24,
.bpp = 3,
+   .bayer = false,
},
{
.code = MEDIA_BUS_FMT_ARGB_1X32,
.pixelformat = V4L2_PIX_FMT_ARGB32,
.bpp = 4,
+   .bayer = false,
},
 
/* Bayer formats */
@@ -45,41 +52,49 @@ static const struct vimc_pix_map vimc_pix_map_list[] = {
.code = MEDIA_BUS_FMT_SBGGR8_1X8,
.pixelformat = V4L2_PIX_FMT_SBGGR8,
.bpp = 1,
+   .bayer = true,
},
{
.code = MEDIA_BUS_FMT_SGBRG8_1X8,
.pixelformat = V4L2_PIX_FMT_SGBRG8,
.bpp = 1,
+   .bayer = true,
},
{
.code = MEDIA_BUS_FMT_SGRBG8_1X8,
.pixelformat = V4L2_PIX_FMT_SGRBG8,
.bpp = 1,
+   .bayer = true,
},
{
.code = MEDIA_BUS_FMT_SRGGB8_1X8,
.pixelformat = V4L2_PIX_FMT_SRGGB8,
.bpp = 1,
+   .bayer = true,
},
{
.code = MEDIA_BUS_FMT_SBGGR10_1X10,
.pixelformat = V4L2_PIX_FMT_SBGGR10,
.bpp = 2,
+   .bayer = true,
},
{
.code = MEDIA_BUS_FMT_SGBRG10_1X10,
.pixelformat = V4L2_PIX_FMT_SGBRG10,
 

[PATCH v4 06/11] [media] vimc: common: Add vimc_colorimetry_clamp

2017-06-13 Thread Helen Koike
Colorimetry value will always be checked in the same way. Adding a
helper macro for that

Signed-off-by: Helen Koike 

---

Changes in v4:
[media] vimc: common: Add vimc_colorimetry_clamp
- this is a new patch in the series

Changes in v3: None
Changes in v2: None


---
 drivers/media/platform/vimc/vimc-common.h | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/drivers/media/platform/vimc/vimc-common.h 
b/drivers/media/platform/vimc/vimc-common.h
index 60ebde2..43483ee 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -23,6 +23,32 @@
 #include 
 
 /**
+ * struct vimc_colorimetry_clamp - Adjust colorimetry parameters
+ *
+ * @fmt:   the pointer to struct v4l2_pix_format or
+ * struct v4l2_mbus_framefmt
+ *
+ * Entities must check if colorimetry given by the userspace is valid, if not
+ * then set them as DEFAULT
+ */
+#define vimc_colorimetry_clamp(fmt)\
+do {   \
+   if ((fmt)->colorspace == V4L2_COLORSPACE_DEFAULT\
+   || (fmt)->colorspace > V4L2_COLORSPACE_DCI_P3) {\
+   (fmt)->colorspace = V4L2_COLORSPACE_DEFAULT;\
+   (fmt)->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;  \
+   (fmt)->quantization = V4L2_QUANTIZATION_DEFAULT;\
+   (fmt)->xfer_func = V4L2_XFER_FUNC_DEFAULT;  \
+   }   \
+   if ((fmt)->ycbcr_enc > V4L2_YCBCR_ENC_SMPTE240M)\
+   (fmt)->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;  \
+   if ((fmt)->quantization > V4L2_QUANTIZATION_LIM_RANGE)  \
+   (fmt)->quantization = V4L2_QUANTIZATION_DEFAULT;\
+   if ((fmt)->xfer_func > V4L2_XFER_FUNC_SMPTE2084)\
+   (fmt)->xfer_func = V4L2_XFER_FUNC_DEFAULT;  \
+} while (0)
+
+/**
  * struct vimc_pix_map - maps media bus code with v4l2 pixel format
  *
  * @code:  media bus format code defined by MEDIA_BUS_FMT_* macros
-- 
2.7.4



[PATCH v4 08/11] [media] vimc: cap: Support several image formats

2017-06-13 Thread Helen Koike
Allow user space to change the image format as the frame size, the
pixel format, colorspace, quantization, field YCbCr encoding
and the transfer function

Signed-off-by: Helen Koike 

---

Changes in v4:
[media] vimc: cap: Support several image formats
- add vimc_colorimetry_clamp macro
- replace V4L2_COLORSPACE_SRGB by V4L2_COLORSPACE_DEFAULT in the
default format struct

Changes in v3:
[media] vimc: cap: Support several image formats
- use *_DEFAULT macros for colorimetry in the default format
- clamp height and width of the image by an even value
- is user try to set colorspace to an invalid format, set all
colorimetry parameters to _DEFAULT
- remove V4L2_FMT_FLAG_COMPRESSED from vimc_cap_enum_fmt_vid_cap
- remove V4L2_BUF_TYPE_VIDEO_CAPTURE from vimc_cap_enum_fmt_vid_cap
- increase step_width and step_height to 2 instead of 1
- remove link validate function, use the one in vimc-common.c

Changes in v2:
[media] vimc: cap: Support several image formats
- this is a new commit in the serie (the old one was splitted in two)
- allow user space to change all fields from struct v4l2_pix_format
  (e.g. colospace, quantization, field, xfer_func, ycbcr_enc)
- link_validate and try_fmt: also checks colospace, quantization, 
field, xfer_func, ycbcr_enc
- add struct v4l2_pix_format fmt_default
- add enum_framesizes
- enum_fmt_vid_cap: enumerate all formats from vimc_pix_map_table
- add mode dev_dbg


---
 drivers/media/platform/vimc/vimc-capture.c | 117 +
 1 file changed, 101 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/vimc/vimc-capture.c 
b/drivers/media/platform/vimc/vimc-capture.c
index 5bdecd1..359f59e 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -40,6 +40,14 @@ struct vimc_cap_device {
struct media_pipeline pipe;
 };
 
+static const struct v4l2_pix_format fmt_default = {
+   .width = 640,
+   .height = 480,
+   .pixelformat = V4L2_PIX_FMT_RGB24,
+   .field = V4L2_FIELD_NONE,
+   .colorspace = V4L2_COLORSPACE_DEFAULT,
+};
+
 struct vimc_cap_buffer {
/*
 * struct vb2_v4l2_buffer must be the first element
@@ -73,7 +81,7 @@ static void vimc_cap_get_format(struct vimc_ent_device *ved,
*fmt = vcap->format;
 }
 
-static int vimc_cap_fmt_vid_cap(struct file *file, void *priv,
+static int vimc_cap_g_fmt_vid_cap(struct file *file, void *priv,
  struct v4l2_format *f)
 {
struct vimc_cap_device *vcap = video_drvdata(file);
@@ -83,16 +91,98 @@ static int vimc_cap_fmt_vid_cap(struct file *file, void 
*priv,
return 0;
 }
 
+static int vimc_cap_try_fmt_vid_cap(struct file *file, void *priv,
+   struct v4l2_format *f)
+{
+   struct v4l2_pix_format *format = &f->fmt.pix;
+   const struct vimc_pix_map *vpix;
+
+   format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH,
+   VIMC_FRAME_MAX_WIDTH) & ~1;
+   format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT,
+VIMC_FRAME_MAX_HEIGHT) & ~1;
+
+   /* Don't accept a pixelformat that is not on the table */
+   vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
+   if (!vpix) {
+   format->pixelformat = fmt_default.pixelformat;
+   vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
+   }
+   /* TODO: Add support for custom bytesperline values */
+   format->bytesperline = format->width * vpix->bpp;
+   format->sizeimage = format->bytesperline * format->height;
+
+   if (format->field == V4L2_FIELD_ANY)
+   format->field = fmt_default.field;
+
+   vimc_colorimetry_clamp(format);
+
+   return 0;
+}
+
+static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+   struct vimc_cap_device *vcap = video_drvdata(file);
+
+   /* Do not change the format while stream is on */
+   if (vb2_is_busy(&vcap->queue))
+   return -EBUSY;
+
+   vimc_cap_try_fmt_vid_cap(file, priv, f);
+
+   dev_dbg(vcap->vdev.v4l2_dev->dev, "%s: format update: "
+   "old:%dx%d (0x%x, %d, %d, %d, %d) "
+   "new:%dx%d (0x%x, %d, %d, %d, %d)\n", vcap->vdev.name,
+   /* old */
+   vcap->format.width, vcap->format.height,
+   vcap->format.pixelformat, vcap->format.colorspace,
+   vcap->format.quantization, vcap->format.xfer_func,
+   vcap->format.ycbcr_enc,
+   /* new */
+   f->fmt.pix.width, f->

  1   2   >