vidc: Adjust core timeout based on input frame size

Video core is dropping certain IDR frames due to timeout.
This is resulting in video corruption. Computing the core
timeout based on input frame size and programming it for
each input frame fixes the issue.

Change-Id: I75d5039bc09f9be6a3028461ee4a2f13064bf53a
CRs-fixed: 370570
Signed-off-by: Rajeshwar Kurapaty <rkurapat@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 3c082e4..0c6aa86 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -310,6 +310,7 @@
 	u32  header_in_start;
 	u32  min_dpb_num;
 	u32  y_cb_cr_size;
+	u32  yuv_size;
 	u32  dynamic_prop_change;
 	u32  dynmic_prop_change_req;
 	u32  flush_pending;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
index 8a33512..db8a777 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
@@ -64,6 +64,7 @@
 #define DDL_VIDC_1080P_48MHZ_TIMEOUT_VALUE	(0xCB8)
 #define DDL_VIDC_1080P_133MHZ_TIMEOUT_VALUE	(0x2355)
 #define DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE	(0x3500)
+#define DDL_VIDC_1080P_MAX_TIMEOUT_MULTIPLIER  (4)
 
 #define DDL_CONTEXT_MEMORY (1024 * 15 * (VCD_MAX_NO_CLIENT + 1))
 
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
index d7ebd54..949e5c0 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -1087,8 +1087,39 @@
 void ddl_set_vidc_timeout(struct ddl_client_context *ddl)
 {
 	u32 vidc_time_out = 0;
+	s32 multiplier = 1;
+	u32 temp = DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE;
+	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
+	struct vcd_frame_data *ip_bitstream = &(ddl->input_frame.vcd_frm);
+
 	if (ddl->codec_data.decoder.idr_only_decoding)
 		vidc_time_out = 2 * DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE;
+	else {
+		vidc_time_out = DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE;
+		multiplier = decoder->yuv_size - (ip_bitstream->data_len +
+						(ip_bitstream->data_len / 2));
+		if (multiplier <= 0) {
+			multiplier = decoder->yuv_size - ip_bitstream->data_len;
+			if (multiplier <= 0) {
+				if (ip_bitstream->data_len)
+					multiplier =
+					DDL_VIDC_1080P_MAX_TIMEOUT_MULTIPLIER;
+			}
+		}
+		if (multiplier == DDL_VIDC_1080P_MAX_TIMEOUT_MULTIPLIER)
+			vidc_time_out = vidc_time_out *
+				DDL_VIDC_1080P_MAX_TIMEOUT_MULTIPLIER;
+		else if (multiplier > 1) {
+			temp = (decoder->yuv_size * 1000) / multiplier;
+			temp = (temp * vidc_time_out) / 1000;
+			if (temp > (u32)(vidc_time_out *
+				DDL_VIDC_1080P_MAX_TIMEOUT_MULTIPLIER))
+				vidc_time_out = vidc_time_out *
+					DDL_VIDC_1080P_MAX_TIMEOUT_MULTIPLIER;
+			else
+				vidc_time_out = temp;
+		}
+	}
 	DDL_MSG_HIGH("%s Video core time out value = 0x%x",
 		 __func__, vidc_time_out);
 	vidc_sm_set_video_core_timeout_value(
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index 58d1f23..6571245 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -189,6 +189,9 @@
 			&decoder->frame_size.height);
 		progressive = seq_hdr_info->dec_progressive;
 	}
+	decoder->yuv_size = decoder->frame_size.width *
+				decoder->frame_size.height;
+	decoder->yuv_size += decoder->yuv_size / 2;
 	decoder->min_dpb_num = seq_hdr_info->min_num_dpb;
 	vidc_sm_get_min_yc_dpb_sizes(
 		&ddl->shared_mem[ddl->command_channel],
@@ -1266,6 +1269,9 @@
 			decoder->frame_size =
 				 output_vcd_frm->dec_op_prop.frm_size;
 			decoder->client_frame_size = decoder->frame_size;
+			decoder->yuv_size = decoder->frame_size.width *
+						decoder->frame_size.height;
+			decoder->yuv_size += decoder->yuv_size / 2;
 			decoder->y_cb_cr_size =
 				ddl_get_yuv_buffer_size(&decoder->frame_size,
 					&decoder->buf_format,
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 14e1331..a6001eb 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -1077,6 +1077,7 @@
 		decoder->flush_pending = false;
 	} else
 		dec_param.dpb_flush = false;
+	ddl_set_vidc_timeout(ddl);
 	vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel],
 		bit_stream->ip_frm_tag);
 	if (ddl_context->pix_cache_enable) {