[PATCH v2 18/34] media: iris: introduce and implement iris vb2 mem ops

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Vikash Garodia <quic_vgarodia@xxxxxxxxxxx>

Implement the iris vb2 mem ops for buffer management for
DMABUF streaming mode. Update video driver buffer
with dma buf information.

Signed-off-by: Vikash Garodia <quic_vgarodia@xxxxxxxxxxx>
Signed-off-by: Dikshita Agarwal <quic_dikshita@xxxxxxxxxxx>
---
 .../media/platform/qcom/vcodec/iris/iris_probe.c   |   1 +
 drivers/media/platform/qcom/vcodec/iris/iris_vb2.c | 147 +++++++++++++++++++++
 drivers/media/platform/qcom/vcodec/iris/iris_vb2.h |  10 ++
 .../media/platform/qcom/vcodec/iris/iris_vidc.c    |  11 ++
 4 files changed, 169 insertions(+)

diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_probe.c b/drivers/media/platform/qcom/vcodec/iris/iris_probe.c
index 50fb93e..bf484a3 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_probe.c
@@ -233,5 +233,6 @@ static struct platform_driver qcom_iris_driver = {
 };
 
 module_platform_driver(qcom_iris_driver);
+MODULE_IMPORT_NS(DMA_BUF);
 MODULE_DESCRIPTION("Qualcomm Iris video driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_vb2.c b/drivers/media/platform/qcom/vcodec/iris/iris_vb2.c
index b040d27..a57b5fb 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_vb2.c
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_vb2.c
@@ -69,3 +69,150 @@ int iris_vb2_queue_setup(struct vb2_queue *q,
 
 	return ret;
 }
+
+void *iris_vb2_attach_dmabuf(struct vb2_buffer *vb, struct device *dev,
+			     struct dma_buf *dbuf, unsigned long size)
+{
+	enum iris_buffer_type buf_type;
+	struct iris_buffers *buffers;
+	struct iris_buffer *iter;
+	struct iris_buffer *buf;
+	struct iris_inst *inst;
+	bool found = false;
+
+	if (!vb || !dev || !dbuf || !vb->vb2_queue)
+		return ERR_PTR(-EINVAL);
+
+	inst = vb->vb2_queue->drv_priv;
+
+	buf_type = v4l2_type_to_driver(vb->type);
+
+	buffers = iris_get_buffer_list(inst, buf_type);
+	if (!buffers)
+		return NULL;
+
+	list_for_each_entry(iter, &buffers->list, list) {
+		if (iter->index == vb->index) {
+			found = true;
+			buf = iter;
+			break;
+		}
+	}
+
+	if (!found)
+		return NULL;
+
+	buf->inst = inst;
+	buf->dmabuf = dbuf;
+
+	buf->attach = dma_buf_attach(dbuf, dev);
+	if (IS_ERR(buf->attach)) {
+		buf->attach = NULL;
+		return NULL;
+	}
+
+	return buf;
+}
+
+int iris_vb2_map_dmabuf(void *buf_priv)
+{
+	struct iris_buffer *buf = buf_priv;
+	struct iris_core *core;
+	struct iris_inst *inst;
+
+	if (!buf || !buf->inst)
+		return -EINVAL;
+
+	inst = buf->inst;
+	core = inst->core;
+
+	if (!buf->attach) {
+		dev_err(core->dev, "trying to map a non attached buffer\n");
+		return -EINVAL;
+	}
+
+	buf->sg_table = dma_buf_map_attachment(buf->attach, DMA_BIDIRECTIONAL);
+	if (IS_ERR(buf->sg_table))
+		return -EINVAL;
+
+	if (!buf->sg_table->sgl) {
+		dma_buf_unmap_attachment(buf->attach, buf->sg_table, DMA_BIDIRECTIONAL);
+		buf->sg_table = NULL;
+		return -EINVAL;
+	}
+
+	buf->device_addr = sg_dma_address(buf->sg_table->sgl);
+
+	return 0;
+}
+
+void iris_vb2_unmap_dmabuf(void *buf_priv)
+{
+	struct iris_buffer *buf = buf_priv;
+	struct iris_core *core;
+	struct iris_inst *inst;
+
+	if (!buf || !buf->inst)
+		return;
+
+	inst = buf->inst;
+	core = inst->core;
+
+	if (!buf->attach) {
+		dev_err(core->dev, "trying to unmap a non attached buffer\n");
+		return;
+	}
+
+	if (!buf->sg_table) {
+		dev_err(core->dev, "dmabuf buffer is already unmapped\n");
+		return;
+	}
+
+	if (buf->attach && buf->sg_table) {
+		dma_buf_unmap_attachment(buf->attach, buf->sg_table, DMA_BIDIRECTIONAL);
+		buf->sg_table = NULL;
+		buf->device_addr = 0x0;
+	}
+}
+
+void iris_vb2_detach_dmabuf(void *buf_priv)
+{
+	struct iris_buffer *buf = buf_priv;
+	struct iris_core *core;
+	struct iris_inst *inst;
+
+	if (!buf || !buf->inst)
+		return;
+
+	inst = buf->inst;
+	core = inst->core;
+
+	if (buf->sg_table) {
+		dev_err(core->dev, "trying to detach an unmapped buffer\n");
+		dma_buf_unmap_attachment(buf->attach, buf->sg_table, DMA_BIDIRECTIONAL);
+		buf->sg_table = NULL;
+	}
+
+	if (buf->attach && buf->dmabuf) {
+		dma_buf_detach(buf->dmabuf, buf->attach);
+		buf->attach = NULL;
+	}
+
+	buf->dmabuf = NULL;
+	buf->inst = NULL;
+}
+
+void *iris_vb2_alloc(struct vb2_buffer *vb, struct device *dev,
+		     unsigned long size)
+{
+	return (void *)0xdeadbeef;
+}
+
+void iris_vb2_put(void *buf_priv)
+{
+}
+
+int iris_vb2_mmap(void *buf_priv, struct vm_area_struct *vma)
+{
+	return 0;
+}
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_vb2.h b/drivers/media/platform/qcom/vcodec/iris/iris_vb2.h
index 8a8e1039..4342034 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_vb2.h
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_vb2.h
@@ -12,4 +12,14 @@ int iris_vb2_queue_setup(struct vb2_queue *q,
 			 unsigned int *num_buffers, unsigned int *num_planes,
 			 unsigned int sizes[], struct device *alloc_devs[]);
 
+/* vb2_mem_ops */
+void *iris_vb2_alloc(struct vb2_buffer *vb, struct device *dev, unsigned long size);
+void *iris_vb2_attach_dmabuf(struct vb2_buffer *vb, struct device *dev, struct dma_buf *dbuf,
+			     unsigned long size);
+void iris_vb2_put(void *buf_priv);
+int iris_vb2_mmap(void *buf_priv, struct vm_area_struct *vma);
+void iris_vb2_detach_dmabuf(void *buf_priv);
+int iris_vb2_map_dmabuf(void *buf_priv);
+void iris_vb2_unmap_dmabuf(void *buf_priv);
+
 #endif
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_vidc.c b/drivers/media/platform/qcom/vcodec/iris/iris_vidc.c
index 410de720..124333a 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_vidc.c
@@ -320,10 +320,21 @@ static const struct vb2_ops iris_vb2_ops = {
 	.queue_setup                    = iris_vb2_queue_setup,
 };
 
+static struct vb2_mem_ops iris_vb2_mem_ops = {
+	.alloc                          = iris_vb2_alloc,
+	.put                            = iris_vb2_put,
+	.mmap                           = iris_vb2_mmap,
+	.attach_dmabuf                  = iris_vb2_attach_dmabuf,
+	.detach_dmabuf                  = iris_vb2_detach_dmabuf,
+	.map_dmabuf                     = iris_vb2_map_dmabuf,
+	.unmap_dmabuf                   = iris_vb2_unmap_dmabuf,
+};
+
 int init_ops(struct iris_core *core)
 {
 	core->v4l2_file_ops = &v4l2_file_ops;
 	core->vb2_ops = &iris_vb2_ops;
+	core->vb2_mem_ops = &iris_vb2_mem_ops;
 
 	return 0;
 }
-- 
2.7.4





[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux