Merge "vidc: Map userspace allocated buffers into video smmu." into msm-3.0
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index 0405513..a8aa44a 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -329,7 +329,7 @@
 			DDL_CLIENT_WAIT_FOR_INITCODEC) ||
 			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) ||
 			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN))) {
-			phys_addr = mv_buff->physical_addr;
+			phys_addr = mv_buff->dev_addr;
 			virt_addr = mv_buff->kernel_virtual_addr;
 			buffer_size = mv_buff->size/mv_buff->count;
 
@@ -853,7 +853,7 @@
 				vcd_property_enc_recon_buffer)) {
 				encoder->hw_bufs.dpb_y[index_hw_bufs].
 				align_physical_addr =
-					recon_buffers->physical_addr;
+					recon_buffers->dev_addr;
 				encoder->hw_bufs.dpb_y[index_hw_bufs].
 				align_virtual_addr =
 					recon_buffers->kernel_virtual_addr;
@@ -861,7 +861,7 @@
 				buffer_size = recon_buffers->buffer_size;
 				encoder->hw_bufs.dpb_c[index_hw_bufs].
 				align_physical_addr =
-				recon_buffers->physical_addr +
+				recon_buffers->dev_addr +
 					ddl_get_yuv_buf_size(
 						encoder->frame_size.width,
 						encoder->frame_size.height,
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 9440f15..a5994dc 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -28,7 +28,7 @@
 #include <linux/android_pmem.h>
 #include <linux/clk.h>
 #include <linux/timer.h>
-
+#include <mach/msm_subsystem_map.h>
 #include "vidc_type.h"
 #include "vcd_api.h"
 #include "vdec_internal.h"
@@ -50,6 +50,8 @@
 static struct vid_dec_dev *vid_dec_device_p;
 static dev_t vid_dec_dev_num;
 static struct class *vid_dec_class;
+static unsigned int vidc_mmu_subsystem[] = {
+	MSM_SUBSYSTEM_VIDEO};
 static s32 vid_dec_get_empty_client_index(void)
 {
 	u32 i, found = false;
@@ -743,9 +745,10 @@
 					struct vdec_h264_mv *mv_data)
 {
 	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_h264_mv_buffer vcd_h264_mv_buffer;
+	struct vcd_property_h264_mv_buffer *vcd_h264_mv_buffer = NULL;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
 	u32 vcd_status = VCD_ERR_FAIL;
-	u32 len;
+	u32 len = 0, flags = 0;
 	struct file *file;
 
 	if (!client_ctx || !mv_data)
@@ -753,29 +756,41 @@
 
 	vcd_property_hdr.prop_id = VCD_I_H264_MV_BUFFER;
 	vcd_property_hdr.sz = sizeof(struct vcd_property_h264_mv_buffer);
+	vcd_h264_mv_buffer = &client_ctx->vcd_h264_mv_buffer;
 
-	memset(&vcd_h264_mv_buffer, 0,
+	memset(&client_ctx->vcd_h264_mv_buffer, 0,
 		   sizeof(struct vcd_property_h264_mv_buffer));
-	vcd_h264_mv_buffer.size = mv_data->size;
-	vcd_h264_mv_buffer.count = mv_data->count;
-	vcd_h264_mv_buffer.pmem_fd = mv_data->pmem_fd;
-	vcd_h264_mv_buffer.offset = mv_data->offset;
+	vcd_h264_mv_buffer->size = mv_data->size;
+	vcd_h264_mv_buffer->count = mv_data->count;
+	vcd_h264_mv_buffer->pmem_fd = mv_data->pmem_fd;
+	vcd_h264_mv_buffer->offset = mv_data->offset;
 
-	if (get_pmem_file(vcd_h264_mv_buffer.pmem_fd,
-		(unsigned long *) (&(vcd_h264_mv_buffer.physical_addr)),
-		(unsigned long *) (&vcd_h264_mv_buffer.kernel_virtual_addr),
+	if (get_pmem_file(vcd_h264_mv_buffer->pmem_fd,
+		(unsigned long *) (&(vcd_h264_mv_buffer->physical_addr)),
+		(unsigned long *) (&vcd_h264_mv_buffer->kernel_virtual_addr),
 		(unsigned long *) (&len), &file)) {
 		ERR("%s(): get_pmem_file failed\n", __func__);
 		return false;
 	}
 	put_pmem_file(file);
 
-	DBG("Virt: %p, Phys %p, fd: %d\n", vcd_h264_mv_buffer.
-		kernel_virtual_addr, vcd_h264_mv_buffer.physical_addr,
-		vcd_h264_mv_buffer.pmem_fd);
-
+	flags = MSM_SUBSYSTEM_MAP_IOVA;
+	mapped_buffer = msm_subsystem_map_buffer(
+		(unsigned long)vcd_h264_mv_buffer->physical_addr, len,
+			flags, vidc_mmu_subsystem,
+			sizeof(vidc_mmu_subsystem)/sizeof(unsigned int));
+	if (IS_ERR(mapped_buffer)) {
+		pr_err("buffer map failed");
+		return false;
+	}
+	vcd_h264_mv_buffer->client_data = (void *) mapped_buffer;
+	vcd_h264_mv_buffer->dev_addr = (u8 *)mapped_buffer->iova[0];
+	DBG("Virt: %p, Phys %p, fd: %d", vcd_h264_mv_buffer->
+		kernel_virtual_addr, vcd_h264_mv_buffer->physical_addr,
+		vcd_h264_mv_buffer->pmem_fd);
+	DBG("Dev addr %p", vcd_h264_mv_buffer->dev_addr);
 	vcd_status = vcd_set_property(client_ctx->vcd_handle,
-				      &vcd_property_hdr, &vcd_h264_mv_buffer);
+				      &vcd_property_hdr, vcd_h264_mv_buffer);
 
 	if (vcd_status)
 		return false;
@@ -837,6 +852,9 @@
 
 	if (!client_ctx)
 		return false;
+	if (client_ctx->vcd_h264_mv_buffer.client_data)
+		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+		client_ctx->vcd_h264_mv_buffer.client_data);
 
 	vcd_property_hdr.prop_id = VCD_I_FREE_H264_MV_BUFFER;
 	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
@@ -888,7 +906,7 @@
 	enum vcd_buffer_type buffer = VCD_BUFFER_INPUT;
 	enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT;
 	u32 vcd_status = VCD_ERR_FAIL;
-	unsigned long kernel_vaddr, buf_adr_offset = 0;
+	unsigned long kernel_vaddr, buf_adr_offset = 0, length;
 
 	if (!client_ctx || !buffer_info)
 		return false;
@@ -898,12 +916,12 @@
 		buffer = VCD_BUFFER_OUTPUT;
 		buf_adr_offset = (unsigned long)buffer_info->buffer.offset;
 	}
-
+	length = buffer_info->buffer.buffer_len;
 	/*If buffer cannot be set, ignore */
 	if (!vidc_insert_addr_table(client_ctx, dir_buffer,
 		(unsigned long)buffer_info->buffer.bufferaddr,
 		&kernel_vaddr, buffer_info->buffer.pmem_fd,
-		buf_adr_offset, MAX_VIDEO_NUM_OF_BUFF)) {
+		buf_adr_offset, MAX_VIDEO_NUM_OF_BUFF, length)) {
 		DBG("%s() : user_virt_addr = %p cannot be set.",
 		    __func__, buffer_info->buffer.bufferaddr);
 		return false;
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 0d8fcc2..125355e 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -966,8 +966,15 @@
 	}
 	case VEN_IOCTL_FREE_RECON_BUFFER:
 	{
+		struct venc_recon_addr venc_recon;
 		DBG("VEN_IOCTL_FREE_RECON_BUFFER\n");
-		result = vid_enc_free_recon_buffers(client_ctx);
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		if (copy_from_user(&venc_recon, venc_msg.in,
+				sizeof(venc_recon)))
+				return -EFAULT;
+		result = vid_enc_free_recon_buffers(client_ctx,
+				&venc_recon);
 		if (!result) {
 			ERR("VEN_IOCTL_FREE_RECON_BUFFER failed\n");
 			return -EIO;
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index d202d81..c3f0219 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -27,7 +27,7 @@
 #include <linux/workqueue.h>
 #include <linux/android_pmem.h>
 #include <linux/clk.h>
-
+#include <mach/msm_subsystem_map.h>
 #include "vidc_type.h"
 #include "vcd_api.h"
 #include "venc_internal.h"
@@ -40,6 +40,9 @@
 #endif
 
 #define ERR(x...) printk(KERN_ERR x)
+static unsigned int vidc_mmu_subsystem[] = {
+	MSM_SUBSYSTEM_VIDEO};
+
 
 u32 vid_enc_set_get_base_cfg(struct video_client_ctx *client_ctx,
 		struct venc_basecfg *base_config, u32 set_flag)
@@ -1530,7 +1533,7 @@
 	enum vcd_buffer_type vcd_buffer_t = VCD_BUFFER_INPUT;
 	enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT;
 	u32 vcd_status = VCD_ERR_FAIL;
-	unsigned long kernel_vaddr;
+	unsigned long kernel_vaddr, length = 0;
 
 	if (!client_ctx || !buffer_info)
 		return false;
@@ -1539,14 +1542,14 @@
 		dir_buffer = BUFFER_TYPE_OUTPUT;
 		vcd_buffer_t = VCD_BUFFER_OUTPUT;
 	}
-
+	length = buffer_info->sz;
 	/*If buffer cannot be set, ignore */
 	if (!vidc_insert_addr_table(client_ctx, dir_buffer,
 					(unsigned long)buffer_info->pbuffer,
 					&kernel_vaddr,
 					buffer_info->fd,
 					(unsigned long)buffer_info->offset,
-					VID_ENC_MAX_NUM_OF_BUFF)) {
+					VID_ENC_MAX_NUM_OF_BUFF, length)) {
 		DBG("%s() : user_virt_addr = %p cannot be set.",
 		    __func__, buffer_info->pbuffer);
 		return false;
@@ -1697,34 +1700,58 @@
 		struct venc_recon_addr *venc_recon)
 {
 	u32 vcd_status = VCD_ERR_FAIL;
-	u32 len;
+	u32 len, i, flags = 0;
 	struct file *file;
 	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_enc_recon_buffer control;
-
-	control.buffer_size = venc_recon->buffer_size;
-	control.kernel_virtual_addr = NULL;
-	control.physical_addr = NULL;
-	control.pmem_fd = venc_recon->pmem_fd;
-	control.offset = venc_recon->offset;
-
-	if (get_pmem_file(control.pmem_fd, (unsigned long *)
-		(&(control.physical_addr)), (unsigned long *)
-		(&control.kernel_virtual_addr),
+	struct vcd_property_enc_recon_buffer *control = NULL;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
+	if (!client_ctx || !venc_recon) {
+		pr_err("%s() Invalid params", __func__);
+		return false;
+	}
+	len = sizeof(client_ctx->recon_buffer)/
+		sizeof(struct vcd_property_enc_recon_buffer);
+	for (i = 0; i < len; i++) {
+		if (!client_ctx->recon_buffer[i].kernel_virtual_addr) {
+			control = &client_ctx->recon_buffer[i];
+			break;
+		}
+	}
+	if (!control) {
+		pr_err("Exceeded max recon buffer setting");
+		return false;
+	}
+	control->buffer_size = venc_recon->buffer_size;
+	control->kernel_virtual_addr = NULL;
+	control->physical_addr = NULL;
+	control->pmem_fd = venc_recon->pmem_fd;
+	control->offset = venc_recon->offset;
+	control->user_virtual_addr = venc_recon->pbuffer;
+	if (get_pmem_file(control->pmem_fd, (unsigned long *)
+		(&(control->physical_addr)), (unsigned long *)
+		(&control->kernel_virtual_addr),
 		(unsigned long *) (&len), &file)) {
 			ERR("%s(): get_pmem_file failed\n", __func__);
 			return false;
 		}
 		put_pmem_file(file);
-		DBG("Virt: %p, Phys %p, fd: %d", control.kernel_virtual_addr,
-			control.physical_addr, control.pmem_fd);
-
+		flags = MSM_SUBSYSTEM_MAP_IOVA;
+		mapped_buffer = msm_subsystem_map_buffer(
+		(unsigned long)control->physical_addr, len,
+		flags, vidc_mmu_subsystem,
+		sizeof(vidc_mmu_subsystem)/sizeof(unsigned int));
+		if (IS_ERR(mapped_buffer)) {
+			pr_err("buffer map failed");
+			return false;
+		}
+		control->client_data = (void *) mapped_buffer;
+		control->dev_addr = (u8 *)mapped_buffer->iova[0];
 		vcd_property_hdr.prop_id = VCD_I_RECON_BUFFERS;
 		vcd_property_hdr.sz =
 			sizeof(struct vcd_property_enc_recon_buffer);
 
 		vcd_status = vcd_set_property(client_ctx->vcd_handle,
-						&vcd_property_hdr, &control);
+						&vcd_property_hdr, control);
 		if (!vcd_status) {
 			DBG("vcd_set_property returned success\n");
 			return true;
@@ -1735,17 +1762,43 @@
 		}
 }
 
-u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx)
+u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx,
+			struct venc_recon_addr *venc_recon)
 {
 	u32 vcd_status = VCD_ERR_FAIL;
 	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_enc_recon_buffer control;
+	struct vcd_property_enc_recon_buffer *control = NULL;
+	u32 len = 0, i;
+
+	if (!client_ctx || !venc_recon) {
+		pr_err("%s() Invalid params", __func__);
+		return false;
+	}
+	len = sizeof(client_ctx->recon_buffer)/
+		sizeof(struct vcd_property_enc_recon_buffer);
+	pr_err(" %s() address  %p", __func__,
+	venc_recon->pbuffer);
+	for (i = 0; i < len; i++) {
+		if (client_ctx->recon_buffer[i].user_virtual_addr
+			== venc_recon->pbuffer) {
+			control = &client_ctx->recon_buffer[i];
+			break;
+		}
+	}
+	if (!control) {
+		pr_err(" %s() address not found %p", __func__,
+			venc_recon->pbuffer);
+		return false;
+	}
+	if (control->client_data)
+		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+		control->client_data);
 
 	vcd_property_hdr.prop_id = VCD_I_FREE_RECON_BUFFERS;
 	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
-
 	vcd_status = vcd_set_property(client_ctx->vcd_handle,
-						&vcd_property_hdr, &control);
+						&vcd_property_hdr, control);
+	memset(control, 0, sizeof(struct vcd_property_enc_recon_buffer));
 	return true;
 }
 
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.h b/drivers/video/msm/vidc/common/enc/venc_internal.h
index 7d4ebca..2b5a532 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.h
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -143,7 +143,8 @@
 u32 vid_enc_set_recon_buffers(struct video_client_ctx *client_ctx,
 		struct venc_recon_addr *venc_recon);
 
-u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx);
+u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx,
+		struct venc_recon_addr *venc_recon);
 
 u32 vid_enc_get_recon_buffer_size(struct video_client_ctx *client_ctx,
 		struct venc_recon_buff_size *venc_recon_size);
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index cda3a91..902a9aa 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -30,7 +30,7 @@
 #include <linux/debugfs.h>
 #include <mach/clk.h>
 #include <linux/pm_runtime.h>
-
+#include <mach/msm_subsystem_map.h>
 #include "vcd_api.h"
 #include "vidc_init_internal.h"
 #include "vidc_init.h"
@@ -49,6 +49,7 @@
 static struct vidc_dev *vidc_device_p;
 static dev_t vidc_dev_num;
 static struct class *vidc_class;
+static unsigned int vidc_mmu_subsystem[] = {MSM_SUBSYSTEM_VIDEO};
 
 static const struct file_operations vidc_fops = {
 	.owner = THIS_MODULE,
@@ -78,7 +79,7 @@
 				u32 *var)
 {
 	struct dentry *vidc_debugfs_file =
-	    debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var);
+		debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var);
 	if (!vidc_debugfs_file)
 		ERR("%s(): Error creating/opening file %s\n", __func__, name);
 }
@@ -413,7 +414,7 @@
 	}
 
 	if (found) {
-		*phy_addr = buf_addr_table[i].phy_addr;
+		*phy_addr = buf_addr_table[i].dev_addr;
 		*pmem_fd = buf_addr_table[i].pmem_fd;
 		*file = buf_addr_table[i].file;
 		*buffer_index = i;
@@ -445,15 +446,17 @@
 u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx,
 	enum buffer_dir buffer, unsigned long user_vaddr,
 	unsigned long *kernel_vaddr, int pmem_fd,
-	unsigned long buffer_addr_offset, unsigned int max_num_buffers)
+	unsigned long buffer_addr_offset, unsigned int max_num_buffers,
+	unsigned long length)
 {
 	unsigned long len, phys_addr;
 	struct file *file;
 	u32 *num_of_buffers = NULL;
-	u32 i;
+	u32 i, flags;
 	struct buf_addr_table *buf_addr_table;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
 
-	if (!client_ctx)
+	if (!client_ctx || !length)
 		return false;
 
 	if (buffer == BUFFER_TYPE_INPUT) {
@@ -493,6 +496,18 @@
 		put_pmem_file(file);
 		phys_addr += buffer_addr_offset;
 		(*kernel_vaddr) += buffer_addr_offset;
+		flags = MSM_SUBSYSTEM_MAP_IOVA;
+		mapped_buffer = msm_subsystem_map_buffer(phys_addr, length,
+		flags, vidc_mmu_subsystem,
+		sizeof(vidc_mmu_subsystem)/sizeof(unsigned int));
+		if (IS_ERR(mapped_buffer)) {
+			pr_err("buffer map failed");
+			return false;
+		}
+		buf_addr_table[*num_of_buffers].client_data = (void *)
+			mapped_buffer;
+		buf_addr_table[*num_of_buffers].dev_addr =
+			mapped_buffer->iova[0];
 		buf_addr_table[*num_of_buffers].user_vaddr = user_vaddr;
 		buf_addr_table[*num_of_buffers].kernel_vaddr = *kernel_vaddr;
 		buf_addr_table[*num_of_buffers].pmem_fd = pmem_fd;
@@ -500,7 +515,7 @@
 		buf_addr_table[*num_of_buffers].phy_addr = phys_addr;
 		*num_of_buffers = *num_of_buffers + 1;
 		DBG("%s() : client_ctx = %p, user_virt_addr = 0x%08lx, "
-			"kernel_vaddr = 0x%08lx inserted!",	__func__,
+			"kernel_vaddr = 0x%08lx inserted!", __func__,
 			client_ctx, user_vaddr, *kernel_vaddr);
 	}
 	return true;
@@ -522,12 +537,10 @@
 	if (buffer == BUFFER_TYPE_INPUT) {
 		buf_addr_table = client_ctx->input_buf_addr_table;
 		num_of_buffers = &client_ctx->num_of_input_buffers;
-		DBG("%s(): buffer = INPUT\n", __func__);
 
 	} else {
 		buf_addr_table = client_ctx->output_buf_addr_table;
 		num_of_buffers = &client_ctx->num_of_output_buffers;
-		DBG("%s(): buffer = OUTPUT\n", __func__);
 	}
 
 	if (!*num_of_buffers)
@@ -538,13 +551,19 @@
 		user_vaddr != buf_addr_table[i].user_vaddr)
 		i++;
 	if (i == *num_of_buffers) {
-		DBG("%s() : client_ctx = %p."
+		pr_err("%s() : client_ctx = %p."
 			" user_virt_addr = 0x%08lx NOT found",
 			__func__, client_ctx, user_vaddr);
 		return false;
 	}
+	msm_subsystem_unmap_buffer(
+	(struct msm_mapped_buffer *)buf_addr_table[i].client_data);
 	*kernel_vaddr = buf_addr_table[i].kernel_vaddr;
 	if (i < (*num_of_buffers - 1)) {
+		buf_addr_table[i].client_data =
+			buf_addr_table[*num_of_buffers - 1].client_data;
+		buf_addr_table[i].dev_addr =
+			buf_addr_table[*num_of_buffers - 1].dev_addr;
 		buf_addr_table[i].user_vaddr =
 			buf_addr_table[*num_of_buffers - 1].user_vaddr;
 		buf_addr_table[i].kernel_vaddr =
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.h b/drivers/video/msm/vidc/common/init/vidc_init.h
index c472718..fecbf59 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.h
+++ b/drivers/video/msm/vidc/common/init/vidc_init.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -30,6 +30,8 @@
 	unsigned long phy_addr;
 	int pmem_fd;
 	struct file *file;
+	unsigned long dev_addr;
+	void *client_data;
 };
 
 struct video_client_ctx {
@@ -42,6 +44,8 @@
 	struct mutex msg_queue_lock;
 	wait_queue_head_t msg_wait;
 	struct completion event;
+	struct vcd_property_h264_mv_buffer vcd_h264_mv_buffer;
+	struct vcd_property_enc_recon_buffer recon_buffer[4];
 	u32 event_status;
 	u32 seq_header_set;
 	u32 stop_msg;
@@ -61,7 +65,7 @@
 	enum buffer_dir buffer, unsigned long user_vaddr,
 	unsigned long *kernel_vaddr, int pmem_fd,
 	unsigned long buffer_addr_offset,
-	unsigned int max_num_buffers);
+	unsigned int max_num_buffers, unsigned long length);
 u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx,
 	enum buffer_dir buffer, unsigned long user_vaddr,
 	unsigned long *kernel_vaddr);
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_property.h b/drivers/video/msm/vidc/common/vcd/vcd_property.h
index 2cb894e..f51d226 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_property.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_property.h
@@ -315,12 +315,15 @@
 };
 
 struct vcd_property_enc_recon_buffer{
+	u8 *user_virtual_addr;
 	u8 *kernel_virtual_addr;
 	u8 *physical_addr;
+	u8 *dev_addr;
 	u32 buffer_size;
 	u32 ysize;
 	int pmem_fd;
 	u32 offset;
+	void *client_data;
 };
 
 struct vcd_property_h264_mv_buffer{
@@ -330,6 +333,8 @@
 	u32 count;
 	int pmem_fd;
 	u32 offset;
+	u8 *dev_addr;
+	void *client_data;
 };
 
 struct vcd_property_buffer_size{