aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/samsung/mfc5x/mfc_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/samsung/mfc5x/mfc_dev.c')
-rw-r--r--drivers/media/video/samsung/mfc5x/mfc_dev.c119
1 files changed, 118 insertions, 1 deletions
diff --git a/drivers/media/video/samsung/mfc5x/mfc_dev.c b/drivers/media/video/samsung/mfc5x/mfc_dev.c
index e3a0b60..23bc10d 100644
--- a/drivers/media/video/samsung/mfc5x/mfc_dev.c
+++ b/drivers/media/video/samsung/mfc5x/mfc_dev.c
@@ -66,6 +66,10 @@
#include <plat/sysmmu.h>
#endif
+#ifdef CONFIG_SLP_DMABUF
+#include <media/videobuf2-core.h>
+#endif
+
#define MFC_MINOR 252
#define MFC_FW_NAME "mfc_fw.bin"
@@ -108,6 +112,79 @@ static inline void clear_magic(unsigned char *addr)
}
#endif
+#ifdef CONFIG_SLP_DMABUF
+/**
+ * _mfc_dmabuf_put() - release memory associated with
+ * a DMABUF shared buffer
+ */
+static void _mfc_dmabuf_put(struct vb2_plane *planes)
+{
+ unsigned int plane;
+
+ for (plane = 0; plane < MFC_NUM_PLANE; ++plane) {
+ void *mem_priv = planes[plane].mem_priv;
+
+ if (mem_priv) {
+ dma_buf_detach(planes[plane].dbuf,
+ planes[plane].mem_priv);
+ dma_buf_put(planes[plane].dbuf);
+ planes[plane].dbuf = NULL;
+ planes[plane].mem_priv = NULL;
+ }
+ }
+}
+
+void mfc_queue_free(struct mfc_inst_ctx *mfc_ctx)
+{
+ struct vb2_plane *planes;
+ int buffer;
+
+ for (buffer = 0; buffer < VIDEO_MAX_PLANES; ++buffer) {
+ planes = mfc_ctx->enc_planes[buffer];
+
+ if (!planes)
+ continue;
+
+ _mfc_dmabuf_put(planes);
+ kfree(planes);
+ planes = NULL;
+ }
+}
+
+int mfc_queue_alloc(struct mfc_inst_ctx *mfc_ctx)
+{
+ struct vb2_plane *planes;
+ int buffer;
+ int ret = 0;
+
+ for (buffer = 0; buffer < MFC_NUM_PLANE; ++buffer) {
+ planes = kzalloc(sizeof(struct vb2_plane), GFP_KERNEL);
+ if (!planes) {
+ printk(KERN_INFO "MFC Queue memory alloc failed\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ planes->mem_priv = NULL;
+ mfc_ctx->enc_planes[buffer] = planes;
+ }
+
+ for (buffer = MFC_NUM_PLANE; buffer < VIDEO_MAX_PLANES; ++buffer)
+ mfc_ctx->enc_planes[buffer] = NULL;
+
+ return ret;
+
+err:
+ for (buffer = 0; buffer < VIDEO_MAX_PLANES; buffer++) {
+ if (mfc_ctx->enc_planes[buffer] != NULL)
+ kfree(mfc_ctx->enc_planes[buffer]);
+ mfc_ctx->enc_planes[buffer] = NULL;
+ }
+
+ return ret;
+}
+#endif
+
static int get_free_inst_id(struct mfc_dev *dev)
{
int slot = 0;
@@ -135,6 +212,25 @@ static int mfc_open(struct inode *inode, struct file *file)
file->private_data = NULL;
mutex_lock(&mfcdev->lock);
+
+#if defined(CONFIG_USE_MFC_CMA) && defined(CONFIG_MACH_M0)
+ if (atomic_read(&mfcdev->inst_cnt) == 0) {
+ size_t size = 0x02800000;
+ mfcdev->cma_vaddr = dma_alloc_coherent(mfcdev->device, size,
+ &mfcdev->cma_dma_addr, 0);
+ if (!mfcdev->cma_vaddr) {
+ printk(KERN_ERR "%s: dma_alloc_coherent returns "
+ "-ENOMEM\n", __func__);
+ mutex_unlock(&mfcdev->lock);
+ return -ENOMEM;
+ }
+ printk(KERN_INFO "%s[%d] size 0x%x, vaddr 0x%x, base 0x%x\n",
+ __func__, __LINE__, (int)size,
+ (int)mfcdev->cma_vaddr,
+ (int)mfcdev->cma_dma_addr);
+ }
+#endif
+
#if SUPPORT_SLICE_ENCODING
mfcdev->frame_working_flag = 1;
mfcdev->frame_sys = 0;
@@ -292,6 +388,13 @@ static int mfc_open(struct inode *inode, struct file *file)
if (mfcdev->wait_frame_timeout == 1)
wake_up(&mfcdev->wait_frame);
#endif
+#ifdef CONFIG_SLP_DMABUF
+ ret = mfc_queue_alloc(mfc_ctx);
+ if (ret < 0) {
+ mfc_err("mfc_queue_alloc failed\n");
+ goto err_inst_ctx;
+ }
+#endif
mfc_info("MFC instance [%d:%d] opened", mfc_ctx->id,
atomic_read(&mfcdev->inst_cnt));
@@ -456,10 +559,24 @@ static int mfc_release(struct inode *inode, struct file *file)
if (mfcdev->wait_frame_timeout == 1)
wake_up(&dev->wait_frame);
#endif
+#ifdef CONFIG_SLP_DMABUF
+ mfc_queue_free(mfc_ctx);
+#endif
err_pwr_disable:
- mutex_unlock(&dev->lock);
+#if defined(CONFIG_USE_MFC_CMA) && defined(CONFIG_MACH_M0)
+ if (atomic_read(&mfcdev->inst_cnt) == 0) {
+ size_t size = 0x02800000;
+ dma_free_coherent(mfcdev->device, size, mfcdev->cma_vaddr,
+ mfcdev->cma_dma_addr);
+ printk(KERN_INFO "%s[%d] size 0x%x, vaddr 0x%x, base 0x0%x\n",
+ __func__, __LINE__, (int)size,
+ (int) mfcdev->cma_vaddr,
+ (int)mfcdev->cma_dma_addr);
+ }
+#endif
+ mutex_unlock(&dev->lock);
return ret;
}