msm: vidc: add support for the bitstream_restrict flag

Adds support for the MFC core to add the bitstream_restrict flag in the
sps/pps for H264 codecs.  This allows for the decoder to determine how
many frames to buffer when decoding.

Change-Id: Ic0de960d92a771d74c303dac7100734d6411fc45
Signed-off-by: Deepak Verma <dverma@codeaurora.org>
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
index b47d9ac..58a9329 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -295,6 +295,7 @@
 	struct ddl_batch_frame_data batch_frame;
 	u32 avc_delimiter_enable;
 	u32 vui_timinginfo_enable;
+	u32 bitstream_restrict_enable;
 };
 struct ddl_decoder_data {
 	struct ddl_codec_data_hdr  hdr;
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 1d14efd..f20008b 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1153,10 +1153,24 @@
 		}
 		break;
 	}
+	case VCD_I_ENABLE_VUI_BITSTREAM_RESTRICT_FLAG:
+	{
+		struct vcd_property_bitstream_restrict_enable *restrict_enable =
+			(struct vcd_property_bitstream_restrict_enable *)
+				property_value;
+		if (sizeof(struct vcd_property_bitstream_restrict_enable) ==
+			property_hdr->sz &&
+			encoder->codec.codec == VCD_CODEC_H264) {
+			encoder->bitstream_restrict_enable =
+			restrict_enable->bitstream_restrict_enable_flag;
+			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;
-	break;
+		break;
 	}
 	return vcd_status;
 }
@@ -1685,6 +1699,15 @@
 			vcd_status = VCD_S_SUCCESS;
 		}
 		break;
+	case VCD_I_ENABLE_VUI_BITSTREAM_RESTRICT_FLAG:
+		if (sizeof(struct vcd_property_bitstream_restrict_enable) ==
+			property_hdr->sz) {
+			((struct vcd_property_bitstream_restrict_enable *)
+				property_value)->bitstream_restrict_enable_flag
+					= encoder->bitstream_restrict_enable;
+			vcd_status = VCD_S_SUCCESS;
+		}
+	break;
 	default:
 		vcd_status = VCD_ERR_ILLEGAL_OP;
 		break;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
index 195b10b..19d7c34 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -85,6 +85,8 @@
 #define VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_SHFT    16
 #define VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_BMSK     0x00004000
 #define VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_SHFT     14
+#define VIDC_SM_ENC_EXT_CTRL_STREAM_RESTRICT_EN_BMSK 0x2000
+#define VIDC_SM_ENC_EXT_CTRL_STREAM_RESTRICT_EN_SHFT 13
 #define VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_BMSK    0x00000800
 #define VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_SHFT    11
 #define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_BMSK  0x80
@@ -460,8 +462,8 @@
 	enum VIDC_SM_frame_skip frame_skip_mode,
 	u32 seq_hdr_in_band, u32 vbv_buffer_size, u32 cpcfc_enable,
 	u32 sps_pps_control, u32 closed_gop_enable,
-	u32 au_delim_enable,
-	u32 vui_timing_info_enable)
+	u32 au_delim_enable, u32 vui_timing_info_enable,
+	u32 restrict_bitstream_enable)
 {
 	u32 enc_ctrl;
 	enc_ctrl = VIDC_SETFIELD((hec_enable) ? 1 : 0,
@@ -490,7 +492,10 @@
 			VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_BMSK) |
 			VIDC_SETFIELD((vui_timing_info_enable) ? 1 : 0,
 			VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_SHFT,
-			VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_BMSK);
+			VIDC_SM_ENC_EXT_CTRL_TIMING_INFO_EN_BMSK) |
+			VIDC_SETFIELD((restrict_bitstream_enable) ? 1 : 0,
+			VIDC_SM_ENC_EXT_CTRL_STREAM_RESTRICT_EN_SHFT,
+			VIDC_SM_ENC_EXT_CTRL_STREAM_RESTRICT_EN_BMSK);
 
 	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_EXT_CTRL_ADDR, enc_ctrl);
 }
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
index 426d7f6..51feaf9 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
@@ -106,7 +106,8 @@
 	struct ddl_buf_addr *shared_mem, u32 hec_enable,
 	enum VIDC_SM_frame_skip  frame_skip_mode, u32 seq_hdr_in_band,
 	u32 vbv_buffer_size, u32 cpcfc_enable, u32 sps_pps_control,
-	u32 closed_gop_enable, u32 au_delim_enable, u32 vui_timing_info_enable);
+	u32 closed_gop_enable, u32 au_delim_enable, u32 vui_timing_info_enable,
+	u32 restrict_bitstream_enable);
 void vidc_sm_set_encoder_param_change(struct ddl_buf_addr *shared_mem,
 	u32 bit_rate_chg, u32 frame_rate_chg, u32 i_period_chg);
 void vidc_sm_set_encoder_vop_time(struct ddl_buf_addr *shared_mem,
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
index 92daca5..b62a7df 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -614,7 +614,8 @@
 		r_cframe_skip, false, 0,
 		h263_cpfc_enable, encoder->sps_pps.sps_pps_for_idr_enable_flag,
 		encoder->closed_gop, encoder->avc_delimiter_enable,
-		encoder->vui_timinginfo_enable);
+		encoder->vui_timinginfo_enable,
+		encoder->bitstream_restrict_enable);
 	if (encoder->vui_timinginfo_enable) {
 		vidc_sm_set_h264_encoder_timing_info(
 			&ddl->shared_mem[ddl->command_channel],
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 6075e06..5adfdc9 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1738,6 +1738,27 @@
 		}
 		break;
 	}
+	case VEN_IOCTL_SET_VUI_BITSTREAM_RESTRICT_FLAG:
+	{
+		struct vcd_property_hdr vcd_property_hdr;
+		struct vcd_property_bitstream_restrict_enable vcd_property_val;
+		u32 vcd_status = VCD_ERR_FAIL;
+
+		vcd_property_hdr.prop_id =
+			VCD_I_ENABLE_VUI_BITSTREAM_RESTRICT_FLAG;
+		vcd_property_hdr.sz = sizeof(struct
+				vcd_property_bitstream_restrict_enable);
+
+		vcd_property_val.bitstream_restrict_enable_flag = true;
+
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				&vcd_property_hdr, &vcd_property_val);
+		if (vcd_status) {
+			pr_err("Setting bitstream restrict flag failed");
+			return -EIO;
+		}
+		break;
+	}
 	case VEN_IOCTL_SET_AC_PREDICTION:
 	case VEN_IOCTL_GET_AC_PREDICTION:
 	case VEN_IOCTL_SET_RVLC:
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index 7914723..2e98f4c 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -464,6 +464,10 @@
 #define VEN_IOCTL_SET_SPS_PPS_FOR_IDR \
 	_IOW(VEN_IOCTLBASE_ENC, 51, struct venc_ioctl_msg)
 
+/*IOCTL params:SET: InputData - NULL, OutputData - NULL.*/
+#define VEN_IOCTL_SET_VUI_BITSTREAM_RESTRICT_FLAG \
+	_IO(VEN_IOCTLBASE_ENC, 52)
+
 struct venc_switch{
 	unsigned char	status;
 };
diff --git a/include/media/msm/vcd_property.h b/include/media/msm/vcd_property.h
index 5b83214..a6359df 100644
--- a/include/media/msm/vcd_property.h
+++ b/include/media/msm/vcd_property.h
@@ -60,6 +60,7 @@
 #define VCD_I_SET_EXT_METABUFFER (VCD_START_BASE + 0x2C)
 #define VCD_I_FREE_EXT_METABUFFER (VCD_START_BASE + 0x2D)
 #define VCD_I_ENABLE_SEC_METADATA (VCD_START_BASE + 0x2E)
+#define VCD_I_ENABLE_VUI_BITSTREAM_RESTRICT_FLAG (VCD_START_BASE + 0x2F)
 
 
 #define VCD_START_REQ      (VCD_START_BASE + 0x1000)
@@ -404,4 +405,8 @@
 	u8 *dev_addr_iommu;
 	void *client_data_iommu;
 };
+
+struct vcd_property_bitstream_restrict_enable {
+	u32 bitstream_restrict_enable_flag;
+};
 #endif