Re: [PATCH] drm/exynos: Add check for IOMMU while passing physically continous memory flag

2013-08-02 Thread Tomasz Figa
Hi Vikas,

On Friday 02 of August 2013 12:08:52 Vikas Sajjan wrote:
> Hi Rob,
> 
> On 2 August 2013 06:03, Rob Clark  wrote:
> > On Thu, Aug 1, 2013 at 7:20 PM, Tomasz Figa  
wrote:
> >> Hi Vikas,
> >> 
> >> On Thursday 01 of August 2013 16:49:32 Vikas Sajjan wrote:
> >>> While trying to get boot-logo up on exynos5420 SMDK which has eDP
> >>> panel
> >>> connected with resolution 2560x1600, following error occured even
> >>> with
> >>> IOMMU enabled:
> >>> [0.88] [drm:lowlevel_buffer_allocate] *ERROR* failed to allocate
> >>> buffer. [0.89] [drm] Initialized exynos 1.0.0 20110530 on minor
> >>> 0
> >>> 
> >>> This patch fixes the issue by adding a check for IOMMU.
> >>> 
> >>> Signed-off-by: Vikas Sajjan 
> >>> Signed-off-by: Arun Kumar 
> >>> ---
> >>> 
> >>>  drivers/gpu/drm/exynos/exynos_drm_fbdev.c |9 -
> >>>  1 file changed, 8 insertions(+), 1 deletion(-)
[snip]
> >>> @@ -166,7 +168,12 @@ static int exynos_drm_fbdev_create(struct
> >>> drm_fb_helper *helper, size = mode_cmd.pitches[0] * mode_cmd.height;
> >>> 
> >>>   /* 0 means to allocate physically continuous memory */
> >>> 
> >>> - exynos_gem_obj = exynos_drm_gem_create(dev, 0, size);
> >>> + if (!is_drm_iommu_supported(dev))
> >>> + flag = 0;
> >>> + else
> >>> + flag = EXYNOS_BO_NONCONTIG;
> >> 
> >> While noncontig memory might be used for devices that support IOMMU,
> >> there should be no problem with using contig memory for them, so
> >> this seems more like masking the original problem rather than
> >> tracking it down.> 
> > it is probably a good idea to not require contig memory when it is not
> > needed for performance or functionality (and if it is only
> > performance, then fallback gracefully to non-contig).. but yeah, would
> > be good to know if this is masking another issue all the same
> 
> Whats happening with CONTIG flag and with IOMMU,  is
> 
>  __iommu_alloc_buffer() ---> dma_alloc_from_contiguous() and in this
> function it fails at
> this condition check  if (pageno >= cma->count)
> 
> So I tried increasing the CONFIG_CMA_SIZE_MBYTES to 24,  this check
> succeeds and it works well without my patch.
> 
> But what about the case where CONFIG_CMA is disabled , yet i want
> bigger memory for a device.
>  I think using IOMMU we can achieve this.
>
>  correct me, if i am wrong.

This is probably fine. I'm not sure about performance aspects of using 
noncontig memory as framebuffer, though. This needs to be checked and if 
there is some performance penalty, I would make noncontig allocation a 
fallback case, if contig fails, as Rob has suggested.

Also I think you should adjust the commit message to say that non-
contiguous memory can be used when IOMMU is supported, so there is no need 
to force contiguous allocations, since this is not a bug fix, but rather a 
feature this patch is adding.

Best regards,
Tomasz
 
> > BR,
> > -R
> > 
> >> Could you check why the allocation fails when requesting contiguous
> >> memory?
> >> 
> >> Best regards,
> >> Tomasz
> >> 
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe
> >> linux-media" in the body of a message to majord...@vger.kernel.org
> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] [media] exynos4-is: Fix potential NULL pointer dereference

2013-08-02 Thread Sylwester Nawrocki
Hi Sachin,

On 08/02/2013 08:32 AM, Sachin Kamat wrote:
> dev->of_node could be NULL. Hence check for the same and return before
> dereferencing it in the subsequent error message.
> 
> Signed-off-by: Sachin Kamat 
> ---
>  drivers/media/platform/exynos4-is/fimc-lite.c |3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c 
> b/drivers/media/platform/exynos4-is/fimc-lite.c
> index 08fbfed..214bde2 100644
> --- a/drivers/media/platform/exynos4-is/fimc-lite.c
> +++ b/drivers/media/platform/exynos4-is/fimc-lite.c
> @@ -1513,6 +1513,9 @@ static int fimc_lite_probe(struct platform_device *pdev)
>   if (of_id)
>   drv_data = (struct flite_drvdata *)of_id->data;
>   fimc->index = of_alias_get_id(dev->of_node, "fimc-lite");
> + } else {
> + dev_err(dev, "device node not found\n");
> + return -EINVAL;
>   }

Thanks for the patch. I would prefer to add a check at very beginning
of fimc_lite_probe() like:

if (!dev->of_node)
return -ENODEV;

Those devices are only used on DT platforms.

--
Regards,
Sylwester
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] videobuf2-dma-sg: Allocate pages as contiguous as possible

2013-08-02 Thread Andre Heider
Hi Ricardo,

sorry for the late answer, but the leak I mentioned in my first reply is still 
there, see below.

On Fri, Jul 19, 2013 at 07:02:33PM +0200, Ricardo Ribalda Delgado wrote:
> Most DMA engines have limitations regarding the number of DMA segments
> (sg-buffers) that they can handle. Videobuffers can easily spread
> through houndreds of pages.
> 
> In the previous aproach, the pages were allocated individually, this
> could led to the creation houndreds of dma segments (sg-buffers) that
> could not be handled by some DMA engines.
> 
> This patch tries to minimize the number of DMA segments by using
> alloc_pages. In the worst case it will behave as before, but most
> of the times it will reduce the number of dma segments
> 
> Signed-off-by: Ricardo Ribalda Delgado 
> ---
>  drivers/media/v4l2-core/videobuf2-dma-sg.c |   60 
> +++-
>  1 file changed, 49 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
> b/drivers/media/v4l2-core/videobuf2-dma-sg.c
> index 16ae3dc..c053605 100644
> --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
> +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
> @@ -42,10 +42,55 @@ struct vb2_dma_sg_buf {
>  
>  static void vb2_dma_sg_put(void *buf_priv);
>  
> +static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf,
> + gfp_t gfp_flags)
> +{
> + unsigned int last_page = 0;
> + int size = buf->sg_desc.size;
> +
> + while (size > 0) {
> + struct page *pages;
> + int order;
> + int i;
> +
> + order = get_order(size);
> + /* Dont over allocate*/
> + if ((PAGE_SIZE << order) > size)
> + order--;
> +
> + pages = NULL;
> + while (!pages) {
> + pages = alloc_pages(GFP_KERNEL | __GFP_ZERO |
> + __GFP_NOWARN | gfp_flags, order);
> + if (pages)
> + break;
> +
> + if (order == 0)
> + while (last_page--) {
> + __free_page(buf->pages[last_page]);
> + return -ENOMEM;
> + }

The return statement doesn't make sense in the while() scope, that way you 
wouldn't need the loop at all.

To prevent leaking pages of prior iterations (those with higher orders), pull 
the return out of there:

while (last_page--)
__free_page(buf->pages[last_page]);
return -ENOMEM;

Regards,
Andre
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] [media] exynos4-is: Fix potential NULL pointer dereference

2013-08-02 Thread Sachin Kamat
Hi Sylwester,

On 2 August 2013 14:15, Sylwester Nawrocki  wrote:
> Hi Sachin,
>
> On 08/02/2013 08:32 AM, Sachin Kamat wrote:
>> dev->of_node could be NULL. Hence check for the same and return before
>> dereferencing it in the subsequent error message.
>>
>> Signed-off-by: Sachin Kamat 
>> ---
>>  drivers/media/platform/exynos4-is/fimc-lite.c |3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c 
>> b/drivers/media/platform/exynos4-is/fimc-lite.c
>> index 08fbfed..214bde2 100644
>> --- a/drivers/media/platform/exynos4-is/fimc-lite.c
>> +++ b/drivers/media/platform/exynos4-is/fimc-lite.c
>> @@ -1513,6 +1513,9 @@ static int fimc_lite_probe(struct platform_device 
>> *pdev)
>>   if (of_id)
>>   drv_data = (struct flite_drvdata *)of_id->data;
>>   fimc->index = of_alias_get_id(dev->of_node, "fimc-lite");
>> + } else {
>> + dev_err(dev, "device node not found\n");
>> + return -EINVAL;
>>   }
>
> Thanks for the patch. I would prefer to add a check at very beginning
> of fimc_lite_probe() like:
>
> if (!dev->of_node)
> return -ENODEV;
>
> Those devices are only used on DT platforms.

OK. Sounds good. I will re-spin this one.

-- 
With warm regards,
Sachin
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/3] [media] exynos4-is: Fix potential NULL pointer dereference

2013-08-02 Thread Sachin Kamat
dev->of_node could be NULL. Hence check for the same and return before
dereferencing it in the subsequent error message.

Signed-off-by: Sachin Kamat 
---
Changes since v1:
Moved the NULL check to beginning of probe.
---
 drivers/media/platform/exynos4-is/fimc-lite.c |   13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c 
b/drivers/media/platform/exynos4-is/fimc-lite.c
index 08fbfed..318d4c3 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1504,16 +1504,17 @@ static int fimc_lite_probe(struct platform_device *pdev)
struct resource *res;
int ret;
 
+   if (!dev->of_node)
+   return -ENODEV;
+
fimc = devm_kzalloc(dev, sizeof(*fimc), GFP_KERNEL);
if (!fimc)
return -ENOMEM;
 
-   if (dev->of_node) {
-   of_id = of_match_node(flite_of_match, dev->of_node);
-   if (of_id)
-   drv_data = (struct flite_drvdata *)of_id->data;
-   fimc->index = of_alias_get_id(dev->of_node, "fimc-lite");
-   }
+   of_id = of_match_node(flite_of_match, dev->of_node);
+   if (of_id)
+   drv_data = (struct flite_drvdata *)of_id->data;
+   fimc->index = of_alias_get_id(dev->of_node, "fimc-lite");
 
if (!drv_data || fimc->index >= drv_data->num_instances ||
fimc->index < 0) {
-- 
1.7.9.5

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


Re: [PATCH v5 7/9] v4l: Renesas R-Car VSP1 driver

2013-08-02 Thread Hans Verkuil
Hi Laurent,

See my single remark below...

On 08/02/2013 03:03 AM, Laurent Pinchart wrote:
> The VSP1 is a video processing engine that includes a blender, scalers,
> filters and statistics computation. Configurable data path routing logic
> allows ordering the internal blocks in a flexible way.
> 
> Due to the configurable nature of the pipeline the driver implements the
> media controller API and doesn't use the V4L2 mem-to-mem framework, even
> though the device usually operates in memory to memory mode.
> 
> Only the read pixel formatters, up/down scalers, write pixel formatters
> and LCDC interface are supported at this stage.
> 
> Signed-off-by: Laurent Pinchart 
> Acked-by: Sakari Ailus 



> diff --git a/drivers/media/platform/vsp1/vsp1_uds.h 
> b/drivers/media/platform/vsp1/vsp1_uds.h
> new file mode 100644
> index 000..972a285
> --- /dev/null
> +++ b/drivers/media/platform/vsp1/vsp1_uds.h

...

> +/* 
> -
> + * V4L2 ioctls
> + */
> +
> +static int
> +vsp1_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
> +{
> + struct v4l2_fh *vfh = file->private_data;
> + struct vsp1_video *video = to_vsp1_video(vfh->vdev);
> +
> + cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
> +   | V4L2_CAP_VIDEO_CAPTURE_MPLANE
> +   | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
> +
> + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
> + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE
> +  | V4L2_CAP_STREAMING;
> + else
> + cap->device_caps = V4L2_CAP_VIDEO_OUTPUT_MPLANE
> +  | V4L2_CAP_STREAMING;
> +
> + strlcpy(cap->driver, "vsp1", sizeof(cap->driver));
> + strlcpy(cap->card, video->video.name, sizeof(cap->card));
> + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
> +  dev_name(video->vsp1->dev));
> +
> + return 0;
> +}
> +
> +static int
> +vsp1_video_get_format(struct file *file, void *fh, struct v4l2_format 
> *format)
> +{
> + struct v4l2_fh *vfh = file->private_data;
> + struct vsp1_video *video = to_vsp1_video(vfh->vdev);
> +
> + if (format->type != video->queue.type)
> + return -EINVAL;
> +
> + mutex_lock(&video->lock);
> + format->fmt.pix_mp = video->format;
> + mutex_unlock(&video->lock);
> +
> + return 0;
> +}
> +
> +static int
> +vsp1_video_try_format(struct file *file, void *fh, struct v4l2_format 
> *format)
> +{
> + struct v4l2_fh *vfh = file->private_data;
> + struct vsp1_video *video = to_vsp1_video(vfh->vdev);
> +
> + if (format->type != video->queue.type)
> + return -EINVAL;
> +
> + return __vsp1_video_try_format(video, &format->fmt.pix_mp, NULL);
> +}
> +
> +static int
> +vsp1_video_set_format(struct file *file, void *fh, struct v4l2_format 
> *format)
> +{
> + struct v4l2_fh *vfh = file->private_data;
> + struct vsp1_video *video = to_vsp1_video(vfh->vdev);
> + const struct vsp1_format_info *info;
> + int ret;
> +
> + if (format->type != video->queue.type)
> + return -EINVAL;
> +
> + ret = __vsp1_video_try_format(video, &format->fmt.pix_mp, &info);
> + if (ret < 0)
> + return ret;
> +
> + mutex_lock(&video->lock);
> +
> + if (vb2_is_busy(&video->queue)) {
> + ret = -EBUSY;
> + goto done;
> + }
> +
> + video->format = format->fmt.pix_mp;
> + video->fmtinfo = info;
> +
> +done:
> + mutex_unlock(&video->lock);
> + return ret;
> +}
> +
> +static int
> +vsp1_video_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers 
> *rb)
> +{
> + struct v4l2_fh *vfh = file->private_data;
> + struct vsp1_video *video = to_vsp1_video(vfh->vdev);
> + int ret;
> +
> + mutex_lock(&video->lock);
> + ret = vb2_ioctl_reqbufs(file, fh, rb);
> + mutex_unlock(&video->lock);
> +
> + return ret;
> +}
> +
> +static int
> +vsp1_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
> +{
> + struct v4l2_fh *vfh = file->private_data;
> + struct vsp1_video *video = to_vsp1_video(vfh->vdev);
> + int ret;
> +
> + mutex_lock(&video->lock);
> + ret = vb2_querybuf(&video->queue, buf);
> + mutex_unlock(&video->lock);
> +
> + return ret;
> +}
> +
> +static int
> +vsp1_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
> +{
> + struct v4l2_fh *vfh = file->private_data;
> + struct vsp1_video *video = to_vsp1_video(vfh->vdev);
> + int ret;
> +
> + mutex_lock(&video->lock);
> + ret = vb2_ioctl_qbuf(file, fh, buf);
> + mutex_unlock(&video->lock);
> +
> + return ret;
> +}
> +
> +static int
> +vsp1_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
> +{
> + struct v4l2_fh *vfh = file->private_data;
> + struct vsp1_video *video = to_vsp1_video(vfh->vd

Re: [PATCH v5 2/9] Documentation: media: Clarify the VIDIOC_CREATE_BUFS format requirements

2013-08-02 Thread Hans Verkuil
Hi Laurent,

On 08/02/2013 03:03 AM, Laurent Pinchart wrote:
> The VIDIOC_CREATE_BUFS ioctl takes a format argument that must contain a
> valid format supported by the driver. Clarify the documentation.
> 
> Signed-off-by: Laurent Pinchart 
> ---
>  Documentation/DocBook/media/v4l/vidioc-create-bufs.xml | 15 ---
>  1 file changed, 8 insertions(+), 7 deletions(-)
> 
> diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml 
> b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
> index cd99436..407937a 100644
> --- a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
> +++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
> @@ -69,10 +69,11 @@ the v4l2_create_buffers 
> structure. They set the
>  structure, to the respective stream or buffer type.
>  count must be set to the number of required 
> buffers.
>  memory specifies the required I/O method. The
> -format field shall typically be filled in using
> -either the VIDIOC_TRY_FMT or
> -VIDIOC_G_FMT ioctl(). Additionally, applications can 
> adjust
> -sizeimage fields to fit their specific needs. The
> +format field must be a valid format supported by 
> the
> +driver. Applications shall typically fill it using either the
> +VIDIOC_TRY_FMT or VIDIOC_G_FMT
> +ioctl(). Any format that would be modified by the
> +VIDIOC_TRY_FMT ioctl() will be rejected with an error. 
> The

I'm a bit unhappy with this formulation. How about: "The format must be a valid 
format,
otherwise an error will be returned."

The main reason for this is that changes made to the 'field' and 'colorspace' 
format
fields by TRY_FMT do not affect CREATE_BUFS. Does a wrong colorspace mean that
CREATE_BUFS should return an error? I'm not sure we want to do that, frankly.

You also removed the bit about the sizeimage field. That should be kept, 
although admittedly
it needs some improvement. The reason for that is that applications cannot set 
sizeimage
when calling S_FMT: that field is set by the driver. Only through CREATE_BUFS 
can apps
select a different (larger) sizeimage.

I think it would be useful if there was a link to CREATE_BUFS was added to the 
'sizeimage'
description of struct v4l2_pix_format in DocBook. It is not exactly obvious 
that CREATE_BUFS
can be used for that purpose. It's really a workaround for a limitation in the 
spec, of
course.

Regards,

Hans

>  reserved array must be zeroed.
>  
>  When the ioctl is called with a pointer to this structure the 
> driver
> @@ -144,9 +145,9 @@ mapped I/O.
>
>   EINVAL
>   
> -   The buffer type (type field) or the
> -requested I/O method (memory) is not
> -supported.
> +   The buffer type (type field),
> +requested I/O method (memory) or format
> +(format field) is not valid.
>   
>
>  
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 1/9] media: Add support for circular graph traversal

2013-08-02 Thread Hans Verkuil


On 08/02/2013 03:03 AM, Laurent Pinchart wrote:
> The graph traversal API (media_entity_graph_walk_*) doesn't support
> cyclic graphs and will fail to correctly walk a graph when circular
> links exist. Support circular graph traversal by checking whether an
> entity has already been visited before pushing it to the stack.
> 
> Signed-off-by: Laurent Pinchart 
> Acked-by: Sakari Ailus 

Acked-by: Hans Verkuil 

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 3/9] videobuf2: Clarify queue_setup() and buf_prepare() usage documentation

2013-08-02 Thread Hans Verkuil


On 08/02/2013 03:03 AM, Laurent Pinchart wrote:
> Explain how the two operations must handle formats and validate buffer
> sizes when used with VIDIOC_CREATE_BUFS.
> 
> Signed-off-by: Laurent Pinchart 

Acked-by: Hans Verkuil 

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 4/9] v4l: Fix V4L2_MBUS_FMT_YUV10_1X30 media bus pixel code value

2013-08-02 Thread Hans Verkuil


On 08/02/2013 03:03 AM, Laurent Pinchart wrote:
> The V4L2_MBUS_FMT_YUV10_1X30 code is documented as being equal to
> 0x2014, while the v4l2-mediabus.h header defines it as 0x2016. Fix the
> documentation.
> 
> Signed-off-by: Laurent Pinchart 
> Acked-by: Sakari Ailus 

Acked-by: Hans Verkuil 

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 5/9] v4l: Add media format codes for ARGB8888 and AYUV8888 on 32-bit busses

2013-08-02 Thread Hans Verkuil


On 08/02/2013 03:03 AM, Laurent Pinchart wrote:
> Signed-off-by: Laurent Pinchart 
> Reviewed-by: Sylwester Nawrocki 

Acked-by: Hans Verkuil 

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 6/9] v4l: Add V4L2_PIX_FMT_NV16M and V4L2_PIX_FMT_NV61M formats

2013-08-02 Thread Hans Verkuil


On 08/02/2013 03:03 AM, Laurent Pinchart wrote:
> NV16M and NV61M are planar YCbCr 4:2:2 and YCrCb 4:2:2 formats with a
> luma plane followed by an interleaved chroma plane. The planes are not
> required to be contiguous in memory, and the formats can only be used
> with the multi-planar formats API.
> 
> Signed-off-by: Laurent Pinchart 
> Reviewed-by: Sylwester Nawrocki 
> Reviewed-by: Sakari Ailus 

Just a few small changes below. Once that is corrected you can add my:

Acked-by: Hans Verkuil 

Regards,

Hans

> ---
>  Documentation/DocBook/media/v4l/pixfmt-nv16m.xml | 171 
> +++
>  Documentation/DocBook/media/v4l/pixfmt.xml   |   1 +
>  include/uapi/linux/videodev2.h   |   2 +
>  3 files changed, 174 insertions(+)
>  create mode 100644 Documentation/DocBook/media/v4l/pixfmt-nv16m.xml
> 
> diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv16m.xml 
> b/Documentation/DocBook/media/v4l/pixfmt-nv16m.xml
> new file mode 100644
> index 000..afec039
> --- /dev/null
> +++ b/Documentation/DocBook/media/v4l/pixfmt-nv16m.xml
> @@ -0,0 +1,171 @@
> +
> +  
> + V4L2_PIX_FMT_NV16M ('NM16'), V4L2_PIX_FMT_NV61M 
> ('NM61')
> + &manvol;
> +  
> +  
> +  id="V4L2-PIX-FMT-NV16M">V4L2_PIX_FMT_NV16M
> +  id="V4L2-PIX-FMT-NV61M">V4L2_PIX_FMT_NV61M
> + Variation of V4L2_PIX_FMT_NV16 and 
> V4L2_PIX_FMT_NV61 with planes
> +   non contiguous in memory. 
> +  
> +  
> + Description
> +
> + This is a multi-planar, two-plane version of the YUV 4:2:0 format.
> +The three components are separated into two sub-images or planes.
> +V4L2_PIX_FMT_NV16M differs from 
> V4L2_PIX_FMT_NV16
> + in that the two planes are non-contiguous in memory, i.e. the 
> chroma
> +plane do not necessarily immediately follows the luma plane.

s/do/does/

> +The luminance data occupies the first plane. The Y plane has one byte per 
> pixel.
> +In the second plane there is a chrominance data with alternating chroma 
> samples.

s/is a/is/

> +The CbCr plane is the same width and height, in bytes, as the Y plane.
> +Each CbCr pair belongs to four pixels. For example,
> +Cb0/Cr0 belongs to
> +Y'00, Y'01,
> +Y'10, Y'11.
> +V4L2_PIX_FMT_NV61M is the same as 
> V4L2_PIX_FMT_NV16M
> +except the Cb and Cr bytes are swapped, the CrCb plane starts with a Cr 
> byte.

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 9/9] vsp1: Use the maximum number of entities defined in platform data

2013-08-02 Thread Hans Verkuil


On 08/02/2013 03:03 AM, Laurent Pinchart wrote:
> From: Katsuya Matsubara 
> 
> The VSP1 driver allows to define the maximum number of each module
> such as RPF, WPF, and UDS in a platform data definition.
> This suppresses operations for nonexistent or unused modules.
> 
> Signed-off-by: Katsuya Matsubara 
> Signed-off-by: Laurent Pinchart 
> Acked-by: Sakari Ailus 

Acked-by: Hans Verkuil 

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 8/9] vsp1: Fix lack of the sink entity registration for enabled links

2013-08-02 Thread Hans Verkuil


On 08/02/2013 03:03 AM, Laurent Pinchart wrote:
> From: Katsuya Matsubara 
> 
> Each source entity maintains a pointer to the counterpart sink
> entity while an enabled link connects them. It should be managed by
> the setup_link callback in the media controller framework at runtime.
> However, enabled links which connect RPFs and WPFs that have an
> equivalent index number are created during initialization.
> This registers the pointer to a sink entity from the source entity
> when an enabled link is created.
> 
> Signed-off-by: Katsuya Matsubara 
> Signed-off-by: Laurent Pinchart 
> Acked-by: Sakari Ailus 

Acked-by: Hans Verkuil 

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] drm/exynos: Add check for IOMMU while passing physically continous memory flag

2013-08-02 Thread Vikas Sajjan
Hi Inki Dae,

On 2 August 2013 12:58, Inki Dae  wrote:
>
>
> 2013/8/2 Vikas Sajjan 
>>
>> Hi Rob,
>>
>> On 2 August 2013 06:03, Rob Clark  wrote:
>> > On Thu, Aug 1, 2013 at 7:20 PM, Tomasz Figa 
>> > wrote:
>> >> Hi Vikas,
>> >>
>> >> On Thursday 01 of August 2013 16:49:32 Vikas Sajjan wrote:
>> >>> While trying to get boot-logo up on exynos5420 SMDK which has eDP
>> >>> panel
>> >>> connected with resolution 2560x1600, following error occured even with
>> >>> IOMMU enabled:
>> >>> [0.88] [drm:lowlevel_buffer_allocate] *ERROR* failed to allocate
>> >>> buffer. [0.89] [drm] Initialized exynos 1.0.0 20110530 on minor 0
>> >>>
>> >>> This patch fixes the issue by adding a check for IOMMU.
>> >>>
>> >>> Signed-off-by: Vikas Sajjan 
>> >>> Signed-off-by: Arun Kumar 
>> >>> ---
>> >>>  drivers/gpu/drm/exynos/exynos_drm_fbdev.c |9 -
>> >>>  1 file changed, 8 insertions(+), 1 deletion(-)
>> >>>
>> >>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
>> >>> b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 8e60bd6..2a8
>> >>> 100644
>> >>> --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
>> >>> +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
>> >>> @@ -16,6 +16,7 @@
>> >>>  #include 
>> >>>  #include 
>> >>>  #include 
>> >>> +#include 
>> >>>
>> >>>  #include "exynos_drm_drv.h"
>> >>>  #include "exynos_drm_fb.h"
>> >>> @@ -143,6 +144,7 @@ static int exynos_drm_fbdev_create(struct
>> >>> drm_fb_helper *helper, struct platform_device *pdev =
>> >>> dev->platformdev;
>> >>>   unsigned long size;
>> >>>   int ret;
>> >>> + unsigned int flag;
>> >>>
>> >>>   DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n",
>> >>>   sizes->surface_width, sizes->surface_height,
>> >>> @@ -166,7 +168,12 @@ static int exynos_drm_fbdev_create(struct
>> >>> drm_fb_helper *helper, size = mode_cmd.pitches[0] * mode_cmd.height;
>> >>>
>> >>>   /* 0 means to allocate physically continuous memory */
>> >>> - exynos_gem_obj = exynos_drm_gem_create(dev, 0, size);
>> >>> + if (!is_drm_iommu_supported(dev))
>> >>> + flag = 0;
>> >>> + else
>> >>> + flag = EXYNOS_BO_NONCONTIG;
>> >>
>> >> While noncontig memory might be used for devices that support IOMMU,
>> >> there
>> >> should be no problem with using contig memory for them, so this seems
>> >> more
>> >> like masking the original problem rather than tracking it down.
>> >
>> > it is probably a good idea to not require contig memory when it is not
>> > needed for performance or functionality (and if it is only
>> > performance, then fallback gracefully to non-contig).. but yeah, would
>> > be good to know if this is masking another issue all the same
>> >
>>
>> Whats happening with CONTIG flag and with IOMMU,  is
>>
>>  __iommu_alloc_buffer() ---> dma_alloc_from_contiguous() and in this
>> function it fails at
>> this condition check  if (pageno >= cma->count)
>>
>> So I tried increasing the CONFIG_CMA_SIZE_MBYTES to 24,  this check
>> succeeds and it works well without my patch.
>>
>> But what about the case where CONFIG_CMA is disabled , yet i want
>> bigger memory for a device.
>>  I think using IOMMU we can achieve this.
>>
>>  correct me, if i am wrong.
>>
>
> I'm on summer vacation so I'm afraid that I cannot test and look into it but
> I guess you guy didn't declare CMA region for Exynos drm. And in this case,
> the size of CMA declared region is 16MB as default. That is why works well
> after increasing default size, CONFIG_CMA_SIZE_MBYTES, to 24MB. And I
> mentioned long time ago, we are required to use physically contiguous memory
> in case that bootloader uses physically contiguous memory for its own
> framebuffer, and kernel wants to share the bootloader's framebuffer region
> to resolve flickering issue while booted; that is required for product. And
> one question, is there any reason that you guy should use non-contiguous
> memory for framebuffer with iommu?
>

yeah, we could not allocate CMA region for FIMD, because the function
dma_declare_contiguous() needs "dev" as the first argument and we have
access to "dev" node only if it is NON-DT way of probing like the way
it is done in arch/arm/mach-davinci/devices-da8xx.c
But now, since the probing is through DT way, there is NO way ( Let me
know if something is newly added ) to call dma_declare_contiguous()
and reserve CMA region .

we don't have any specific requirement for NON_CONTIG or CONTIG
memory, but only requirement was to allocate a bigger memory like (
2560 * 1600 * 4 ) for FB.

But as Rob suggested, we should have fall-back case if CONTIG memory
allocation fails, as below

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index df43fa9..15de626 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -144,7 +144,6 @@ static int exynos_drm_fbdev_create(struct
drm_fb_helper *helper,
struct platform_device *

Re: [PATCH v5 7/9] v4l: Renesas R-Car VSP1 driver

2013-08-02 Thread Laurent Pinchart
Hi Hans,

On Friday 02 August 2013 11:23:46 Hans Verkuil wrote:
> Hi Laurent,
> 
> See my single remark below...
> 
> On 08/02/2013 03:03 AM, Laurent Pinchart wrote:
> > The VSP1 is a video processing engine that includes a blender, scalers,
> > filters and statistics computation. Configurable data path routing logic
> > allows ordering the internal blocks in a flexible way.
> > 
> > Due to the configurable nature of the pipeline the driver implements the
> > media controller API and doesn't use the V4L2 mem-to-mem framework, even
> > though the device usually operates in memory to memory mode.
> > 
> > Only the read pixel formatters, up/down scalers, write pixel formatters
> > and LCDC interface are supported at this stage.
> > 
> > Signed-off-by: Laurent Pinchart
> > 
> > Acked-by: Sakari Ailus 
> > 
> > diff --git a/drivers/media/platform/vsp1/vsp1_uds.h
> > b/drivers/media/platform/vsp1/vsp1_uds.h new file mode 100644
> > index 000..972a285

[snip]

> > +int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf)
> > +{
> > +   const char *direction;
> > +   int ret;
> > +
> > +   switch (video->type) {
> > +   case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
> > +   direction = "output";
> > +   video->pad.flags = MEDIA_PAD_FL_SINK;
> > +   break;
> > +
> > +   case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
> > +   direction = "input";
> > +   video->pad.flags = MEDIA_PAD_FL_SOURCE;
> > +   video->video.vfl_dir = VFL_DIR_TX;
> > +   break;
> > +
> > +   default:
> > +   return -EINVAL;
> > +   }
> > +
> > +   video->rwpf = rwpf;
> > +
> > +   mutex_init(&video->lock);
> > +   spin_lock_init(&video->irqlock);
> > +   INIT_LIST_HEAD(&video->irqqueue);
> > +
> > +   mutex_init(&video->pipe.lock);
> > +   spin_lock_init(&video->pipe.irqlock);
> > +   INIT_LIST_HEAD(&video->pipe.entities);
> > +   init_waitqueue_head(&video->pipe.wq);
> > +   video->pipe.state = VSP1_PIPELINE_STOPPED;
> > +
> > +   /* Initialize the media entity... */
> > +   ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
> > +   if (ret < 0)
> > +   return ret;
> > +
> > +   /* ... and the format ... */
> > +   video->fmtinfo = vsp1_get_format_info(VSP1_VIDEO_DEF_FORMAT);
> > +   video->format.pixelformat = video->fmtinfo->fourcc;
> > +   video->format.colorspace = V4L2_COLORSPACE_SRGB;
> > +   video->format.field = V4L2_FIELD_NONE;
> > +   video->format.width = VSP1_VIDEO_DEF_WIDTH;
> > +   video->format.height = VSP1_VIDEO_DEF_HEIGHT;
> > +   video->format.num_planes = 1;
> > +   video->format.plane_fmt[0].bytesperline =
> > +   video->format.width * video->fmtinfo->bpp[0] / 8;
> > +   video->format.plane_fmt[0].sizeimage =
> > +   video->format.plane_fmt[0].bytesperline * video->format.height;
> > +
> > +   /* ... and the video node... */
> > +   video->video.v4l2_dev = &video->vsp1->v4l2_dev;
> > +   video->video.fops = &vsp1_video_fops;
> > +   snprintf(video->video.name, sizeof(video->video.name), "%s %s",
> > +rwpf->subdev.name, direction);
> > +   video->video.vfl_type = VFL_TYPE_GRABBER;
> > +   video->video.release = video_device_release_empty;
> > +   video->video.ioctl_ops = &vsp1_video_ioctl_ops;
> > +
> > +   video_set_drvdata(&video->video, video);
> > +
> > +   /* ... and the buffers queue... */
> > +   video->alloc_ctx = vb2_dma_contig_init_ctx(video->vsp1->dev);
> > +   if (IS_ERR(video->alloc_ctx))
> > +   goto error;
> > +
> > +   video->queue.type = video->type;
> > +   video->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
> > +   video->queue.drv_priv = video;
> > +   video->queue.buf_struct_size = sizeof(struct vsp1_video_buffer);
> > +   video->queue.ops = &vsp1_video_queue_qops;
> > +   video->queue.mem_ops = &vb2_dma_contig_memops;
> > +   video->queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> 
> If you set video->queue.lock to &video->lock, then you can drop all the vb2
> ioctl and fop helper functions directly without having to make your own
> wrapper functions.

Right, I'll do so. I will also drop the manual lock handling from the STREAMON 
and STREAMOFF handlers, as the core will use the queue lock for those.

> It saves a fair bit of code that way. The only place where there is a
> difference as far as I can see is in vb2_fop_mmap: there the queue.lock
> isn't taken whereas you do take the lock. It has never been 100% clear to
> me whether or not that lock should be taken. However, as far as I can tell
> vb2_mmap never calls any driver callbacks, so it seems to be me that there
> is no need to take the lock.

Couldn't mmap() race with for instance REQBUFS(0) if we don't lock it ?

> > +   ret = vb2_queue_init(&video->queue);
> > +   if (ret < 0) {
> > +   dev_err(video->vsp1->dev, "failed to initialize vb2 queue\n");
> > +   goto error;
> > +   }
> > +
> > +   /* ... and register the video device. */
> > +   video->video.queue = &video->queue;
> > +   r

Re: [PATCH] drm/exynos: Add check for IOMMU while passing physically continous memory flag

2013-08-02 Thread Sylwester Nawrocki
Hi Vikas,

On 08/02/2013 12:10 PM, Vikas Sajjan wrote:
> yeah, we could not allocate CMA region for FIMD, because the function
> dma_declare_contiguous() needs "dev" as the first argument and we have
> access to "dev" node only if it is NON-DT way of probing like the way
> it is done in arch/arm/mach-davinci/devices-da8xx.c
> But now, since the probing is through DT way, there is NO way ( Let me
> know if something is newly added ) to call dma_declare_contiguous()
> and reserve CMA region .

See this patch series [1]. We have have been using this kind of bindings
for assigning physically contiguous memory regions to the Exynos 
multimedia devices, instead of what's currently in mainline where same
physical addresses are repeated in dts for various boards without much
thought. And where custom device specific parsing code is required at 
arch side.

$ git grep mfc\-[lr] arch/arm/boot/dts

arch/arm/boot/dts/exynos4210-origen.dts: samsung,mfc-r = <0x4300 
0x80>;
arch/arm/boot/dts/exynos4210-origen.dts: samsung,mfc-l = <0x5100 
0x80>;
arch/arm/boot/dts/exynos4210-smdkv310.dts:   samsung,mfc-r = <0x4300 
0x80>;
arch/arm/boot/dts/exynos4210-smdkv310.dts:   samsung,mfc-l = <0x5100 
0x80>;
arch/arm/boot/dts/exynos4412-origen.dts: samsung,mfc-r = <0x4300 
0x80>;
arch/arm/boot/dts/exynos4412-origen.dts: samsung,mfc-l = <0x5100 
0x80>;
arch/arm/boot/dts/exynos4412-smdk4412.dts:   samsung,mfc-r = <0x4300 
0x80>;
arch/arm/boot/dts/exynos4412-smdk4412.dts:   samsung,mfc-l = <0x5100 
0x80>;
arch/arm/boot/dts/exynos5250-arndale.dts:samsung,mfc-r = <0x4300 
0x80>;
arch/arm/boot/dts/exynos5250-arndale.dts:samsung,mfc-l = <0x5100 
0x80>;
arch/arm/boot/dts/exynos5250-smdk5250.dts:   samsung,mfc-r = <0x4300 
0x80>;
arch/arm/boot/dts/exynos5250-smdk5250.dts:   samsung,mfc-l = <0x5100 
0x80>;


[1] http://www.spinics.net/lists/arm-kernel/msg263130.html

Regards,
Sylwester
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 7/9] v4l: Renesas R-Car VSP1 driver

2013-08-02 Thread Hans Verkuil


On 08/02/2013 12:57 PM, Laurent Pinchart wrote:
> Hi Hans,
> 
> On Friday 02 August 2013 11:23:46 Hans Verkuil wrote:
>> Hi Laurent,
>>
>> See my single remark below...
>>
>> On 08/02/2013 03:03 AM, Laurent Pinchart wrote:
>>> The VSP1 is a video processing engine that includes a blender, scalers,
>>> filters and statistics computation. Configurable data path routing logic
>>> allows ordering the internal blocks in a flexible way.
>>>
>>> Due to the configurable nature of the pipeline the driver implements the
>>> media controller API and doesn't use the V4L2 mem-to-mem framework, even
>>> though the device usually operates in memory to memory mode.
>>>
>>> Only the read pixel formatters, up/down scalers, write pixel formatters
>>> and LCDC interface are supported at this stage.
>>>
>>> Signed-off-by: Laurent Pinchart
>>> 
>>> Acked-by: Sakari Ailus 
>>>
>>> diff --git a/drivers/media/platform/vsp1/vsp1_uds.h
>>> b/drivers/media/platform/vsp1/vsp1_uds.h new file mode 100644
>>> index 000..972a285
> 
> [snip]
> 
>>> +int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf)
>>> +{
>>> +   const char *direction;
>>> +   int ret;
>>> +
>>> +   switch (video->type) {
>>> +   case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
>>> +   direction = "output";
>>> +   video->pad.flags = MEDIA_PAD_FL_SINK;
>>> +   break;
>>> +
>>> +   case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
>>> +   direction = "input";
>>> +   video->pad.flags = MEDIA_PAD_FL_SOURCE;
>>> +   video->video.vfl_dir = VFL_DIR_TX;
>>> +   break;
>>> +
>>> +   default:
>>> +   return -EINVAL;
>>> +   }
>>> +
>>> +   video->rwpf = rwpf;
>>> +
>>> +   mutex_init(&video->lock);
>>> +   spin_lock_init(&video->irqlock);
>>> +   INIT_LIST_HEAD(&video->irqqueue);
>>> +
>>> +   mutex_init(&video->pipe.lock);
>>> +   spin_lock_init(&video->pipe.irqlock);
>>> +   INIT_LIST_HEAD(&video->pipe.entities);
>>> +   init_waitqueue_head(&video->pipe.wq);
>>> +   video->pipe.state = VSP1_PIPELINE_STOPPED;
>>> +
>>> +   /* Initialize the media entity... */
>>> +   ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
>>> +   if (ret < 0)
>>> +   return ret;
>>> +
>>> +   /* ... and the format ... */
>>> +   video->fmtinfo = vsp1_get_format_info(VSP1_VIDEO_DEF_FORMAT);
>>> +   video->format.pixelformat = video->fmtinfo->fourcc;
>>> +   video->format.colorspace = V4L2_COLORSPACE_SRGB;
>>> +   video->format.field = V4L2_FIELD_NONE;
>>> +   video->format.width = VSP1_VIDEO_DEF_WIDTH;
>>> +   video->format.height = VSP1_VIDEO_DEF_HEIGHT;
>>> +   video->format.num_planes = 1;
>>> +   video->format.plane_fmt[0].bytesperline =
>>> +   video->format.width * video->fmtinfo->bpp[0] / 8;
>>> +   video->format.plane_fmt[0].sizeimage =
>>> +   video->format.plane_fmt[0].bytesperline * video->format.height;
>>> +
>>> +   /* ... and the video node... */
>>> +   video->video.v4l2_dev = &video->vsp1->v4l2_dev;
>>> +   video->video.fops = &vsp1_video_fops;
>>> +   snprintf(video->video.name, sizeof(video->video.name), "%s %s",
>>> +rwpf->subdev.name, direction);
>>> +   video->video.vfl_type = VFL_TYPE_GRABBER;
>>> +   video->video.release = video_device_release_empty;
>>> +   video->video.ioctl_ops = &vsp1_video_ioctl_ops;
>>> +
>>> +   video_set_drvdata(&video->video, video);
>>> +
>>> +   /* ... and the buffers queue... */
>>> +   video->alloc_ctx = vb2_dma_contig_init_ctx(video->vsp1->dev);
>>> +   if (IS_ERR(video->alloc_ctx))
>>> +   goto error;
>>> +
>>> +   video->queue.type = video->type;
>>> +   video->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
>>> +   video->queue.drv_priv = video;
>>> +   video->queue.buf_struct_size = sizeof(struct vsp1_video_buffer);
>>> +   video->queue.ops = &vsp1_video_queue_qops;
>>> +   video->queue.mem_ops = &vb2_dma_contig_memops;
>>> +   video->queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
>>
>> If you set video->queue.lock to &video->lock, then you can drop all the vb2
>> ioctl and fop helper functions directly without having to make your own
>> wrapper functions.
> 
> Right, I'll do so. I will also drop the manual lock handling from the 
> STREAMON 
> and STREAMOFF handlers, as the core will use the queue lock for those.
> 
>> It saves a fair bit of code that way. The only place where there is a
>> difference as far as I can see is in vb2_fop_mmap: there the queue.lock
>> isn't taken whereas you do take the lock. It has never been 100% clear to
>> me whether or not that lock should be taken. However, as far as I can tell
>> vb2_mmap never calls any driver callbacks, so it seems to be me that there
>> is no need to take the lock.
> 
> Couldn't mmap() race with for instance REQBUFS(0) if we don't lock it ?

Hmm, good point. It would require a very convoluted program, but yes, there is
a possible race condition. The same is true for vb2_get_unmapped_area.

Can you prepare a patch adding locking for these two fops

Re: [PATCH v5 7/9] v4l: Renesas R-Car VSP1 driver

2013-08-02 Thread Laurent Pinchart
On Friday 02 August 2013 13:14:09 Hans Verkuil wrote:
> On 08/02/2013 12:57 PM, Laurent Pinchart wrote:
> > On Friday 02 August 2013 11:23:46 Hans Verkuil wrote:
> >> On 08/02/2013 03:03 AM, Laurent Pinchart wrote:
> >>> The VSP1 is a video processing engine that includes a blender, scalers,
> >>> filters and statistics computation. Configurable data path routing logic
> >>> allows ordering the internal blocks in a flexible way.
> >>> 
> >>> Due to the configurable nature of the pipeline the driver implements the
> >>> media controller API and doesn't use the V4L2 mem-to-mem framework, even
> >>> though the device usually operates in memory to memory mode.
> >>> 
> >>> Only the read pixel formatters, up/down scalers, write pixel formatters
> >>> and LCDC interface are supported at this stage.
> >>> 
> >>> Signed-off-by: Laurent Pinchart
> >>> 
> >>> Acked-by: Sakari Ailus 
> >>> 
> >>> diff --git a/drivers/media/platform/vsp1/vsp1_uds.h
> >>> b/drivers/media/platform/vsp1/vsp1_uds.h new file mode 100644
> >>> index 000..972a285
> > 
> > [snip]
> > 
> >>> +int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf)
> >>> +{
> >>> + const char *direction;
> >>> + int ret;
> >>> +
> >>> + switch (video->type) {
> >>> + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
> >>> + direction = "output";
> >>> + video->pad.flags = MEDIA_PAD_FL_SINK;
> >>> + break;
> >>> +
> >>> + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
> >>> + direction = "input";
> >>> + video->pad.flags = MEDIA_PAD_FL_SOURCE;
> >>> + video->video.vfl_dir = VFL_DIR_TX;
> >>> + break;
> >>> +
> >>> + default:
> >>> + return -EINVAL;
> >>> + }
> >>> +
> >>> + video->rwpf = rwpf;
> >>> +
> >>> + mutex_init(&video->lock);
> >>> + spin_lock_init(&video->irqlock);
> >>> + INIT_LIST_HEAD(&video->irqqueue);
> >>> +
> >>> + mutex_init(&video->pipe.lock);
> >>> + spin_lock_init(&video->pipe.irqlock);
> >>> + INIT_LIST_HEAD(&video->pipe.entities);
> >>> + init_waitqueue_head(&video->pipe.wq);
> >>> + video->pipe.state = VSP1_PIPELINE_STOPPED;
> >>> +
> >>> + /* Initialize the media entity... */
> >>> + ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
> >>> + if (ret < 0)
> >>> + return ret;
> >>> +
> >>> + /* ... and the format ... */
> >>> + video->fmtinfo = vsp1_get_format_info(VSP1_VIDEO_DEF_FORMAT);
> >>> + video->format.pixelformat = video->fmtinfo->fourcc;
> >>> + video->format.colorspace = V4L2_COLORSPACE_SRGB;
> >>> + video->format.field = V4L2_FIELD_NONE;
> >>> + video->format.width = VSP1_VIDEO_DEF_WIDTH;
> >>> + video->format.height = VSP1_VIDEO_DEF_HEIGHT;
> >>> + video->format.num_planes = 1;
> >>> + video->format.plane_fmt[0].bytesperline =
> >>> + video->format.width * video->fmtinfo->bpp[0] / 8;
> >>> + video->format.plane_fmt[0].sizeimage =
> >>> + video->format.plane_fmt[0].bytesperline * video->format.height;
> >>> +
> >>> + /* ... and the video node... */
> >>> + video->video.v4l2_dev = &video->vsp1->v4l2_dev;
> >>> + video->video.fops = &vsp1_video_fops;
> >>> + snprintf(video->video.name, sizeof(video->video.name), "%s %s",
> >>> +  rwpf->subdev.name, direction);
> >>> + video->video.vfl_type = VFL_TYPE_GRABBER;
> >>> + video->video.release = video_device_release_empty;
> >>> + video->video.ioctl_ops = &vsp1_video_ioctl_ops;
> >>> +
> >>> + video_set_drvdata(&video->video, video);
> >>> +
> >>> + /* ... and the buffers queue... */
> >>> + video->alloc_ctx = vb2_dma_contig_init_ctx(video->vsp1->dev);
> >>> + if (IS_ERR(video->alloc_ctx))
> >>> + goto error;
> >>> +
> >>> + video->queue.type = video->type;
> >>> + video->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
> >>> + video->queue.drv_priv = video;
> >>> + video->queue.buf_struct_size = sizeof(struct vsp1_video_buffer);
> >>> + video->queue.ops = &vsp1_video_queue_qops;
> >>> + video->queue.mem_ops = &vb2_dma_contig_memops;
> >>> + video->queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> >> 
> >> If you set video->queue.lock to &video->lock, then you can drop all the
> >> vb2 ioctl and fop helper functions directly without having to make your
> >> own wrapper functions.
> > 
> > Right, I'll do so. I will also drop the manual lock handling from the
> > STREAMON and STREAMOFF handlers, as the core will use the queue lock for
> > those.
> >
> >> It saves a fair bit of code that way. The only place where there is a
> >> difference as far as I can see is in vb2_fop_mmap: there the queue.lock
> >> isn't taken whereas you do take the lock. It has never been 100% clear to
> >> me whether or not that lock should be taken. However, as far as I can
> >> tell vb2_mmap never calls any driver callbacks, so it seems to be me that
> >> there is no need to take the lock.
> > 
> > Couldn't mmap() race with for instance REQBUFS(0) if we don't lock it ?
> 
> Hmm, good point. It would require a very convoluted program, but yes, there
> is a possible race condition. 

[PATCH v3 2/2] videobuf2-dma-sg: Replace vb2_dma_sg_desc with sg_table

2013-08-02 Thread Ricardo Ribalda Delgado
Replace the private struct vb2_dma_sg_desc with the struct sg_table so
we can benefit from all the helping functions in lib/scatterlist.c for
things like allocating the sg or compacting the descriptor

marvel-ccic and solo6x10 drivers, that uses this api has been updated

Acked-by: Marek Szyprowski 
Signed-off-by: Ricardo Ribalda Delgado 
---
 drivers/media/platform/marvell-ccic/mcam-core.c|   14 +--
 drivers/media/v4l2-core/videobuf2-dma-sg.c |  103 
 drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c |   20 ++--
 include/media/videobuf2-dma-sg.h   |   10 +-
 4 files changed, 63 insertions(+), 84 deletions(-)

diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c 
b/drivers/media/platform/marvell-ccic/mcam-core.c
index 64ab91e..0ac51bd 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
@@ -1040,16 +1040,16 @@ static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
 {
struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
-   struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0);
+   struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0);
struct mcam_dma_desc *desc = mvb->dma_desc;
struct scatterlist *sg;
int i;
 
-   mvb->dma_desc_nent = dma_map_sg(cam->dev, sgd->sglist, sgd->num_pages,
-   DMA_FROM_DEVICE);
+   mvb->dma_desc_nent = dma_map_sg(cam->dev, sg_table->sgl,
+   sg_table->nents, DMA_FROM_DEVICE);
if (mvb->dma_desc_nent <= 0)
return -EIO;  /* Not sure what's right here */
-   for_each_sg(sgd->sglist, sg, mvb->dma_desc_nent, i) {
+   for_each_sg(sg_table->sgl, sg, mvb->dma_desc_nent, i) {
desc->dma_addr = sg_dma_address(sg);
desc->segment_len = sg_dma_len(sg);
desc++;
@@ -1060,9 +1060,11 @@ static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
 static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb)
 {
struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
-   struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0);
+   struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0);
 
-   dma_unmap_sg(cam->dev, sgd->sglist, sgd->num_pages, DMA_FROM_DEVICE);
+   if (sg_table)
+   dma_unmap_sg(cam->dev, sg_table->sgl,
+   sg_table->nents, DMA_FROM_DEVICE);
return 0;
 }
 
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index 4a7b59b..0328899 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -35,7 +35,9 @@ struct vb2_dma_sg_buf {
struct page **pages;
int write;
int offset;
-   struct vb2_dma_sg_desc  sg_desc;
+   struct sg_table sg_table;
+   size_t  size;
+   unsigned intnum_pages;
atomic_trefcount;
struct vb2_vmarea_handler   handler;
 };
@@ -46,7 +48,7 @@ static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf 
*buf,
gfp_t gfp_flags)
 {
unsigned int last_page = 0;
-   int size = buf->sg_desc.size;
+   int size = buf->size;
 
while (size > 0) {
struct page *pages;
@@ -74,12 +76,8 @@ static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf 
*buf,
}
 
split_page(pages, order);
-   for (i = 0; i < (1sg_desc.sglist[last_page],
-   buf->pages[last_page], PAGE_SIZE, 0);
-   last_page++;
-   }
+   for (i = 0; i < (1vaddr = NULL;
buf->write = 0;
buf->offset = 0;
-   buf->sg_desc.size = size;
+   buf->size = size;
/* size is already page aligned */
-   buf->sg_desc.num_pages = size >> PAGE_SHIFT;
-
-   buf->sg_desc.sglist = vzalloc(buf->sg_desc.num_pages *
- sizeof(*buf->sg_desc.sglist));
-   if (!buf->sg_desc.sglist)
-   goto fail_sglist_alloc;
-   sg_init_table(buf->sg_desc.sglist, buf->sg_desc.num_pages);
+   buf->num_pages = size >> PAGE_SHIFT;
 
-   buf-

[PATCH v3 1/2] videobuf2-dma-sg: Allocate pages as contiguous as possible

2013-08-02 Thread Ricardo Ribalda Delgado
Most DMA engines have limitations regarding the number of DMA segments
(sg-buffers) that they can handle. Videobuffers can easily spread
through houndreds of pages.

In the previous aproach, the pages were allocated individually, this
could led to the creation houndreds of dma segments (sg-buffers) that
could not be handled by some DMA engines.

This patch tries to minimize the number of DMA segments by using
alloc_pages. In the worst case it will behave as before, but most
of the times it will reduce the number of dma segments

Acked-by: Marek Szyprowski 
Signed-off-by: Ricardo Ribalda Delgado 
---
 drivers/media/v4l2-core/videobuf2-dma-sg.c |   60 +++-
 1 file changed, 49 insertions(+), 11 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index 16ae3dc..4a7b59b 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -42,10 +42,55 @@ struct vb2_dma_sg_buf {
 
 static void vb2_dma_sg_put(void *buf_priv);
 
+static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf,
+   gfp_t gfp_flags)
+{
+   unsigned int last_page = 0;
+   int size = buf->sg_desc.size;
+
+   while (size > 0) {
+   struct page *pages;
+   int order;
+   int i;
+
+   order = get_order(size);
+   /* Dont over allocate*/
+   if ((PAGE_SIZE << order) > size)
+   order--;
+
+   pages = NULL;
+   while (!pages) {
+   pages = alloc_pages(GFP_KERNEL | __GFP_ZERO |
+   __GFP_NOWARN | gfp_flags, order);
+   if (pages)
+   break;
+
+   if (order == 0) {
+   while (last_page--)
+   __free_page(buf->pages[last_page]);
+   return -ENOMEM;
+   }
+   order--;
+   }
+
+   split_page(pages, order);
+   for (i = 0; i < (1sg_desc.sglist[last_page],
+   buf->pages[last_page], PAGE_SIZE, 0);
+   last_page++;
+   }
+
+   size -= PAGE_SIZE << order;
+   }
+
+   return 0;
+}
+
 static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t 
gfp_flags)
 {
struct vb2_dma_sg_buf *buf;
-   int i;
+   int ret;
 
buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
@@ -69,14 +114,9 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned 
long size, gfp_t gfp_fla
if (!buf->pages)
goto fail_pages_array_alloc;
 
-   for (i = 0; i < buf->sg_desc.num_pages; ++i) {
-   buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO |
-  __GFP_NOWARN | gfp_flags);
-   if (NULL == buf->pages[i])
-   goto fail_pages_alloc;
-   sg_set_page(&buf->sg_desc.sglist[i],
-   buf->pages[i], PAGE_SIZE, 0);
-   }
+   ret = vb2_dma_sg_alloc_compacted(buf, gfp_flags);
+   if (ret)
+   goto fail_pages_alloc;
 
buf->handler.refcount = &buf->refcount;
buf->handler.put = vb2_dma_sg_put;
@@ -89,8 +129,6 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long 
size, gfp_t gfp_fla
return buf;
 
 fail_pages_alloc:
-   while (--i >= 0)
-   __free_page(buf->pages[i]);
kfree(buf->pages);
 
 fail_pages_array_alloc:
-- 
1.7.10.4

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


[PATCH 0/2] videobuf2-dma-sg: Contiguos memory allocation

2013-08-02 Thread Ricardo Ribalda Delgado
Allocate memory as contiguos as possible to support dma engines with limitated 
amount of sg-descriptors.

Replace private structer vb2_dma_sg_desc with generic struct sg_table.

PS: This series of patches is the evolution of my previous patch for vb2-dma-sg 
to allocate the memory as contiguos as possible.

v3: Constains feedback from Andre Heider
Andre: Fix error handling (--pages) was wrongly fixed

v2: Contains feedback from Andre Heider and Sylwester Nawrocki

Andre: Fix error handling (--pages)
Sylwester: Squash p3 and p4 into p2

Ricardo Ribalda Delgado (2):
  videobuf2-dma-sg: Allocate pages as contiguous as possible
  videobuf2-dma-sg: Replace vb2_dma_sg_desc with sg_table

 drivers/media/platform/marvell-ccic/mcam-core.c|   14 +-
 drivers/media/v4l2-core/videobuf2-dma-sg.c |  149 +++-
 drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c |   20 +--
 include/media/videobuf2-dma-sg.h   |   10 +-
 4 files changed, 105 insertions(+), 88 deletions(-)

-- 
1.7.10.4

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


Re: [PATCH 1/2] videobuf2-dma-sg: Allocate pages as contiguous as possible

2013-08-02 Thread Ricardo Ribalda Delgado
Hi Andre,

Nice catch! thanks.

I have just uploaded a new version.

https://patchwork.linuxtv.org/patch/19502/
https://patchwork.linuxtv.org/patch/19503/


Thanks for your help

On Fri, Aug 2, 2013 at 10:46 AM, Andre Heider  wrote:
> Hi Ricardo,
>
> sorry for the late answer, but the leak I mentioned in my first reply is 
> still there, see below.
>
> On Fri, Jul 19, 2013 at 07:02:33PM +0200, Ricardo Ribalda Delgado wrote:
>> Most DMA engines have limitations regarding the number of DMA segments
>> (sg-buffers) that they can handle. Videobuffers can easily spread
>> through houndreds of pages.
>>
>> In the previous aproach, the pages were allocated individually, this
>> could led to the creation houndreds of dma segments (sg-buffers) that
>> could not be handled by some DMA engines.
>>
>> This patch tries to minimize the number of DMA segments by using
>> alloc_pages. In the worst case it will behave as before, but most
>> of the times it will reduce the number of dma segments
>>
>> Signed-off-by: Ricardo Ribalda Delgado 
>> ---
>>  drivers/media/v4l2-core/videobuf2-dma-sg.c |   60 
>> +++-
>>  1 file changed, 49 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
>> b/drivers/media/v4l2-core/videobuf2-dma-sg.c
>> index 16ae3dc..c053605 100644
>> --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
>> +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
>> @@ -42,10 +42,55 @@ struct vb2_dma_sg_buf {
>>
>>  static void vb2_dma_sg_put(void *buf_priv);
>>
>> +static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf,
>> + gfp_t gfp_flags)
>> +{
>> + unsigned int last_page = 0;
>> + int size = buf->sg_desc.size;
>> +
>> + while (size > 0) {
>> + struct page *pages;
>> + int order;
>> + int i;
>> +
>> + order = get_order(size);
>> + /* Dont over allocate*/
>> + if ((PAGE_SIZE << order) > size)
>> + order--;
>> +
>> + pages = NULL;
>> + while (!pages) {
>> + pages = alloc_pages(GFP_KERNEL | __GFP_ZERO |
>> + __GFP_NOWARN | gfp_flags, order);
>> + if (pages)
>> + break;
>> +
>> + if (order == 0)
>> + while (last_page--) {
>> + __free_page(buf->pages[last_page]);
>> + return -ENOMEM;
>> + }
>
> The return statement doesn't make sense in the while() scope, that way you 
> wouldn't need the loop at all.
>
> To prevent leaking pages of prior iterations (those with higher orders), pull 
> the return out of there:
>
> while (last_page--)
> __free_page(buf->pages[last_page]);
> return -ENOMEM;
>
> Regards,
> Andre



-- 
Ricardo Ribalda
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/5] qv4l2: add ALSA audio playback

2013-08-02 Thread BÃ¥rd Eirik Winther
The qv4l2 test utility now supports ALSA playback of audio.
This allows for PCM playback during capture for supported devices.

Signed-off-by: BÃ¥rd Eirik Winther 
---
 utils/qv4l2/general-tab.cpp | 296 +++-
 utils/qv4l2/general-tab.h   |  36 ++
 utils/qv4l2/qv4l2.cpp   | 143 -
 utils/qv4l2/qv4l2.h |   7 ++
 4 files changed, 478 insertions(+), 4 deletions(-)

diff --git a/utils/qv4l2/general-tab.cpp b/utils/qv4l2/general-tab.cpp
index 10b14ca..5996c03 100644
--- a/utils/qv4l2/general-tab.cpp
+++ b/utils/qv4l2/general-tab.cpp
@@ -30,6 +30,16 @@
 
 #include 
 #include 
+#include 
+
+bool GeneralTab::m_fullAudioName = false;
+
+enum audioDeviceAdd {
+   AUDIO_ADD_NO,
+   AUDIO_ADD_READ,
+   AUDIO_ADD_WRITE,
+   AUDIO_ADD_READWRITE
+};
 
 GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget 
*parent) :
QGridLayout(parent),
@@ -48,12 +58,16 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int 
n, QWidget *parent)
m_vidCapFormats(NULL),
m_frameSize(NULL),
m_vidOutFormats(NULL),
-   m_vbiMethods(NULL)
+   m_vbiMethods(NULL),
+   m_audioInDevice(NULL),
+   m_audioOutDevice(NULL)
 {
+   m_device.append(device);
setSpacing(3);
 
setSizeConstraint(QLayout::SetMinimumSize);
 
+
if (querycap(m_querycap)) {
addLabel("Device:");
addLabel(device + (useWrapper() ? " (wrapped)" : ""), 
Qt::AlignLeft);
@@ -132,6 +146,42 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, 
int n, QWidget *parent)
updateAudioOutput();
}
 
+   if (hasAlsaAudio()) {
+   m_audioInDevice = new QComboBox(parent);
+   m_audioOutDevice = new QComboBox(parent);
+   
m_audioInDevice->setSizeAdjustPolicy(QComboBox::AdjustToContents);
+   
m_audioOutDevice->setSizeAdjustPolicy(QComboBox::AdjustToContents);
+
+   if (createAudioDeviceList()) {
+   addLabel("Audio Input Device");
+   connect(m_audioInDevice, SIGNAL(activated(int)), 
SLOT(changeAudioDevice()));
+   addWidget(m_audioInDevice);
+
+   addLabel("Audio Output Device");
+   connect(m_audioOutDevice, SIGNAL(activated(int)), 
SLOT(changeAudioDevice()));
+   addWidget(m_audioOutDevice);
+
+   if (isRadio()) {
+   setAudioDeviceBufferSize(75);
+   } else {
+   v4l2_fract fract;
+   if (!v4l2::get_interval(fract)) {
+   // Default values are for 30 FPS
+   fract.numerator = 33;
+   fract.denominator = 1000;
+   }
+   // Standard capacity is two frames
+   setAudioDeviceBufferSize((fract.numerator * 
2000) / fract.denominator);
+   }
+   } else {
+   fprintf(stderr, "BANNA\n");
+   delete m_audioInDevice;
+   delete m_audioOutDevice;
+   m_audioInDevice = NULL;
+   m_audioOutDevice = NULL;
+   }
+   }
+
if (needsStd) {
v4l2_std_id tmp;
 
@@ -370,6 +420,180 @@ done:
setRowStretch(rowCount() - 1, 1);
 }
 
+void GeneralTab::showAllAudioDevices(bool use)
+{
+   QString oldIn(m_audioInDevice->currentText());
+   QString oldOut(m_audioOutDevice->currentText());
+
+   m_fullAudioName = use;
+   if (oldIn == NULL || oldOut == NULL || !createAudioDeviceList())
+   return;
+
+   // Select a similar device as before the listings method change
+   // check by comparing old selection with any matching in the new list
+   bool setIn = false, setOut = false;
+   int listSize = std::max(m_audioInDevice->count(), 
m_audioOutDevice->count());
+
+   for (int i = 0; i < listSize; i++) {
+   QString 
oldInCmp(oldIn.left(std::min(m_audioInDevice->itemText(i).length(), 
oldIn.length(;
+   QString 
oldOutCmp(oldOut.left(std::min(m_audioOutDevice->itemText(i).length(), 
oldOut.length(;
+
+   if (!setIn && i < m_audioInDevice->count()
+   && m_audioInDevice->itemText(i).startsWith(oldInCmp)) {
+   setIn = true;
+   m_audioInDevice->setCurrentIndex(i);
+   }
+
+   if (!setOut && i < m_audioOutDevice->count()
+   && m_audioOutDevice->itemText(i).startsWith(oldOutCmp)) {
+   setOut = true;
+   m_audioOutDevice->setCurrentIndex(i);
+   }
+   }
+}
+
+bool GeneralTab::filter

[PATCH 4/5] qv4l2: fix a bug where the alsa thread never stops

2013-08-02 Thread BÃ¥rd Eirik Winther
If the output audio device never read the buffer then the alsa thread
would continue to fill it up and never stop when the capture stops.

Signed-off-by: BÃ¥rd Eirik Winther 
---
 utils/qv4l2/alsa_stream.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/utils/qv4l2/alsa_stream.c b/utils/qv4l2/alsa_stream.c
index 90d3afb..43ecda3 100644
--- a/utils/qv4l2/alsa_stream.c
+++ b/utils/qv4l2/alsa_stream.c
@@ -436,7 +436,7 @@ static snd_pcm_sframes_t writebuf(snd_pcm_t *handle, char 
*buf, long len)
 {
 snd_pcm_sframes_t r;
 
-while (1) {
+while (!stop_alsa) {
r = snd_pcm_writei(handle, buf, len);
if (r == len)
return 0;
-- 
1.8.3.2

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


[PATCH 2/5] qv4l2: new ALSA stream source code

2013-08-02 Thread BÃ¥rd Eirik Winther
Code copied from xawtv3

Signed-off-by: BÃ¥rd Eirik Winther 
---
 utils/qv4l2/alsa_stream.c | 645 ++
 utils/qv4l2/alsa_stream.h |   5 +
 2 files changed, 650 insertions(+)
 create mode 100644 utils/qv4l2/alsa_stream.c
 create mode 100644 utils/qv4l2/alsa_stream.h

diff --git a/utils/qv4l2/alsa_stream.c b/utils/qv4l2/alsa_stream.c
new file mode 100644
index 000..3e33b5e
--- /dev/null
+++ b/utils/qv4l2/alsa_stream.c
@@ -0,0 +1,645 @@
+/*
+ *  ALSA streaming support
+ *
+ *  Originally written by:
+ *  Copyright (c) by Devin Heitmueller 
+ * for usage at tvtime
+ *  Derived from the alsa-driver test tool latency.c:
+ *Copyright (c) by Jaroslav Kysela 
+ *
+ *  Copyright (c) 2011 - Mauro Carvalho Chehab 
+ * Ported to xawtv, with bug fixes and improvements
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include "config.h"
+
+#ifdef HAVE_ALSA_ASOUNDLIB_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "alsa_stream.h"
+
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
+
+/* Private vars to control alsa thread status */
+static int stop_alsa = 0;
+
+/* Error handlers */
+snd_output_t *output = NULL;
+FILE *error_fp;
+int verbose = 0;
+
+struct final_params {
+int bufsize;
+int rate;
+int latency;
+int channels;
+};
+
+static int setparams_stream(snd_pcm_t *handle,
+   snd_pcm_hw_params_t *params,
+   snd_pcm_format_t format,
+   int *channels,
+   const char *id)
+{
+int err;
+
+err = snd_pcm_hw_params_any(handle, params);
+if (err < 0) {
+   fprintf(error_fp,
+   "alsa: Broken configuration for %s PCM: no configurations 
available: %s\n",
+   snd_strerror(err), id);
+   return err;
+}
+
+err = snd_pcm_hw_params_set_access(handle, params,
+  SND_PCM_ACCESS_RW_INTERLEAVED);
+if (err < 0) {
+   fprintf(error_fp, "alsa: Access type not available for %s: %s\n", id,
+   snd_strerror(err));
+   return err;
+}
+
+err = snd_pcm_hw_params_set_format(handle, params, format);
+if (err < 0) {
+   fprintf(error_fp, "alsa: Sample format not available for %s: %s\n", id,
+  snd_strerror(err));
+   return err;
+}
+
+retry:
+err = snd_pcm_hw_params_set_channels(handle, params, *channels);
+if (err < 0) {
+   if (strcmp(id, "capture") == 0 && *channels == 2) {
+   *channels = 1;
+   goto retry; /* Retry with mono capture */
+   }
+   fprintf(error_fp, "alsa: Channels count (%i) not available for %s: 
%s\n",
+   *channels, id, snd_strerror(err));
+   return err;
+}
+
+return 0;
+}
+
+static void getparams_periods(snd_pcm_t *handle,
+ snd_pcm_hw_params_t *params,
+ unsigned int *usecs,
+ unsigned int *count,
+ const char *id)
+{
+unsigned min = 0, max = 0;
+
+snd_pcm_hw_params_get_periods_min(params, &min, 0);
+snd_pcm_hw_params_get_periods_max(params, &max, 0);
+if (min && max) {
+   if (verbose)
+   fprintf(error_fp, "alsa: %s periods range between %u and %u. Want: 
%u\n",
+   id, min, max, *count);
+   if (*count < min)
+   *count = min;
+   if (*count > max)
+   *count = max;
+}
+
+min = max = 0;
+snd_pcm_hw_params_get_period_time_min(params, &min, 0);
+snd_pcm_hw_params_get_period_time_max(params, &max, 0);
+if (min && max) {
+   if (verbose)
+   fprintf(error_fp, "alsa: %s period time range between %u and %u. 
Want: %u\n",
+   id, min, max, *usecs);
+   if (*usecs < min)
+   *usecs = min;
+   if (*usecs > max)
+   *usecs = max;
+}
+}
+
+static int setparams_periods(snd_pcm_t *handle,
+ snd_pcm_hw_params_t *params,
+ unsigned int *usecs,
+ unsigned int *count,
+ const char *id)
+{
+int err;
+
+err = snd_pcm_hw_params_set_period_time_near(handle, params, usecs, 0);
+if (err < 0) {

[PATCH 1/5] qv4l2: alter capture menu

2013-08-02 Thread BÃ¥rd Eirik Winther
Corrected Use OpenGL Render to Rendering and removed the separation line.

Signed-off-by: BÃ¥rd Eirik Winther 
---
 utils/qv4l2/qv4l2.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp
index 4dc5a3e..275b399 100644
--- a/utils/qv4l2/qv4l2.cpp
+++ b/utils/qv4l2/qv4l2.cpp
@@ -131,12 +131,11 @@ ApplicationWindow::ApplicationWindow() :
QMenu *captureMenu = menuBar()->addMenu("&Capture");
captureMenu->addAction(m_capStartAct);
captureMenu->addAction(m_showFramesAct);
-   captureMenu->addSeparator();
 
if (CaptureWinGL::isSupported()) {
m_renderMethod = QV4L2_RENDER_GL;
 
-   m_useGLAct = new QAction("Use Open&GL Render", this);
+   m_useGLAct = new QAction("Use Open&GL Rendering", this);
m_useGLAct->setStatusTip("Use GPU with OpenGL for video capture 
if set.");
m_useGLAct->setCheckable(true);
m_useGLAct->setChecked(true);
-- 
1.8.3.2

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


[PATCH 0/5] qv4l2: add ALSA audio playback

2013-08-02 Thread BÃ¥rd Eirik Winther
The qv4l2 test utility now supports ALSA playback of audio.
This allows for PCM playback during capture for supported devices.

This requires at least the OpenGL patch series' "qv4l2: add Capture menu" patch.
A device must be ALSA compatible in order to be used with the qv4l2.
The ALSA implementation requires ALSA on the system. If ALSA support is not 
present,
then this feature will not be compiled in.

Some of the changes/improvements:
- Capturing will also capture audio
- Added audio controls to the capture menu
- Selectable audio devices (can also have no audio)
- Automatically find corresponding audio source for a given video device if 
applicable
- Supports both radio, video and audio devices that uses PCM.
- Bug fixes

Known issues:
- Sometimes when generating the audio in and out device lists,
  it may take some time for the combo boxes to render correctly.
- If the audio causes underruns/overruns, try increase the audio buffer.
- Not all audio input/output combination will work, depending on system and 
devices.
- The A-V difference in ms is not always correct, but should still help as an 
indicator

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


[PATCH 3/5] qv4l2: add ALSA stream to qv4l2

2013-08-02 Thread BÃ¥rd Eirik Winther
Changes the ALSA streaming code to work with qv4l2 and allows it to
be compiled in. qv4l2 does not use the streaming function yet.

Signed-off-by: BÃ¥rd Eirik Winther 
---
 configure.ac  |  6 ++
 utils/qv4l2/Makefile.am   |  9 -
 utils/qv4l2/alsa_stream.c | 21 +++--
 utils/qv4l2/alsa_stream.h | 13 ++---
 4 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/configure.ac b/configure.ac
index d74da61..e12507e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -136,6 +136,11 @@ if test "x$qt_pkgconfig_gl" = "xfalse"; then
AC_MSG_WARN(Qt4 OpenGL or higher is not available)
 fi
 
+PKG_CHECK_MODULES(ALSA, [alsa], [alsa_pkgconfig=true], [alsa_pkgconfig=false])
+if test "x$alsa_pkgconfig" = "xfalse"; then
+   AC_MSG_WARN(ALSA library not available)
+fi
+
 AC_SUBST([JPEG_LIBS])
 
 # The dlopen() function is in the C library for *BSD and in
@@ -243,6 +248,7 @@ AM_CONDITIONAL([WITH_LIBV4L], [test x$enable_libv4l != xno])
 AM_CONDITIONAL([WITH_V4LUTILS], [test x$enable_v4lutils != xno])
 AM_CONDITIONAL([WITH_QV4L2], [test ${qt_pkgconfig} = true -a x$enable_qv4l2 != 
xno])
 AM_CONDITIONAL([WITH_QV4L2_GL], [test WITH_QV4L2 -a ${qt_pkgconfig_gl} = true])
+AM_CONDITIONAL([WITH_QV4L2_ALSA], [test WITH_QV4L2 -a ${alsa_pkgconfig} = 
true])
 AM_CONDITIONAL([WITH_V4L_PLUGINS], [test x$enable_libv4l != xno -a 
x$enable_shared != xno])
 AM_CONDITIONAL([WITH_V4L_WRAPPERS], [test x$enable_libv4l != xno -a 
x$enable_shared != xno])
 
diff --git a/utils/qv4l2/Makefile.am b/utils/qv4l2/Makefile.am
index 22d4c17..eed25b0 100644
--- a/utils/qv4l2/Makefile.am
+++ b/utils/qv4l2/Makefile.am
@@ -4,7 +4,8 @@ qv4l2_SOURCES = qv4l2.cpp general-tab.cpp ctrl-tab.cpp 
vbi-tab.cpp v4l2-api.cpp
   capture-win-qt.cpp capture-win-qt.h capture-win-gl.cpp capture-win-gl.h \
   raw2sliced.cpp qv4l2.h capture-win.h general-tab.h vbi-tab.h v4l2-api.h 
raw2sliced.h
 nodist_qv4l2_SOURCES = moc_qv4l2.cpp moc_general-tab.cpp moc_capture-win.cpp 
moc_vbi-tab.cpp qrc_qv4l2.cpp
-qv4l2_LDADD = ../../lib/libv4l2/libv4l2.la 
../../lib/libv4lconvert/libv4lconvert.la ../libv4l2util/libv4l2util.la
+qv4l2_LDADD = ../../lib/libv4l2/libv4l2.la 
../../lib/libv4lconvert/libv4lconvert.la ../libv4l2util/libv4l2util.la \
+  ../libmedia_dev/libmedia_dev.la
 
 if WITH_QV4L2_GL
 qv4l2_CPPFLAGS = $(QTGL_CFLAGS) -DENABLE_GL
@@ -14,6 +15,12 @@ qv4l2_CPPFLAGS = $(QT_CFLAGS)
 qv4l2_LDFLAGS = $(QT_LIBS)
 endif
 
+if WITH_QV4L2_ALSA
+qv4l2_CPPFLAGS += $(ALSA_CFLAGS) -DENABLE_ALSA
+qv4l2_LDFLAGS += $(ALSA_LIBS) -pthread
+qv4l2_SOURCES += alsa_stream.c alsa_stream.h
+endif
+
 EXTRA_DIST = exit.png fileopen.png qv4l2_24x24.png qv4l2_64x64.png qv4l2.png 
qv4l2.svg snapshot.png \
   video-television.png fileclose.png qv4l2_16x16.png qv4l2_32x32.png 
qv4l2.desktop qv4l2.qrc record.png \
   saveraw.png qv4l2.pro
diff --git a/utils/qv4l2/alsa_stream.c b/utils/qv4l2/alsa_stream.c
index 3e33b5e..90d3afb 100644
--- a/utils/qv4l2/alsa_stream.c
+++ b/utils/qv4l2/alsa_stream.c
@@ -26,9 +26,7 @@
  *
  */
 
-#include "config.h"
-
-#ifdef HAVE_ALSA_ASOUNDLIB_H
+#include "alsa_stream.h"
 
 #include 
 #include 
@@ -40,12 +38,12 @@
 #include 
 #include 
 #include 
-#include "alsa_stream.h"
 
 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
 
 /* Private vars to control alsa thread status */
 static int stop_alsa = 0;
+static snd_htimestamp_t timestamp;
 
 /* Error handlers */
 snd_output_t *output = NULL;
@@ -422,7 +420,8 @@ static int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle,
 static snd_pcm_sframes_t readbuf(snd_pcm_t *handle, char *buf, long len)
 {
 snd_pcm_sframes_t r;
-
+snd_pcm_uframes_t frames;
+snd_pcm_htimestamp(handle, &frames, ×tamp);
 r = snd_pcm_readi(handle, buf, len);
 if (r < 0 && r != -EAGAIN) {
r = snd_pcm_recover(handle, r, 0);
@@ -453,6 +452,7 @@ static snd_pcm_sframes_t writebuf(snd_pcm_t *handle, char 
*buf, long len)
len -= r;
snd_pcm_wait(handle, 100);
 }
+return -1;
 }
 
 static int alsa_stream(const char *pdevice, const char *cdevice, int latency)
@@ -642,4 +642,13 @@ int alsa_thread_is_running(void)
 return alsa_is_running;
 }
 
-#endif
+void alsa_thread_timestamp(struct timeval *tv)
+{
+   if (alsa_thread_is_running()) {
+   tv->tv_sec = timestamp.tv_sec;
+   tv->tv_usec = timestamp.tv_nsec / 1000;
+   } else {
+   tv->tv_sec = 1337;
+   tv->tv_usec = 0;
+   }
+}
diff --git a/utils/qv4l2/alsa_stream.h b/utils/qv4l2/alsa_stream.h
index c68fd6d..b74c3aa 100644
--- a/utils/qv4l2/alsa_stream.h
+++ b/utils/qv4l2/alsa_stream.h
@@ -1,5 +1,12 @@
-int alsa_thread_startup(const char *pdevice, const char *cdevice, int latency,
-   FILE *__error_fp,
-   int __verbose);
+#ifndef ALSA_STRAM_H
+#define ALSA_STRAM_H
+
+#include 
+#include 
+
+int alsa_thread_startup(const char *pdevice, const char *cdevice,
+   int latency, FILE *__error_fp, int __verbos

Re: [PATCH 3/5] qv4l2: add ALSA stream to qv4l2

2013-08-02 Thread Hans Verkuil
Hi BÃ¥rd!

Two small comments below...

On 08/02/2013 02:05 PM, BÃ¥rd Eirik Winther wrote:
> Changes the ALSA streaming code to work with qv4l2 and allows it to
> be compiled in. qv4l2 does not use the streaming function yet.
> 
> Signed-off-by: BÃ¥rd Eirik Winther 
> ---
>  configure.ac  |  6 ++
>  utils/qv4l2/Makefile.am   |  9 -
>  utils/qv4l2/alsa_stream.c | 21 +++--
>  utils/qv4l2/alsa_stream.h | 13 ++---
>  4 files changed, 39 insertions(+), 10 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index d74da61..e12507e 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -136,6 +136,11 @@ if test "x$qt_pkgconfig_gl" = "xfalse"; then
> AC_MSG_WARN(Qt4 OpenGL or higher is not available)
>  fi
>  
> +PKG_CHECK_MODULES(ALSA, [alsa], [alsa_pkgconfig=true], 
> [alsa_pkgconfig=false])
> +if test "x$alsa_pkgconfig" = "xfalse"; then
> +   AC_MSG_WARN(ALSA library not available)
> +fi
> +
>  AC_SUBST([JPEG_LIBS])
>  
>  # The dlopen() function is in the C library for *BSD and in
> @@ -243,6 +248,7 @@ AM_CONDITIONAL([WITH_LIBV4L], [test x$enable_libv4l != 
> xno])
>  AM_CONDITIONAL([WITH_V4LUTILS], [test x$enable_v4lutils != xno])
>  AM_CONDITIONAL([WITH_QV4L2], [test ${qt_pkgconfig} = true -a x$enable_qv4l2 
> != xno])
>  AM_CONDITIONAL([WITH_QV4L2_GL], [test WITH_QV4L2 -a ${qt_pkgconfig_gl} = 
> true])
> +AM_CONDITIONAL([WITH_QV4L2_ALSA], [test WITH_QV4L2 -a ${alsa_pkgconfig} = 
> true])
>  AM_CONDITIONAL([WITH_V4L_PLUGINS], [test x$enable_libv4l != xno -a 
> x$enable_shared != xno])
>  AM_CONDITIONAL([WITH_V4L_WRAPPERS], [test x$enable_libv4l != xno -a 
> x$enable_shared != xno])
>  
> diff --git a/utils/qv4l2/Makefile.am b/utils/qv4l2/Makefile.am
> index 22d4c17..eed25b0 100644
> --- a/utils/qv4l2/Makefile.am
> +++ b/utils/qv4l2/Makefile.am
> @@ -4,7 +4,8 @@ qv4l2_SOURCES = qv4l2.cpp general-tab.cpp ctrl-tab.cpp 
> vbi-tab.cpp v4l2-api.cpp
>capture-win-qt.cpp capture-win-qt.h capture-win-gl.cpp capture-win-gl.h \
>raw2sliced.cpp qv4l2.h capture-win.h general-tab.h vbi-tab.h v4l2-api.h 
> raw2sliced.h
>  nodist_qv4l2_SOURCES = moc_qv4l2.cpp moc_general-tab.cpp moc_capture-win.cpp 
> moc_vbi-tab.cpp qrc_qv4l2.cpp
> -qv4l2_LDADD = ../../lib/libv4l2/libv4l2.la 
> ../../lib/libv4lconvert/libv4lconvert.la ../libv4l2util/libv4l2util.la
> +qv4l2_LDADD = ../../lib/libv4l2/libv4l2.la 
> ../../lib/libv4lconvert/libv4lconvert.la ../libv4l2util/libv4l2util.la \
> +  ../libmedia_dev/libmedia_dev.la
>  
>  if WITH_QV4L2_GL
>  qv4l2_CPPFLAGS = $(QTGL_CFLAGS) -DENABLE_GL
> @@ -14,6 +15,12 @@ qv4l2_CPPFLAGS = $(QT_CFLAGS)
>  qv4l2_LDFLAGS = $(QT_LIBS)
>  endif
>  
> +if WITH_QV4L2_ALSA
> +qv4l2_CPPFLAGS += $(ALSA_CFLAGS) -DENABLE_ALSA
> +qv4l2_LDFLAGS += $(ALSA_LIBS) -pthread
> +qv4l2_SOURCES += alsa_stream.c alsa_stream.h
> +endif
> +
>  EXTRA_DIST = exit.png fileopen.png qv4l2_24x24.png qv4l2_64x64.png qv4l2.png 
> qv4l2.svg snapshot.png \
>video-television.png fileclose.png qv4l2_16x16.png qv4l2_32x32.png 
> qv4l2.desktop qv4l2.qrc record.png \
>saveraw.png qv4l2.pro
> diff --git a/utils/qv4l2/alsa_stream.c b/utils/qv4l2/alsa_stream.c
> index 3e33b5e..90d3afb 100644
> --- a/utils/qv4l2/alsa_stream.c
> +++ b/utils/qv4l2/alsa_stream.c
> @@ -26,9 +26,7 @@
>   *
>   */
>  
> -#include "config.h"
> -
> -#ifdef HAVE_ALSA_ASOUNDLIB_H
> +#include "alsa_stream.h"
>  
>  #include 
>  #include 
> @@ -40,12 +38,12 @@
>  #include 
>  #include 
>  #include 
> -#include "alsa_stream.h"
>  
>  #define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
>  
>  /* Private vars to control alsa thread status */
>  static int stop_alsa = 0;
> +static snd_htimestamp_t timestamp;
>  
>  /* Error handlers */
>  snd_output_t *output = NULL;
> @@ -422,7 +420,8 @@ static int setparams(snd_pcm_t *phandle, snd_pcm_t 
> *chandle,
>  static snd_pcm_sframes_t readbuf(snd_pcm_t *handle, char *buf, long len)
>  {
>  snd_pcm_sframes_t r;
> -
> +snd_pcm_uframes_t frames;
> +snd_pcm_htimestamp(handle, &frames, ×tamp);
>  r = snd_pcm_readi(handle, buf, len);
>  if (r < 0 && r != -EAGAIN) {
>   r = snd_pcm_recover(handle, r, 0);
> @@ -453,6 +452,7 @@ static snd_pcm_sframes_t writebuf(snd_pcm_t *handle, char 
> *buf, long len)
>   len -= r;
>   snd_pcm_wait(handle, 100);
>  }
> +return -1;
>  }
>  
>  static int alsa_stream(const char *pdevice, const char *cdevice, int latency)
> @@ -642,4 +642,13 @@ int alsa_thread_is_running(void)
>  return alsa_is_running;
>  }
>  
> -#endif
> +void alsa_thread_timestamp(struct timeval *tv)
> +{
> + if (alsa_thread_is_running()) {
> + tv->tv_sec = timestamp.tv_sec;
> + tv->tv_usec = timestamp.tv_nsec / 1000;
> + } else {
> + tv->tv_sec = 1337;

Why 1337? I would expect either 0, or a bool return from this function to 
signify that there
is no valid timestamp.

> + tv->tv_usec = 0;
> + }
> +}
> diff --git a/utils/qv4l2/alsa_stream.h b/utils/qv4l2/alsa_stream.h
> i

[PATCH] V4L: Drop meaningless video_is_registered() call in v4l2_open()

2013-08-02 Thread Sylwester Nawrocki
As it currently stands this code doesn't protect against any races
between video device open() and its unregistration. Races could be
avoided by doing the video_is_registered() check protected by the
core mutex, while the video device unregistration is also done with
this mutex held.

The history of this code is that the second video_is_registered()
call has been added in commit ee6869afc922a9849979e49bb3bbcad7948
"V4L/DVB: v4l2: add core serialization lock" together with addition
of the core mutex support in fops:

mutex_unlock(&videodev_lock);
-   if (vdev->fops->open)
-   ret = vdev->fops->open(filp);
+   if (vdev->fops->open) {
+   if (vdev->lock)
+   mutex_lock(vdev->lock);
+   if (video_is_registered(vdev))
+   ret = vdev->fops->open(filp);
+   else
+   ret = -ENODEV;
+   if (vdev->lock)
+   mutex_unlock(vdev->lock);
+   }

While commit cf5337358548b813479b58478539fc20ee86556c
"[media] v4l2-dev: remove V4L2_FL_LOCK_ALL_FOPS"
removed only code touching the mutex:

mutex_unlock(&videodev_lock);
if (vdev->fops->open) {
-   if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
-   mutex_lock_interruptible(vdev->lock)) {
-   ret = -ERESTARTSYS;
-   goto err;
-   }
if (video_is_registered(vdev))
ret = vdev->fops->open(filp);
else
ret = -ENODEV;
-   if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
-   mutex_unlock(vdev->lock);
}

Remove the remaining video_is_registered() call as it doesn't provide
any real protection and just adds unnecessary overhead.

The drivers need to perform the unregistration check themselves inside
their file operation handlers, while holding respective mutex.

Signed-off-by: Sylwester Nawrocki 
Signed-off-by: Kyungmin Park 
---
 drivers/media/v4l2-core/v4l2-dev.c |8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index c8859d6..1743119 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -444,13 +444,9 @@ static int v4l2_open(struct inode *inode, struct file 
*filp)
/* and increase the device refcount */
video_get(vdev);
mutex_unlock(&videodev_lock);
-   if (vdev->fops->open) {
-   if (video_is_registered(vdev))
-   ret = vdev->fops->open(filp);
-   else
-   ret = -ENODEV;
-   }

+   if (vdev->fops->open)
+   ret = vdev->fops->open(filp);
if (vdev->debug)
printk(KERN_DEBUG "%s: open (%d)\n",
video_device_node_name(vdev), ret);
--
1.7.9.5

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


Re: [PATCH] V4L: Drop meaningless video_is_registered() call in v4l2_open()

2013-08-02 Thread Hans Verkuil
Hi Sylwester,

The patch is good, but I have some issues with the commit message itself.

On 08/02/2013 02:27 PM, Sylwester Nawrocki wrote:
> As it currently stands this code doesn't protect against any races
> between video device open() and its unregistration. Races could be
> avoided by doing the video_is_registered() check protected by the
> core mutex, while the video device unregistration is also done with
> this mutex held.

The video_unregister_device() is called completely asynchronously,
particularly in the case of usb drivers. So it was never the goal of
the video_is_registered() to be fool proof, since that isn't possible,
nor is that necessary.

The goal was that the v4l2 core would use it for the various file
operations and ioctls as a quick check whether the device was unregistered
and to return the correct error. This prevents drivers from having to do
the same thing.

> The history of this code is that the second video_is_registered()
> call has been added in commit ee6869afc922a9849979e49bb3bbcad7948
> "V4L/DVB: v4l2: add core serialization lock" together with addition
> of the core mutex support in fops:
> 
> mutex_unlock(&videodev_lock);
> -   if (vdev->fops->open)
> -   ret = vdev->fops->open(filp);
> +   if (vdev->fops->open) {
> +   if (vdev->lock)
> +   mutex_lock(vdev->lock);
> +   if (video_is_registered(vdev))
> +   ret = vdev->fops->open(filp);
> +   else
> +   ret = -ENODEV;
> +   if (vdev->lock)
> +   mutex_unlock(vdev->lock);
> +   }

The history is slightly more complicated: this commit moved the 
video_is_registered
call from before the mutex_unlock(&videodev_lock); to just before the fops->open
call.

Commit ca9afe6f87b569cdf8e797395381f18ae23a2905 "v4l2-dev: fix race condition"
added the video_is_registered() call to where it was originally (inside the
videodev_lock critical section), but it didn't bother to remove the duplicate
second video_is_registered call.

So that's how v4l2_open ended up with two calls to video_is_registered.

> 
> While commit cf5337358548b813479b58478539fc20ee86556c
> "[media] v4l2-dev: remove V4L2_FL_LOCK_ALL_FOPS"
> removed only code touching the mutex:
> 
> mutex_unlock(&videodev_lock);
> if (vdev->fops->open) {
> -   if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
> -   mutex_lock_interruptible(vdev->lock)) {
> -   ret = -ERESTARTSYS;
> -   goto err;
> -   }
> if (video_is_registered(vdev))
> ret = vdev->fops->open(filp);
> else
> ret = -ENODEV;
> -   if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
> -   mutex_unlock(vdev->lock);
> }
> 
> Remove the remaining video_is_registered() call as it doesn't provide
> any real protection and just adds unnecessary overhead.

True.

> The drivers need to perform the unregistration check themselves inside
> their file operation handlers, while holding respective mutex.

No, drivers do not need to do the unregistration check. Since unregistration
is asynchronous it can happen at any time, so there really is no point in
checking for it other than in the core. If the device is unregistered while
in the middle of a file operation, then that means that any USB activity will
return an error, and that any future file operations other than release() will
be met by an error as well from the v4l2 core.

> 
> Signed-off-by: Sylwester Nawrocki 
> Signed-off-by: Kyungmin Park 
> ---
>  drivers/media/v4l2-core/v4l2-dev.c |8 ++--
>  1 file changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
> b/drivers/media/v4l2-core/v4l2-dev.c
> index c8859d6..1743119 100644
> --- a/drivers/media/v4l2-core/v4l2-dev.c
> +++ b/drivers/media/v4l2-core/v4l2-dev.c
> @@ -444,13 +444,9 @@ static int v4l2_open(struct inode *inode, struct file 
> *filp)
>   /* and increase the device refcount */
>   video_get(vdev);
>   mutex_unlock(&videodev_lock);
> - if (vdev->fops->open) {
> - if (video_is_registered(vdev))
> - ret = vdev->fops->open(filp);
> - else
> - ret = -ENODEV;
> - }
> 
> + if (vdev->fops->open)
> + ret = vdev->fops->open(filp);
>   if (vdev->debug)
>   printk(KERN_DEBUG "%s: open (%d)\n",
>   video_device_node_name(vdev), ret);
> --
> 1.7.9.5
> 

A long story, but the patch is good, although the commit message needs work :-)

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[GIT PULL FOR v3.11] Just one fix

2013-08-02 Thread Hans Verkuil
Note: this patch is already merged in linuxtv/master, but it should also go
to 3.11.

Regards,

Hans

The following changes since commit 5ae90d8e467e625e447000cb4335c4db973b1095:

  Linux 3.11-rc3 (2013-07-28 20:53:33 -0700)

are available in the git repository at:

  git://linuxtv.org/hverkuil/media_tree.git for-v3.11b

for you to fetch changes up to 08efa3ee4aac27407f0651ad781c441367f90308:

  ml86v7667: override default field interlace order (2013-07-29 16:08:52 +0200)


Vladimir Barinov (1):
  ml86v7667: override default field interlace order

 drivers/media/i2c/ml86v7667.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 7/8] v4l2: use new V4L2_DV_BT_BLANKING/FRAME defines

2013-08-02 Thread Hans Verkuil
Prabhakar,

Can you please double check this patch? I'd like to have your Acked-by before I
commit it.

Thanks!

Hans

On 07/29/2013 02:41 PM, Hans Verkuil wrote:
> From: Hans Verkuil 
> 
> Use the new blanking and frame size defines. This also fixed a bug in
> these drivers: they assumed that the height for interlaced formats was
> the field height, however height is the frame height. So the height
> for a field is actually bt->height / 2.
> 
> Signed-off-by: Hans Verkuil 
> Cc: Lad, Prabhakar 
> ---
>  drivers/media/platform/davinci/vpif_capture.c | 10 ++
>  drivers/media/platform/davinci/vpif_display.c | 10 ++
>  2 files changed, 4 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/media/platform/davinci/vpif_capture.c 
> b/drivers/media/platform/davinci/vpif_capture.c
> index b11d7a7..e1b6a3b 100644
> --- a/drivers/media/platform/davinci/vpif_capture.c
> +++ b/drivers/media/platform/davinci/vpif_capture.c
> @@ -1799,19 +1799,15 @@ static int vpif_s_dv_timings(struct file *file, void 
> *priv,
>  
>   /* Configure video port timings */
>  
> - std_info->eav2sav = bt->hbackporch + bt->hfrontporch +
> - bt->hsync - 8;
> + std_info->eav2sav = V4L2_DV_BT_BLANKING_WIDTH(bt) - 8;
>   std_info->sav2eav = bt->width;
>  
>   std_info->l1 = 1;
>   std_info->l3 = bt->vsync + bt->vbackporch + 1;
>  
> + std_info->vsize = V4L2_DV_BT_FRAME_HEIGHT(bt);
>   if (bt->interlaced) {
>   if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
> - std_info->vsize = bt->height * 2 +
> - bt->vfrontporch + bt->vsync + bt->vbackporch +
> - bt->il_vfrontporch + bt->il_vsync +
> - bt->il_vbackporch;
>   std_info->l5 = std_info->vsize/2 -
>   (bt->vfrontporch - 1);
>   std_info->l7 = std_info->vsize/2 + 1;
> @@ -1825,8 +1821,6 @@ static int vpif_s_dv_timings(struct file *file, void 
> *priv,
>   return -EINVAL;
>   }
>   } else {
> - std_info->vsize = bt->height + bt->vfrontporch +
> - bt->vsync + bt->vbackporch;
>   std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
>   }
>   strncpy(std_info->name, "Custom timings BT656/1120", VPIF_MAX_NAME);
> diff --git a/drivers/media/platform/davinci/vpif_display.c 
> b/drivers/media/platform/davinci/vpif_display.c
> index c2ff067..a42e43c 100644
> --- a/drivers/media/platform/davinci/vpif_display.c
> +++ b/drivers/media/platform/davinci/vpif_display.c
> @@ -1436,19 +1436,15 @@ static int vpif_s_dv_timings(struct file *file, void 
> *priv,
>  
>   /* Configure video port timings */
>  
> - std_info->eav2sav = bt->hbackporch + bt->hfrontporch +
> - bt->hsync - 8;
> + std_info->eav2sav = V4L2_DV_BT_BLANKING_WIDTH(bt) - 8;
>   std_info->sav2eav = bt->width;
>  
>   std_info->l1 = 1;
>   std_info->l3 = bt->vsync + bt->vbackporch + 1;
>  
> + std_info->vsize = V4L2_DV_BT_FRAME_HEIGHT(bt);
>   if (bt->interlaced) {
>   if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
> - std_info->vsize = bt->height * 2 +
> - bt->vfrontporch + bt->vsync + bt->vbackporch +
> - bt->il_vfrontporch + bt->il_vsync +
> - bt->il_vbackporch;
>   std_info->l5 = std_info->vsize/2 -
>   (bt->vfrontporch - 1);
>   std_info->l7 = std_info->vsize/2 + 1;
> @@ -1462,8 +1458,6 @@ static int vpif_s_dv_timings(struct file *file, void 
> *priv,
>   return -EINVAL;
>   }
>   } else {
> - std_info->vsize = bt->height + bt->vfrontporch +
> - bt->vsync + bt->vbackporch;
>   std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
>   }
>   strncpy(std_info->name, "Custom timings BT656/1120",
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] videobuf2-dma-sg: Allocate pages as contiguous as possible

2013-08-02 Thread Andre Heider
Hi Ricardo,

I messed up one thing in my initial reply, sorry :(

And two additional nitpicks, while we're at it.

On Fri, Jul 19, 2013 at 07:02:33PM +0200, Ricardo Ribalda Delgado wrote:
> Most DMA engines have limitations regarding the number of DMA segments
> (sg-buffers) that they can handle. Videobuffers can easily spread
> through houndreds of pages.
> 
> In the previous aproach, the pages were allocated individually, this
> could led to the creation houndreds of dma segments (sg-buffers) that
> could not be handled by some DMA engines.

s/houndreds/hundreds/

> 
> This patch tries to minimize the number of DMA segments by using
> alloc_pages. In the worst case it will behave as before, but most
> of the times it will reduce the number of dma segments
> 
> Signed-off-by: Ricardo Ribalda Delgado 

With those changes you can add:

Reviewed-by: Andre Heider 

> ---
>  drivers/media/v4l2-core/videobuf2-dma-sg.c |   60 
> +++-
>  1 file changed, 49 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
> b/drivers/media/v4l2-core/videobuf2-dma-sg.c
> index 16ae3dc..c053605 100644
> --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
> +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
> @@ -42,10 +42,55 @@ struct vb2_dma_sg_buf {
>  
>  static void vb2_dma_sg_put(void *buf_priv);
>  
> +static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf,
> + gfp_t gfp_flags)
> +{
> + unsigned int last_page = 0;
> + int size = buf->sg_desc.size;
> +
> + while (size > 0) {
> + struct page *pages;
> + int order;
> + int i;
> +
> + order = get_order(size);
> + /* Dont over allocate*/
> + if ((PAGE_SIZE << order) > size)
> + order--;
> +
> + pages = NULL;
> + while (!pages) {
> + pages = alloc_pages(GFP_KERNEL | __GFP_ZERO |
> + __GFP_NOWARN | gfp_flags, order);
> + if (pages)
> + break;
> +
> + if (order == 0)
> + while (last_page--) {
> + __free_page(buf->pages[last_page]);
> + return -ENOMEM;
> + }
> + order--;
> + }
> +
> + split_page(pages, order);
> + for (i = 0; i < (1< + buf->pages[last_page] = pages[i];

My fault, it should read:

buf->pages[last_page] = &pages[i];

> + sg_set_page(&buf->sg_desc.sglist[last_page],
> + buf->pages[last_page], PAGE_SIZE, 0);
> + last_page++;
> + }
> +
> + size -= PAGE_SIZE << order;
> + }
> +
> + return 0;
> +}
> +
>  static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t 
> gfp_flags)
>  {
>   struct vb2_dma_sg_buf *buf;
> - int i;
> + int ret;
>  
>   buf = kzalloc(sizeof *buf, GFP_KERNEL);
>   if (!buf)
> @@ -69,14 +114,9 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned 
> long size, gfp_t gfp_fla
>   if (!buf->pages)
>   goto fail_pages_array_alloc;
>  
> - for (i = 0; i < buf->sg_desc.num_pages; ++i) {
> - buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO |
> -__GFP_NOWARN | gfp_flags);
> - if (NULL == buf->pages[i])
> - goto fail_pages_alloc;
> - sg_set_page(&buf->sg_desc.sglist[i],
> - buf->pages[i], PAGE_SIZE, 0);
> - }
> + ret = vb2_dma_sg_alloc_compacted(buf, gfp_flags);
> + if (ret)
> + goto fail_pages_alloc;
>  
>   buf->handler.refcount = &buf->refcount;
>   buf->handler.put = vb2_dma_sg_put;
> @@ -89,8 +129,6 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned 
> long size, gfp_t gfp_fla
>   return buf;
>  
>  fail_pages_alloc:
> - while (--i >= 0)
> - __free_page(buf->pages[i]);
>   kfree(buf->pages);
>  
>  fail_pages_array_alloc:
> -- 
> 1.7.10.4
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/6] v4l: ti-vpe: Create a vpdma helper library

2013-08-02 Thread Archit Taneja
The primary function of VPDMA is to move data between external memory and
internal processing modules(in our case, VPE) that source or sink data. VPDMA is
capable of buffering this data and then delivering the data as demanded to the
modules as programmed. The modules that source or sink data are referred to as
clients or ports. A channel is setup inside the VPDMA to connect a specific
memory buffer to a specific client. The VPDMA centralizes the DMA control
functions and buffering required to allow all the clients to minimize the
effect of long latency times.

Add the following to the VPDMA helper:

- A data struct which describe VPDMA channels. For now, these channels are the
  ones used only by VPE, the list of channels will increase when VIP(Video
  Input Port) also uses the VPDMA library. This channel information will be
  used to populate fields required by data descriptors.

- Data structs which describe the different data types supported by VPDMA. This
  data type information will be used to populate fields required by data
  descriptors and used by the VPE driver to map a V4L2 format to the
  corresponding VPDMA data type.

- Provide VPDMA register offset definitions, functions to read, write and modify
  VPDMA registers.

- Functions to create and submit a VPDMA list. A list is a group of descriptors
  that makes up a set of DMA transfers that need to be completed. Each
  descriptor will either perform a DMA transaction to fetch input buffers and
  write to output buffers(data descriptors), or configure the MMRs of sub blocks
  of VPE(configuration descriptors), or provide control information to VPDMA
  (control descriptors).

- Functions to allocate, map and unmap buffers needed for the descriptor list,
  payloads containing MMR values and motion vector buffers. These use the
  DMA mapping APIs to ensure exclusive access to VPDMA.

- Functions to enable VPDMA interrupts. VPDMA can trigger an interrupt on the
  VPE interrupt line when a descriptor list is parsed completely and the DMA
  transactions are completed. This requires masking the events in VPDMA
  registers and configuring some top level VPE interrupt registers.

- Enable some VPDMA specific parameters: frame start event(when to start DMA for
  a client) and line mode(whether each line fetched should be mirrored or not).

- Function to load firmware required by VPDMA. VPDMA requires a firmware for
  it's internal list manager. We add the required request_firmware apis to fetch
  this firmware from user space.

- Function to dump VPDMA registers.

- A function to initialize VPDMA, this will be called by the VPE driver with
  it's platform device pointer, this function will take care of loading VPDMA
  firmware and returning a handle back to the VPE driver. The VIP driver will
  also call the same init function to initialize it's own VPDMA instance.

Signed-off-by: Archit Taneja 
---
 drivers/media/platform/ti-vpe/vpdma.c  | 589 +
 drivers/media/platform/ti-vpe/vpdma.h  | 154 
 drivers/media/platform/ti-vpe/vpdma_priv.h | 119 ++
 3 files changed, 862 insertions(+)
 create mode 100644 drivers/media/platform/ti-vpe/vpdma.c
 create mode 100644 drivers/media/platform/ti-vpe/vpdma.h
 create mode 100644 drivers/media/platform/ti-vpe/vpdma_priv.h

diff --git a/drivers/media/platform/ti-vpe/vpdma.c 
b/drivers/media/platform/ti-vpe/vpdma.c
new file mode 100644
index 000..b15b3dd
--- /dev/null
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -0,0 +1,589 @@
+/*
+ * VPDMA helper library
+ *
+ * Copyright (c) 2013 Texas Instruments Inc.
+ *
+ * David Griego, 
+ * Dale Farnsworth, 
+ * Archit Taneja, 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "vpdma.h"
+#include "vpdma_priv.h"
+
+#define VPDMA_FIRMWARE "vpdma-1b8.bin"
+
+struct vpdma_data_format vpdma_yuv_fmts[] = {
+   [VPDMA_DATA_FMT_Y444] = {
+   .data_type  = DATA_TYPE_Y444,
+   .depth  = 8,
+   },
+   [VPDMA_DATA_FMT_Y422] = {
+   .data_type  = DATA_TYPE_Y422,
+   .depth  = 8,
+   },
+   [VPDMA_DATA_FMT_Y420] = {
+   .data_type  = DATA_TYPE_Y420,
+   .depth  = 8,
+   },
+   [VPDMA_DATA_FMT_C444] = {
+   .data_type  = DATA_TYPE_C444,
+   .depth  = 8,
+   },
+   [VPDMA_DATA_FMT_C422] = {
+   .data_type  = DATA_TYPE_C422,
+   .depth  = 8,
+   },
+   [VPDMA_DATA_FMT_C420] = {
+   .data_type  = DATA_TYPE_C420,
+   .depth  = 4,
+   },
+   [VPDMA_DATA_FMT_YC422] = {
+   .data_type  = DATA_TYPE_YC422,
+  

[PATCH 5/6] arm: dra7xx: hwmod data: add VPE hwmod data and ocp_if info

2013-08-02 Thread Archit Taneja
Add hwmod data for the VPE IP, this is needed for the IP to be reset during
boot, and control the functional clock when the driver needs it via
pm_runtime apis. Add the corresponding ocp_if struct and add it DRA7XX's
ocp interface list.

Cc: Rajendra Nayak 
Cc: Sricharan R 
Signed-off-by: Archit Taneja 
---
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 42 +++
 1 file changed, 42 insertions(+)

diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index f647998b..181365d 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -1883,6 +1883,39 @@ static struct omap_hwmod dra7xx_wd_timer2_hwmod = {
},
 };
 
+/*
+ * 'vpe' class
+ *
+ */
+
+static struct omap_hwmod_class_sysconfig dra7xx_vpe_sysc = {
+   .sysc_offs  = 0x0010,
+   .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
+   .idlemodes  = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+  SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+  MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+   .sysc_fields= &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dra7xx_vpe_hwmod_class = {
+   .name   = "vpe",
+   .sysc   = &dra7xx_vpe_sysc,
+};
+
+/* vpe */
+static struct omap_hwmod dra7xx_vpe_hwmod = {
+   .name   = "vpe",
+   .class  = &dra7xx_vpe_hwmod_class,
+   .clkdm_name = "vpe_clkdm",
+   .main_clk   = "dpll_core_h23x2_ck",
+   .prcm = {
+   .omap4 = {
+   .clkctrl_offs = DRA7XX_CM_VPE_VPE_CLKCTRL_OFFSET,
+   .context_offs = DRA7XX_RM_VPE_VPE_CONTEXT_OFFSET,
+   .modulemode   = MODULEMODE_HWCTRL,
+   },
+   },
+};
 
 /*
  * Interfaces
@@ -2636,6 +2669,14 @@ static struct omap_hwmod_ocp_if 
dra7xx_l4_wkup__wd_timer2 = {
.user   = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/* l4_per3 -> vpe */
+static struct omap_hwmod_ocp_if dra7xx_l4_per3__vpe = {
+   .master = &dra7xx_l4_per3_hwmod,
+   .slave  = &dra7xx_vpe_hwmod,
+   .clk= "l3_iclk_div",
+   .user   = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
&dra7xx_l3_main_2__l3_instr,
&dra7xx_l4_cfg__l3_main_1,
@@ -2714,6 +2755,7 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] 
__initdata = {
&dra7xx_l3_main_1__vcp2,
&dra7xx_l4_per2__vcp2,
&dra7xx_l4_wkup__wd_timer2,
+   &dra7xx_l4_per3__vpe,
NULL,
 };
 
-- 
1.8.1.2

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


[PATCH 4/6] v4l: ti-vpe: Add de-interlacer support in VPE

2013-08-02 Thread Archit Taneja
Add support for the de-interlacer block in VPE.

For de-interlacer to work, we need to enable 2 more sets of VPE input ports
which fetch data from the 'last' and 'last to last' fields of the interlaced
video. Apart from that, we need to enable the Motion vector output and input
ports, and also allocate DMA buffers for them.

We need to make sure that two most recent fields in the source queue are
available and in the 'READY' state. Once a mem2mem context gets access to the
VPE HW(in device_run), it extracts the addresses of the 3 buffers, and provides
it to the data descriptors for the 3 sets of input ports((LUMA1, CHROMA1),
(LUMA2, CHROMA2), and (LUMA3, CHROMA3)) respectively for the 3 consecutive
fields. The motion vector and output port descriptors are configured and the
list is submitted to VPDMA.

Once the transaction is done, the v4l2 buffer corresponding to the oldest
field(the 3rd one) is changed to the state 'DONE', and the buffers corresponding
to 1st and 2nd fields become the 2nd and 3rd field for the next de-interlace
operation. This way, for each deinterlace operation, we have the 3 most recent
fields. After each transaction, we also swap the motion vector buffers, the new
input motion vector buffer contains the resultant motion information of all the
previous frames, and the new output motion vector buffer will be used to hold
the updated motion vector to capture the motion changes in the next field.

The de-interlacer is removed from bypass mode, it requires some extra default
configurations which are now added. The chrominance upsampler coefficients are
added for interlaced frames. Some VPDMA parameters like frame start event and
line mode are configured for the 2 extra sets of input ports.

Signed-off-by: Archit Taneja 
---
 drivers/media/platform/ti-vpe/vpe.c | 372 
 1 file changed, 337 insertions(+), 35 deletions(-)

diff --git a/drivers/media/platform/ti-vpe/vpe.c 
b/drivers/media/platform/ti-vpe/vpe.c
index 14a292b..5b1410c 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -69,6 +69,8 @@
 #define VPE_CHROMA 1
 
 /* per m2m context info */
+#define VPE_MAX_SRC_BUFS   3   /* need 3 src fields to de-interlace */
+
 #define VPE_DEF_BUFS_PER_JOB   1   /* default one buffer per batch job */
 
 /*
@@ -104,12 +106,44 @@ struct vpe_us_coeffs {
 /*
  * Default upsampler coefficients
  */
-static struct vpe_us_coeffs us_coeffs[] = {
+static struct vpe_us_coeffs us_coeffs[2] = {
{
/* Coefficients for progressive input */
0x00C8, 0x0348, 0x0018, 0x3FD8, 0x3FB8, 0x0378, 0x00E8, 0x3FE8,
0x00C8, 0x0348, 0x0018, 0x3FD8, 0x3FB8, 0x0378, 0x00E8, 0x3FE8,
},
+   {
+   /* Coefficients for Top Field Interlaced input */
+   0x0051, 0x03D5, 0x3FE3, 0x3FF7, 0x3FB5, 0x02E9, 0x018F, 0x3FD3,
+   /* Coefficients for Bottom Field Interlaced input */
+   0x016B, 0x0247, 0x00B1, 0x3F9D, 0x3FCF, 0x03DB, 0x005D, 0x3FF9,
+   },
+};
+
+/*
+ * the following registers are for configuring some of the parameters of the
+ * motion and edge detection blocks inside DEI, these generally remain the 
same,
+ * these could be passed later via userspace if some one needs to tweak these.
+ */
+struct vpe_dei_regs {
+   unsigned long mdt_spacial_freq_thr_reg; /* VPE_DEI_REG2 */
+   unsigned long edi_config_reg;   /* VPE_DEI_REG3 */
+   unsigned long edi_lut_reg0; /* VPE_DEI_REG4 */
+   unsigned long edi_lut_reg1; /* VPE_DEI_REG5 */
+   unsigned long edi_lut_reg2; /* VPE_DEI_REG6 */
+   unsigned long edi_lut_reg3; /* VPE_DEI_REG7 */
+};
+
+/*
+ * default expert DEI register values, unlikely to be modified.
+ */
+static struct vpe_dei_regs dei_regs = {
+   0x020C0804u,
+   0x0118100Fu,
+   0x08040200u,
+   0x1010100Cu,
+   0x10101010u,
+   0x10101010u,
 };
 
 /*
@@ -117,6 +151,7 @@ static struct vpe_us_coeffs us_coeffs[] = {
  */
 struct vpe_port_data {
enum vpdma_channel channel; /* VPDMA channel */
+   u8  vb_index;   /* input frame f, f-1, f-2 index */
u8  vb_part;/* plane index for co-panar formats */
 };
 
@@ -125,6 +160,12 @@ struct vpe_port_data {
  */
 #define VPE_PORT_LUMA1_IN  0
 #define VPE_PORT_CHROMA1_IN1
+#define VPE_PORT_LUMA2_IN  2
+#define VPE_PORT_CHROMA2_IN3
+#define VPE_PORT_LUMA3_IN  4
+#define VPE_PORT_CHROMA3_IN5
+#define VPE_PORT_MV_IN 6
+#define VPE_PORT_MV_OUT7
 #define VPE_PORT_LUMA_OUT  8
 #define VPE_PORT_CHROMA_OUT9
 #define VPE_PORT_RGB_OUT   10
@@ -132,12 +173,40 @@ struct vpe_port_data {
 static struct vpe_port_data port_data[11] = {
[VPE_PORT_LUMA1_IN] = {
.channel= VPE_CHAN_LUMA1_IN,
+

[PATCH 0/6] v4l: VPE mem to mem driver

2013-08-02 Thread Archit Taneja
VPE:
VPE(Video Processing Engine) is an IP found on DRA7xx, and in some past TI
multimedia SoCs which don't have baseport support in the mainline kernel.

VPE is a memory to memory block used for performing de-interlacing, scaling and
color conversion on input buffers. It's primarily used to de-interlace decoded
DVD/Blu Ray video buffers, and provide the content to progressive display or do
some other post processing. VPE can also be used for other tasks like fast
color space conversion, scaling and chrominance up/down sampling. The scaler in
particular is based on a polyphase filter and supports 32 phases and 5/7 taps.

VPE's De-interlacer IP:
The De-interlacer module performs a combination of spatial and temporal
interlacing, it determines the weight-age by keeping a track of the change in
motion between fields by maintaining and updating a motion vector buffer in
the RAM. The de-interlacer needs the current field and the 2 previous fields
(along with the motion vector info)to generate a progressive frame. It operates
on YUV422 data.

VPDMA:
All the DMAs are done through a dedicated DMA IP called VPDMA(Video Port Direct
Memory Access). This DMA IP is specialized for transferring video buffers, the
input and output data ports of VPDMA are configured via descriptor lists loaded
to the VPDMA list manager. VPDMA is also used to load MMRs of the various VPE
sub blocks.

VPDMA is advanced enough to support multiple clients like a system DMA,
however, the way it's integrated in the SoC is such that it can be used only by
the VPE IP. The same IP is also used on DRA7x in another block called VIP
(full form) used to capture camera sensor content. It's again dedicated to the
VIP block, and therefore doesn't have multiple clients. These factors made us
consider writing the VPDMA block as a library, providing functions to
VPE(and VIP in the future) to add descriptors and start DMA. It might have
made sense to make it a dmaengine driver if there were multiple clients using
VPDMA.

VPE and VPDMA look something like this:

   ---   ---
  |MVin   |>|   |
  |   | |   |
  |   Mvout   |<|   |---
  |   |-|   |   |   |
  | f |-->| CHR_US1 |-->| D |   | S |--
  | (YUV in)  |-| E |-->| C |-->|CHR_DS|
  |   |-| I |   |   |   |-- |
  |   f - 1   |-->| CHR_US2 |-->|   |   |   |   |   |
  | (YUV in)  |-|   |---|-  |
  |   |-|   |-->| CSC |--   |
  |   f - 2   |-->| CHR_US3 |-->|   |-   |  |
  | (YUV in)  |-|   ||  |
  |   |  --- |  |
  |   |  |  |   
  
  | (YUV out) |<-   |
  |   | |
  | (RGB out) |<
   ---
 VPDMAVPE

f, f - 1, and f - 2 are input ports fetching 3 consecutive fields for the
de-interlacer. MVin and MVout are ports which fetch the current motion vector
and output the updated motion vector respectively. There are 2 output ports,
one for YUV output and the other for RGB output if the color space
converter(CSC) is used. The inputs can be YUV packed or semiplanar formats. The
chrominance upsampler(CHR_USx) is used when the input format is NV12, the
chrominance downsampler(CHR_DS) is used if the the output content needs to be
NV12 format. The scaler(SC) can be used to scale the de-interlaced content if
needed.

This series adds VPE as a mem to mem v4l2 driver, and VPDMA as a helper
library. For now, only the de-interlacer is configured, the scaler and color
space converter are bypassed.

These patches were tested over the patch series which provides initial baseport
support for DRA7XX:

http://marc.info/?l=linux-omap&m=137518359422774&w=2

Archit Taneja (6):
  v4l: ti-vpe: Create a vpdma helper library
  v4l: ti-vpe: Add helpers for creating VPDMA descriptors
  v4l: ti-vpe: Add VPE mem to mem driver
  v4l: ti-vpe: Add de-interlacer support in VPE
  arm: dra7xx: hwmod data: add VPE hwmod data and ocp_if info
  experimental: arm: dts: dra7xx: Add a DT node for VPE

 arch/arm/boot/dts/dra7.dtsi|   11 +
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c  |   42 +
 drivers/media/platform/Kconfig |   10 +
 drivers/media/platform/Makefile|2 +
 drivers/media/platform/ti-vpe/vpdma.c  |  858 
 drivers/media/platform/ti-vpe/vpdma.h  |  202 +++
 drivers/media/platform/ti-vpe/vpdma_priv.h |  814 +++
 drivers/media/platform/ti-vpe/vpe.c| 2065 
 drivers/media/platform/ti-vpe/vpe_regs.h 

[PATCH 6/6] experimental: arm: dts: dra7xx: Add a DT node for VPE

2013-08-02 Thread Archit Taneja
Add a DT node for VPE in dra7.dtsi. This is experimental because we might need
to split the VPE address space a bit more, and also because the IRQ line
described is accessible the IRQ crossbar driver is added for DRA7XX.

Cc: Rajendra Nayak 
Cc: Sricharan R 
Signed-off-by: Archit Taneja 
---
 arch/arm/boot/dts/dra7.dtsi | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index ce9a0f0..3237972 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -484,6 +484,17 @@
dmas = <&sdma 70>, <&sdma 71>;
dma-names = "tx0", "rx0";
};
+
+   vpe {
+   compatible = "ti,vpe";
+   ti,hwmods = "vpe";
+   reg = <0x489d 0xd000>, <0x489dd000 0x400>;
+   reg-names = "vpe", "vpdma";
+   interrupts = <0 159 0x4>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
+
};
 
clocks {
-- 
1.8.1.2

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


[PATCH 2/6] v4l: ti-vpe: Add helpers for creating VPDMA descriptors

2013-08-02 Thread Archit Taneja
Create functions which the VPE driver can use to create a VPDMA descriptor and
add it to a VPDMA descriptor list. These functions take a pointer to an existing
list, and append the configuration/data/control descriptor header to the list.

In the case of configuration descriptors, the creation of a payload block may be
required(the payloads can hold VPE MMR values, or scaler coefficients). The
allocation of the payload buffer and it's content is left to the VPE driver.
However, the VPDMA library provides helper macros to create payload in the
correct format.

Add debug functions to dump the descriptors in a way such that it's easy to see
the values of different fields in the descriptors.

Signed-off-by: Archit Taneja 
---
 drivers/media/platform/ti-vpe/vpdma.c  | 269 +++
 drivers/media/platform/ti-vpe/vpdma.h  |  48 ++
 drivers/media/platform/ti-vpe/vpdma_priv.h | 695 +
 3 files changed, 1012 insertions(+)

diff --git a/drivers/media/platform/ti-vpe/vpdma.c 
b/drivers/media/platform/ti-vpe/vpdma.c
index b15b3dd..b957381 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "vpdma.h"
 #include "vpdma_priv.h"
@@ -425,6 +426,274 @@ int vpdma_submit_descs(struct vpdma_data *vpdma, struct 
vpdma_desc_list *list)
return 0;
 }
 
+static void dump_cfd(struct vpdma_cfd *cfd)
+{
+   int class;
+
+   class = cfd_get_class(cfd);
+
+   pr_debug("config descriptor of payload class: %s\n",
+   class == CFD_CLS_BLOCK ? "simple block" :
+   "address data block");
+
+   if (class == CFD_CLS_BLOCK)
+   pr_debug("word0: dst_addr_offset = 0x%08x\n",
+   cfd_get_dest_addr_offset(cfd));
+
+   if (class == CFD_CLS_BLOCK)
+   pr_debug("word1: num_data_wrds = %d\n", cfd_get_block_len(cfd));
+
+   pr_debug("word2: payload_addr = 0x%08x\n", cfd_get_payload_addr(cfd));
+
+   pr_debug("word3: pkt_type = %d, direct = %d, class = %d, dest = %d, "
+   "payload_len = %d\n", cfd_get_pkt_type(cfd),
+   cfd_get_direct(cfd), class, cfd_get_dest(cfd),
+   cfd_get_payload_len(cfd));
+}
+
+/*
+ * append a configuration descriptor to the given descriptor list, where the
+ * payload is in the form of a simple data block specified in the descriptor
+ * header, this is used to upload scaler coefficients to the scaler module
+ */
+void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
+   struct vpdma_buf *blk, u32 dest_offset)
+{
+   struct vpdma_cfd *cfd;
+   int len = blk->size;
+
+   WARN_ON(blk->dma_addr & VPDMA_DESC_ALIGN);
+
+   cfd = list->next;
+   WARN_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size));
+
+   cfd_set_dest_addr_offset(cfd, dest_offset);
+   cfd_set_block_len(cfd, len);
+   cfd_set_payload_addr(cfd, blk->dma_addr);
+   cfd_set_pkt_payload_len(cfd, CFD_INDIRECT, CFD_CLS_BLOCK, client,
+   len >> 4);
+
+   list->next = cfd + 1;
+
+   dump_cfd(cfd);
+}
+
+/*
+ * append a configuration descriptor to the given descriptor list, where the
+ * payload is in the address data block format, this is used to a configure a
+ * discontiguous set of MMRs
+ */
+void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
+   struct vpdma_buf *adb)
+{
+   struct vpdma_cfd *cfd;
+   unsigned int len = adb->size;
+
+   WARN_ON(len & VPDMA_ADB_SIZE_ALIGN);
+   WARN_ON(adb->dma_addr & VPDMA_DESC_ALIGN);
+
+   cfd = list->next;
+   BUG_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size));
+
+   cfd_set_w0(cfd, 0);
+   cfd_set_w1(cfd, 0);
+   cfd_set_payload_addr(cfd, adb->dma_addr);
+   cfd_set_pkt_payload_len(cfd, CFD_INDIRECT, CFD_CLS_ADB, client,
+   len >> 4);
+
+   list->next = cfd + 1;
+
+   dump_cfd(cfd);
+};
+
+/*
+ * control descriptor format change based on what type of control descriptor it
+ * is, we only use 'sync on channel' control descriptors for now, so assume 
it's
+ * that
+ */
+static void dump_ctd(struct vpdma_ctd *ctd)
+{
+   pr_debug("control descriptor\n");
+
+   pr_debug("word3: pkt_type = %d, source = %d, ctl_type = %d\n",
+   ctd_get_pkt_type(ctd), ctd_get_source(ctd), ctd_get_ctl(ctd));
+}
+
+/*
+ * append a 'sync on channel' type control descriptor to the given descriptor
+ * list, this descriptor stalls the VPDMA list till the time DMA is completed
+ * on the specified channel
+ */
+void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
+   enum vpdma_channel chan)
+{
+   struct vpdma_ctd *ctd;
+
+   ctd = list->next;
+   WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size));
+
+   ctd_set_w0(ctd, 0);
+   ctd_set_w1(ctd, 0);
+   ctd_set_w2(ctd, 0);
+   ctd_set_type_source_ctl(ctd, cha

[PATCH v4 1/2] videobuf2-dma-sg: Allocate pages as contiguous as possible

2013-08-02 Thread Ricardo Ribalda Delgado
Most DMA engines have limitations regarding the number of DMA segments
(sg-buffers) that they can handle. Videobuffers can easily spread
through hundreds of pages.

In the previous aproach, the pages were allocated individually, this
could led to the creation houndreds of dma segments (sg-buffers) that
could not be handled by some DMA engines.

This patch tries to minimize the number of DMA segments by using
alloc_pages. In the worst case it will behave as before, but most
of the times it will reduce the number of dma segments

Acked-by: Marek Szyprowski 
Reviewed-by: Andre Heider 
Signed-off-by: Ricardo Ribalda Delgado 
---
 drivers/media/v4l2-core/videobuf2-dma-sg.c |   60 +++-
 1 file changed, 49 insertions(+), 11 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index 16ae3dc..4999c48 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -42,10 +42,55 @@ struct vb2_dma_sg_buf {
 
 static void vb2_dma_sg_put(void *buf_priv);
 
+static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf,
+   gfp_t gfp_flags)
+{
+   unsigned int last_page = 0;
+   int size = buf->sg_desc.size;
+
+   while (size > 0) {
+   struct page *pages;
+   int order;
+   int i;
+
+   order = get_order(size);
+   /* Dont over allocate*/
+   if ((PAGE_SIZE << order) > size)
+   order--;
+
+   pages = NULL;
+   while (!pages) {
+   pages = alloc_pages(GFP_KERNEL | __GFP_ZERO |
+   __GFP_NOWARN | gfp_flags, order);
+   if (pages)
+   break;
+
+   if (order == 0) {
+   while (last_page--)
+   __free_page(buf->pages[last_page]);
+   return -ENOMEM;
+   }
+   order--;
+   }
+
+   split_page(pages, order);
+   for (i = 0; i < (1 << order); i++) {
+   buf->pages[last_page] = &pages[i];
+   sg_set_page(&buf->sg_desc.sglist[last_page],
+   buf->pages[last_page], PAGE_SIZE, 0);
+   last_page++;
+   }
+
+   size -= PAGE_SIZE << order;
+   }
+
+   return 0;
+}
+
 static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t 
gfp_flags)
 {
struct vb2_dma_sg_buf *buf;
-   int i;
+   int ret;
 
buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
@@ -69,14 +114,9 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned 
long size, gfp_t gfp_fla
if (!buf->pages)
goto fail_pages_array_alloc;
 
-   for (i = 0; i < buf->sg_desc.num_pages; ++i) {
-   buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO |
-  __GFP_NOWARN | gfp_flags);
-   if (NULL == buf->pages[i])
-   goto fail_pages_alloc;
-   sg_set_page(&buf->sg_desc.sglist[i],
-   buf->pages[i], PAGE_SIZE, 0);
-   }
+   ret = vb2_dma_sg_alloc_compacted(buf, gfp_flags);
+   if (ret)
+   goto fail_pages_alloc;
 
buf->handler.refcount = &buf->refcount;
buf->handler.put = vb2_dma_sg_put;
@@ -89,8 +129,6 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long 
size, gfp_t gfp_fla
return buf;
 
 fail_pages_alloc:
-   while (--i >= 0)
-   __free_page(buf->pages[i]);
kfree(buf->pages);
 
 fail_pages_array_alloc:
-- 
1.7.10.4

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


[PATCH v4 2/2] videobuf2-dma-sg: Replace vb2_dma_sg_desc with sg_table

2013-08-02 Thread Ricardo Ribalda Delgado
Replace the private struct vb2_dma_sg_desc with the struct sg_table so
we can benefit from all the helping functions in lib/scatterlist.c for
things like allocating the sg or compacting the descriptor

marvel-ccic and solo6x10 drivers, that uses this api has been updated

Acked-by: Marek Szyprowski 
Reviewed-by: Andre Heider 
Signed-off-by: Ricardo Ribalda Delgado 
---
 drivers/media/platform/marvell-ccic/mcam-core.c|   14 +--
 drivers/media/v4l2-core/videobuf2-dma-sg.c |  103 
 drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c |   20 ++--
 include/media/videobuf2-dma-sg.h   |   10 +-
 4 files changed, 63 insertions(+), 84 deletions(-)

diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c 
b/drivers/media/platform/marvell-ccic/mcam-core.c
index 64ab91e..0ac51bd 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
@@ -1040,16 +1040,16 @@ static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
 {
struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
-   struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0);
+   struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0);
struct mcam_dma_desc *desc = mvb->dma_desc;
struct scatterlist *sg;
int i;
 
-   mvb->dma_desc_nent = dma_map_sg(cam->dev, sgd->sglist, sgd->num_pages,
-   DMA_FROM_DEVICE);
+   mvb->dma_desc_nent = dma_map_sg(cam->dev, sg_table->sgl,
+   sg_table->nents, DMA_FROM_DEVICE);
if (mvb->dma_desc_nent <= 0)
return -EIO;  /* Not sure what's right here */
-   for_each_sg(sgd->sglist, sg, mvb->dma_desc_nent, i) {
+   for_each_sg(sg_table->sgl, sg, mvb->dma_desc_nent, i) {
desc->dma_addr = sg_dma_address(sg);
desc->segment_len = sg_dma_len(sg);
desc++;
@@ -1060,9 +1060,11 @@ static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
 static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb)
 {
struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
-   struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0);
+   struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0);
 
-   dma_unmap_sg(cam->dev, sgd->sglist, sgd->num_pages, DMA_FROM_DEVICE);
+   if (sg_table)
+   dma_unmap_sg(cam->dev, sg_table->sgl,
+   sg_table->nents, DMA_FROM_DEVICE);
return 0;
 }
 
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index 4999c48..2f86054 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -35,7 +35,9 @@ struct vb2_dma_sg_buf {
struct page **pages;
int write;
int offset;
-   struct vb2_dma_sg_desc  sg_desc;
+   struct sg_table sg_table;
+   size_t  size;
+   unsigned intnum_pages;
atomic_trefcount;
struct vb2_vmarea_handler   handler;
 };
@@ -46,7 +48,7 @@ static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf 
*buf,
gfp_t gfp_flags)
 {
unsigned int last_page = 0;
-   int size = buf->sg_desc.size;
+   int size = buf->size;
 
while (size > 0) {
struct page *pages;
@@ -74,12 +76,8 @@ static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf 
*buf,
}
 
split_page(pages, order);
-   for (i = 0; i < (1 << order); i++) {
-   buf->pages[last_page] = &pages[i];
-   sg_set_page(&buf->sg_desc.sglist[last_page],
-   buf->pages[last_page], PAGE_SIZE, 0);
-   last_page++;
-   }
+   for (i = 0; i < (1 << order); i++)
+   buf->pages[last_page++] = &pages[i];
 
size -= PAGE_SIZE << order;
}
@@ -91,6 +89,7 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long 
size, gfp_t gfp_fla
 {
struct vb2_dma_sg_buf *buf;
int ret;
+   int num_pages;
 
buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
@@ -99,17 +98,11 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned 
long size, gfp_t gfp_fla
buf->vaddr = NULL;
buf->write = 0;
buf->offset = 0;
-   buf->sg_desc.size = size;
+   buf->size = size;
/* size is already page aligned */
-   buf->sg_desc.num_pages = size >> PAGE_SHIFT;
-
-   buf->sg_desc.sglist = vzalloc(buf->sg_desc.num_pages *
- sizeof(*buf->sg_desc.sglist));
-   if (!buf->sg_desc.sglist)
-   goto fail_sglist_alloc;
- 

[PATCH v4 0/2] videobuf2-dma-sg: Contiguos memory allocation

2013-08-02 Thread Ricardo Ribalda Delgado
Allocate memory as contiguos as possible to support dma engines with limitated 
amount of sg-descriptors.

Replace private structer vb2_dma_sg_desc with generic struct sg_table.

PS: This series of patches is the evolution of my previous patch for vb2-dma-sg 
to allocate the memory as contiguos as possible.

v4: Constains feedback from Andre Heider
Andre: spelling, spaces around <<  and &pages

v3: Constains feedback from Andre Heider
Andre: Fix error handling (--pages) was wrongly fixed

v2: Contains feedback from Andre Heider and Sylwester Nawrocki

Andre: Fix error handling (--pages)
Sylwester: Squash p3 and p4 into p2


Ricardo Ribalda Delgado (2):
  videobuf2-dma-sg: Allocate pages as contiguous as possible
  videobuf2-dma-sg: Replace vb2_dma_sg_desc with sg_table

 drivers/media/platform/marvell-ccic/mcam-core.c|   14 +-
 drivers/media/v4l2-core/videobuf2-dma-sg.c |  149 +++-
 drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c |   20 +--
 include/media/videobuf2-dma-sg.h   |   10 +-
 4 files changed, 105 insertions(+), 88 deletions(-)

-- 
1.7.10.4

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


Re: [PATCH 1/2] videobuf2-dma-sg: Allocate pages as contiguous as possible

2013-08-02 Thread Ricardo Ribalda Delgado
Thanks, I have just send a new version.

Regards!

On Fri, Aug 2, 2013 at 3:47 PM, Andre Heider  wrote:
> Hi Ricardo,
>
> I messed up one thing in my initial reply, sorry :(
>
> And two additional nitpicks, while we're at it.
>
> On Fri, Jul 19, 2013 at 07:02:33PM +0200, Ricardo Ribalda Delgado wrote:
>> Most DMA engines have limitations regarding the number of DMA segments
>> (sg-buffers) that they can handle. Videobuffers can easily spread
>> through houndreds of pages.
>>
>> In the previous aproach, the pages were allocated individually, this
>> could led to the creation houndreds of dma segments (sg-buffers) that
>> could not be handled by some DMA engines.
>
> s/houndreds/hundreds/
>
>>
>> This patch tries to minimize the number of DMA segments by using
>> alloc_pages. In the worst case it will behave as before, but most
>> of the times it will reduce the number of dma segments
>>
>> Signed-off-by: Ricardo Ribalda Delgado 
>
> With those changes you can add:
>
> Reviewed-by: Andre Heider 
>
>> ---
>>  drivers/media/v4l2-core/videobuf2-dma-sg.c |   60 
>> +++-
>>  1 file changed, 49 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
>> b/drivers/media/v4l2-core/videobuf2-dma-sg.c
>> index 16ae3dc..c053605 100644
>> --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
>> +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
>> @@ -42,10 +42,55 @@ struct vb2_dma_sg_buf {
>>
>>  static void vb2_dma_sg_put(void *buf_priv);
>>
>> +static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf,
>> + gfp_t gfp_flags)
>> +{
>> + unsigned int last_page = 0;
>> + int size = buf->sg_desc.size;
>> +
>> + while (size > 0) {
>> + struct page *pages;
>> + int order;
>> + int i;
>> +
>> + order = get_order(size);
>> + /* Dont over allocate*/
>> + if ((PAGE_SIZE << order) > size)
>> + order--;
>> +
>> + pages = NULL;
>> + while (!pages) {
>> + pages = alloc_pages(GFP_KERNEL | __GFP_ZERO |
>> + __GFP_NOWARN | gfp_flags, order);
>> + if (pages)
>> + break;
>> +
>> + if (order == 0)
>> + while (last_page--) {
>> + __free_page(buf->pages[last_page]);
>> + return -ENOMEM;
>> + }
>> + order--;
>> + }
>> +
>> + split_page(pages, order);
>> + for (i = 0; i < (1<
> whitespace nit: "(1 << order)"
>
>> + buf->pages[last_page] = pages[i];
>
> My fault, it should read:
>
> buf->pages[last_page] = &pages[i];
>
>> + sg_set_page(&buf->sg_desc.sglist[last_page],
>> + buf->pages[last_page], PAGE_SIZE, 0);
>> + last_page++;
>> + }
>> +
>> + size -= PAGE_SIZE << order;
>> + }
>> +
>> + return 0;
>> +}
>> +
>>  static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t 
>> gfp_flags)
>>  {
>>   struct vb2_dma_sg_buf *buf;
>> - int i;
>> + int ret;
>>
>>   buf = kzalloc(sizeof *buf, GFP_KERNEL);
>>   if (!buf)
>> @@ -69,14 +114,9 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned 
>> long size, gfp_t gfp_fla
>>   if (!buf->pages)
>>   goto fail_pages_array_alloc;
>>
>> - for (i = 0; i < buf->sg_desc.num_pages; ++i) {
>> - buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO |
>> -__GFP_NOWARN | gfp_flags);
>> - if (NULL == buf->pages[i])
>> - goto fail_pages_alloc;
>> - sg_set_page(&buf->sg_desc.sglist[i],
>> - buf->pages[i], PAGE_SIZE, 0);
>> - }
>> + ret = vb2_dma_sg_alloc_compacted(buf, gfp_flags);
>> + if (ret)
>> + goto fail_pages_alloc;
>>
>>   buf->handler.refcount = &buf->refcount;
>>   buf->handler.put = vb2_dma_sg_put;
>> @@ -89,8 +129,6 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned 
>> long size, gfp_t gfp_fla
>>   return buf;
>>
>>  fail_pages_alloc:
>> - while (--i >= 0)
>> - __free_page(buf->pages[i]);
>>   kfree(buf->pages);
>>
>>  fail_pages_array_alloc:
>> --
>> 1.7.10.4
>>



-- 
Ricardo Ribalda
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/6] v4l: ti-vpe: Add VPE mem to mem driver

2013-08-02 Thread Hans Verkuil
Hi Archit,

I've got a few comments:

On 08/02/2013 04:03 PM, Archit Taneja wrote:
> VPE is a block which consists of a single memory to memory path which can
> perform chrominance up/down sampling, de-interlacing, scaling, and color space
> conversion of raster or tiled YUV420 coplanar, YUV422 coplanar or YUV422
> interleaved video formats.
> 
> We create a mem2mem driver based primarily on the mem2mem-testdev example.
> The de-interlacer, scaler and color space converter are all bypassed for now
> to keep the driver simple. Chroma up/down sampler blocks are implemented, so
> conversion beteen different YUV formats is possible.
> 
> Each mem2mem context allocates a buffer for VPE MMR values which it will use
> when it gets access to the VPE HW via the mem2mem queue, it also allocates
> a VPDMA descriptor list to which configuration and data descriptors are added.
> 
> Based on the information received via v4l2 ioctls for the source and
> destination queues, the driver configures the values for the MMRs, and stores
> them in the buffer. There are also some VPDMA parameters like frame start and
> line mode which needs to be configured, these are configured by direct 
> register
> writes via the VPDMA helper functions.
> 
> The driver's device_run() mem2mem op will add each descriptor based on how the
> source and destination queues are set up for the given ctx, once the list is
> prepared, it's submitted to VPDMA, these descriptors when parsed by VPDMA will
> upload MMR registers, start DMA of video buffers on the various input and 
> output
> clients/ports.
> 
> When the list is parsed completely(and the DMAs on all the output ports done),
> an interrupt is generated which we use to notify that the source and 
> destination
> buffers are done.
> 
> The rest of the driver is quite similar to other mem2mem drivers, we use the
> multiplane v4l2 ioctls as the HW support coplanar formats.
> 
> Signed-off-by: Archit Taneja 
> ---
>  drivers/media/platform/Kconfig   |   10 +
>  drivers/media/platform/Makefile  |2 +
>  drivers/media/platform/ti-vpe/vpe.c  | 1763 
> ++
>  drivers/media/platform/ti-vpe/vpe_regs.h |  496 +
>  4 files changed, 2271 insertions(+)
>  create mode 100644 drivers/media/platform/ti-vpe/vpe.c
>  create mode 100644 drivers/media/platform/ti-vpe/vpe_regs.h
> 

...

> +/*
> + * video ioctls
> + */
> +static int vpe_querycap(struct file *file, void *priv,
> + struct v4l2_capability *cap)
> +{
> + strncpy(cap->driver, VPE_MODULE_NAME, sizeof(cap->driver) - 1);
> + strncpy(cap->card, VPE_MODULE_NAME, sizeof(cap->card) - 1);
> + strlcpy(cap->bus_info, VPE_MODULE_NAME, sizeof(cap->bus_info));
> + cap->device_caps  = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING |
> + V4L2_CAP_VIDEO_CAPTURE_MPLANE |
> + V4L2_CAP_VIDEO_OUTPUT_MPLANE;

That should be: V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;

No CAPTURE/OUTPUT_MPLANE.

> + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
> + return 0;
> +}
> +
> +static int __enum_fmt(struct v4l2_fmtdesc *f, u32 type)
> +{
> + int i, index;
> + struct vpe_fmt *fmt = NULL;
> +
> + index = 0;
> + for (i = 0; i < ARRAY_SIZE(vpe_formats); ++i) {
> + if (vpe_formats[i].types & type) {
> + if (index == f->index) {
> + fmt = &vpe_formats[i];
> + break;
> + }
> + index++;
> + }
> + }
> +
> + if (!fmt)
> + return -EINVAL;
> +
> + strncpy(f->description, fmt->name, sizeof(f->description) - 1);
> + f->pixelformat = fmt->fourcc;
> + return 0;
> +}
> +
> +static int vpe_enum_fmt(struct file *file, void *priv,
> + struct v4l2_fmtdesc *f)
> +{
> + if (V4L2_TYPE_IS_OUTPUT(f->type))
> + return __enum_fmt(f, VPE_FMT_TYPE_OUTPUT);
> + else
> + return __enum_fmt(f, VPE_FMT_TYPE_CAPTURE);
> +}
> +
> +static int vpe_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
> +{
> + struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
> + struct vpe_ctx *ctx = file2ctx(file);
> + struct vb2_queue *vq;
> + struct vpe_q_data *q_data;
> + int i;
> +
> + vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
> + if (!vq)
> + return -EINVAL;
> +
> + q_data = get_q_data(ctx, f->type);
> +
> + pix->width = q_data->width;
> + pix->height = q_data->height;
> + pix->pixelformat = q_data->fmt->fourcc;
> + pix->colorspace = q_data->colorspace;
> + pix->num_planes = q_data->fmt->coplanar ? 2 : 1;
> +
> + for (i = 0; i < pix->num_planes; i++) {
> + pix->plane_fmt[i].bytesperline = q_data->bytesperline[i];
> + pix->plane_fmt[i].sizeimage = q_data->sizeimage[i];
> + }
> +
> + return 0;
> +}
> +
> +static

Re: [PATCH 4/6] v4l: ti-vpe: Add de-interlacer support in VPE

2013-08-02 Thread Hans Verkuil
More comments...

On 08/02/2013 04:03 PM, Archit Taneja wrote:
> Add support for the de-interlacer block in VPE.
> 
> For de-interlacer to work, we need to enable 2 more sets of VPE input ports
> which fetch data from the 'last' and 'last to last' fields of the interlaced
> video. Apart from that, we need to enable the Motion vector output and input
> ports, and also allocate DMA buffers for them.
> 
> We need to make sure that two most recent fields in the source queue are
> available and in the 'READY' state. Once a mem2mem context gets access to the
> VPE HW(in device_run), it extracts the addresses of the 3 buffers, and 
> provides
> it to the data descriptors for the 3 sets of input ports((LUMA1, CHROMA1),
> (LUMA2, CHROMA2), and (LUMA3, CHROMA3)) respectively for the 3 consecutive
> fields. The motion vector and output port descriptors are configured and the
> list is submitted to VPDMA.
> 
> Once the transaction is done, the v4l2 buffer corresponding to the oldest
> field(the 3rd one) is changed to the state 'DONE', and the buffers 
> corresponding
> to 1st and 2nd fields become the 2nd and 3rd field for the next de-interlace
> operation. This way, for each deinterlace operation, we have the 3 most recent
> fields. After each transaction, we also swap the motion vector buffers, the 
> new
> input motion vector buffer contains the resultant motion information of all 
> the
> previous frames, and the new output motion vector buffer will be used to hold
> the updated motion vector to capture the motion changes in the next field.
> 
> The de-interlacer is removed from bypass mode, it requires some extra default
> configurations which are now added. The chrominance upsampler coefficients are
> added for interlaced frames. Some VPDMA parameters like frame start event and
> line mode are configured for the 2 extra sets of input ports.
> 
> Signed-off-by: Archit Taneja 
> ---
>  drivers/media/platform/ti-vpe/vpe.c | 372 
> 
>  1 file changed, 337 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/media/platform/ti-vpe/vpe.c 
> b/drivers/media/platform/ti-vpe/vpe.c
> index 14a292b..5b1410c 100644
> --- a/drivers/media/platform/ti-vpe/vpe.c
> +++ b/drivers/media/platform/ti-vpe/vpe.c

...

> @@ -1035,7 +1310,8 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct 
> v4l2_format *f,
>  
>   if (pix->field == V4L2_FIELD_ANY)
>   pix->field = V4L2_FIELD_NONE;
> - else if (V4L2_FIELD_NONE != pix->field)
> + else if (V4L2_FIELD_NONE != pix->field &&
> + V4L2_FIELD_ALTERNATE != pix->field)
>   return -EINVAL;

As mentioned before, this shouldn't result in an error, but map to a valid
field format.

For a deinterlacer I would expect NONE for the output of the deinterlacer (or
capture buffer type) and ALTERNATE for the input of the deinterlacer (or output
buffer type).

>  
>   v4l_bound_align_image(&pix->width, MIN_W, MAX_W, W_ALIGN,
> @@ -1104,6 +1380,7 @@ static int __vpe_s_fmt(struct vpe_ctx *ctx, struct 
> v4l2_format *f)
>   q_data->width   = pix->width;
>   q_data->height  = pix->height;
>   q_data->colorspace  = pix->colorspace;
> + q_data->field   = pix->field;
>  
>   for (i = 0; i < pix->num_planes; i++) {
>   plane_fmt = &pix->plane_fmt[i];
> @@ -1117,6 +1394,11 @@ static int __vpe_s_fmt(struct vpe_ctx *ctx, struct 
> v4l2_format *f)
>   q_data->c_rect.width= q_data->width;
>   q_data->c_rect.height   = q_data->height;
>  
> + if (q_data->field == V4L2_FIELD_ALTERNATE)
> + q_data->flags |= Q_DATA_INTERLACED;
> + else
> + q_data->flags &= ~Q_DATA_INTERLACED;
> +
>   vpe_dbg(ctx->dev, "Setting format for type %d, wxh: %dx%d, fmt: %d 
> bpl_y %d",
>   f->type, q_data->width, q_data->height, q_data->fmt->fourcc,
>   q_data->bytesperline[VPE_LUMA]);
> @@ -1194,6 +1476,22 @@ static int vpe_streamoff(struct file *file, void 
> *priv, enum v4l2_buf_type type)
>   return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
>  }
>  
> +static void set_dei_shadow_registers(struct vpe_ctx *ctx)
> +{
> + struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
> + u32 *dei_mmr = &mmr_adb->dei_regs[0];
> + struct vpe_dei_regs *cur = &dei_regs;
> +
> + dei_mmr[2]  = cur->mdt_spacial_freq_thr_reg;
> + dei_mmr[3]  = cur->edi_config_reg;
> + dei_mmr[4]  = cur->edi_lut_reg0;
> + dei_mmr[5]  = cur->edi_lut_reg1;
> + dei_mmr[6]  = cur->edi_lut_reg2;
> + dei_mmr[7]  = cur->edi_lut_reg3;
> +
> + ctx->load_mmrs = true;
> +}
> +
>  #define V4L2_CID_TRANS_NUM_BUFS  (V4L2_CID_USER_BASE)
>  
>  static int vpe_s_ctrl(struct v4l2_ctrl *ctrl)
> @@ -1425,6 +1723,7 @@ static int vpe_open(struct file *file)
>   s_q_data->sizeimage[VPE_LUMA] = (s_q_data->width * s_q_data->height *
>   s_q_data->fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3;
>   s_q

Re: [PATCH 3/6] v4l: ti-vpe: Add VPE mem to mem driver

2013-08-02 Thread Archit Taneja

Hi Hans,

Thanks for the comments. Some replies below.

On Friday 02 August 2013 08:06 PM, Hans Verkuil wrote:

Hi Archit,

I've got a few comments:

On 08/02/2013 04:03 PM, Archit Taneja wrote:

VPE is a block which consists of a single memory to memory path which can
perform chrominance up/down sampling, de-interlacing, scaling, and color space
conversion of raster or tiled YUV420 coplanar, YUV422 coplanar or YUV422
interleaved video formats.

We create a mem2mem driver based primarily on the mem2mem-testdev example.
The de-interlacer, scaler and color space converter are all bypassed for now
to keep the driver simple. Chroma up/down sampler blocks are implemented, so
conversion beteen different YUV formats is possible.

Each mem2mem context allocates a buffer for VPE MMR values which it will use
when it gets access to the VPE HW via the mem2mem queue, it also allocates
a VPDMA descriptor list to which configuration and data descriptors are added.

Based on the information received via v4l2 ioctls for the source and
destination queues, the driver configures the values for the MMRs, and stores
them in the buffer. There are also some VPDMA parameters like frame start and
line mode which needs to be configured, these are configured by direct register
writes via the VPDMA helper functions.

The driver's device_run() mem2mem op will add each descriptor based on how the
source and destination queues are set up for the given ctx, once the list is
prepared, it's submitted to VPDMA, these descriptors when parsed by VPDMA will
upload MMR registers, start DMA of video buffers on the various input and output
clients/ports.

When the list is parsed completely(and the DMAs on all the output ports done),
an interrupt is generated which we use to notify that the source and destination
buffers are done.

The rest of the driver is quite similar to other mem2mem drivers, we use the
multiplane v4l2 ioctls as the HW support coplanar formats.

Signed-off-by: Archit Taneja 
---
  drivers/media/platform/Kconfig   |   10 +
  drivers/media/platform/Makefile  |2 +
  drivers/media/platform/ti-vpe/vpe.c  | 1763 ++
  drivers/media/platform/ti-vpe/vpe_regs.h |  496 +
  4 files changed, 2271 insertions(+)
  create mode 100644 drivers/media/platform/ti-vpe/vpe.c
  create mode 100644 drivers/media/platform/ti-vpe/vpe_regs.h



...


+/*
+ * video ioctls
+ */
+static int vpe_querycap(struct file *file, void *priv,
+   struct v4l2_capability *cap)
+{
+   strncpy(cap->driver, VPE_MODULE_NAME, sizeof(cap->driver) - 1);
+   strncpy(cap->card, VPE_MODULE_NAME, sizeof(cap->card) - 1);
+   strlcpy(cap->bus_info, VPE_MODULE_NAME, sizeof(cap->bus_info));
+   cap->device_caps  = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING |
+   V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+   V4L2_CAP_VIDEO_OUTPUT_MPLANE;


That should be: V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;

No CAPTURE/OUTPUT_MPLANE.


Sure, I'll fix this.




+
+   if (pix->field == V4L2_FIELD_ANY)
+   pix->field = V4L2_FIELD_NONE;
+   else if (V4L2_FIELD_NONE != pix->field)
+   return -EINVAL;


No, TRY_FMT should map field to a valid field type. In this case it is simple:
just set field to V4L2_FIELD_NONE.


Okay, I'll correct this.

I saw your comment on the de-interlacer patch. The de-interlacer can be 
bypassed, so for both ouput buffer type and capture buffer type, we can 
have interlaced and progressive content, so I guess NONE and ALTERNATE 
are possible for both.





+
+   v4l_bound_align_image(&pix->width, MIN_W, MAX_W, W_ALIGN,
+ &pix->height, MIN_H, MAX_H, H_ALIGN,
+ S_ALIGN);
+
+   pix->num_planes = fmt->coplanar ? 2 : 1;
+   pix->pixelformat = fmt->fourcc;
+   pix->colorspace = fmt->fourcc == V4L2_PIX_FMT_RGB24 ?
+   V4L2_COLORSPACE_SRGB : V4L2_COLORSPACE_SMPTE170M;
+
+
+   for (i = 0; i < pix->num_planes; i++) {
+   int depth;
+
+   plane_fmt = &pix->plane_fmt[i];
+   depth = fmt->vpdma_fmt[i]->depth;
+
+   if (i == VPE_LUMA)
+   plane_fmt->bytesperline =
+   round_up((pix->width * depth) >> 3,
+   1 << L_ALIGN);
+   else
+   plane_fmt->bytesperline = pix->width;
+
+   plane_fmt->sizeimage =
+   (pix->height * pix->width * depth) >> 3;
+   }
+
+   return 0;
+}
+
+static int vpe_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
+{
+   struct vpe_ctx *ctx = file2ctx(file);
+   struct vpe_fmt *fmt = find_format(f);
+
+   if (V4L2_TYPE_IS_OUTPUT(f->type))
+   return __vpe_try_fmt(ctx, f, fmt, VPE_FMT_TYPE_OUTPUT);
+   else
+   return __vpe

[RFC v3 00/13] Exynos5 IS driver

2013-08-02 Thread Arun Kumar K
The patch series add support for Exynos5 camera subsystem. It
re-uses mipi-csis and fimc-lite from exynos4-is and adds a new
media device and fimc-is device drivers for exynos5.
The media device supports asynchronos subdev registration for the
fimc-is sensors and is based on the patch series from Sylwester
for exynos4-is [1].

[1] http://www.mail-archive.com/linux-media@vger.kernel.org/msg64653.html

Changes from v2
---
- Added exynos5 media device driver from Shaik to this series
- Added ISP pipeline support in media device driver
- Based on Sylwester's latest exynos4-is development
- Asynchronos registration of sensor subdevs
- Made independent IS-sensor support
- Add s5k4e5 sensor driver
- Addressed review comments from Sylwester, Hans, Andrzej, Sachin

Changes from v1
---
- Addressed all review comments from Sylwester
- Made sensor subdevs as independent i2c devices
- Lots of cleanup
- Debugfs support added
- Removed PMU global register access

Arun Kumar K (12):
  [media] exynos5-fimc-is: Add Exynos5 FIMC-IS device tree bindings
documentation
  [media] exynos5-fimc-is: Add driver core files
  [media] exynos5-fimc-is: Add common driver header files
  [media] exynos5-fimc-is: Add register definition and context header
  [media] exynos5-fimc-is: Add isp subdev
  [media] exynos5-fimc-is: Add scaler subdev
  [media] exynos5-fimc-is: Add sensor interface
  [media] exynos5-fimc-is: Add the hardware pipeline control
  [media] exynos5-fimc-is: Add the hardware interface module
  [media] exynos5-is: Add Kconfig and Makefile
  V4L: s5k6a3: Change sensor min/max resolutions
  V4L: Add driver for s5k4e5 image sensor

Shaik Ameer Basha (1):
  [media] exynos5-is: Adding media device driver for exynos5

 .../devicetree/bindings/media/exynos5-fimc-is.txt  |   52 +
 .../devicetree/bindings/media/exynos5-mdev.txt |  153 ++
 drivers/media/i2c/Kconfig  |8 +
 drivers/media/i2c/Makefile |1 +
 drivers/media/i2c/s5k4e5.c |  362 
 drivers/media/i2c/s5k6a3.c |   14 +-
 drivers/media/platform/Kconfig |1 +
 drivers/media/platform/Makefile|1 +
 drivers/media/platform/exynos5-is/Kconfig  |   19 +
 drivers/media/platform/exynos5-is/Makefile |7 +
 drivers/media/platform/exynos5-is/exynos5-mdev.c   | 1471 +++
 drivers/media/platform/exynos5-is/exynos5-mdev.h   |  199 ++
 drivers/media/platform/exynos5-is/fimc-is-cmd.h|  187 ++
 drivers/media/platform/exynos5-is/fimc-is-core.c   |  394 
 drivers/media/platform/exynos5-is/fimc-is-core.h   |  122 ++
 drivers/media/platform/exynos5-is/fimc-is-err.h|  257 +++
 .../media/platform/exynos5-is/fimc-is-interface.c  |  861 +
 .../media/platform/exynos5-is/fimc-is-interface.h  |  128 ++
 drivers/media/platform/exynos5-is/fimc-is-isp.c|  509 +
 drivers/media/platform/exynos5-is/fimc-is-isp.h|   93 +
 .../media/platform/exynos5-is/fimc-is-metadata.h   |  767 
 drivers/media/platform/exynos5-is/fimc-is-param.h  | 1212 
 .../media/platform/exynos5-is/fimc-is-pipeline.c   | 1961 
 .../media/platform/exynos5-is/fimc-is-pipeline.h   |  129 ++
 drivers/media/platform/exynos5-is/fimc-is-regs.h   |  105 ++
 drivers/media/platform/exynos5-is/fimc-is-scaler.c |  458 +
 drivers/media/platform/exynos5-is/fimc-is-scaler.h |  112 ++
 drivers/media/platform/exynos5-is/fimc-is-sensor.c |   46 +
 drivers/media/platform/exynos5-is/fimc-is-sensor.h |   69 +
 drivers/media/platform/exynos5-is/fimc-is.h|  153 ++
 30 files changed, 9847 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/exynos5-fimc-is.txt
 create mode 100644 Documentation/devicetree/bindings/media/exynos5-mdev.txt
 create mode 100644 drivers/media/i2c/s5k4e5.c
 create mode 100644 drivers/media/platform/exynos5-is/Kconfig
 create mode 100644 drivers/media/platform/exynos5-is/Makefile
 create mode 100644 drivers/media/platform/exynos5-is/exynos5-mdev.c
 create mode 100644 drivers/media/platform/exynos5-is/exynos5-mdev.h
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-cmd.h
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-core.c
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-core.h
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-err.h
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-interface.c
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-interface.h
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-isp.c
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-isp.h
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-metadata.h
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-param.h
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-pipeline.c
 create mode 100644 drivers/media/platf

[RFC v3 02/13] [media] exynos5-fimc-is: Add Exynos5 FIMC-IS device tree bindings documentation

2013-08-02 Thread Arun Kumar K
The patch adds the DT binding documentation for Samsung
Exynos5 SoC series imaging subsystem (FIMC-IS).

Signed-off-by: Arun Kumar K 
---
 .../devicetree/bindings/media/exynos5-fimc-is.txt  |   52 
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/exynos5-fimc-is.txt

diff --git a/Documentation/devicetree/bindings/media/exynos5-fimc-is.txt 
b/Documentation/devicetree/bindings/media/exynos5-fimc-is.txt
new file mode 100644
index 000..49a373a
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/exynos5-fimc-is.txt
@@ -0,0 +1,52 @@
+Samsung EXYNOS5 SoC series Imaging Subsystem (FIMC-IS)
+--
+
+The camera subsystem on Samsung Exynos5 SoC has some changes relative
+to previous SoC versions. Exynos5 has almost similar MIPI-CSIS and
+FIMC-LITE IPs but has a much improved version of FIMC-IS which can
+handle sensor controls and camera post-processing operations. The
+Exynos5 FIMC-IS has a dedicated ARM Cortex A5 processor, many
+post-processing blocks (ISP, DRC, FD, ODC, DIS, 3DNR) and two
+dedicated scalers (SCC and SCP).
+
+fimc-is node
+
+
+Required properties:
+
+- compatible: must be "samsung,exynos5250-fimc-is"
+- reg   : physical base address and size of the memory mapped
+  registers
+- interrupt-parent  : Parent interrupt controller
+- interrupts: fimc-is interrupt to the parent combiner
+- clocks: list of clock specifiers, corresponding to entries in
+  clock-names property;
+- clock-names   : must contain "isp", "mcu_isp", "isp_div0", "isp_div1",
+  "isp_divmpwm", "mcu_isp_div0", "mcu_isp_div1" entries,
+  matching entries in the clocks property.
+
+pmu subnode
+---
+
+Required properties:
+ - reg : should contain PMU physical base address and size of the memory
+ mapped registers.
+
+i2c-isp (ISP I2C bus controller) nodes
+--
+
+Required properties:
+
+- compatible   : should be "samsung,exynos4212-i2c-isp" for Exynos4212,
+ Exynos4412 and Exynos5250 SoCs;
+- reg  : physical base address and length of the registers set;
+- clocks   : must contain gate clock specifier for this controller;
+- clock-names  : must contain "i2c_isp" entry.
+
+For the above nodes it is required to specify a pinctrl state named "default",
+according to the pinctrl bindings defined in ../pinctrl/pinctrl-bindings.txt.
+
+Device tree nodes of the image sensors' controlled directly by the FIMC-IS
+firmware must be child nodes of their corresponding ISP I2C bus controller 
node.
+The data link of these image sensors must be specified using the common video
+interfaces bindings, defined in video-interfaces.txt.
-- 
1.7.9.5

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


[RFC v3 06/13] [media] exynos5-fimc-is: Add isp subdev

2013-08-02 Thread Arun Kumar K
fimc-is driver takes video data input from the ISP video node
which is added in this patch. This node accepts Bayer input
buffers which is given from the IS sensors.

Signed-off-by: Arun Kumar K 
Signed-off-by: Kilyeon Im 
---
 drivers/media/platform/exynos5-is/fimc-is-isp.c |  509 +++
 drivers/media/platform/exynos5-is/fimc-is-isp.h |   93 +
 2 files changed, 602 insertions(+)
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-isp.c
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-isp.h

diff --git a/drivers/media/platform/exynos5-is/fimc-is-isp.c 
b/drivers/media/platform/exynos5-is/fimc-is-isp.c
new file mode 100644
index 000..e97e473
--- /dev/null
+++ b/drivers/media/platform/exynos5-is/fimc-is-isp.c
@@ -0,0 +1,509 @@
+/*
+ * Samsung EXYNOS5250 FIMC-IS (Imaging Subsystem) driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ *  Arun Kumar K 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+
+#include "fimc-is.h"
+
+#define ISP_DRV_NAME "fimc-is-isp"
+
+static const struct fimc_is_fmt formats[] = {
+   {
+   .name   = "Bayer GR-BG 8bits",
+   .fourcc = V4L2_PIX_FMT_SGRBG8,
+   .depth  = { 8 },
+   .num_planes = 1,
+   },
+   {
+   .name   = "Bayer GR-BG 10bits",
+   .fourcc = V4L2_PIX_FMT_SGRBG10,
+   .depth  = { 16 },
+   .num_planes = 1,
+   },
+   {
+   .name   = "Bayer GR-BG 12bits",
+   .fourcc = V4L2_PIX_FMT_SGRBG12,
+   .depth  = { 16 },
+   .num_planes = 1,
+   },
+};
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+static const struct fimc_is_fmt *find_format(struct v4l2_format *f)
+{
+   unsigned int i;
+
+   for (i = 0; i < NUM_FORMATS; i++) {
+   if (formats[i].fourcc == f->fmt.pix_mp.pixelformat)
+   return &formats[i];
+   }
+   return NULL;
+}
+
+static int isp_video_output_start_streaming(struct vb2_queue *vq,
+   unsigned int count)
+{
+   struct fimc_is_isp *isp = vb2_get_drv_priv(vq);
+
+   set_bit(STATE_RUNNING, &isp->output_state);
+   return 0;
+}
+
+static int isp_video_output_stop_streaming(struct vb2_queue *vq)
+{
+   struct fimc_is_isp *isp = vb2_get_drv_priv(vq);
+
+   clear_bit(STATE_RUNNING, &isp->output_state);
+   return 0;
+}
+
+static int isp_video_output_queue_setup(struct vb2_queue *vq,
+   const struct v4l2_format *pfmt,
+   unsigned int *num_buffers, unsigned int *num_planes,
+   unsigned int sizes[], void *allocators[])
+{
+   struct fimc_is_isp *isp = vb2_get_drv_priv(vq);
+   const struct fimc_is_fmt *fmt = isp->fmt;
+   unsigned int wh, i;
+
+   if (!fmt)
+   return -EINVAL;
+
+   *num_planes = fmt->num_planes;
+   wh = isp->width * isp->height;
+
+   for (i = 0; i < *num_planes; i++) {
+   allocators[i] = isp->alloc_ctx;
+   sizes[i] = (wh * fmt->depth[i]) / 8;
+   }
+   return 0;
+}
+
+static int isp_video_output_buffer_init(struct vb2_buffer *vb)
+{
+   struct vb2_queue *vq = vb->vb2_queue;
+   struct fimc_is_isp *isp = vb2_get_drv_priv(vq);
+   struct fimc_is_buf *buf;
+
+   buf = &isp->output_bufs[vb->v4l2_buf.index];
+   /* Initialize buffer */
+   buf->vb = vb;
+   buf->paddr[0] = vb2_dma_contig_plane_dma_addr(vb, 0);
+   isp->out_buf_cnt++;
+   return 0;
+}
+
+static void isp_video_output_buffer_queue(struct vb2_buffer *vb)
+{
+   struct vb2_queue *vq = vb->vb2_queue;
+   struct fimc_is_isp *isp = vb2_get_drv_priv(vq);
+   struct fimc_is_buf *buf;
+
+   buf = &isp->output_bufs[vb->v4l2_buf.index];
+
+   fimc_is_pipeline_buf_lock(isp->pipeline);
+   fimc_is_isp_wait_queue_add(isp, buf);
+   fimc_is_pipeline_buf_unlock(isp->pipeline);
+
+   /* Call shot command */
+   fimc_is_pipeline_shot(isp->pipeline);
+}
+
+static const struct vb2_ops isp_video_output_qops = {
+   .queue_setup = isp_video_output_queue_setup,
+   .buf_init= isp_video_output_buffer_init,
+   .buf_queue   = isp_video_output_buffer_queue,
+   .wait_prepare= vb2_ops_wait_prepare,
+   .wait_finish = vb2_ops_wait_finish,
+   .start_streaming = isp_video_output_start_streaming,
+   .stop_streaming  = isp_video_output_stop_streaming,
+};
+
+static const struct v4l2_file_operations isp_video_output_fops = {
+   .owner  = THIS_MODULE,
+   .open   = v4l2_fh_open,
+   .release= vb2_fop_release,
+   .poll   = vb2_fop_po

[RFC v3 01/13] [media] exynos5-is: Adding media device driver for exynos5

2013-08-02 Thread Arun Kumar K
From: Shaik Ameer Basha 

This patch adds support for media device for EXYNOS5 SoCs.
The current media device supports the following ips to connect
through the media controller framework.

* MIPI-CSIS
  Support interconnection(subdev interface) between devices

* FIMC-LITE
  Support capture interface from device(Sensor, MIPI-CSIS) to memory
  Support interconnection(subdev interface) between devices

* FIMC-IS
  Camera post-processing IP having multiple sub-nodes.

G-Scaler will be added later to the current media device.

The media device creates two kinds of pipelines for connecting
the above mentioned IPs.
The pipeline0 is uses Sensor, MIPI-CSIS and FIMC-LITE which captures
image data and dumps to memory.
Pipeline1 uses FIMC-IS components for doing post-processing
operations on the captured image and give scaled YUV output.

Pipeline0
  ++ +---+ +---+ ++
  | Sensor | --> | MIPI-CSIS | --> | FIMC-LITE | --> | Memory |
  ++ +---+ +---+ ++

Pipeline1
 ++  ++ +---+ +---+
 | Memory | -->  |  ISP   | --> |SCC| --> |SCP|
 ++  ++ +---+ +---+

Signed-off-by: Shaik Ameer Basha 
Signed-off-by: Arun Kumar K 
---
 .../devicetree/bindings/media/exynos5-mdev.txt |  153 ++
 drivers/media/platform/exynos5-is/exynos5-mdev.c   | 1471 
 drivers/media/platform/exynos5-is/exynos5-mdev.h   |  199 +++
 3 files changed, 1823 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/exynos5-mdev.txt
 create mode 100644 drivers/media/platform/exynos5-is/exynos5-mdev.c
 create mode 100644 drivers/media/platform/exynos5-is/exynos5-mdev.h

diff --git a/Documentation/devicetree/bindings/media/exynos5-mdev.txt 
b/Documentation/devicetree/bindings/media/exynos5-mdev.txt
new file mode 100644
index 000..d7d419b
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/exynos5-mdev.txt
@@ -0,0 +1,153 @@
+Samsung EXYNOS5 SoC Camera Subsystem (FIMC)
+--
+
+The Exynos5 SoC Camera subsystem comprises of multiple sub-devices
+represented by separate device tree nodes. Currently this includes: FIMC-LITE,
+MIPI CSIS and FIMC-IS.
+
+The sub-subdevices are defined as child nodes of the common 'camera' node which
+also includes common properties of the whole subsystem not really specific to
+any single sub-device, like common camera port pins or the CAMCLK clock outputs
+for external image sensors attached to an SoC.
+
+Common 'camera' node
+
+
+Required properties:
+
+- compatible   : must be "samsung,exynos5-fimc", "simple-bus"
+- clocks   : list of clock specifiers, corresponding to entries in
+ the clock-names property;
+- clock-names  : must contain "sclk_cam0", "sclk_cam1" entries,
+ matching entries in the clocks property.
+
+The pinctrl bindings defined in ../pinctrl/pinctrl-bindings.txt must be used
+to define a required pinctrl state named "default" and optional pinctrl states:
+"idle", "active-a", active-b". These optional states can be used to switch the
+camera port pinmux at runtime. The "idle" state should configure both the 
camera
+ports A and B into high impedance state, especially the CAMCLK clock output
+should be inactive. For the "active-a" state the camera port A must be 
activated
+and the port B deactivated and for the state "active-b" it should be the other
+way around.
+
+The 'camera' node must include at least one 'fimc-lite' child node.
+
+'parallel-ports' node
+-
+
+This node should contain child 'port' nodes specifying active parallel video
+input ports. It includes camera A and camera B inputs. 'reg' property in the
+port nodes specifies data input - 0, 1 indicates input A, B respectively.
+
+Optional properties
+
+- samsung,camclk-out : specifies clock output for remote sensor,
+  0 - CAM_A_CLKOUT, 1 - CAM_B_CLKOUT;
+
+Image sensor nodes
+--
+
+The sensor device nodes should be added to their control bus controller (e.g.
+I2C0) nodes and linked to a port node in the csis or the parallel-ports node,
+using the common video interfaces bindings, defined in video-interfaces.txt.
+The implementation of this bindings requires clock-frequency property to be
+present in the sensor device nodes.
+
+Example:
+
+   aliases {
+   fimc-lite0 = &fimc_lite_0
+   };
+
+   /* Parallel bus IF sensor */
+   i2c_0: i2c@1386 {
+   s5k6aa: sensor@3c {
+   compatible = "samsung,s5k6aafx";
+   reg = <0x3c>;
+   vddio-supply = <...>;
+
+   clock-frequency = <2400>;
+   clocks = <...>;
+   clock-names = "mclk";
+
+   port {
+   s5k6aa_ep: endp

[RFC v3 08/13] [media] exynos5-fimc-is: Add sensor interface

2013-08-02 Thread Arun Kumar K
Some sensors to be used with fimc-is are exclusively controlled
by the fimc-is firmware. This minimal sensor driver provides
the required info for the firmware to configure the sensors
sitting on I2C bus.

Signed-off-by: Arun Kumar K 
---
 drivers/media/platform/exynos5-is/fimc-is-sensor.c |   46 +
 drivers/media/platform/exynos5-is/fimc-is-sensor.h |   69 
 2 files changed, 115 insertions(+)
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-sensor.c
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-sensor.h

diff --git a/drivers/media/platform/exynos5-is/fimc-is-sensor.c 
b/drivers/media/platform/exynos5-is/fimc-is-sensor.c
new file mode 100644
index 000..3e4aae9
--- /dev/null
+++ b/drivers/media/platform/exynos5-is/fimc-is-sensor.c
@@ -0,0 +1,46 @@
+/*
+ * Samsung EXYNOS5250 FIMC-IS (Imaging Subsystem) driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Authors:  Sylwester Nawrocki 
+ *   Arun Kumar K 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "fimc-is-sensor.h"
+
+static const struct sensor_drv_data s5k6a3_drvdata = {
+   .id = FIMC_IS_SENSOR_ID_S5K6A3,
+   .open_timeout   = S5K6A3_OPEN_TIMEOUT,
+   .setfile_name   = "setfile_6a3.bin",
+};
+
+static const struct sensor_drv_data s5k4e5_drvdata = {
+   .id = FIMC_IS_SENSOR_ID_S5K4E5,
+   .open_timeout   = S5K4E5_OPEN_TIMEOUT,
+   .setfile_name   = "setfile_4e5.bin",
+};
+
+static const struct of_device_id fimc_is_sensor_of_ids[] = {
+   {
+   .compatible = "samsung,s5k6a3",
+   .data   = &s5k6a3_drvdata,
+   },
+   {
+   .compatible = "samsung,s5k4e5",
+   .data   = &s5k4e5_drvdata,
+   },
+   {  }
+};
+
+const struct sensor_drv_data *exynos5_is_sensor_get_drvdata(
+   struct device_node *node)
+{
+   const struct of_device_id *of_id;
+
+   of_id = of_match_node(fimc_is_sensor_of_ids, node);
+   return of_id ? of_id->data : NULL;
+}
diff --git a/drivers/media/platform/exynos5-is/fimc-is-sensor.h 
b/drivers/media/platform/exynos5-is/fimc-is-sensor.h
new file mode 100644
index 000..51e18ea
--- /dev/null
+++ b/drivers/media/platform/exynos5-is/fimc-is-sensor.h
@@ -0,0 +1,69 @@
+/*
+ * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ *
+ * Authors:  Sylwester Nawrocki 
+ *  Younghwan Joo 
+ *  Arun Kumar K 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef FIMC_IS_SENSOR_H_
+#define FIMC_IS_SENSOR_H_
+
+#include 
+#include 
+
+#define S5K6A3_OPEN_TIMEOUT2000 /* ms */
+#define S5K6A3_SENSOR_WIDTH1392
+#define S5K6A3_SENSOR_HEIGHT   1392
+
+#define S5K4E5_OPEN_TIMEOUT2000 /* ms */
+#define S5K4E5_SENSOR_WIDTH2560
+#define S5K4E5_SENSOR_HEIGHT   1920
+
+#define SENSOR_WIDTH_PADDING   16
+#define SENSOR_HEIGHT_PADDING  10
+
+enum fimc_is_sensor_id {
+   FIMC_IS_SENSOR_ID_S5K3H2 = 1,
+   FIMC_IS_SENSOR_ID_S5K6A3,
+   FIMC_IS_SENSOR_ID_S5K4E5,
+   FIMC_IS_SENSOR_ID_S5K3H7,
+   FIMC_IS_SENSOR_ID_CUSTOM,
+   FIMC_IS_SENSOR_ID_END
+};
+
+#define IS_SENSOR_CTRL_BUS_I2C00
+#define IS_SENSOR_CTRL_BUS_I2C11
+
+struct sensor_drv_data {
+   enum fimc_is_sensor_id id;
+   /* sensor open timeout in ms */
+   unsigned short open_timeout;
+   char *setfile_name;
+};
+
+/**
+ * struct fimc_is_sensor - fimc-is sensor data structure
+ * @drvdata: a pointer to the sensor's parameters data structure
+ * @i2c_bus: ISP I2C bus index (0...1)
+ * @test_pattern: true to enable video test pattern
+ */
+struct fimc_is_sensor {
+   const struct sensor_drv_data *drvdata;
+   unsigned int i2c_bus;
+   unsigned int width;
+   unsigned int height;
+   unsigned int pixel_width;
+   unsigned int pixel_height;
+   u8 test_pattern;
+};
+
+const struct sensor_drv_data *exynos5_is_sensor_get_drvdata(
+   struct device_node *node);
+
+#endif /* FIMC_IS_SENSOR_H_ */
-- 
1.7.9.5

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


[RFC v3 07/13] [media] exynos5-fimc-is: Add scaler subdev

2013-08-02 Thread Arun Kumar K
FIMC-IS has two hardware scalers named as scaler-codec and
scaler-preview. This patch adds the common code handling the
video nodes and subdevs of both the scalers.

Signed-off-by: Arun Kumar K 
Signed-off-by: Kilyeon Im 
---
 drivers/media/platform/exynos5-is/fimc-is-scaler.c |  458 
 drivers/media/platform/exynos5-is/fimc-is-scaler.h |  112 +
 2 files changed, 570 insertions(+)
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-scaler.c
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-scaler.h

diff --git a/drivers/media/platform/exynos5-is/fimc-is-scaler.c 
b/drivers/media/platform/exynos5-is/fimc-is-scaler.c
new file mode 100644
index 000..7cff186
--- /dev/null
+++ b/drivers/media/platform/exynos5-is/fimc-is-scaler.c
@@ -0,0 +1,458 @@
+/*
+ * Samsung EXYNOS5250 FIMC-IS (Imaging Subsystem) driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ *  Arun Kumar K 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+
+#include "fimc-is.h"
+
+#define IS_SCALER_DRV_NAME "fimc-is-scaler"
+
+static const struct fimc_is_fmt formats[] = {
+   {
+   .name   = "YUV 4:2:0 3p MultiPlanar",
+   .fourcc = V4L2_PIX_FMT_YUV420M,
+   .depth  = {8, 2, 2},
+   .num_planes = 3,
+   },
+   {
+   .name   = "YUV 4:2:0 2p MultiPlanar",
+   .fourcc = V4L2_PIX_FMT_NV12M,
+   .depth  = {8, 4},
+   .num_planes = 2,
+   },
+   {
+   .name   = "YUV 4:2:2 1p MultiPlanar",
+   .fourcc = V4L2_PIX_FMT_NV16,
+   .depth  = {16},
+   .num_planes = 1,
+   },
+};
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+static const struct fimc_is_fmt *find_format(struct v4l2_format *f)
+{
+   unsigned int i;
+
+   for (i = 0; i < NUM_FORMATS; i++) {
+   if (formats[i].fourcc == f->fmt.pix_mp.pixelformat)
+   return &formats[i];
+   }
+   return NULL;
+}
+
+static int scaler_video_capture_start_streaming(struct vb2_queue *vq,
+   unsigned int count)
+{
+   struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq);
+   int ret;
+
+   /* Scaler start */
+   ret = fimc_is_pipeline_scaler_start(ctx->pipeline,
+   ctx->scaler_id,
+   (unsigned int **)ctx->buf_paddr,
+   vq->num_buffers,
+   ctx->fmt->num_planes);
+   if (ret) {
+   pr_err("Scaler start failed.\n");
+   return -EINVAL;
+   }
+
+   set_bit(STATE_RUNNING, &ctx->capture_state);
+   return 0;
+}
+
+static int scaler_video_capture_stop_streaming(struct vb2_queue *vq)
+{
+   struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq);
+   int ret;
+
+   /* Scaler stop */
+   ret = fimc_is_pipeline_scaler_stop(ctx->pipeline, ctx->scaler_id);
+   if (ret)
+   pr_debug("Scaler already stopped.\n");
+
+   clear_bit(STATE_RUNNING, &ctx->capture_state);
+   return 0;
+}
+
+static int scaler_video_capture_queue_setup(struct vb2_queue *vq,
+   const struct v4l2_format *pfmt,
+   unsigned int *num_buffers, unsigned int *num_planes,
+   unsigned int sizes[], void *allocators[])
+{
+   struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq);
+   const struct fimc_is_fmt *fmt = ctx->fmt;
+   unsigned int wh;
+   int i;
+
+   if (!fmt)
+   return -EINVAL;
+
+   *num_planes = fmt->num_planes;
+   wh = ctx->width * ctx->height;
+
+   for (i = 0; i < *num_planes; i++) {
+   allocators[i] = ctx->alloc_ctx;
+   sizes[i] = (wh * fmt->depth[i]) / 8;
+   }
+   return 0;
+}
+
+static int scaler_video_capture_buffer_init(struct vb2_buffer *vb)
+{
+   struct vb2_queue *vq = vb->vb2_queue;
+   struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq);
+   struct fimc_is_buf *buf;
+   const struct fimc_is_fmt *fmt;
+   int i;
+
+   buf = &ctx->capture_bufs[vb->v4l2_buf.index];
+   /* Initialize buffer */
+   buf->vb = vb;
+   fmt = ctx->fmt;
+   for (i = 0; i < fmt->num_planes; i++)
+   buf->paddr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
+
+   ctx->cap_buf_cnt++;
+   return 0;
+}
+
+static void scaler_video_capture_buffer_queue(struct vb2_buffer *vb)
+{
+   struct vb2_queue *vq = vb->vb2_queue;
+   struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq);
+   struct fimc_is_buf *buf;
+
+   buf = &ctx->capture_bufs[vb->v4l2_buf.index];
+
+   /* Add buffer to the wait queue */
+   pr_debug("Add buffer %d in Scaler %d\n

[RFC v3 03/13] [media] exynos5-fimc-is: Add driver core files

2013-08-02 Thread Arun Kumar K
This driver is for the FIMC-IS IP available in Samsung Exynos5
SoC onwards. This patch adds the core files for the new driver.

Signed-off-by: Arun Kumar K 
Signed-off-by: Kilyeon Im 
---
 drivers/media/platform/exynos5-is/fimc-is-core.c |  394 ++
 drivers/media/platform/exynos5-is/fimc-is-core.h |  122 +++
 2 files changed, 516 insertions(+)
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-core.c
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-core.h

diff --git a/drivers/media/platform/exynos5-is/fimc-is-core.c 
b/drivers/media/platform/exynos5-is/fimc-is-core.c
new file mode 100644
index 000..7b7762b
--- /dev/null
+++ b/drivers/media/platform/exynos5-is/fimc-is-core.c
@@ -0,0 +1,394 @@
+/*
+ * Samsung EXYNOS5 FIMC-IS (Imaging Subsystem) driver
+*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Arun Kumar K 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fimc-is.h"
+#include "fimc-is-i2c.h"
+
+#define CLK_MCU_ISP_DIV0_FREQ  (200 * 100)
+#define CLK_MCU_ISP_DIV1_FREQ  (100 * 100)
+#define CLK_ISP_DIV0_FREQ  (134 * 100)
+#define CLK_ISP_DIV1_FREQ  (68 * 100)
+#define CLK_ISP_DIVMPWM_FREQ   (34 * 100)
+
+static char *fimc_is_clock_name[] = {
+   [IS_CLK_ISP]= "isp",
+   [IS_CLK_MCU_ISP]= "mcu_isp",
+   [IS_CLK_ISP_DIV0]   = "isp_div0",
+   [IS_CLK_ISP_DIV1]   = "isp_div1",
+   [IS_CLK_ISP_DIVMPWM]= "isp_divmpwm",
+   [IS_CLK_MCU_ISP_DIV0]   = "mcu_isp_div0",
+   [IS_CLK_MCU_ISP_DIV1]   = "mcu_isp_div1",
+};
+
+static void fimc_is_put_clocks(struct fimc_is *is)
+{
+   int i;
+
+   for (i = 0; i < IS_CLK_MAX_NUM; i++) {
+   if (IS_ERR(is->clock[i]))
+   continue;
+   clk_unprepare(is->clock[i]);
+   clk_put(is->clock[i]);
+   is->clock[i] = NULL;
+   }
+}
+
+static int fimc_is_get_clocks(struct fimc_is *is)
+{
+   struct device *dev = &is->pdev->dev;
+   int i, ret;
+
+   for (i = 0; i < IS_CLK_MAX_NUM; i++) {
+   is->clock[i] = clk_get(dev, fimc_is_clock_name[i]);
+   if (IS_ERR(is->clock[i]))
+   goto err;
+   ret = clk_prepare(is->clock[i]);
+   if (ret < 0) {
+   clk_put(is->clock[i]);
+   is->clock[i] = ERR_PTR(-EINVAL);
+   goto err;
+   }
+   }
+   return 0;
+err:
+   fimc_is_put_clocks(is);
+   pr_err("Failed to get clock: %s\n", fimc_is_clock_name[i]);
+   return -ENXIO;
+}
+
+static int fimc_is_configure_clocks(struct fimc_is *is)
+{
+   int i, ret;
+
+   for (i = 0; i < IS_CLK_MAX_NUM; i++)
+   is->clock[i] = ERR_PTR(-EINVAL);
+
+   ret = fimc_is_get_clocks(is);
+   if (ret)
+   return ret;
+
+   /* Set rates */
+   ret = clk_set_rate(is->clock[IS_CLK_MCU_ISP_DIV0],
+   CLK_MCU_ISP_DIV0_FREQ);
+   if (ret)
+   return ret;
+   ret = clk_set_rate(is->clock[IS_CLK_MCU_ISP_DIV1],
+   CLK_MCU_ISP_DIV1_FREQ);
+   if (ret)
+   return ret;
+   ret = clk_set_rate(is->clock[IS_CLK_ISP_DIV0], CLK_ISP_DIV0_FREQ);
+   if (ret)
+   return ret;
+   ret = clk_set_rate(is->clock[IS_CLK_ISP_DIV1], CLK_ISP_DIV1_FREQ);
+   if (ret)
+   return ret;
+   ret = clk_set_rate(is->clock[IS_CLK_ISP_DIVMPWM],
+   CLK_ISP_DIVMPWM_FREQ);
+   return ret;
+}
+
+static void fimc_is_pipelines_destroy(struct fimc_is *is)
+{
+   int i;
+
+   for (i = 0; i < is->num_instance; i++)
+   fimc_is_pipeline_destroy(&is->pipeline[i]);
+}
+
+static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index,
+   struct device_node *node)
+{
+   struct fimc_is_sensor *sensor = &is->sensor[index];
+   u32 tmp = 0;
+   int ret;
+
+   sensor->drvdata = exynos5_is_sensor_get_drvdata(node);
+   if (!sensor->drvdata) {
+   dev_err(&is->pdev->dev, "no driver data found for: %s\n",
+node->full_name);
+   return -EINVAL;
+   }
+
+   node = v4l2_of_get_next_endpoint(node, NULL);
+   if (!node)
+   return -ENXIO;
+
+   node = v4l2_of_get_remote_port(node);
+   if (!no

[RFC v3 05/13] [media] exynos5-fimc-is: Add register definition and context header

2013-08-02 Thread Arun Kumar K
This patch adds the register definition file for the fimc-is driver
and also the header file containing the main context for the driver.

Signed-off-by: Arun Kumar K 
Signed-off-by: Kilyeon Im 
---
 drivers/media/platform/exynos5-is/fimc-is-regs.h |  105 +++
 drivers/media/platform/exynos5-is/fimc-is.h  |  153 ++
 2 files changed, 258 insertions(+)
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-regs.h
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is.h

diff --git a/drivers/media/platform/exynos5-is/fimc-is-regs.h 
b/drivers/media/platform/exynos5-is/fimc-is-regs.h
new file mode 100644
index 000..06aa466
--- /dev/null
+++ b/drivers/media/platform/exynos5-is/fimc-is-regs.h
@@ -0,0 +1,105 @@
+/*
+ * Samsung Exynos5 SoC series FIMC-IS driver
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd
+ * Arun Kumar K 
+ * Kil-yeon Lim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef FIMC_IS_REGS_H
+#define FIMC_IS_REGS_H
+
+/* WDT_ISP register */
+#define WDT0x0017
+/* MCUCTL register */
+#define MCUCTL 0x0018
+/* MCU Controller Register */
+#define MCUCTLR(MCUCTL+0x00)
+#define MCUCTLR_AXI_ISPX_AWCACHE(x)((x) << 16)
+#define MCUCTLR_AXI_ISPX_ARCACHE(x)((x) << 12)
+#define MCUCTLR_MSWRST (1 << 0)
+/* Boot Base OFfset Address Register */
+#define BBOAR  (MCUCTL+0x04)
+#define BBOAR_BBOA(x)  ((x) << 0)
+
+/* Interrupt Generation Register 0 from Host CPU to VIC */
+#define INTGR0 (MCUCTL+0x08)
+#define INTGR0_INTGC(n)(1 << ((n) + 16))
+#define INTGR0_INTGD(n)(1 << (n))
+
+/* Interrupt Clear Register 0 from Host CPU to VIC */
+#define INTCR0 (MCUCTL+0x0c)
+#define INTCR0_INTCC(n)(1 << ((n) + 16))
+#define INTCR0_INTCD(n)(1 << (n))
+
+/* Interrupt Mask Register 0 from Host CPU to VIC */
+#define INTMR0 (MCUCTL+0x10)
+#define INTMR0_INTMC(n)(1 << ((n) + 16))
+#define INTMR0_INTMD(n)(1 << (n))
+
+/* Interrupt Status Register 0 from Host CPU to VIC */
+#define INTSR0 (MCUCTL+0x14)
+#define INTSR0_GET_INTSD(n, x) (((x) >> (n)) & 0x1)
+#define INTSR0_GET_INTSC(n, x) (((x) >> ((n) + 16)) & 0x1)
+
+/* Interrupt Mask Status Register 0 from Host CPU to VIC */
+#define INTMSR0(MCUCTL+0x18)
+#define INTMSR0_GET_INTMSD(n, x)   (((x) >> (n)) & 0x1)
+#define INTMSR0_GET_INTMSC(n, x)   (((x) >> ((n) + 16)) & 0x1)
+
+/* Interrupt Generation Register 1 from ISP CPU to Host IC */
+#define INTGR1 (MCUCTL+0x1c)
+#define INTGR1_INTGC(n)(1 << (n))
+
+/* Interrupt Clear Register 1 from ISP CPU to Host IC */
+#define INTCR1 (MCUCTL+0x20)
+#define INTCR1_INTCC(n)(1 << (n))
+
+/* Interrupt Mask Register 1 from ISP CPU to Host IC */
+#define INTMR1 (MCUCTL+0x24)
+#define INTMR1_INTMC(n)(1 << (n))
+
+/* Interrupt Status Register 1 from ISP CPU to Host IC */
+#define INTSR1 (MCUCTL+0x28)
+/* Interrupt Mask Status Register 1 from ISP CPU to Host IC */
+#define INTMSR1(MCUCTL+0x2c)
+/* Interrupt Clear Register 2 from ISP BLK's interrupts to Host IC */
+#define INTCR2 (MCUCTL+0x30)
+#define INTCR2_INTCC(n)(1 << (n))
+
+/* Interrupt Mask Register 2 from ISP BLK's interrupts to Host IC */
+#define INTMR2 (MCUCTL+0x34)
+#define INTMR2_INTMCIS(n)  (1 << (n))
+
+/* Interrupt Status Register 2 from ISP BLK's interrupts to Host IC */
+#define INTSR2 (MCUCTL+0x38)
+/* Interrupt Mask Status Register 2 from ISP BLK's interrupts to Host IC */
+#define INTMSR2(MCUCTL+0x3c)
+/* General Purpose Output Control Register (0~17) */
+#define GPOCTLR(MCUCTL+0x40)
+#define GPOCTLR_GPOG(n, x) ((x) << (n))
+
+/* General Purpose Pad Output Enable Register (0~17) */
+#define GPOENCTLR  (MCUCTL+0x44)
+#define GPOENCTLR_GPOEN0(n, x) ((x) << (n))
+
+/* General Purpose Input Control Register (0~17) */
+#define GPICTLR(MCUCTL+0x48)
+
+/* IS Shared Registers between ISP CPU and HOST CPU */
+#define ISSR(n)(MCUCTL + 0x80 + (n))
+
+/* PMU for FIMC-IS*/
+#define PMUREG_CMU_RESET_ISP_SYS_PWR_REG   0x1584
+#define PMUREG_ISP_ARM_CONFIGURATION   0x2280
+#define P

[RFC v3 12/13] V4L: s5k6a3: Change sensor min/max resolutions

2013-08-02 Thread Arun Kumar K
s5k6a3 sensor has actual pixel resolution of 1408x1402 against
the active resolution 1392x1392. The real resolution is needed
when raw sensor SRGB data is dumped to memory by fimc-lite.

Signed-off-by: Arun Kumar K 
---
 drivers/media/i2c/s5k6a3.c |   14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
index ccbb4fc..d81638d 100644
--- a/drivers/media/i2c/s5k6a3.c
+++ b/drivers/media/i2c/s5k6a3.c
@@ -30,6 +30,9 @@
 #define S5K6A3_SENSOR_MIN_WIDTH32
 #define S5K6A3_SENSOR_MIN_HEIGHT   32
 
+#define S5K6A3_WIDTH_PADDING   16
+#define S5K6A3_HEIGHT_PADDING  10
+
 #define S5K6A3_DEF_PIX_WIDTH   1296
 #define S5K6A3_DEF_PIX_HEIGHT  732
 
@@ -107,10 +110,13 @@ static void s5k6a3_try_format(struct v4l2_mbus_framefmt 
*mf)
 
fmt = find_sensor_format(mf);
mf->code = fmt->code;
-   v4l_bound_align_image(&mf->width, S5K6A3_SENSOR_MIN_WIDTH,
- S5K6A3_SENSOR_MAX_WIDTH, 0,
- &mf->height, S5K6A3_SENSOR_MIN_HEIGHT,
- S5K6A3_SENSOR_MAX_HEIGHT, 0, 0);
+   v4l_bound_align_image(&mf->width,
+   S5K6A3_SENSOR_MIN_WIDTH + S5K6A3_WIDTH_PADDING,
+   S5K6A3_SENSOR_MAX_WIDTH + S5K6A3_WIDTH_PADDING, 0,
+   &mf->height,
+   S5K6A3_SENSOR_MIN_HEIGHT + S5K6A3_HEIGHT_PADDING,
+   S5K6A3_SENSOR_MAX_HEIGHT + S5K6A3_HEIGHT_PADDING, 0,
+   0);
 }
 
 static struct v4l2_mbus_framefmt *__s5k6a3_get_format(
-- 
1.7.9.5

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


[RFC v3 13/13] V4L: Add driver for s5k4e5 image sensor

2013-08-02 Thread Arun Kumar K
This patch adds subdev driver for Samsung S5K4E5 raw image sensor.
Like s5k6a3, it is also another fimc-is firmware controlled
sensor. This minimal sensor driver doesn't do any I2C communications
as its done by ISP firmware. It can be updated if needed to a
regular sensor driver by adding the I2C communication.

Signed-off-by: Arun Kumar K 
---
 drivers/media/i2c/Kconfig  |8 +
 drivers/media/i2c/Makefile |1 +
 drivers/media/i2c/s5k4e5.c |  362 
 3 files changed, 371 insertions(+)
 create mode 100644 drivers/media/i2c/s5k4e5.c

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index f7e9147..271028b 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -572,6 +572,14 @@ config VIDEO_S5K6A3
  This is a V4L2 sensor-level driver for Samsung S5K6A3 raw
  camera sensor.
 
+config VIDEO_S5K4E5
+   tristate "Samsung S5K4E5 sensor support"
+   depends on MEDIA_CAMERA_SUPPORT
+   depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
+   ---help---
+ This is a V4L2 sensor-level driver for Samsung S5K4E5 raw
+ camera sensor.
+
 config VIDEO_S5K4ECGX
 tristate "Samsung S5K4ECGX sensor support"
 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index cf3cf03..0aeed8e 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)+= noon010pc30.o
 obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o
 obj-$(CONFIG_VIDEO_S5K6A3) += s5k6a3.o
+obj-$(CONFIG_VIDEO_S5K4E5) += s5k4e5.o
 obj-$(CONFIG_VIDEO_S5K4ECGX)   += s5k4ecgx.o
 obj-$(CONFIG_VIDEO_S5C73M3)+= s5c73m3/
 obj-$(CONFIG_VIDEO_ADP1653)+= adp1653.o
diff --git a/drivers/media/i2c/s5k4e5.c b/drivers/media/i2c/s5k4e5.c
new file mode 100644
index 000..a713c6a
--- /dev/null
+++ b/drivers/media/i2c/s5k4e5.c
@@ -0,0 +1,362 @@
+/*
+ * Samsung S5K4E5 image sensor driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Arun Kumar K 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define S5K4E5_SENSOR_MAX_WIDTH2560
+#define S5K4E5_SENSOR_MAX_HEIGHT   1920
+#define S5K4E5_SENSOR_MIN_WIDTH32
+#define S5K4E5_SENSOR_MIN_HEIGHT   32
+
+#define S5K4E5_WIDTH_PADDING   16
+#define S5K4E5_HEIGHT_PADDING  10
+
+#define S5K4E5_DEF_PIX_WIDTH   1296
+#define S5K4E5_DEF_PIX_HEIGHT  732
+
+#define S5K4E5_DRV_NAME"S5K4E5"
+#define S5K4E5_CLK_NAME"mclk"
+
+#define S5K4E5_NUM_SUPPLIES2
+
+/**
+ * struct s5k4e5 - fimc-is sensor data structure
+ * @dev: pointer to this I2C client device structure
+ * @subdev: the image sensor's v4l2 subdev
+ * @pad: subdev media source pad
+ * @supplies: image sensor's voltage regulator supplies
+ * @gpio_reset: GPIO connected to the sensor's reset pin
+ * @lock: mutex protecting the structure's members below
+ * @format: media bus format at the sensor's source pad
+ */
+struct s5k4e5 {
+   struct device *dev;
+   struct v4l2_subdev subdev;
+   struct media_pad pad;
+   struct regulator_bulk_data supplies[S5K4E5_NUM_SUPPLIES];
+   int gpio_reset;
+   struct mutex lock;
+   struct v4l2_mbus_framefmt format;
+   struct clk *clock;
+   u32 clock_frequency;
+};
+
+static const char * const s5k4e5_supply_names[] = {
+   "svdda",
+   "svddio"
+};
+
+static inline struct s5k4e5 *sd_to_s5k4e5(struct v4l2_subdev *sd)
+{
+   return container_of(sd, struct s5k4e5, subdev);
+}
+
+static const struct v4l2_mbus_framefmt s5k4e5_formats[] = {
+   {
+   .code = V4L2_MBUS_FMT_SGRBG10_1X10,
+   .colorspace = V4L2_COLORSPACE_SRGB,
+   .field = V4L2_FIELD_NONE,
+   }
+};
+
+static const struct v4l2_mbus_framefmt *find_sensor_format(
+   struct v4l2_mbus_framefmt *mf)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(s5k4e5_formats); i++)
+   if (mf->code == s5k4e5_formats[i].code)
+   return &s5k4e5_formats[i];
+
+   return &s5k4e5_formats[0];
+}
+
+static int s5k4e5_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_fh *fh,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+   if (code->index >= ARRAY_SIZE(s5k4e5_formats))
+   return -EINVAL;
+
+   code->code = s5k4e5_formats[code->index].code;
+   return 0;
+}
+
+static void s5k4e5_try_format(s

[RFC v3 10/13] [media] exynos5-fimc-is: Add the hardware interface module

2013-08-02 Thread Arun Kumar K
The hardware interface module finally sends the commands to the
FIMC-IS firmware and runs the interrupt handler for getting the
responses.

Signed-off-by: Arun Kumar K 
Signed-off-by: Kilyeon Im 
---
 .../media/platform/exynos5-is/fimc-is-interface.c  |  861 
 .../media/platform/exynos5-is/fimc-is-interface.h  |  128 +++
 2 files changed, 989 insertions(+)
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-interface.c
 create mode 100644 drivers/media/platform/exynos5-is/fimc-is-interface.h

diff --git a/drivers/media/platform/exynos5-is/fimc-is-interface.c 
b/drivers/media/platform/exynos5-is/fimc-is-interface.c
new file mode 100644
index 000..12073be
--- /dev/null
+++ b/drivers/media/platform/exynos5-is/fimc-is-interface.c
@@ -0,0 +1,861 @@
+/*
+ * Samsung EXYNOS5 FIMC-IS (Imaging Subsystem) driver
+*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Kil-yeon Lim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include "fimc-is.h"
+#include "fimc-is-cmd.h"
+#include "fimc-is-regs.h"
+
+#define init_request_barrier(itf) mutex_init(&itf->request_barrier)
+#define enter_request_barrier(itf) mutex_lock(&itf->request_barrier)
+#define exit_request_barrier(itf) mutex_unlock(&itf->request_barrier)
+
+static inline void itf_get_cmd(struct fimc_is_interface *itf,
+   struct fimc_is_msg *msg, unsigned int index)
+{
+   struct is_common_reg __iomem *com_regs = itf->com_regs;
+
+   memset(msg, 0, sizeof(*msg));
+
+   switch (index) {
+   case INTR_GENERAL:
+   msg->command = com_regs->ihcmd;
+   msg->instance = com_regs->ihc_sensorid;
+   msg->param[0] = com_regs->ihc_param[0];
+   msg->param[1] = com_regs->ihc_param[1];
+   msg->param[2] = com_regs->ihc_param[2];
+   msg->param[3] = com_regs->ihc_param[3];
+   break;
+   case INTR_SCC_FDONE:
+   msg->command = IHC_FRAME_DONE;
+   msg->instance = com_regs->scc_sensor_id;
+   msg->param[0] = com_regs->scc_param[0];
+   msg->param[1] = com_regs->scc_param[1];
+   msg->param[2] = com_regs->scc_param[2];
+   break;
+   case INTR_SCP_FDONE:
+   msg->command = IHC_FRAME_DONE;
+   msg->instance = com_regs->scp_sensor_id;
+   msg->param[0] = com_regs->scp_param[0];
+   msg->param[1] = com_regs->scp_param[1];
+   msg->param[2] = com_regs->scp_param[2];
+   break;
+   case INTR_META_DONE:
+   msg->command = IHC_FRAME_DONE;
+   msg->instance = com_regs->meta_sensor_id;
+   msg->param[0] = com_regs->meta_param1;
+   break;
+   case INTR_SHOT_DONE:
+   msg->command = IHC_FRAME_DONE;
+   msg->instance = com_regs->shot_sensor_id;
+   msg->param[0] = com_regs->shot_param[0];
+   msg->param[1] = com_regs->shot_param[1];
+   break;
+   default:
+   pr_err("unknown command getting\n");
+   break;
+   }
+}
+
+static inline unsigned int itf_get_intr(struct fimc_is_interface *itf)
+{
+   unsigned int status;
+   struct is_common_reg __iomem *com_regs = itf->com_regs;
+
+   status = readl(itf->regs + INTMSR1) | com_regs->ihcmd_iflag |
+   com_regs->scc_iflag |
+   com_regs->scp_iflag |
+   com_regs->meta_iflag |
+   com_regs->shot_iflag;
+
+   return status;
+}
+
+static void itf_set_state(struct fimc_is_interface *itf,
+   unsigned long state)
+{
+   unsigned long flags;
+   spin_lock_irqsave(&itf->slock_state, flags);
+   __set_bit(state, &itf->state);
+   spin_unlock_irqrestore(&itf->slock_state, flags);
+}
+
+static void itf_clr_state(struct fimc_is_interface *itf,
+   unsigned long state)
+{
+   unsigned long flags;
+   spin_lock_irqsave(&itf->slock_state, flags);
+   __clear_bit(state, &itf->state);
+   spin_unlock_irqrestore(&itf->slock_state, flags);
+}
+
+static int itf_get_state(struct fimc_is_interface *itf,
+   unsigned long state)
+{
+   int ret = 0;
+   unsigned long flags;
+
+   spin_lock_irqsave(&itf->slock_state, flags);
+   ret = test_bit(state, &itf->state);
+   spin_unlock_irqrestore(&itf->slock_state, flags);
+   return ret;
+}
+
+static void itf_init_wakeup(struct fimc_is_interface *itf)
+{
+   itf_set_state(itf, IS_IF_STATE_INIT);
+   wake_up(&itf->irq_queue);
+}
+
+void itf_busy_wakeup(struct fimc_is_interface *itf)
+{
+   itf_clr_state(itf, IS_IF_STATE_BUSY);
+   wake_up(&itf->irq_queue);
+}
+
+static int itf_wait_hw_ready(struct fimc_is_interface *itf)
+{
+   int t;
+   for (

[RFC v3 11/13] [media] exynos5-is: Add Kconfig and Makefile

2013-08-02 Thread Arun Kumar K
Adds Kconfig and Makefile for exynos5-is driver files.

Signed-off-by: Shaik Ameer Basha 
Signed-off-by: Kilyeon Im 
Signed-off-by: Arun Kumar K 
---
 drivers/media/platform/Kconfig |1 +
 drivers/media/platform/Makefile|1 +
 drivers/media/platform/exynos5-is/Kconfig  |   19 +++
 drivers/media/platform/exynos5-is/Makefile |7 +++
 4 files changed, 28 insertions(+)
 create mode 100644 drivers/media/platform/exynos5-is/Kconfig
 create mode 100644 drivers/media/platform/exynos5-is/Makefile

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 08de865..4b0475e 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -123,6 +123,7 @@ config VIDEO_S3C_CAMIF
 
 source "drivers/media/platform/soc_camera/Kconfig"
 source "drivers/media/platform/exynos4-is/Kconfig"
+source "drivers/media/platform/exynos5-is/Kconfig"
 source "drivers/media/platform/s5p-tv/Kconfig"
 
 endif # V4L_PLATFORM_DRIVERS
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index eee28dd..b1225e5 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV)+= s5p-tv/
 
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D)+= s5p-g2d/
 obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC) += exynos-gsc/
+obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS5_MDEV)   += exynos5-is/
 
 obj-$(CONFIG_BLACKFIN)  += blackfin/
 
diff --git a/drivers/media/platform/exynos5-is/Kconfig 
b/drivers/media/platform/exynos5-is/Kconfig
new file mode 100644
index 000..99d5edf
--- /dev/null
+++ b/drivers/media/platform/exynos5-is/Kconfig
@@ -0,0 +1,19 @@
+config VIDEO_SAMSUNG_EXYNOS5_MDEV
+   bool "Samsung Exynos5 Media Device driver"
+   depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && PM_RUNTIME && 
VIDEO_SAMSUNG_EXYNOS4_IS
+   help
+ This is a v4l2 based media controller driver for
+ Exynos5 SoC.
+
+if VIDEO_SAMSUNG_EXYNOS5_MDEV
+
+config VIDEO_SAMSUNG_EXYNOS5_FIMC_IS
+   tristate "Samsung Exynos5 SoC FIMC-IS driver"
+   depends on I2C && OF
+   depends on VIDEO_EXYNOS4_FIMC_IS
+   select VIDEOBUF2_DMA_CONTIG
+   help
+ This is a V4L2 driver for Samsung Exynos5 SoC series Imaging
+ Subsystem known as FIMC-IS.
+
+endif #VIDEO_SAMSUNG_EXYNOS5_MDEV
diff --git a/drivers/media/platform/exynos5-is/Makefile 
b/drivers/media/platform/exynos5-is/Makefile
new file mode 100644
index 000..c4e37e0
--- /dev/null
+++ b/drivers/media/platform/exynos5-is/Makefile
@@ -0,0 +1,7 @@
+ccflags-y += -Idrivers/media/platform/exynos4-is
+exynos5-fimc-is-objs := fimc-is-core.o fimc-is-isp.o fimc-is-scaler.o
+exynos5-fimc-is-objs += fimc-is-pipeline.o fimc-is-interface.o fimc-is-sensor.o
+exynos-mdevice-objs := exynos5-mdev.o
+
+obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS5_FIMC_IS) += exynos5-fimc-is.o
+obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS5_MDEV) += exynos-mdevice.o
-- 
1.7.9.5

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


[GIT PULL FOR 3.11] Exynos/S5P fixes

2013-08-02 Thread Sylwester Nawrocki
Mauro,

Here are couple critical/regression fixes for the exynos/s5p drivers.
Please pull for v3.11.

The following changes since commit ad81f0545ef01ea651886dddac4bef6cec930092:

  Linux 3.11-rc1 (2013-07-14 15:18:27 -0700)

are available in the git repository at:

  git://linuxtv.org/snawrocki/samsung.git v3.11-fixes-1

for you to fetch changes up to 31de1930009b91cd5f0319fb1485549914e2b153:

  exynos4-is: Fix entity unregistration on error path (2013-07-29 22:04:39 
+0200)


Arun Kumar K (2):
  exynos4-is: Fix fimc-lite bayer formats
  exynos-gsc: Register v4l2 device

Sachin Kamat (1):
  s5p-g2d: Fix registration failure

Sylwester Nawrocki (1):
  exynos4-is: Fix entity unregistration on error path

 drivers/media/platform/exynos-gsc/gsc-core.c  |9 -
 drivers/media/platform/exynos-gsc/gsc-core.h  |1 +
 drivers/media/platform/exynos-gsc/gsc-m2m.c   |1 +
 drivers/media/platform/exynos4-is/fimc-lite.c |4 ++--
 drivers/media/platform/exynos4-is/media-dev.c |2 +-
 drivers/media/platform/s5p-g2d/g2d.c  |1 +
 6 files changed, 14 insertions(+), 4 deletions(-)

--
Thanks,
Sylwester
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


cron job: media_tree daily build: ERRORS

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

Results of the daily build of media_tree:

date:   Fri Aug  2 19:00:23 CEST 2013
git branch: test
git hash:   dfb9f94e8e5e7f73c8e2bcb7d4fb1de57e7c333d
gcc version:i686-linux-gcc (GCC) 4.8.1
sparse version: v0.4.5-rc1
host hardware:  x86_64
host os:3.9-7.slh.1-amd64

linux-git-arm-at91: OK
linux-git-arm-davinci: OK
linux-git-arm-exynos: OK
linux-git-arm-mx: OK
linux-git-arm-omap: OK
linux-git-arm-omap1: OK
linux-git-arm-pxa: OK
linux-git-blackfin: OK
linux-git-i686: OK
linux-git-m32r: OK
linux-git-mips: ERRORS
linux-git-powerpc64: OK
linux-git-sh: OK
linux-git-x86_64: OK
linux-2.6.31.14-i686: ERRORS
linux-2.6.32.27-i686: ERRORS
linux-2.6.33.7-i686: ERRORS
linux-2.6.34.7-i686: ERRORS
linux-2.6.35.9-i686: ERRORS
linux-2.6.36.4-i686: ERRORS
linux-2.6.37.6-i686: ERRORS
linux-2.6.38.8-i686: ERRORS
linux-2.6.39.4-i686: WARNINGS
linux-3.0.60-i686: OK
linux-3.10-i686: OK
linux-3.1.10-i686: OK
linux-3.2.37-i686: OK
linux-3.3.8-i686: OK
linux-3.4.27-i686: WARNINGS
linux-3.5.7-i686: WARNINGS
linux-3.6.11-i686: WARNINGS
linux-3.7.4-i686: WARNINGS
linux-3.8-i686: WARNINGS
linux-3.9.2-i686: WARNINGS
linux-2.6.31.14-x86_64: ERRORS
linux-2.6.32.27-x86_64: ERRORS
linux-2.6.33.7-x86_64: ERRORS
linux-2.6.34.7-x86_64: ERRORS
linux-2.6.35.9-x86_64: ERRORS
linux-2.6.36.4-x86_64: ERRORS
linux-2.6.37.6-x86_64: ERRORS
linux-2.6.38.8-x86_64: ERRORS
linux-2.6.39.4-x86_64: WARNINGS
linux-3.0.60-x86_64: OK
linux-3.10-x86_64: OK
linux-3.1.10-x86_64: OK
linux-3.2.37-x86_64: OK
linux-3.3.8-x86_64: OK
linux-3.4.27-x86_64: WARNINGS
linux-3.5.7-x86_64: WARNINGS
linux-3.6.11-x86_64: WARNINGS
linux-3.7.4-x86_64: WARNINGS
linux-3.8-x86_64: WARNINGS
linux-3.9.2-x86_64: WARNINGS
apps: WARNINGS
spec-git: OK
sparse version: v0.4.5-rc1
sparse: ERRORS

Detailed results are available here:

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

Full logs are available here:

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

The Media Infrastructure API from this daily build is here:

http://www.xs4all.nl/~hverkuil/spec/media.html
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V3 0/3] networking: Use ETH_ALEN where appropriate

2013-08-02 Thread David Miller
From: Joe Perches 
Date: Thu,  1 Aug 2013 16:17:46 -0700

> Convert the uses mac addresses to ETH_ALEN so
> it's easier to find and verify where mac addresses
> need to be __aligned(2)

Series applied to net-next, thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Help with omap3isp resizing from CCDC

2013-08-02 Thread Samuel.Rasmussen
Hi,

I've been having problems getting the resizer to take its input from the
CCDC.  From the linux-media mail-archive, it looks like Paul Chiha ran
into a similar problem in Oct 2011 with his message "Help with omap3isp
resizing".  Paul had a patch at the end of the discussion, but even his
patch hasn't fixed my problem yet.  I might have made a mistake porting
the patch since I'm on a newer kernel, or perhaps it doesn't work with
my TVP5151 decoder.

My setup: DM 3730 board, 3.5 kernel, and TVP5151 decoder.

The video looks great with a 640x480 resolution, and the CCDC is
de-interlacing the video.  However, for my needs the video must be
resized to 320x240 or 160x120.  The video, coming from the resizer, is
split into a top and bottom half.  Both halves are identical where
everything in the video is too wide and too short.  The CCDC must not be
de-interlacing the video going to the resizer.  I tried setting up the
pipeline to send the CCDC to the resizer, but something must have gone
wrong.

Up until this point, I was using the UYVY2X8 format.  Then I saw the
discussion Paul Chiha created.  In that discussion Laurent said:

>But the original poster wants to use the sensor -> ccdc -> resizer ->
resizer 
>output pipeline.

>> Also several sensor drivers that i have checked, usually define its
>> output as 2X8 output. I think is more natural to add 2X8 support to
>> CCDC and Resizer engines instead to modifying exiting drivers.

>Sure, sensor drivers should not be modified. What I was talking about
was to 
>configure the pipeline as

>sensor:0 [YUYV8_2X8], CCDC:0 [YUYV8_2X8], CCDC:1 [YUYV8_1X16],
resizer:0 [YUYV8_1X16]

I wasn't sure if Laurent's advice would also apply to the TVP5151, but I
wanted to test it out.  I implemented Paul's patch so I could use the
YUYV8_2X8 and YUYV8_1X16 formats.  The 640x480 resolution looked good in
the YUYV8_2X8 format.  However, once again the video from the resizer
was not de-interlaced so it had a top and bottom half (using YUYV8_2X8
and YUYV8_1X16).  This time it was even worse because the video from the
resizer was very green.

Does anyone have suggestions for resizing video from the TVP5151?

Thanks for taking the time to read this,
Samuel

I'm adding some media-ctl details below.
media-ctl commands I'm using:

media-ctl -v -l '"tvp5150 3-005c":0->"OMAP3 ISP CCDC":0[1]'
media-ctl -v -l '"OMAP3 ISP CCDC":1->"OMAP3 ISP resizer":0[1]'
media-ctl -v -l '"OMAP3 ISP resizer":1->"OMAP3 ISP resizer output":0[1]'
media-ctl -v -f '"tvp5150 3-005c":0 [YUYV2X8 640x480]'
media-ctl -v -f '"OMAP3 ISP CCDC":0 [YUYV2X8 640x480]'
media-ctl -v -f '"OMAP3 ISP CCDC":1 [YUYV 640x480]'
media-ctl -v -f '"OMAP3 ISP resizer":1 [YUYV 320x240]'
LD_PRELOAD=/usr/lib/libv4l/v4l2convert.so mplayer tv:// -tv
driver=v4l2:device=/dev/video6

Output of medi-ctl -p:

Opening media device /dev/media0
Enumerating entities
Found 16 entities
Enumerating pads and links
Media controller API version 0.0.0

Media device information

driver  omap3isp
model   TI OMAP3 ISP
serial  
bus info
hw revision 0xf0
driver version  0.0.0

Device topology
- entity 1: OMAP3 ISP CCP2 (2 pads, 2 links)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev0
pad0: Sink
[fmt:SGRBG10/4096x4096]
<- "OMAP3 ISP CCP2 input":0 []
pad1: Source
[fmt:SGRBG10/4096x4096]
-> "OMAP3 ISP CCDC":0 []

- entity 2: OMAP3 ISP CCP2 input (1 pad, 1 link)
type Node subtype V4L flags 0
device node name /dev/video0
pad0: Source
-> "OMAP3 ISP CCP2":0 []

- entity 3: OMAP3 ISP CSI2a (2 pads, 2 links)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev1
pad0: Sink
[fmt:SGRBG10/4096x4096]
pad1: Source
[fmt:SGRBG10/4096x4096]
-> "OMAP3 ISP CSI2a output":0 []
-> "OMAP3 ISP CCDC":0 []

- entity 4: OMAP3 ISP CSI2a output (1 pad, 1 link)
type Node subtype V4L flags 0
device node name /dev/video1
pad0: Sink
<- "OMAP3 ISP CSI2a":1 []

- entity 5: OMAP3 ISP CCDC (3 pads, 9 links)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev2
pad0: Sink
[fmt:YUYV2X8/640x480]
<- "OMAP3 ISP CCP2":1 []
<- "OMAP3 ISP CSI2a":1 []
<- "tvp5150 3-005c":0 [ENABLED]
pad1: Source
[fmt:YUYV/640x480
 crop.bounds:(0,0)/640x480
 crop:(0,0)/640x480]
-> "OMAP3 ISP CCDC output":0 []
-> "OMAP3 ISP resizer":0 [ENABLED]
pad2: Source
[fmt:unknown/640x479]
-> "OMAP3 ISP preview":0 []
-> "OMAP3 ISP AEWB":0 [ENABLED,IMMUTABLE]
-> "

Re: [PATCH 2/2] libv4lconvert: Support for RGB32 and BGR32 format

2013-08-02 Thread Gregor Jasny

Hello,

On 8/1/13 3:04 PM, Ricardo Ribalda Delgado wrote:

--- a/lib/libv4lconvert/libv4lconvert-priv.h
+++ b/lib/libv4lconvert/libv4lconvert-priv.h
@@ -108,7 +108,7 @@ unsigned char *v4lconvert_alloc_buffer(int needed,
  int v4lconvert_oom_error(struct v4lconvert_data *data);

  void v4lconvert_rgb24_to_yuv420(const unsigned char *src, unsigned char *dest,
-   const struct v4l2_format *src_fmt, int bgr, int yvu);
+   const struct v4l2_format *src_fmt, int bgr, int yvu, int rgb32);

  void v4lconvert_yuv420_to_rgb24(const unsigned char *src, unsigned char *dst,
int width, int height, int yvu);



@@ -47,9 +47,15 @@ void v4lconvert_rgb24_to_yuv420(const unsigned char *src, 
unsigned char *dest,
RGB2Y(src[2], src[1], src[0], *dest++);
else
RGB2Y(src[0], src[1], src[2], *dest++);
-   src += 3;
+   if (rgb32)
+   src += 4;
+   else
+   src += 3;


Instead of passing a 0/1 flag here I would call this variable 
bits_per_pixel or bpp and pass 3 or 4 here. This would reduce the if 
condition ugliness.


Thanks,
Gregor

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


Re: [PATCH 3/5] qv4l2: add ALSA stream to qv4l2

2013-08-02 Thread Gregor Jasny

Hello,


diff --git a/utils/qv4l2/Makefile.am b/utils/qv4l2/Makefile.am
index 22d4c17..eed25b0 100644
--- a/utils/qv4l2/Makefile.am
+++ b/utils/qv4l2/Makefile.am
@@ -4,7 +4,8 @@ qv4l2_SOURCES = qv4l2.cpp general-tab.cpp ctrl-tab.cpp 
vbi-tab.cpp v4l2-api.cpp
capture-win-qt.cpp capture-win-qt.h capture-win-gl.cpp capture-win-gl.h \
raw2sliced.cpp qv4l2.h capture-win.h general-tab.h vbi-tab.h v4l2-api.h 
raw2sliced.h
  nodist_qv4l2_SOURCES = moc_qv4l2.cpp moc_general-tab.cpp moc_capture-win.cpp 
moc_vbi-tab.cpp qrc_qv4l2.cpp
-qv4l2_LDADD = ../../lib/libv4l2/libv4l2.la 
../../lib/libv4lconvert/libv4lconvert.la ../libv4l2util/libv4l2util.la
+qv4l2_LDADD = ../../lib/libv4l2/libv4l2.la 
../../lib/libv4lconvert/libv4lconvert.la ../libv4l2util/libv4l2util.la \
+  ../libmedia_dev/libmedia_dev.la

  if WITH_QV4L2_GL
  qv4l2_CPPFLAGS = $(QTGL_CFLAGS) -DENABLE_GL
@@ -14,6 +15,12 @@ qv4l2_CPPFLAGS = $(QT_CFLAGS)
  qv4l2_LDFLAGS = $(QT_LIBS)
  endif

+if WITH_QV4L2_ALSA
+qv4l2_CPPFLAGS += $(ALSA_CFLAGS) -DENABLE_ALSA


I would prefer if you don't add another define to the command line. To 
check for ALSA support please include config.h and use the flag provided 
there.



diff --git a/utils/qv4l2/alsa_stream.h b/utils/qv4l2/alsa_stream.h
index c68fd6d..b74c3aa 100644
--- a/utils/qv4l2/alsa_stream.h
+++ b/utils/qv4l2/alsa_stream.h
@@ -1,5 +1,12 @@
-int alsa_thread_startup(const char *pdevice, const char *cdevice, int latency,
-   FILE *__error_fp,
-   int __verbose);
+#ifndef ALSA_STRAM_H
+#define ALSA_STRAM_H


unimportant typo here

Thanks,
Gregor

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


[PATCH v2 1/2] libv4lconvert: Support for Y16 pixel format

2013-08-02 Thread Ricardo Ribalda Delgado
This patch adds support for V4L2_PIX_FMT_Y16 format.

Signed-off-by: Ricardo Ribalda Delgado 
---
 lib/libv4lconvert/libv4lconvert-priv.h |6 ++
 lib/libv4lconvert/libv4lconvert.c  |   19 +++
 lib/libv4lconvert/rgbyuv.c |   30 ++
 3 files changed, 55 insertions(+)

diff --git a/lib/libv4lconvert/libv4lconvert-priv.h 
b/lib/libv4lconvert/libv4lconvert-priv.h
index c37e220..6422fdd 100644
--- a/lib/libv4lconvert/libv4lconvert-priv.h
+++ b/lib/libv4lconvert/libv4lconvert-priv.h
@@ -152,6 +152,12 @@ void v4lconvert_grey_to_rgb24(const unsigned char *src, 
unsigned char *dest,
 void v4lconvert_grey_to_yuv420(const unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt);
 
+void v4lconvert_y16_to_rgb24(const unsigned char *src, unsigned char *dest,
+   int width, int height);
+
+void v4lconvert_y16_to_yuv420(const unsigned char *src, unsigned char *dest,
+   const struct v4l2_format *src_fmt);
+
 int v4lconvert_y10b_to_rgb24(struct v4lconvert_data *data,
const unsigned char *src, unsigned char *dest, int width, int height);
 
diff --git a/lib/libv4lconvert/libv4lconvert.c 
b/lib/libv4lconvert/libv4lconvert.c
index 60010f1..bc5e34f 100644
--- a/lib/libv4lconvert/libv4lconvert.c
+++ b/lib/libv4lconvert/libv4lconvert.c
@@ -128,6 +128,7 @@ static const struct v4lconvert_pixfmt 
supported_src_pixfmts[] = {
{ V4L2_PIX_FMT_Y4,   8, 20, 20, 0 },
{ V4L2_PIX_FMT_Y6,   8, 20, 20, 0 },
{ V4L2_PIX_FMT_Y10BPACK,10, 20, 20, 0 },
+   { V4L2_PIX_FMT_Y16, 16, 20, 20, 0 },
 };
 
 static const struct v4lconvert_pixfmt supported_dst_pixfmts[] = {
@@ -989,6 +990,24 @@ static int v4lconvert_convert_pixfmt(struct 
v4lconvert_data *data,
break;
}
 
+   case V4L2_PIX_FMT_Y16:
+   switch (dest_pix_fmt) {
+   case V4L2_PIX_FMT_RGB24:
+   case V4L2_PIX_FMT_BGR24:
+   v4lconvert_y16_to_rgb24(src, dest, width, height);
+   break;
+   case V4L2_PIX_FMT_YUV420:
+   case V4L2_PIX_FMT_YVU420:
+   v4lconvert_y16_to_yuv420(src, dest, fmt);
+   break;
+   }
+   if (src_size < (width * height * 2)) {
+   V4LCONVERT_ERR("short y16 data frame\n");
+   errno = EPIPE;
+   result = -1;
+   }
+   break;
+
case V4L2_PIX_FMT_GREY:
case V4L2_PIX_FMT_Y4:
case V4L2_PIX_FMT_Y6:
diff --git a/lib/libv4lconvert/rgbyuv.c b/lib/libv4lconvert/rgbyuv.c
index d05abe9..bef034f 100644
--- a/lib/libv4lconvert/rgbyuv.c
+++ b/lib/libv4lconvert/rgbyuv.c
@@ -586,6 +586,36 @@ void v4lconvert_rgb565_to_yuv420(const unsigned char *src, 
unsigned char *dest,
}
 }
 
+void v4lconvert_y16_to_rgb24(const unsigned char *src, unsigned char *dest,
+   int width, int height)
+{
+   int j;
+   while (--height >= 0) {
+   for (j = 0; j < width; j++) {
+   *dest++ = *src;
+   *dest++ = *src;
+   *dest++ = *src;
+   src+=2;
+   }
+   }
+}
+
+void v4lconvert_y16_to_yuv420(const unsigned char *src, unsigned char *dest,
+   const struct v4l2_format *src_fmt)
+{
+   int x, y;
+
+   /* Y */
+   for (y = 0; y < src_fmt->fmt.pix.height; y++)
+   for (x = 0; x < src_fmt->fmt.pix.width; x++){
+   *dest++ = *src;
+   src+=2;
+   }
+
+   /* Clear U/V */
+   memset(dest, 0x80, src_fmt->fmt.pix.width * src_fmt->fmt.pix.height / 
2);
+}
+
 void v4lconvert_grey_to_rgb24(const unsigned char *src, unsigned char *dest,
int width, int height)
 {
-- 
1.7.10.4

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


[PATCH v2 0/2] Add support for V4L2_PIX_FMT_Y16, V4L2_PIX_FMT_RGB32 and V4L2_PIX_FMT_BGR32

2013-08-02 Thread Ricardo Ribalda Delgado
This patch adds support for 3 new formats.

v2: Includes feedback from Gregor Jasny
Gregor: Replaces rbg32 flag with bytesperpixes

Ricardo Ribalda Delgado (2):
  libv4lconvert: Support for Y16 pixel format
  libv4lconvert: Support for RGB32 and BGR32 format

 lib/libv4lconvert/libv4lconvert-priv.h |   11 -
 lib/libv4lconvert/libv4lconvert.c  |   77 +---
 lib/libv4lconvert/rgbyuv.c |   75 ++-
 3 files changed, 145 insertions(+), 18 deletions(-)

-- 
1.7.10.4

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


[PATCH v2 2/2] libv4lconvert: Support for RGB32 and BGR32 format

2013-08-02 Thread Ricardo Ribalda Delgado
This patch adds support for V4L2_PIX_FMT_BGR32 and V4L2_PIX_FMT_BGR32
formats.

Signed-off-by: Ricardo Ribalda Delgado 
---
 lib/libv4lconvert/libv4lconvert-priv.h |5 ++-
 lib/libv4lconvert/libv4lconvert.c  |   58 
 lib/libv4lconvert/rgbyuv.c |   45 +++--
 3 files changed, 90 insertions(+), 18 deletions(-)

diff --git a/lib/libv4lconvert/libv4lconvert-priv.h 
b/lib/libv4lconvert/libv4lconvert-priv.h
index 6422fdd..ac1391e 100644
--- a/lib/libv4lconvert/libv4lconvert-priv.h
+++ b/lib/libv4lconvert/libv4lconvert-priv.h
@@ -108,7 +108,7 @@ unsigned char *v4lconvert_alloc_buffer(int needed,
 int v4lconvert_oom_error(struct v4lconvert_data *data);
 
 void v4lconvert_rgb24_to_yuv420(const unsigned char *src, unsigned char *dest,
-   const struct v4l2_format *src_fmt, int bgr, int yvu);
+   const struct v4l2_format *src_fmt, int bgr, int yvu, int bpp);
 
 void v4lconvert_yuv420_to_rgb24(const unsigned char *src, unsigned char *dst,
int width, int height, int yvu);
@@ -158,6 +158,9 @@ void v4lconvert_y16_to_rgb24(const unsigned char *src, 
unsigned char *dest,
 void v4lconvert_y16_to_yuv420(const unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt);
 
+void v4lconvert_rgb32_to_rgb24(const unsigned char *src, unsigned char *dest,
+   int width, int height, int bgr);
+
 int v4lconvert_y10b_to_rgb24(struct v4lconvert_data *data,
const unsigned char *src, unsigned char *dest, int width, int height);
 
diff --git a/lib/libv4lconvert/libv4lconvert.c 
b/lib/libv4lconvert/libv4lconvert.c
index bc5e34f..2aec99a 100644
--- a/lib/libv4lconvert/libv4lconvert.c
+++ b/lib/libv4lconvert/libv4lconvert.c
@@ -84,6 +84,8 @@ static const struct v4lconvert_pixfmt supported_src_pixfmts[] 
= {
SUPPORTED_DST_PIXFMTS,
/* packed rgb formats */
{ V4L2_PIX_FMT_RGB565,  16,  4,  6, 0 },
+   { V4L2_PIX_FMT_BGR32,   32,  4,  6, 0 },
+   { V4L2_PIX_FMT_RGB32,   32,  4,  6, 0 },
/* yuv 4:2:2 formats */
{ V4L2_PIX_FMT_YUYV,16,  5,  4, 0 },
{ V4L2_PIX_FMT_YVYU,16,  5,  4, 0 },
@@ -981,10 +983,10 @@ static int v4lconvert_convert_pixfmt(struct 
v4lconvert_data *data,
v4lconvert_swap_rgb(d, dest, width, height);
break;
case V4L2_PIX_FMT_YUV420:
-   v4lconvert_rgb24_to_yuv420(d, dest, fmt, 0, 0);
+   v4lconvert_rgb24_to_yuv420(d, dest, fmt, 0, 0, 3);
break;
case V4L2_PIX_FMT_YVU420:
-   v4lconvert_rgb24_to_yuv420(d, dest, fmt, 0, 1);
+   v4lconvert_rgb24_to_yuv420(d, dest, fmt, 0, 1, 3);
break;
}
break;
@@ -1079,10 +1081,10 @@ static int v4lconvert_convert_pixfmt(struct 
v4lconvert_data *data,
v4lconvert_swap_rgb(src, dest, width, height);
break;
case V4L2_PIX_FMT_YUV420:
-   v4lconvert_rgb24_to_yuv420(src, dest, fmt, 0, 0);
+   v4lconvert_rgb24_to_yuv420(src, dest, fmt, 0, 0, 3);
break;
case V4L2_PIX_FMT_YVU420:
-   v4lconvert_rgb24_to_yuv420(src, dest, fmt, 0, 1);
+   v4lconvert_rgb24_to_yuv420(src, dest, fmt, 0, 1, 3);
break;
}
if (src_size < (width * height * 3)) {
@@ -1101,10 +1103,10 @@ static int v4lconvert_convert_pixfmt(struct 
v4lconvert_data *data,
memcpy(dest, src, width * height * 3);
break;
case V4L2_PIX_FMT_YUV420:
-   v4lconvert_rgb24_to_yuv420(src, dest, fmt, 1, 0);
+   v4lconvert_rgb24_to_yuv420(src, dest, fmt, 1, 0, 3);
break;
case V4L2_PIX_FMT_YVU420:
-   v4lconvert_rgb24_to_yuv420(src, dest, fmt, 1, 1);
+   v4lconvert_rgb24_to_yuv420(src, dest, fmt, 1, 1, 3);
break;
}
if (src_size < (width * height * 3)) {
@@ -1114,6 +1116,50 @@ static int v4lconvert_convert_pixfmt(struct 
v4lconvert_data *data,
}
break;
 
+   case V4L2_PIX_FMT_RGB32:
+   switch (dest_pix_fmt) {
+   case V4L2_PIX_FMT_RGB24:
+   v4lconvert_rgb32_to_rgb24(src, dest, width, height, 0);
+   break;
+   case V4L2_PIX_FMT_BGR24:
+   v4lconvert_rgb32_to_rgb24(src, dest, width, height, 1);
+   break;
+   case V4L2_PIX_FMT_YUV420:
+   v4lconvert_rgb24_to_yuv42

Re: [PATCH 2/2] libv4lconvert: Support for RGB32 and BGR32 format

2013-08-02 Thread Ricardo Ribalda Delgado
Hello Gregor

Totally agree,

I have just uploaded a new set.

Thanks!

On Sat, Aug 3, 2013 at 12:15 AM, Gregor Jasny  wrote:
> Hello,
>
>
> On 8/1/13 3:04 PM, Ricardo Ribalda Delgado wrote:
>>
>> --- a/lib/libv4lconvert/libv4lconvert-priv.h
>> +++ b/lib/libv4lconvert/libv4lconvert-priv.h
>> @@ -108,7 +108,7 @@ unsigned char *v4lconvert_alloc_buffer(int needed,
>>   int v4lconvert_oom_error(struct v4lconvert_data *data);
>>
>>   void v4lconvert_rgb24_to_yuv420(const unsigned char *src, unsigned char
>> *dest,
>> -   const struct v4l2_format *src_fmt, int bgr, int yvu);
>> +   const struct v4l2_format *src_fmt, int bgr, int yvu, int
>> rgb32);
>>
>>   void v4lconvert_yuv420_to_rgb24(const unsigned char *src, unsigned char
>> *dst,
>> int width, int height, int yvu);
>
>
>> @@ -47,9 +47,15 @@ void v4lconvert_rgb24_to_yuv420(const unsigned char
>> *src, unsigned char *dest,
>> RGB2Y(src[2], src[1], src[0], *dest++);
>> else
>> RGB2Y(src[0], src[1], src[2], *dest++);
>> -   src += 3;
>> +   if (rgb32)
>> +   src += 4;
>> +   else
>> +   src += 3;
>
>
> Instead of passing a 0/1 flag here I would call this variable bits_per_pixel
> or bpp and pass 3 or 4 here. This would reduce the if condition ugliness.
>
> Thanks,
> Gregor
>



-- 
Ricardo Ribalda
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


System Administrator

2013-08-02 Thread Jessie Phillips
Your password will expire in 3 Days Click  
Here to validate your e-mail.

Thanks
System Administrator
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


MESSAGE FROM YONG WONG!

2013-08-02 Thread YONG
Good Day,

I appologize for using this medium of internet to
reach you, though it has been greatly abused, but I
chose to reach you because it is still the fastest means
of communication in the world, however this correspondent
is unofficial and private.

My name is Yong Wong, I work with the hang seng Bank Hong Kong,
I have a business proposition for you involving the sum of
$24.500.000.00 Million Dollars in my bank which I know we will
be of mutual benefit to both of us,There is no risk involved.
If interested please reply back to my private email: wongyong...@yahoo.com.hk

Regards,
Yong Wong.




















































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