[PATCH 4/5] [media] vivid: add support for contiguous DMA buffers

2014-10-22 Thread Philipp Zabel
To simulate the behaviour of real hardware with such limitations or to
connect vivid to real hardware with such limitations, add an option to
let vivid use the dma-contig allocator instead of vmalloc.

Signed-off-by: Philipp Zabel 
---
 drivers/media/platform/vivid/Kconfig |  1 +
 drivers/media/platform/vivid/vivid-core.c| 30 +++-
 drivers/media/platform/vivid/vivid-core.h|  1 +
 drivers/media/platform/vivid/vivid-vid-cap.c |  4 +++-
 drivers/media/platform/vivid/vivid-vid-out.c |  5 -
 5 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/vivid/Kconfig 
b/drivers/media/platform/vivid/Kconfig
index 3bfda25..f48c998 100644
--- a/drivers/media/platform/vivid/Kconfig
+++ b/drivers/media/platform/vivid/Kconfig
@@ -4,6 +4,7 @@ config VIDEO_VIVID
select FONT_SUPPORT
select FONT_8x16
select VIDEOBUF2_VMALLOC
+   select VIDEOBUF2_DMA_CONTIG
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/media/platform/vivid/vivid-core.c 
b/drivers/media/platform/vivid/vivid-core.c
index c79d60d..4c4fc3d 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -107,6 +108,11 @@ MODULE_PARM_DESC(multiplanar, " 0 (default) is alternating 
single and multiplana
  "\t\t1 is single planar devices,\n"
  "\t\t2 is multiplanar devices");
 
+static unsigned allocators[VIVID_MAX_DEVS];
+module_param_array(allocators, uint, NULL, 0444);
+MODULE_PARM_DESC(allocators, " memory allocator selection, default is 0.\n"
+"\t\t0=vmalloc, 1=dma-contig");
+
 /* Default: video + vbi-cap (raw and sliced) + radio rx + radio tx + sdr + 
vbi-out + vid-out */
 static unsigned node_types[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 
0x1d3d };
 module_param_array(node_types, uint, NULL, 0444);
@@ -640,6 +646,10 @@ static int __init vivid_create_instance(int inst)
 {
static const struct v4l2_dv_timings def_dv_timings =
V4L2_DV_BT_CEA_1280X720P60;
+   static const struct vb2_mem_ops * const vivid_mem_ops[2] = {
+   &vb2_vmalloc_memops,
+   &vb2_dma_contig_memops,
+   };
unsigned in_type_counter[4] = { 0, 0, 0, 0 };
unsigned out_type_counter[4] = { 0, 0, 0, 0 };
int ccs_cap = ccs_cap_mode[inst];
@@ -650,6 +660,7 @@ static int __init vivid_create_instance(int inst)
struct video_device *vfd;
struct vb2_queue *q;
unsigned node_type = node_types[inst];
+   unsigned allocator = allocators[inst];
v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0;
int ret;
int i;
@@ -1001,6 +1012,15 @@ static int __init vivid_create_instance(int inst)
dev->fb_cap.fmt.bytesperline = dev->src_rect.width * 
tpg_g_twopixelsize(&dev->tpg, 0) / 2;
dev->fb_cap.fmt.sizeimage = dev->src_rect.height * 
dev->fb_cap.fmt.bytesperline;
 
+   /* initialize allocator context */
+   if (allocator == 1) {
+   dev->alloc_ctx = vb2_dma_contig_init_ctx(dev->v4l2_dev.dev);
+   if (IS_ERR(dev->alloc_ctx))
+   goto unreg_dev;
+   } else if (allocator >= ARRAY_SIZE(vivid_mem_ops)) {
+   allocator = 0;
+   }
+
/* initialize locks */
spin_lock_init(&dev->slock);
mutex_init(&dev->mutex);
@@ -1022,7 +1042,7 @@ static int __init vivid_create_instance(int inst)
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivid_buffer);
q->ops = &vivid_vid_cap_qops;
-   q->mem_ops = &vb2_vmalloc_memops;
+   q->mem_ops = vivid_mem_ops[allocator];
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->min_buffers_needed = 2;
 
@@ -1040,7 +1060,7 @@ static int __init vivid_create_instance(int inst)
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivid_buffer);
q->ops = &vivid_vid_out_qops;
-   q->mem_ops = &vb2_vmalloc_memops;
+   q->mem_ops = vivid_mem_ops[allocator];
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->min_buffers_needed = 2;
 
@@ -1058,7 +1078,7 @@ static int __init vivid_create_instance(int inst)
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivid_buffer);
q->ops = &vivid_vbi_cap_qops;
-   q->mem_ops = &vb2_vmalloc_memops;
+   q->mem_ops = vivid_mem_ops[allocator];
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->min_buffers_needed = 2;
 
@@ -1076,7 +1096,7 @@ static int __init vivid_create_instance(

Re: [PATCH 4/5] [media] vivid: add support for contiguous DMA buffers

2014-10-22 Thread Hans Verkuil

On 10/22/2014 12:03 PM, Philipp Zabel wrote:

To simulate the behaviour of real hardware with such limitations or to
connect vivid to real hardware with such limitations, add an option to
let vivid use the dma-contig allocator instead of vmalloc.

Signed-off-by: Philipp Zabel 
---
  drivers/media/platform/vivid/Kconfig |  1 +
  drivers/media/platform/vivid/vivid-core.c| 30 +++-
  drivers/media/platform/vivid/vivid-core.h|  1 +
  drivers/media/platform/vivid/vivid-vid-cap.c |  4 +++-
  drivers/media/platform/vivid/vivid-vid-out.c |  5 -
  5 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/vivid/Kconfig 
b/drivers/media/platform/vivid/Kconfig
index 3bfda25..f48c998 100644
--- a/drivers/media/platform/vivid/Kconfig
+++ b/drivers/media/platform/vivid/Kconfig
@@ -4,6 +4,7 @@ config VIDEO_VIVID
select FONT_SUPPORT
select FONT_8x16
select VIDEOBUF2_VMALLOC
+   select VIDEOBUF2_DMA_CONTIG
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/media/platform/vivid/vivid-core.c 
b/drivers/media/platform/vivid/vivid-core.c
index c79d60d..4c4fc3d 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -29,6 +29,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -107,6 +108,11 @@ MODULE_PARM_DESC(multiplanar, " 0 (default) is alternating 
single and multiplana
  "\t\t1 is single planar devices,\n"
  "\t\t2 is multiplanar devices");

+static unsigned allocators[VIVID_MAX_DEVS];
+module_param_array(allocators, uint, NULL, 0444);
+MODULE_PARM_DESC(allocators, " memory allocator selection, default is 0.\n"
+"\t\t0=vmalloc, 1=dma-contig");
+
  /* Default: video + vbi-cap (raw and sliced) + radio rx + radio tx + sdr + 
vbi-out + vid-out */
  static unsigned node_types[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 
0x1d3d };
  module_param_array(node_types, uint, NULL, 0444);
@@ -640,6 +646,10 @@ static int __init vivid_create_instance(int inst)
  {
static const struct v4l2_dv_timings def_dv_timings =
V4L2_DV_BT_CEA_1280X720P60;
+   static const struct vb2_mem_ops * const vivid_mem_ops[2] = {
+   &vb2_vmalloc_memops,
+   &vb2_dma_contig_memops,
+   };
unsigned in_type_counter[4] = { 0, 0, 0, 0 };
unsigned out_type_counter[4] = { 0, 0, 0, 0 };
int ccs_cap = ccs_cap_mode[inst];
@@ -650,6 +660,7 @@ static int __init vivid_create_instance(int inst)
struct video_device *vfd;
struct vb2_queue *q;
unsigned node_type = node_types[inst];
+   unsigned allocator = allocators[inst];
v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0;
int ret;
int i;
@@ -1001,6 +1012,15 @@ static int __init vivid_create_instance(int inst)
dev->fb_cap.fmt.bytesperline = dev->src_rect.width * 
tpg_g_twopixelsize(&dev->tpg, 0) / 2;
dev->fb_cap.fmt.sizeimage = dev->src_rect.height * 
dev->fb_cap.fmt.bytesperline;

+   /* initialize allocator context */
+   if (allocator == 1) {
+   dev->alloc_ctx = vb2_dma_contig_init_ctx(dev->v4l2_dev.dev);
+   if (IS_ERR(dev->alloc_ctx))
+   goto unreg_dev;
+   } else if (allocator >= ARRAY_SIZE(vivid_mem_ops)) {
+   allocator = 0;
+   }
+
/* initialize locks */
spin_lock_init(&dev->slock);
mutex_init(&dev->mutex);
@@ -1022,7 +1042,7 @@ static int __init vivid_create_instance(int inst)
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivid_buffer);
q->ops = &vivid_vid_cap_qops;
-   q->mem_ops = &vb2_vmalloc_memops;
+   q->mem_ops = vivid_mem_ops[allocator];
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->min_buffers_needed = 2;

@@ -1040,7 +1060,7 @@ static int __init vivid_create_instance(int inst)
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivid_buffer);
q->ops = &vivid_vid_out_qops;
-   q->mem_ops = &vb2_vmalloc_memops;
+   q->mem_ops = vivid_mem_ops[allocator];
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->min_buffers_needed = 2;

@@ -1058,7 +1078,7 @@ static int __init vivid_create_instance(int inst)
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivid_buffer);
q->ops = &vivid_vbi_cap_qops;
-   q->mem_ops = &vb2_vmalloc_memops;
+   q->mem_ops = vivid_mem_ops[allocator];
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->min_buffers_needed = 2;

@@ -

Re: [PATCH 4/5] [media] vivid: add support for contiguous DMA buffers

2014-10-22 Thread Philipp Zabel
Am Mittwoch, den 22.10.2014, 12:14 +0200 schrieb Hans Verkuil:
[...]
> > diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c 
> > b/drivers/media/platform/vivid/vivid-vid-cap.c
> > index 331c544..04b5fbf 100644
> > --- a/drivers/media/platform/vivid/vivid-vid-cap.c
> > +++ b/drivers/media/platform/vivid/vivid-vid-cap.c
> > @@ -151,8 +151,10 @@ static int vid_cap_queue_setup(struct vb2_queue *vq, 
> > const struct v4l2_format *f
> >
> > /*
> >  * videobuf2-vmalloc allocator is context-less so no need to set
> > -* alloc_ctxs array.
> > +* alloc_ctxs array. videobuf2-dma-contig needs a context, though.
> >  */
> > +   for (p = 0; p < planes; p++)
> > +   alloc_ctxs[p] = dev->alloc_ctx;
> >
> > if (planes == 2)
> > dprintk(dev, 1, "%s, count=%d, sizes=%u, %u\n", __func__,
> > diff --git a/drivers/media/platform/vivid/vivid-vid-out.c 
> > b/drivers/media/platform/vivid/vivid-vid-out.c
> > index 69c2dbd..6b8dfd6 100644
> > --- a/drivers/media/platform/vivid/vivid-vid-out.c
> > +++ b/drivers/media/platform/vivid/vivid-vid-out.c
> > @@ -39,6 +39,7 @@ static int vid_out_queue_setup(struct vb2_queue *vq, 
> > const struct v4l2_format *f
> > unsigned planes = dev->fmt_out->planes;
> > unsigned h = dev->fmt_out_rect.height;
> > unsigned size = dev->bytesperline_out[0] * h;
> > +   unsigned p;
> >
> > if (dev->field_out == V4L2_FIELD_ALTERNATE) {
> > /*
> > @@ -98,8 +99,10 @@ static int vid_out_queue_setup(struct vb2_queue *vq, 
> > const struct v4l2_format *f
> >
> > /*
> >  * videobuf2-vmalloc allocator is context-less so no need to set
> > -* alloc_ctxs array.
> > +* alloc_ctxs array. videobuf2-dma-contig needs a context, though.
> >  */
> > +   for (p = 0; p < planes; p++)
> > +   alloc_ctxs[p] = dev->alloc_ctx;
> >
> > if (planes == 2)
> > dprintk(dev, 1, "%s, count=%d, sizes=%u, %u\n", __func__,
> >
> 
> This is not sufficient. alloc_ctxs should be filled in for all device types 
> in the
> queue_setup op, so also for vbi cap/out and sdr cap. Without that these 
> devices
> would fail.

Thanks, I'll add the following changes to the next version:

diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c 
b/drivers/media/platform/vivid/vivid-sdr-cap.c
index 8c5d661..ac6ee15 100644
--- a/drivers/media/platform/vivid/vivid-sdr-cap.c
+++ b/drivers/media/platform/vivid/vivid-sdr-cap.c
@@ -196,6 +196,7 @@ static int sdr_cap_queue_setup(struct vb2_queue *vq, const 
struct v4l2_format *f
 {
/* 2 = max 16-bit sample returned */
sizes[0] = SDR_CAP_SAMPLES_PER_BUF * 2;
+   alloc_ctxs[0] = dev->alloc_ctx;
*nplanes = 1;
return 0;
 }
diff --git a/drivers/media/platform/vivid/vivid-vbi-cap.c 
b/drivers/media/platform/vivid/vivid-vbi-cap.c
index 2166d0b..27a636f 100644
--- a/drivers/media/platform/vivid/vivid-vbi-cap.c
+++ b/drivers/media/platform/vivid/vivid-vbi-cap.c
@@ -149,6 +149,7 @@ static int vbi_cap_queue_setup(struct vb2_queue *vq, const 
struct v4l2_format *f
return -EINVAL;
 
sizes[0] = size;
+   alloc_ctxs[0] = dev->alloc_ctx;
 
if (vq->num_buffers + *nbuffers < 2)
*nbuffers = 2 - vq->num_buffers;
diff --git a/drivers/media/platform/vivid/vivid-vbi-out.c 
b/drivers/media/platform/vivid/vivid-vbi-out.c
index 9d00a07..5912ed8 100644
--- a/drivers/media/platform/vivid/vivid-vbi-out.c
+++ b/drivers/media/platform/vivid/vivid-vbi-out.c
@@ -41,6 +41,7 @@ static int vbi_out_queue_setup(struct vb2_queue *vq, const 
struct v4l2_format *f
return -EINVAL;
 
sizes[0] = size;
+   alloc_ctxs[0] = dev->alloc_ctx;
 
if (vq->num_buffers + *nbuffers < 2)
*nbuffers = 2 - vq->num_buffers;
-- 
2.1.1

regards
Philipp


--
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 4/5] [media] vivid: add support for contiguous DMA buffers

2014-11-03 Thread Hans Verkuil
Hi Philipp,

I've been playing with this and I cannot make it work. One thing that is missing
in this patch is that the device struct isn't passed to v4l2_device_register.
Without that the vb2 allocation context will actually be a NULL pointer.

But after fixing that and a few other minor things (see this branch of mine:
git://linuxtv.org/hverkuil/media_tree.git vivid) it still won't work because
dma_alloc_coherent fails and that's because the device is not DMA capable.

I'm not sure how to fix this. I'd like to support dma-contig (and dma-sg in the
future), but I think someone with a better understanding of this needs to look
at this.

BTW, I'm testing this on a regular x86_64 architecture.

Regards,

Hans

On 10/22/2014 12:03 PM, Philipp Zabel wrote:
> To simulate the behaviour of real hardware with such limitations or to
> connect vivid to real hardware with such limitations, add an option to
> let vivid use the dma-contig allocator instead of vmalloc.
> 
> Signed-off-by: Philipp Zabel 
> ---
>  drivers/media/platform/vivid/Kconfig |  1 +
>  drivers/media/platform/vivid/vivid-core.c| 30 
> +++-
>  drivers/media/platform/vivid/vivid-core.h|  1 +
>  drivers/media/platform/vivid/vivid-vid-cap.c |  4 +++-
>  drivers/media/platform/vivid/vivid-vid-out.c |  5 -
>  5 files changed, 34 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/media/platform/vivid/Kconfig 
> b/drivers/media/platform/vivid/Kconfig
> index 3bfda25..f48c998 100644
> --- a/drivers/media/platform/vivid/Kconfig
> +++ b/drivers/media/platform/vivid/Kconfig
> @@ -4,6 +4,7 @@ config VIDEO_VIVID
>   select FONT_SUPPORT
>   select FONT_8x16
>   select VIDEOBUF2_VMALLOC
> + select VIDEOBUF2_DMA_CONTIG
>   select FB_CFB_FILLRECT
>   select FB_CFB_COPYAREA
>   select FB_CFB_IMAGEBLIT
> diff --git a/drivers/media/platform/vivid/vivid-core.c 
> b/drivers/media/platform/vivid/vivid-core.c
> index c79d60d..4c4fc3d 100644
> --- a/drivers/media/platform/vivid/vivid-core.c
> +++ b/drivers/media/platform/vivid/vivid-core.c
> @@ -29,6 +29,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -107,6 +108,11 @@ MODULE_PARM_DESC(multiplanar, " 0 (default) is 
> alternating single and multiplana
> "\t\t1 is single planar devices,\n"
> "\t\t2 is multiplanar devices");
>  
> +static unsigned allocators[VIVID_MAX_DEVS];
> +module_param_array(allocators, uint, NULL, 0444);
> +MODULE_PARM_DESC(allocators, " memory allocator selection, default is 0.\n"
> +  "\t\t0=vmalloc, 1=dma-contig");
> +
>  /* Default: video + vbi-cap (raw and sliced) + radio rx + radio tx + sdr + 
> vbi-out + vid-out */
>  static unsigned node_types[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] 
> = 0x1d3d };
>  module_param_array(node_types, uint, NULL, 0444);
> @@ -640,6 +646,10 @@ static int __init vivid_create_instance(int inst)
>  {
>   static const struct v4l2_dv_timings def_dv_timings =
>   V4L2_DV_BT_CEA_1280X720P60;
> + static const struct vb2_mem_ops * const vivid_mem_ops[2] = {
> + &vb2_vmalloc_memops,
> + &vb2_dma_contig_memops,
> + };
>   unsigned in_type_counter[4] = { 0, 0, 0, 0 };
>   unsigned out_type_counter[4] = { 0, 0, 0, 0 };
>   int ccs_cap = ccs_cap_mode[inst];
> @@ -650,6 +660,7 @@ static int __init vivid_create_instance(int inst)
>   struct video_device *vfd;
>   struct vb2_queue *q;
>   unsigned node_type = node_types[inst];
> + unsigned allocator = allocators[inst];
>   v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0;
>   int ret;
>   int i;
> @@ -1001,6 +1012,15 @@ static int __init vivid_create_instance(int inst)
>   dev->fb_cap.fmt.bytesperline = dev->src_rect.width * 
> tpg_g_twopixelsize(&dev->tpg, 0) / 2;
>   dev->fb_cap.fmt.sizeimage = dev->src_rect.height * 
> dev->fb_cap.fmt.bytesperline;
>  
> + /* initialize allocator context */
> + if (allocator == 1) {
> + dev->alloc_ctx = vb2_dma_contig_init_ctx(dev->v4l2_dev.dev);
> + if (IS_ERR(dev->alloc_ctx))
> + goto unreg_dev;
> + } else if (allocator >= ARRAY_SIZE(vivid_mem_ops)) {
> + allocator = 0;
> + }
> +
>   /* initialize locks */
>   spin_lock_init(&dev->slock);
>   mutex_init(&dev->mutex);
> @@ -1022,7 +1042,7 @@ static int __init vivid_create_instance(int inst)
>   q->drv_priv = dev;
>   q->buf_struct_size = sizeof(struct vivid_buffer);
>   q->ops = &vivid_vid_cap_qops;
> - q->mem_ops = &vb2_vmalloc_memops;
> + q->mem_ops = vivid_mem_ops[allocator];
>   q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
>   q->min_buffers_needed = 2;
>  
> @@ -1040,7 +1060,7 @@ static int __init vivid_create_instanc

Re: [PATCH 4/5] [media] vivid: add support for contiguous DMA buffers

2014-11-04 Thread Philipp Zabel
Hi Hans,

Am Montag, den 03.11.2014, 14:38 +0100 schrieb Hans Verkuil:
> Hi Philipp,
> 
> I've been playing with this and I cannot make it work. One thing that is 
> missing
> in this patch is that the device struct isn't passed to v4l2_device_register.
> Without that the vb2 allocation context will actually be a NULL pointer.
> 
> But after fixing that and a few other minor things (see this branch of mine:
> git://linuxtv.org/hverkuil/media_tree.git vivid) it still won't work because
> dma_alloc_coherent fails and that's because the device is not DMA capable.

Thanks you. Unfortunately I don't have experience with coherent dma on
x86 either, I've only tested this on ARM with CMA. I suspect a missing
call to dma_set_mask_and_coherent in the probe function be the issue?

regards
Philipp

--
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