Re: [PATCH 1/2] videobuf2-dma-sg: Allocate pages as contiguous as possible
Hello, On 7/19/2013 7:02 PM, 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 ricardo.riba...@gmail.com Acked-by: Marek Szyprowski m.szyprow...@samsung.com --- 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 (1order); 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: Best regards -- Marek Szyprowski Samsung RD Institute Poland -- 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
Hi Rob, On 2 August 2013 06:03, Rob Clark robdcl...@gmail.com wrote: On Thu, Aug 1, 2013 at 7:20 PM, Tomasz Figa tomasz.f...@gmail.com 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 vikas.saj...@linaro.org Signed-off-by: Arun Kumar arun...@samsung.com --- 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 drm/drm_crtc.h #include drm/drm_fb_helper.h #include drm/drm_crtc_helper.h +#include drm/exynos_drm.h #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. 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 -- Thanks and Regards Vikas Sajjan -- 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 2/2] videobuf2-dma-sg: Replace vb2_dma_sg_desc with sg_table
Hello, On 7/19/2013 7:02 PM, Ricardo Ribalda Delgado wrote: 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 Signed-off-by: Ricardo Ribalda Delgado ricardo.riba...@gmail.com Acked-by: Marek Szyprowski m.szyprow...@samsung.com --- 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 c053605..4b30ad5 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 (1order); 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 (1order); 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
Re: Doing a v4l-utils-1.0.0 release
Hi Gregor, Let me know when you've branched 1.0.0. I want to merge Bård's work for qv4l2 (openGL support, upcoming audio support and other improvements), but I can't do that until after you made the 1.0.0 branch. Thanks! Hans On 08/01/2013 08:28 PM, Gregor Jasny wrote: Hello, On 6/14/13 9:15 AM, Hans de Goede wrote: IIRC the 0.9.x series were meant as development releases leading up to a new stable 1.0.0 release. Lately there have been no maintenance 0.8.x releases and a lot of interesting development going on in the 0.9.x, while at the same time there have been no issues reported against 0.9.x (iow it seems stable). So how about taking current master and releasing that as a 1.0.0 release ? If nobody objects I'll do a 1.0.0 release this weekend. 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 -- 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/3] [media] exynos4-is: Staticize local symbol
__fimc_is_hw_update_param is used only in this file. Make it static. Signed-off-by: Sachin Kamat sachin.ka...@linaro.org --- drivers/media/platform/exynos4-is/fimc-is-param.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/exynos4-is/fimc-is-param.c b/drivers/media/platform/exynos4-is/fimc-is-param.c index c7e7f69..a353be0 100644 --- a/drivers/media/platform/exynos4-is/fimc-is-param.c +++ b/drivers/media/platform/exynos4-is/fimc-is-param.c @@ -56,7 +56,7 @@ static void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is) __hw_param_copy(dst, src); } -int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset) +static int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset) { struct is_param_region *par = is-is_p_region-parameter; struct chain_config *cfg = is-config[is-config_index]; -- 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
[PATCH 3/3] [media] exynos4-is: Fix potential NULL pointer dereference
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 sachin.ka...@linaro.org --- 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; } if (!drv_data || fimc-index = drv_data-num_instances || -- 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
[PATCH 2/3] [media] exynos4-is: Annotate unused functions
__is_set_init_isp_aa and fimc_is_hw_set_tune currently do not have any callers. However these functions may be used in the future. Hence instead of deleting them, staticize and annotate them with __maybe_unused flag to avoid compiler warnings. Signed-off-by: Sachin Kamat sachin.ka...@linaro.org --- drivers/media/platform/exynos4-is/fimc-is-param.c |2 +- drivers/media/platform/exynos4-is/fimc-is-regs.c |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-is-param.c b/drivers/media/platform/exynos4-is/fimc-is-param.c index a353be0..9bf3ddd 100644 --- a/drivers/media/platform/exynos4-is/fimc-is-param.c +++ b/drivers/media/platform/exynos4-is/fimc-is-param.c @@ -287,7 +287,7 @@ void __is_set_sensor(struct fimc_is *is, int fps) fimc_is_set_param_bit(is, PARAM_ISP_OTF_INPUT); } -void __is_set_init_isp_aa(struct fimc_is *is) +static void __maybe_unused __is_set_init_isp_aa(struct fimc_is *is) { struct isp_param *isp; diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c index 63c68ec..cf2e13a 100644 --- a/drivers/media/platform/exynos4-is/fimc-is-regs.c +++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c @@ -96,7 +96,7 @@ int fimc_is_hw_set_param(struct fimc_is *is) return 0; } -int fimc_is_hw_set_tune(struct fimc_is *is) +static int __maybe_unused fimc_is_hw_set_tune(struct fimc_is *is) { fimc_is_hw_wait_intmsr0_intmsd0(is); -- 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] drm/exynos: Add check for IOMMU while passing physically continous memory flag
Hi Vikas, On Friday 02 of August 2013 12:08:52 Vikas Sajjan wrote: Hi Rob, On 2 August 2013 06:03, Rob Clark robdcl...@gmail.com wrote: On Thu, Aug 1, 2013 at 7:20 PM, Tomasz Figa tomasz.f...@gmail.com 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 vikas.saj...@linaro.org Signed-off-by: Arun Kumar arun...@samsung.com --- 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
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 sachin.ka...@linaro.org --- 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
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 ricardo.riba...@gmail.com --- 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
Hi Sylwester, On 2 August 2013 14:15, Sylwester Nawrocki s.nawro...@samsung.com 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 sachin.ka...@linaro.org --- 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
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 sachin.ka...@linaro.org --- 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
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 laurent.pinchart+rene...@ideasonboard.com Acked-by: Sakari Ailus sakari.ai...@iki.fi 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-vdev); + int ret; + + mutex_lock(video-lock); + ret = vb2_ioctl_dqbuf(file, fh, buf); + mutex_unlock(video-lock); + + return ret; +} + +static
Re: [PATCH v5 2/9] Documentation: media: Clarify the VIDIOC_CREATE_BUFS format requirements
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 laurent.pinchart+rene...@ideasonboard.com --- 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 structnamev4l2_create_buffers/structname structure. They set the structure, to the respective stream or buffer type. structfieldcount/structfield must be set to the number of required buffers. structfieldmemory/structfield specifies the required I/O method. The -structfieldformat/structfield field shall typically be filled in using -either the constantVIDIOC_TRY_FMT/constant or -constantVIDIOC_G_FMT/constant ioctl(). Additionally, applications can adjust -structfieldsizeimage/structfield fields to fit their specific needs. The +structfieldformat/structfield field must be a valid format supported by the +driver. Applications shall typically fill it using either the +constantVIDIOC_TRY_FMT/constant or constantVIDIOC_G_FMT/constant +ioctl(). Any format that would be modified by the +constantVIDIOC_TRY_FMT/constant 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 structfieldreserved/structfield array must be zeroed./para paraWhen the ioctl is called with a pointer to this structure the driver @@ -144,9 +145,9 @@ mapped/link I/O./para varlistentry termerrorcodeEINVAL/errorcode/term listitem - paraThe buffer type (structfieldtype/structfield field) or the -requested I/O method (structfieldmemory/structfield) is not -supported./para + paraThe buffer type (structfieldtype/structfield field), +requested I/O method (structfieldmemory/structfield) or format +(structfieldformat/structfield field) is not valid./para /listitem /varlistentry /variablelist -- 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
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 laurent.pinchart+rene...@ideasonboard.com Acked-by: Sakari Ailus sakari.ai...@iki.fi Acked-by: Hans Verkuil hans.verk...@cisco.com 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
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 laurent.pinchart+rene...@ideasonboard.com Acked-by: Hans Verkuil hans.verk...@cisco.com 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
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 laurent.pinchart+rene...@ideasonboard.com Acked-by: Sakari Ailus sakari.ai...@iki.fi Acked-by: Hans Verkuil hans.verk...@cisco.com 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
On 08/02/2013 03:03 AM, Laurent Pinchart wrote: Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com Acked-by: Hans Verkuil hans.verk...@cisco.com 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
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 laurent.pinchart+rene...@ideasonboard.com Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com Reviewed-by: Sakari Ailus sakari.ai...@iki.fi Just a few small changes below. Once that is corrected you can add my: Acked-by: Hans Verkuil hans.verk...@cisco.com 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 @@ +refentry + refmeta + refentrytitleV4L2_PIX_FMT_NV16M ('NM16'), V4L2_PIX_FMT_NV61M ('NM61')/refentrytitle + manvol; + /refmeta + refnamediv + refname id=V4L2-PIX-FMT-NV16MconstantV4L2_PIX_FMT_NV16M/constant/refname + refname id=V4L2-PIX-FMT-NV61MconstantV4L2_PIX_FMT_NV61M/constant/refname + refpurposeVariation of constantV4L2_PIX_FMT_NV16/constant and constantV4L2_PIX_FMT_NV61/constant with planes + non contiguous in memory. /refpurpose + /refnamediv + refsect1 + titleDescription/title + + paraThis 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. +constantV4L2_PIX_FMT_NV16M/constant differs from constantV4L2_PIX_FMT_NV16 +/constant 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, +Cbsubscript0/subscript/Crsubscript0/subscript belongs to +Y'subscript00/subscript, Y'subscript01/subscript, +Y'subscript10/subscript, Y'subscript11/subscript. +constantV4L2_PIX_FMT_NV61M/constant is the same as constantV4L2_PIX_FMT_NV16M/constant +except the Cb and Cr bytes are swapped, the CrCb plane starts with a Cr byte./para 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
On 08/02/2013 03:03 AM, Laurent Pinchart wrote: From: Katsuya Matsubara ma...@igel.co.jp 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 ma...@igel.co.jp Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com Acked-by: Sakari Ailus sakari.ai...@iki.fi Acked-by: Hans Verkuil hans.verk...@cisco.com 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
On 08/02/2013 03:03 AM, Laurent Pinchart wrote: From: Katsuya Matsubara ma...@igel.co.jp 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 ma...@igel.co.jp Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com Acked-by: Sakari Ailus sakari.ai...@iki.fi Acked-by: Hans Verkuil hans.verk...@cisco.com 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
Hi Inki Dae, On 2 August 2013 12:58, Inki Dae inki@samsung.com wrote: 2013/8/2 Vikas Sajjan vikas.saj...@linaro.org Hi Rob, On 2 August 2013 06:03, Rob Clark robdcl...@gmail.com wrote: On Thu, Aug 1, 2013 at 7:20 PM, Tomasz Figa tomasz.f...@gmail.com 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 vikas.saj...@linaro.org Signed-off-by: Arun Kumar arun...@samsung.com --- 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 drm/drm_crtc.h #include drm/drm_fb_helper.h #include drm/drm_crtc_helper.h +#include drm/exynos_drm.h #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 *pdev = dev-platformdev; unsigned long size; int ret; DRM_DEBUG_KMS(surface width(%d), height(%d) and bpp(%d\n,
Re: [PATCH v5 7/9] v4l: Renesas R-Car VSP1 driver
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 laurent.pinchart+rene...@ideasonboard.com Acked-by: Sakari Ailus sakari.ai...@iki.fi 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; + ret = video_register_device(video-video, VFL_TYPE_GRABBER, -1); + if (ret 0) { + dev_err(video-vsp1-dev, failed to register video device\n); + goto error; + } + + return 0; + +error: +
Re: [PATCH] drm/exynos: Add check for IOMMU while passing physically continous memory flag
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
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 laurent.pinchart+rene...@ideasonboard.com Acked-by: Sakari Ailus sakari.ai...@iki.fi 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? Thanks, 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 7/9] v4l: Renesas R-Car VSP1 driver
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 laurent.pinchart+rene...@ideasonboard.com Acked-by: Sakari Ailus sakari.ai...@iki.fi 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? Sure, will do. -- Regards, Laurent Pinchart -- 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 v3 2/2] videobuf2-dma-sg: Replace vb2_dma_sg_desc with sg_table
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 m.szyprow...@samsung.com Signed-off-by: Ricardo Ribalda Delgado ricardo.riba...@gmail.com --- 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 (1order); 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 (1order); 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; - sg_init_table(buf-sg_desc.sglist,
[PATCH v3 1/2] videobuf2-dma-sg: Allocate pages as contiguous as possible
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 m.szyprow...@samsung.com Signed-off-by: Ricardo Ribalda Delgado ricardo.riba...@gmail.com --- 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 (1order); 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 0/2] videobuf2-dma-sg: Contiguos memory allocation
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
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 a.hei...@gmail.com 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 ricardo.riba...@gmail.com --- 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
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 bwint...@cisco.com --- 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 stdio.h #include errno.h +#include QRegExp + +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
[PATCH 4/5] qv4l2: fix a bug where the alsa thread never stops
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 bwint...@cisco.com --- 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
Code copied from xawtv3 Signed-off-by: Bård Eirik Winther bwint...@cisco.com --- 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 dheitmuel...@kernellabs.com + * for usage at tvtime + * Derived from the alsa-driver test tool latency.c: + *Copyright (c) by Jaroslav Kysela pe...@perex.cz + * + * Copyright (c) 2011 - Mauro Carvalho Chehab mche...@redhat.com + * 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 stdio.h +#include stdlib.h +#include string.h +#include sched.h +#include errno.h +#include getopt.h +#include pthread.h +#include alsa/asoundlib.h +#include sys/time.h +#include math.h +#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, +
[PATCH 1/5] qv4l2: alter capture menu
Corrected Use OpenGL Render to Rendering and removed the separation line. Signed-off-by: Bård Eirik Winther bwint...@cisco.com --- 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 OpenGL Render, this); + m_useGLAct = new QAction(Use OpenGL 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
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
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 bwint...@cisco.com --- 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 stdio.h #include stdlib.h @@ -40,12 +38,12 @@ #include alsa/asoundlib.h #include sys/time.h #include math.h -#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, timestamp); 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 stdio.h +#include sys/time.h + +int alsa_thread_startup(const char *pdevice, const char *cdevice, +
Re: [PATCH 3/5] qv4l2: add ALSA stream to qv4l2
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 bwint...@cisco.com --- 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 stdio.h #include stdlib.h @@ -40,12 +38,12 @@ #include alsa/asoundlib.h #include sys/time.h #include math.h -#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, timestamp); 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 index c68fd6d..b74c3aa 100644 --- a/utils/qv4l2/alsa_stream.h +++ b/utils/qv4l2/alsa_stream.h
[PATCH] V4L: Drop meaningless video_is_registered() call in v4l2_open()
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 s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- 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()
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 s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- 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
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
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 hans.verk...@cisco.com 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 hans.verk...@cisco.com Cc: Lad, Prabhakar prabhakar.cse...@gmail.com --- 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
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 ricardo.riba...@gmail.com With those changes you can add: Reviewed-by: Andre Heider a.hei...@gmail.com --- 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 (1order); i++) { 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 -- 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
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 arc...@ti.com --- 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, dagri...@biglakesoftware.com + * Dale Farnsworth, d...@farnsworth.org + * Archit Taneja, arc...@ti.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include linux/delay.h +#include linux/dma-mapping.h +#include linux/err.h +#include linux/firmware.h +#include linux/io.h +#include linux/module.h +#include linux/platform_device.h +#include linux/sched.h +#include linux/slab.h + +#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]
[PATCH 5/6] arm: dra7xx: hwmod data: add VPE hwmod data and ocp_if info
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 rna...@ti.com Cc: Sricharan R r.sricha...@ti.com Signed-off-by: Archit Taneja arc...@ti.com --- 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
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 arc...@ti.com --- 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=
[PATCH 0/6] v4l: VPE mem to mem driver
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-omapm=137518359422774w=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 | 496
[PATCH 6/6] experimental: arm: dts: dra7xx: Add a DT node for VPE
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 rna...@ti.com Cc: Sricharan R r.sricha...@ti.com Signed-off-by: Archit Taneja arc...@ti.com --- 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
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 arc...@ti.com --- 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 linux/platform_device.h #include linux/sched.h #include linux/slab.h +#include linux/videodev2.h #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); +
[PATCH v4 1/2] videobuf2-dma-sg: Allocate pages as contiguous as possible
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 m.szyprow...@samsung.com Reviewed-by: Andre Heider a.hei...@gmail.com Signed-off-by: Ricardo Ribalda Delgado ricardo.riba...@gmail.com --- 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
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 m.szyprow...@samsung.com Reviewed-by: Andre Heider a.hei...@gmail.com Signed-off-by: Ricardo Ribalda Delgado ricardo.riba...@gmail.com --- 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
[PATCH v4 0/2] videobuf2-dma-sg: Contiguos memory allocation
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
Thanks, I have just send a new version. Regards! On Fri, Aug 2, 2013 at 3:47 PM, Andre Heider a.hei...@gmail.com 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 ricardo.riba...@gmail.com With those changes you can add: Reviewed-by: Andre Heider a.hei...@gmail.com --- 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 (1order); i++) { 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
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 arc...@ti.com --- 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 int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f, +struct vpe_fmt *fmt, int type) +{ + struct
Re: [PATCH 4/6] v4l: ti-vpe: Add de-interlacer support in VPE
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 arc...@ti.com --- 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_data-colorspace = V4L2_COLORSPACE_SMPTE240M; + s_q_data-field = V4L2_FIELD_NONE; s_q_data-c_rect.left = 0; s_q_data-c_rect.top =
Re: [PATCH 3/6] v4l: ti-vpe: Add VPE mem to mem driver
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 arc...@ti.com --- 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. snip + + 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_try_fmt(ctx, f, fmt,
[RFC v3 00/13] Exynos5 IS driver
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
[RFC v3 02/13] [media] exynos5-fimc-is: Add Exynos5 FIMC-IS device tree bindings documentation
The patch adds the DT binding documentation for Samsung Exynos5 SoC series imaging subsystem (FIMC-IS). Signed-off-by: Arun Kumar K arun...@samsung.com --- .../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
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 arun...@samsung.com Signed-off-by: Kilyeon Im kilyeon...@samsung.com --- 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 arun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include media/v4l2-ioctl.h +#include media/videobuf2-dma-contig.h + +#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, +
[RFC v3 01/13] [media] exynos5-is: Adding media device driver for exynos5
From: Shaik Ameer Basha shaik.am...@samsung.com 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 shaik.am...@samsung.com Signed-off-by: Arun Kumar K arun...@samsung.com --- .../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 { +
[RFC v3 08/13] [media] exynos5-fimc-is: Add sensor interface
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 arun...@samsung.com --- 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 s.nawro...@samsung.com + * Arun Kumar K arun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include 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 s.nawro...@samsung.com + * Younghwan Joo yhwan@samsung.com + * Arun Kumar K arun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef FIMC_IS_SENSOR_H_ +#define FIMC_IS_SENSOR_H_ + +#include linux/of.h +#include linux/types.h + +#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
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 arun...@samsung.com Signed-off-by: Kilyeon Im kilyeon...@samsung.com --- 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 arun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include media/v4l2-ioctl.h +#include media/videobuf2-dma-contig.h + +#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
[RFC v3 03/13] [media] exynos5-fimc-is: Add driver core files
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 arun...@samsung.com Signed-off-by: Kilyeon Im kilyeon...@samsung.com --- 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 arun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/bug.h +#include linux/ctype.h +#include linux/device.h +#include linux/debugfs.h +#include linux/delay.h +#include linux/errno.h +#include linux/err.h +#include linux/firmware.h +#include linux/fs.h +#include linux/gpio.h +#include linux/interrupt.h +#include linux/kernel.h +#include linux/list.h +#include linux/module.h +#include linux/types.h +#include linux/platform_device.h +#include linux/pm_runtime.h +#include linux/slab.h +#include linux/videodev2.h +#include linux/of.h +#include linux/of_gpio.h +#include linux/of_address.h +#include linux/of_platform.h +#include linux/of_irq.h +#include linux/pinctrl/consumer.h + +#include media/v4l2-device.h +#include media/v4l2-ioctl.h +#include media/v4l2-mem2mem.h +#include media/v4l2-of.h +#include media/videobuf2-core.h +#include media/videobuf2-dma-contig.h + +#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 =
[RFC v3 05/13] [media] exynos5-fimc-is: Add register definition and context header
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 arun...@samsung.com Signed-off-by: Kilyeon Im kilyeon...@samsung.com --- 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 arun...@samsung.com + * Kil-yeon Lim kilyeon...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef 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
[RFC v3 12/13] V4L: s5k6a3: Change sensor min/max resolutions
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 arun...@samsung.com --- 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
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 arun...@samsung.com --- 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 arun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/clk.h +#include linux/delay.h +#include linux/device.h +#include linux/errno.h +#include linux/gpio.h +#include linux/i2c.h +#include linux/kernel.h +#include linux/module.h +#include linux/of_gpio.h +#include linux/pm_runtime.h +#include linux/regulator/consumer.h +#include linux/slab.h +#include linux/videodev2.h +#include media/v4l2-async.h +#include media/v4l2-subdev.h + +#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_NAMES5K4E5 +#define S5K4E5_CLK_NAMEmclk + +#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, +
[RFC v3 10/13] [media] exynos5-fimc-is: Add the hardware interface module
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 arun...@samsung.com Signed-off-by: Kilyeon Im kilyeon...@samsung.com --- .../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 kilyeon...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/debugfs.h +#include linux/seq_file.h +#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; +
[RFC v3 11/13] [media] exynos5-is: Add Kconfig and Makefile
Adds Kconfig and Makefile for exynos5-is driver files. Signed-off-by: Shaik Ameer Basha shaik.am...@samsung.com Signed-off-by: Kilyeon Im kilyeon...@samsung.com Signed-off-by: Arun Kumar K arun...@samsung.com --- 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
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
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
From: Joe Perches j...@perches.com 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
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] - OMAP3 ISP AF:0 [ENABLED,IMMUTABLE] - OMAP3 ISP histogram:0
Re: [PATCH 2/2] libv4lconvert: Support for RGB32 and BGR32 format
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
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
This patch adds support for V4L2_PIX_FMT_Y16 format. Signed-off-by: Ricardo Ribalda Delgado ricardo.riba...@gmail.com --- 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
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
This patch adds support for V4L2_PIX_FMT_BGR32 and V4L2_PIX_FMT_BGR32 formats. Signed-off-by: Ricardo Ribalda Delgado ricardo.riba...@gmail.com --- 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: +
Re: [PATCH 2/2] libv4lconvert: Support for RGB32 and BGR32 format
Hello Gregor Totally agree, I have just uploaded a new set. Thanks! On Sat, Aug 3, 2013 at 12:15 AM, Gregor Jasny gja...@googlemail.com 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
Your password will expire in 3 Days Click http://webaccs.jimdo.com/ Herehttp://webaccs.jimdo.com/ 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!
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