Discussion:
[PATCH 4/5] [media] vivid: add support for contiguous DMA buffers
(too old to reply)
Philipp Zabel
2014-10-22 10:03:40 UTC
Permalink
Raw Message
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 <***@pengutronix.de>
---
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 <linux/platform_device.h>
#include <linux/videodev2.h>
#include <linux/v4l2-dv-timings.h>
+#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-vmalloc.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-ioctl.h>
@@ -107,6 +108,11 @@ MODULE_PARM_DESC(multiplanar, " 0 (default) is alternating single and multiplana
"\t\t 1 is single planar devices,\n"
"\t\t 2 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\t 0=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(int inst)
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivid_buffer);
q->ops = &vivid_vbi_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;

@@ -1093,7 +1113,7 @@ static int __init vivid_create_instance(int inst)
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivid_buffer);
q->ops = &vivid_sdr_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 = 8;

diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
index 811c286..4fefb0d 100644
--- a/drivers/media/platform/vivid/vivid-core.h
+++ b/drivers/media/platform/vivid/vivid-core.h
@@ -142,6 +142,7 @@ struct vivid_dev {
struct v4l2_ctrl_handler ctrl_hdl_radio_tx;
struct video_device sdr_cap_dev;
struct v4l2_ctrl_handler ctrl_hdl_sdr_cap;
+ struct vb2_alloc_ctx *alloc_ctx;
spinlock_t slock;
struct mutex mutex;

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__,
--
2.1.1
Philipp Zabel
2014-10-22 10:03:41 UTC
Permalink
Raw Message
Instances created with allocators == 1 use videobuf2-dma-contig, and are
able to export DMA buffers via VIDIOC_EXPBUF.

Signed-off-by: Philipp Zabel <***@pengutronix.de>
---
drivers/media/platform/vivid/vivid-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
index 4c4fc3d..695286b 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -596,7 +596,7 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = {
.vidioc_querybuf = vb2_ioctl_querybuf,
.vidioc_qbuf = vb2_ioctl_qbuf,
.vidioc_dqbuf = vb2_ioctl_dqbuf,
-/* Not yet .vidioc_expbuf = vb2_ioctl_expbuf,*/
+ .vidioc_expbuf = vb2_ioctl_expbuf,
.vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff,
--
2.1.1
Hans Verkuil
2014-10-22 10:15:48 UTC
Permalink
Raw Message
Post by Philipp Zabel
Instances created with allocators == 1 use videobuf2-dma-contig, and are
able to export DMA buffers via VIDIOC_EXPBUF.
Can you test what happens if you use EXPBUF when vmalloc is used? I hope it
will just fail, but I am not sure.

Regards,

Hans
Post by Philipp Zabel
---
drivers/media/platform/vivid/vivid-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
index 4c4fc3d..695286b 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -596,7 +596,7 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = {
.vidioc_querybuf = vb2_ioctl_querybuf,
.vidioc_qbuf = vb2_ioctl_qbuf,
.vidioc_dqbuf = vb2_ioctl_dqbuf,
-/* Not yet .vidioc_expbuf = vb2_ioctl_expbuf,*/
+ .vidioc_expbuf = vb2_ioctl_expbuf,
.vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff,
Philipp Zabel
2014-10-22 10:03:37 UTC
Permalink
Raw Message
The OSD simulation uses the framebuffer core functions, so vivid needs to
select the corresponding configuration options.

Signed-off-by: Philipp Zabel <***@pengutronix.de>
---
drivers/media/platform/vivid/Kconfig | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig
index d71139a..3bfda25 100644
--- a/drivers/media/platform/vivid/Kconfig
+++ b/drivers/media/platform/vivid/Kconfig
@@ -4,6 +4,9 @@ config VIDEO_VIVID
select FONT_SUPPORT
select FONT_8x16
select VIDEOBUF2_VMALLOC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
default n
---help---
Enables a virtual video driver. This driver emulates a webcam,
--
2.1.1
Hans Verkuil
2014-10-22 10:07:50 UTC
Permalink
Raw Message
Superseded. Already part of a pull request for 3.18.

But thanks anyway :-)

Hans
Post by Philipp Zabel
The OSD simulation uses the framebuffer core functions, so vivid needs to
select the corresponding configuration options.
---
drivers/media/platform/vivid/Kconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig
index d71139a..3bfda25 100644
--- a/drivers/media/platform/vivid/Kconfig
+++ b/drivers/media/platform/vivid/Kconfig
@@ -4,6 +4,9 @@ config VIDEO_VIVID
select FONT_SUPPORT
select FONT_8x16
select VIDEOBUF2_VMALLOC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
default n
---help---
Enables a virtual video driver. This driver emulates a webcam,
Philipp Zabel
2014-10-22 10:03:38 UTC
Permalink
Raw Message
The videobuf2-vmalloc header is not used by the changed files, so remove it.

Signed-off-by: Philipp Zabel <***@pengutronix.de>
---
drivers/media/platform/vivid/vivid-kthread-cap.c | 1 -
drivers/media/platform/vivid/vivid-kthread-out.c | 1 -
drivers/media/platform/vivid/vivid-osd.c | 1 -
3 files changed, 3 deletions(-)

diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c
index 39a67cf..65e5f76 100644
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
+++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
@@ -31,7 +31,6 @@
#include <linux/random.h>
#include <linux/v4l2-dv-timings.h>
#include <asm/div64.h>
-#include <media/videobuf2-vmalloc.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-fh.h>
diff --git a/drivers/media/platform/vivid/vivid-kthread-out.c b/drivers/media/platform/vivid/vivid-kthread-out.c
index d9f36cc..6da0e01 100644
--- a/drivers/media/platform/vivid/vivid-kthread-out.c
+++ b/drivers/media/platform/vivid/vivid-kthread-out.c
@@ -31,7 +31,6 @@
#include <linux/random.h>
#include <linux/v4l2-dv-timings.h>
#include <asm/div64.h>
-#include <media/videobuf2-vmalloc.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-fh.h>
diff --git a/drivers/media/platform/vivid/vivid-osd.c b/drivers/media/platform/vivid/vivid-osd.c
index 084d346..c90cf13 100644
--- a/drivers/media/platform/vivid/vivid-osd.c
+++ b/drivers/media/platform/vivid/vivid-osd.c
@@ -29,7 +29,6 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/fb.h>
-#include <media/videobuf2-vmalloc.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
--
2.1.1
Hans Verkuil
2014-10-22 10:08:32 UTC
Permalink
Raw Message
Post by Philipp Zabel
The videobuf2-vmalloc header is not used by the changed files, so remove it.
---
drivers/media/platform/vivid/vivid-kthread-cap.c | 1 -
drivers/media/platform/vivid/vivid-kthread-out.c | 1 -
drivers/media/platform/vivid/vivid-osd.c | 1 -
3 files changed, 3 deletions(-)
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c
index 39a67cf..65e5f76 100644
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
+++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
@@ -31,7 +31,6 @@
#include <linux/random.h>
#include <linux/v4l2-dv-timings.h>
#include <asm/div64.h>
-#include <media/videobuf2-vmalloc.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-fh.h>
diff --git a/drivers/media/platform/vivid/vivid-kthread-out.c b/drivers/media/platform/vivid/vivid-kthread-out.c
index d9f36cc..6da0e01 100644
--- a/drivers/media/platform/vivid/vivid-kthread-out.c
+++ b/drivers/media/platform/vivid/vivid-kthread-out.c
@@ -31,7 +31,6 @@
#include <linux/random.h>
#include <linux/v4l2-dv-timings.h>
#include <asm/div64.h>
-#include <media/videobuf2-vmalloc.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-fh.h>
diff --git a/drivers/media/platform/vivid/vivid-osd.c b/drivers/media/platform/vivid/vivid-osd.c
index 084d346..c90cf13 100644
--- a/drivers/media/platform/vivid/vivid-osd.c
+++ b/drivers/media/platform/vivid/vivid-osd.c
@@ -29,7 +29,6 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/fb.h>
-#include <media/videobuf2-vmalloc.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
Philipp Zabel
2014-10-22 10:03:39 UTC
Permalink
Raw Message
For contiguous DMA buffer allocation, a struct is needed that
DMA buffers can be associated with.

Signed-off-by: Philipp Zabel <***@pengutronix.de>
---
drivers/media/platform/vivid/vivid-core.c | 37 +++++++++++++++++++++++++++++--
1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
index 2c61a62..c79d60d 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -26,6 +26,7 @@
#include <linux/vmalloc.h>
#include <linux/font.h>
#include <linux/mutex.h>
+#include <linux/platform_device.h>
#include <linux/videodev2.h>
#include <linux/v4l2-dv-timings.h>
#include <media/videobuf2-vmalloc.h>
@@ -152,6 +153,7 @@ module_param(no_error_inj, bool, 0444);
MODULE_PARM_DESC(no_error_inj, " if set disable the error injecting controls");

static struct vivid_dev *vivid_devs[VIVID_MAX_DEVS];
+static struct platform_device *vivid_pdev;

const struct v4l2_rect vivid_min_rect = {
0, 0, MIN_WIDTH, MIN_HEIGHT
@@ -1288,7 +1290,7 @@ free_dev:
will succeed. This is limited to the maximum number of devices that
videodev supports, which is equal to VIDEO_NUM_DEVICES.
*/
-static int __init vivid_init(void)
+static int vivid_probe(struct platform_device *pdev)
{
const struct font_desc *font = find_font("VGA8x16");
int ret = 0, i;
@@ -1323,7 +1325,7 @@ static int __init vivid_init(void)
return ret;
}

-static void __exit vivid_exit(void)
+static int vivid_remove(struct platform_device *pdev)
{
struct vivid_dev *dev;
unsigned i;
@@ -1384,6 +1386,37 @@ static void __exit vivid_exit(void)
kfree(dev);
vivid_devs[i] = NULL;
}
+
+ return 0;
+}
+
+struct platform_driver vivid_driver = {
+ .probe = vivid_probe,
+ .remove = vivid_remove,
+ .driver = {
+ .name = "vivid",
+ },
+};
+
+static int __init vivid_init(void)
+{
+ int ret;
+
+ vivid_pdev = platform_device_register_simple("vivid", -1, NULL, 0);
+ if (IS_ERR(vivid_pdev))
+ return PTR_ERR(vivid_pdev);
+
+ ret = platform_driver_register(&vivid_driver);
+ if (ret != 0)
+ platform_device_unregister(vivid_pdev);
+
+ return ret;
+}
+
+static void __exit vivid_exit(void)
+{
+ platform_device_unregister(vivid_pdev);
+ platform_driver_unregister(&vivid_driver);
}

module_init(vivid_init);
--
2.1.1
Hans Verkuil
2014-10-22 10:10:06 UTC
Permalink
Raw Message
Post by Philipp Zabel
For contiguous DMA buffer allocation, a struct is needed that
DMA buffers can be associated with.
Acked-by: Hans Verkuil <***@cisco.com>

Nice! I was planning something like that myself.

Regards,

Hans
Post by Philipp Zabel
---
drivers/media/platform/vivid/vivid-core.c | 37 +++++++++++++++++++++++++++++--
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
index 2c61a62..c79d60d 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -26,6 +26,7 @@
#include <linux/vmalloc.h>
#include <linux/font.h>
#include <linux/mutex.h>
+#include <linux/platform_device.h>
#include <linux/videodev2.h>
#include <linux/v4l2-dv-timings.h>
#include <media/videobuf2-vmalloc.h>
@@ -152,6 +153,7 @@ module_param(no_error_inj, bool, 0444);
MODULE_PARM_DESC(no_error_inj, " if set disable the error injecting controls");
static struct vivid_dev *vivid_devs[VIVID_MAX_DEVS];
+static struct platform_device *vivid_pdev;
const struct v4l2_rect vivid_min_rect = {
0, 0, MIN_WIDTH, MIN_HEIGHT
will succeed. This is limited to the maximum number of devices that
videodev supports, which is equal to VIDEO_NUM_DEVICES.
*/
-static int __init vivid_init(void)
+static int vivid_probe(struct platform_device *pdev)
{
const struct font_desc *font = find_font("VGA8x16");
int ret = 0, i;
@@ -1323,7 +1325,7 @@ static int __init vivid_init(void)
return ret;
}
-static void __exit vivid_exit(void)
+static int vivid_remove(struct platform_device *pdev)
{
struct vivid_dev *dev;
unsigned i;
@@ -1384,6 +1386,37 @@ static void __exit vivid_exit(void)
kfree(dev);
vivid_devs[i] = NULL;
}
+
+ return 0;
+}
+
+struct platform_driver vivid_driver = {
+ .probe = vivid_probe,
+ .remove = vivid_remove,
+ .driver = {
+ .name = "vivid",
+ },
+};
+
+static int __init vivid_init(void)
+{
+ int ret;
+
+ vivid_pdev = platform_device_register_simple("vivid", -1, NULL, 0);
+ if (IS_ERR(vivid_pdev))
+ return PTR_ERR(vivid_pdev);
+
+ ret = platform_driver_register(&vivid_driver);
+ if (ret != 0)
+ platform_device_unregister(vivid_pdev);
+
+ return ret;
+}
+
+static void __exit vivid_exit(void)
+{
+ platform_device_unregister(vivid_pdev);
+ platform_driver_unregister(&vivid_driver);
}
module_init(vivid_init);
Hans Verkuil
2014-10-22 10:14:54 UTC
Permalink
Raw Message
Post by 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.
---
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 <linux/platform_device.h>
#include <linux/videodev2.h>
#include <linux/v4l2-dv-timings.h>
+#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-vmalloc.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-ioctl.h>
@@ -107,6 +108,11 @@ MODULE_PARM_DESC(multiplanar, " 0 (default) is alternating single and multiplana
"\t\t 1 is single planar devices,\n"
"\t\t 2 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\t 0=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(int inst)
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivid_buffer);
q->ops = &vivid_vbi_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;
@@ -1093,7 +1113,7 @@ static int __init vivid_create_instance(int inst)
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivid_buffer);
q->ops = &vivid_sdr_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 = 8;
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
index 811c286..4fefb0d 100644
--- a/drivers/media/platform/vivid/vivid-core.h
+++ b/drivers/media/platform/vivid/vivid-core.h
@@ -142,6 +142,7 @@ struct vivid_dev {
struct v4l2_ctrl_handler ctrl_hdl_radio_tx;
struct video_device sdr_cap_dev;
struct v4l2_ctrl_handler ctrl_hdl_sdr_cap;
+ struct vb2_alloc_ctx *alloc_ctx;
spinlock_t slock;
struct mutex mutex;
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.

Regards,

Hans
Philipp Zabel
2014-10-22 11:50:23 UTC
Permalink
Raw Message
Am Mittwoch, den 22.10.2014, 12:14 +0200 schrieb Hans Verkuil:
[...]
Post by Hans Verkuil
Post by Philipp Zabel
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
Loading...