vidc: Add metabuffer mode support for encoder driver.

Video encoder driver when configured in meta buffer mode,
will allow clients to register buffers in data path.

Change-Id: I23e2cb07386461275da5731134d8aad7df1cd060
Signed-off-by: Gopikrishnaiah Anandan <gopikr@codeaurora.org>
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 a8aa44a..29f178d 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -901,6 +901,9 @@
 			property_value);
 		vcd_status = VCD_S_SUCCESS;
 	break;
+	case VCD_I_META_BUFFER_MODE:
+		vcd_status = VCD_S_SUCCESS;
+		break;
 	default:
 		DDL_MSG_ERROR("INVALID ID %d\n", (int)property_hdr->prop_id);
 		vcd_status = VCD_ERR_ILLEGAL_OP;
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 1435b86..5ee315f 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1540,6 +1540,29 @@
 			return -EFAULT;
 		break;
 	}
+	case VEN_IOCTL_SET_METABUFFER_MODE:
+	{
+		u32 metabuffer_mode, vcd_status;
+		struct vcd_property_hdr vcd_property_hdr;
+		struct vcd_property_live live_mode;
+
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		if (copy_from_user(&metabuffer_mode, venc_msg.in,
+			sizeof(metabuffer_mode)))
+			return -EFAULT;
+		vcd_property_hdr.prop_id = VCD_I_META_BUFFER_MODE;
+		vcd_property_hdr.sz =
+			sizeof(struct vcd_property_live);
+		live_mode.live = metabuffer_mode;
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					&vcd_property_hdr, &live_mode);
+		if (vcd_status) {
+			pr_err(" Setting metabuffer mode failed");
+			return -EIO;
+		}
+		break;
+	}
 	case VEN_IOCTL_SET_AC_PREDICTION:
 	case VEN_IOCTL_GET_AC_PREDICTION:
 	case VEN_IOCTL_SET_RVLC:
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
index 973ed48..e00e85f 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
@@ -90,13 +90,13 @@
 		return VCD_ERR_ILLEGAL_OP;
 	}
 
-	if (!cctxt->in_buf_pool.entries ||
+	if ((!cctxt->meta_mode && !cctxt->in_buf_pool.entries) ||
 	    !cctxt->out_buf_pool.entries ||
-	    cctxt->in_buf_pool.validated != cctxt->in_buf_pool.count ||
+	    (!cctxt->meta_mode &&
+		 cctxt->in_buf_pool.validated != cctxt->in_buf_pool.count) ||
 	    cctxt->out_buf_pool.validated !=
 	    cctxt->out_buf_pool.count) {
 		VCD_MSG_ERROR("Buffer pool is not completely setup yet");
-
 		return VCD_ERR_BAD_STATE;
 	}
 
@@ -495,6 +495,13 @@
 	rc = ddl_set_property(cctxt->ddl_handle, prop_hdr, prop_val);
 	VCD_FAILED_RETURN(rc, "Failed: ddl_set_property");
 	switch (prop_hdr->prop_id) {
+	case VCD_I_META_BUFFER_MODE:
+		{
+			struct vcd_property_live *live =
+			    (struct vcd_property_live *)prop_val;
+			cctxt->meta_mode = live->live;
+			break;
+		}
 	case VCD_I_LIVE:
 		{
 			struct vcd_property_live *live =
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_core.h b/drivers/video/msm/vidc/common/vcd/vcd_core.h
index b424059..64dec2d 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_core.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_core.h
@@ -208,6 +208,7 @@
 	struct ion_client *vcd_ion_client;
 	u32 vcd_enable_ion;
 	struct vcd_clnt_ctxt *next;
+	u32 meta_mode;
 };
 
 #define VCD_BUFFERPOOL_INUSE_DECREMENT(val) \
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_property.h b/drivers/video/msm/vidc/common/vcd/vcd_property.h
index f51d226..3f7b131 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_property.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_property.h
@@ -47,6 +47,7 @@
 #define VCD_I_GET_H264_MV_SIZE (VCD_START_BASE + 0x1F)
 #define VCD_I_DEC_PICTYPE (VCD_START_BASE + 0x20)
 #define VCD_I_CONT_ON_RECONFIG (VCD_START_BASE + 0x21)
+#define VCD_I_META_BUFFER_MODE (VCD_START_BASE + 0x22)
 
 #define VCD_START_REQ      (VCD_START_BASE + 0x1000)
 #define VCD_I_REQ_IFRAME   (VCD_START_REQ + 0x1)
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index 75e0acf..217030f 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -653,7 +653,7 @@
 	VCD_FAILED_RETURN(rc, "Invalid buffer type provided");
 
 	first_frm_recvd &= cctxt->status.mask;
-	if (first_frm_recvd) {
+	if (first_frm_recvd && !cctxt->meta_mode) {
 		VCD_MSG_ERROR(
 			"VCD free buffer called when data path is active");
 		return VCD_ERR_BAD_STATE;
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index 12c7afd..45199cb 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -435,6 +435,9 @@
 #define VEN_IOCTL_GET_NUMBER_INSTANCES \
 	_IOR(VEN_IOCTLBASE_ENC, 46, struct venc_ioctl_msg)
 
+#define VEN_IOCTL_SET_METABUFFER_MODE \
+	_IOW(VEN_IOCTLBASE_ENC, 47, struct venc_ioctl_msg)
+
 struct venc_switch{
 	unsigned char	status;
 };