Browse Source

video: driver: add support for MMAP io mode

If a device supports streaming, it should support MMAP
streaming mode, as it's the one streaming mode that is
always available, so applications can rely on this.

Partially Fixes: v4l2-compliance:
                 test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF.

Change-Id: Ibcb29f75f3fed4e767e05c9d203d611d45f02e8b
Signed-off-by: Dikshita Agarwal <[email protected]>
Dikshita Agarwal 3 years ago
parent
commit
8ab5854042

+ 8 - 5
driver/vidc/inc/msm_vidc_vb2.h

@@ -15,17 +15,20 @@ struct vb2_queue *msm_vidc_get_vb2q(struct msm_vidc_inst *inst,
 
 /* vb2_mem_ops */
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
-void *msm_vb2_get_userptr(struct device *dev, unsigned long vaddr,
-			unsigned long size, enum dma_data_direction dma_dir);
+void *msm_vb2_alloc(struct device *dev, unsigned long attrs,
+	unsigned long size, enum dma_data_direction dma_dir,
+	gfp_t gfp_flags);
 void *msm_vb2_attach_dmabuf(struct device *dev, struct dma_buf *dbuf,
 	unsigned long size, enum dma_data_direction dma_dir);
 #else
-void *msm_vb2_get_userptr(struct vb2_buffer *vb, struct device *dev,
-		unsigned long vaddr, unsigned long size);
+void *msm_vb2_alloc(struct vb2_buffer *vb, struct device *dev,
+	unsigned long size);
 void *msm_vb2_attach_dmabuf(struct vb2_buffer *vb, struct device *dev,
 		struct dma_buf *dbuf, unsigned long size);
 #endif
-void msm_vb2_put_userptr(void *buf_priv);
+
+void msm_vb2_put(void *buf_priv);
+int msm_vb2_mmap(void *buf_priv, struct vm_area_struct *vma);
 void msm_vb2_detach_dmabuf(void *buf_priv);
 int msm_vb2_map_dmabuf(void *buf_priv);
 void msm_vb2_unmap_dmabuf(void *buf_priv);

+ 1 - 1
driver/vidc/src/msm_vidc_driver.c

@@ -3774,7 +3774,7 @@ static int vb2q_init(struct msm_vidc_inst *inst,
 	core = inst->core;
 
 	q->type = type;
-	q->io_modes = VB2_DMABUF;
+	q->io_modes = VB2_MMAP | VB2_DMABUF;
 	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 	q->ops = core->vb2_ops;
 	q->mem_ops = core->vb2_mem_ops;

+ 3 - 2
driver/vidc/src/msm_vidc_platform.c

@@ -129,8 +129,9 @@ static struct vb2_ops msm_vb2_ops = {
 };
 
 static struct vb2_mem_ops msm_vb2_mem_ops = {
-	.get_userptr                    = msm_vb2_get_userptr,
-	.put_userptr                    = msm_vb2_put_userptr,
+	.alloc                          = msm_vb2_alloc,
+	.put                            = msm_vb2_put,
+	.mmap                           = msm_vb2_mmap,
 	.attach_dmabuf                  = msm_vb2_attach_dmabuf,
 	.detach_dmabuf                  = msm_vb2_detach_dmabuf,
 	.map_dmabuf                     = msm_vb2_map_dmabuf,

+ 28 - 5
driver/vidc/src/msm_vidc_vb2.c

@@ -39,8 +39,9 @@ struct vb2_queue *msm_vidc_get_vb2q(struct msm_vidc_inst *inst,
 }
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
-void *msm_vb2_get_userptr(struct device *dev, unsigned long vaddr,
-			unsigned long size, enum dma_data_direction dma_dir)
+void *msm_vb2_alloc(struct device *dev, unsigned long attrs,
+	unsigned long size, enum dma_data_direction dma_dir,
+	gfp_t gfp_flags)
 {
 	return (void *)0xdeadbeef;
 }
@@ -50,9 +51,10 @@ void *msm_vb2_attach_dmabuf(struct device *dev, struct dma_buf *dbuf,
 {
 	return (void *)0xdeadbeef;
 }
+
 #else
-void *msm_vb2_get_userptr(struct vb2_buffer *vb, struct device *dev,
-	unsigned long vaddr, unsigned long size)
+void *msm_vb2_alloc(struct vb2_buffer *vb, struct device *dev,
+	unsigned long size)
 {
 	return (void *)0xdeadbeef;
 }
@@ -64,10 +66,15 @@ void *msm_vb2_attach_dmabuf(struct vb2_buffer *vb, struct device *dev,
 }
 #endif
 
-void msm_vb2_put_userptr(void *buf_priv)
+void msm_vb2_put(void *buf_priv)
 {
 }
 
+int msm_vb2_mmap(void *buf_priv, struct vm_area_struct *vma)
+{
+	return 0;
+}
+
 void msm_vb2_detach_dmabuf(void *buf_priv)
 {
 }
@@ -88,6 +95,7 @@ int msm_vidc_queue_setup(struct vb2_queue *q,
 	int rc = 0;
 	struct msm_vidc_inst *inst;
 	int port;
+	struct v4l2_format *f;
 
 	if (!q || !num_buffers || !num_planes
 		|| !sizes || !q->drv_priv) {
@@ -110,6 +118,21 @@ int msm_vidc_queue_setup(struct vb2_queue *q,
 	if (port < 0)
 		return -EINVAL;
 
+	if (*num_planes) {
+		f = &inst->fmts[port];
+		if (*num_planes != f->fmt.pix_mp.num_planes) {
+			i_vpr_i(inst, "%s: requested num_planes %d not supported\n",
+			__func__, *num_planes, f->fmt.pix_mp.num_planes);
+			return -EINVAL;
+		}
+		if (sizes[0] < inst->fmts[port].fmt.pix_mp.plane_fmt[0].sizeimage) {
+			i_vpr_e(inst, "%s: requested size %d not acceptable\n",
+			__func__, sizes[0]);
+			return -EINVAL;
+		}
+	}
+
+
 	if (port == INPUT_PORT) {
 		*num_planes = 1;
 		if (*num_buffers < inst->buffers.input.min_count +