vidc: 1080p : Add support for slice delivery mode to encoder

Slice delivery mode enables confguring the encoder to deliver
one slice per output buffer. This mode is valid only for h264
codec when multi slice config is set to slice by mb.

Change-Id: I1bb88a67fecf4a76ad828f4c4981ff3cad648f24
Signed-off-by: Pradnya Chaphekar <pradnyac@codeaurora.org>
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
index 6ebc955..8156505 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c
@@ -300,6 +300,27 @@
 				encoder->seq_header.virtual_base_addr,
 				encoder->seq_header.buffer_size,
 				ION_IOC_CLEAN_INV_CACHES);
+	if (encoder->slice_delivery_info.enable) {
+		DDL_MSG_LOW("%s: slice mode allocate memory for struct\n",
+					__func__);
+		ptr = ddl_pmem_alloc(&encoder->batch_frame.slice_batch_in,
+				DDL_ENC_SLICE_BATCH_INPSTRUCT_SIZE,
+				DDL_LINEAR_BUFFER_ALIGN_BYTES);
+		if (ptr) {
+			ptr = ddl_pmem_alloc(
+				&encoder->batch_frame.slice_batch_out,
+				DDL_ENC_SLICE_BATCH_OUTSTRUCT_SIZE,
+				DDL_LINEAR_BUFFER_ALIGN_BYTES);
+		}
+		if (!ptr) {
+			ddl_pmem_free(&encoder->batch_frame.slice_batch_in);
+			ddl_pmem_free(&encoder->batch_frame.slice_batch_out);
+			ddl_free_enc_hw_buffers(ddl);
+			ddl_pmem_free(&encoder->seq_header);
+			DDL_MSG_ERROR("ddlEncStart:SeqHdrAllocFailed");
+			return VCD_ERR_ALLOC_FAIL;
+		}
+	}
 	if (!ddl_take_command_channel(ddl_context, ddl, client_data))
 		return VCD_ERR_BUSY;
 	ddl_vidc_channel_set(ddl);
@@ -451,7 +472,17 @@
 	struct ddl_client_context *ddl =
 		(struct ddl_client_context *) ddl_handle;
 	struct ddl_context *ddl_context;
+	struct ddl_encoder_data *encoder =
+		&ddl->codec_data.encoder;
 	u32 vcd_status = VCD_S_SUCCESS;
+	if (encoder->slice_delivery_info.enable) {
+		return ddl_encode_frame_batch(ddl_handle,
+					input_frame,
+					output_bit,
+					1,
+					encoder->slice_delivery_info.num_slices,
+					client_data);
+	}
 
 	DDL_MSG_HIGH("ddl_encode_frame");
 	if (vidc_msg_timing)
@@ -519,6 +550,76 @@
 	return vcd_status;
 }
 
+u32 ddl_encode_frame_batch(u32 *ddl_handle,
+	struct ddl_frame_data_tag *input_frame,
+	struct ddl_frame_data_tag *output_bit,
+	u32 num_in_frames, u32 num_out_frames,
+	void *client_data)
+{
+	struct ddl_client_context *ddl =
+		(struct ddl_client_context *) ddl_handle;
+	struct ddl_context *ddl_context;
+	u32 vcd_status = VCD_S_SUCCESS;
+	struct ddl_encoder_data *encoder;
+
+	DDL_MSG_LOW("ddl_encode_frame_batch");
+	ddl_context = ddl_get_context();
+	if (!DDL_IS_INITIALIZED(ddl_context)) {
+		DDL_MSG_ERROR("ddl_enc_frame:Not_inited");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (DDL_IS_BUSY(ddl_context)) {
+		DDL_MSG_ERROR("ddl_enc_frame:Ddl_busy");
+		return VCD_ERR_BUSY;
+	}
+	if (!ddl || ddl->decoding) {
+		DDL_MSG_ERROR("ddl_enc_frame:Bad_handle");
+	return VCD_ERR_BAD_HANDLE;
+	}
+	if (!input_frame || !input_frame->vcd_frm.physical	||
+		!input_frame->vcd_frm.data_len) {
+		DDL_MSG_ERROR("ddl_enc_frame:Bad_input_params");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	if ((((u32) input_frame->vcd_frm.physical +
+		input_frame->vcd_frm.offset) &
+		(DDL_STREAMBUF_ALIGN_GUARD_BYTES))) {
+		DDL_MSG_ERROR("ddl_enc_frame:Un_aligned_yuv_start_address");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	if (!output_bit || !output_bit->vcd_frm.physical ||
+		!output_bit->vcd_frm.alloc_len) {
+		DDL_MSG_ERROR("ddl_enc_frame:Bad_output_params");
+		return VCD_ERR_ILLEGAL_PARM;
+	}
+	if ((ddl->codec_data.encoder.output_buf_req.sz +
+		output_bit->vcd_frm.offset) >
+		output_bit->vcd_frm.alloc_len)
+		DDL_MSG_ERROR("ddl_enc_frame:offset_large,"
+			"Exceeds_min_buf_size");
+	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) {
+		DDL_MSG_ERROR("ddl_enc_frame:Wrong_state");
+		return VCD_ERR_ILLEGAL_OP;
+	}
+	if (!ddl_take_command_channel(ddl_context, ddl, client_data))
+		return VCD_ERR_BUSY;
+	encoder = &ddl->codec_data.encoder;
+	if (encoder->slice_delivery_info.enable) {
+		DDL_MEMCPY((void *)&(encoder->batch_frame.output_frame[0]),
+			(void *)output_bit,
+			sizeof(struct ddl_frame_data_tag) * num_out_frames);
+		encoder->batch_frame.num_output_frames = num_out_frames;
+		ddl->input_frame = *input_frame;
+		vcd_status = ddl_insert_input_frame_to_pool(ddl, input_frame);
+		if (!vcd_status)
+			ddl_vidc_encode_slice_batch_run(ddl);
+		else
+			DDL_MSG_ERROR("insert to frame pool failed %u",
+					vcd_status);
+	}
+	return vcd_status;
+}
+
 u32 ddl_decode_end(u32 *ddl_handle, void *client_data)
 {
 	struct ddl_client_context *ddl =
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
index c3874fa..d05e542 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h
@@ -113,6 +113,7 @@
 	DDL_CMD_ENCODE_FRAME    = 0x8,
 	DDL_CMD_EOS             = 0x9,
 	DDL_CMD_CHANNEL_END     = 0xA,
+	DDL_CMD_ENCODE_CONTINUE = 0xB,
 	DDL_CMD_32BIT           = 0x7FFFFFFF
 };
 enum ddl_client_state{
@@ -129,6 +130,7 @@
 	DDL_CLIENT_WAIT_FOR_CHEND          = 0xA,
 	DDL_CLIENT_FATAL_ERROR             = 0xB,
 	DDL_CLIENT_FAVIDC_ERROR            = 0xC,
+	DDL_CLIENT_WAIT_FOR_CONTINUE       = 0xD,
 	DDL_CLIENT_32BIT                   = 0x7FFFFFFF
 };
 struct ddl_hw_interface{
@@ -215,6 +217,15 @@
 struct ddl_codec_data_hdr{
 	u32  decoding;
 };
+struct ddl_batch_frame_data {
+	struct ddl_buf_addr slice_batch_in;
+	struct ddl_buf_addr slice_batch_out;
+	struct ddl_frame_data_tag input_frame;
+	struct ddl_frame_data_tag output_frame
+			[DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH];
+	u32 num_output_frames;
+	u32 out_frm_next_frmindex;
+};
 struct ddl_encoder_data{
 	struct ddl_codec_data_hdr   hdr;
 	struct vcd_property_codec   codec;
@@ -262,6 +273,8 @@
 	u32  ext_enc_control_val;
 	u32  num_references_for_p_frame;
 	u32  closed_gop;
+	struct vcd_property_slice_delivery_info slice_delivery_info;
+	struct ddl_batch_frame_data batch_frame;
 };
 struct ddl_decoder_data {
 	struct ddl_codec_data_hdr  hdr;
@@ -344,6 +357,8 @@
 		(struct vidc_1080p_enc_seq_start_param *param);
 	void(*vidc_encode_frame_start[2])
 		(struct vidc_1080p_enc_frame_start_param *param);
+	void(*vidc_encode_slice_batch_start[2])
+		(struct vidc_1080p_enc_frame_start_param *param);
 	u32 frame_channel_depth;
 };
 struct ddl_client_context{
@@ -375,9 +390,12 @@
 void ddl_vidc_channel_end(struct ddl_client_context *);
 void ddl_vidc_encode_init_codec(struct ddl_client_context *);
 void ddl_vidc_decode_init_codec(struct ddl_client_context *);
+void ddl_vidc_encode_frame_continue(struct ddl_client_context *);
 void ddl_vidc_encode_frame_run(struct ddl_client_context *);
+void ddl_vidc_encode_slice_batch_run(struct ddl_client_context *);
 void ddl_vidc_decode_frame_run(struct ddl_client_context *);
 void ddl_vidc_decode_eos_run(struct ddl_client_context *ddl);
+void ddl_vidc_encode_eos_run(struct ddl_client_context *ddl);
 void ddl_release_context_buffers(struct ddl_context *);
 void ddl_release_client_internal_buffers(struct ddl_client_context *ddl);
 u32  ddl_vidc_decode_set_buffers(struct ddl_client_context *);
@@ -438,9 +456,10 @@
 
 u32 ddl_get_input_frame_from_pool(struct ddl_client_context *ddl,
 	u8 *input_buffer_address);
+u32 ddl_get_stream_buf_from_batch_pool(struct ddl_client_context *ddl,
+	struct ddl_frame_data_tag *stream_buffer);
 u32 ddl_insert_input_frame_to_pool(struct ddl_client_context *ddl,
 	struct ddl_frame_data_tag *ddl_input_frame);
-
 void ddl_decoder_chroma_dpb_change(struct ddl_client_context *ddl);
 u32  ddl_check_reconfig(struct ddl_client_context *ddl);
 void ddl_handle_reconfig(u32 res_change, struct ddl_client_context *ddl);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
index 433dad4..5c1ee21 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h
@@ -62,6 +62,11 @@
 	u32 disable_static_region_as_flag;
 	u32 disable_activity_region_flag;
 };
+struct vcd_property_slice_delivery_info {
+	u32  enable;
+	u32  num_slices;
+	u32  num_slices_enc;
+};
 struct ddl_property_dec_pic_buffers{
 	struct ddl_frame_data_tag *dec_pic_buffers;
 	u32 no_of_dec_pic_buf;
@@ -94,6 +99,11 @@
 u32 ddl_encode_frame(u32 *ddl_handle,
 	struct ddl_frame_data_tag *input_frame,
 	struct ddl_frame_data_tag *output_bit, void *client_data);
+u32 ddl_encode_frame_batch(u32 *ddl_handle,
+	struct ddl_frame_data_tag *input_frame,
+	struct ddl_frame_data_tag *output_bit,
+	u32 num_in_frames, u32 num_out_frames,
+	void *client_data);
 u32 ddl_encode_end(u32 *ddl_handle, void *client_data);
 u32 ddl_decode_start(u32 *ddl_handle, struct vcd_sequence_hdr *header,
 	void *client_data);
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 a8ccebf..41604b0 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
@@ -64,13 +64,20 @@
 #define DDL_FW_INST_GLOBAL_CONTEXT_SPACE_SIZE  (DDL_KILO_BYTE(800))
 #define DDL_FW_H264DEC_CONTEXT_SPACE_SIZE      (DDL_KILO_BYTE(800))
 #define DDL_FW_H264ENC_CONTEXT_SPACE_SIZE      (DDL_KILO_BYTE(20))
-#define DDL_FW_OTHER_CONTEXT_SPACE_SIZE        (DDL_KILO_BYTE(10))
+#define DDL_FW_OTHER_CONTEXT_SPACE_SIZE        (DDL_KILO_BYTE(20))
 
 #define VCD_DEC_CPB_SIZE         (DDL_KILO_BYTE(512))
 #define DDL_DBG_CORE_DUMP_SIZE   (DDL_KILO_BYTE(10))
+#define DDL_VIDC_1080P_BASE_OFFSET_SHIFT        11
 
 #define DDL_BUFEND_PAD                    256
 #define DDL_ENC_SEQHEADER_SIZE            (512+DDL_BUFEND_PAD)
+#define DDL_ENC_SLICE_BATCH_FACTOR         5
+#define DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH   8
+#define DDL_ENC_SLICE_BATCH_INPSTRUCT_SIZE (128 + \
+				32 * DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH)
+#define DDL_ENC_SLICE_BATCH_OUTSTRUCT_SIZE (64 + \
+				64 * DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH)
 #define DDL_MAX_BUFFER_COUNT              32
 #define DDL_MIN_BUFFER_COUNT              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 62f0976..0d0ba3e 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -375,6 +375,8 @@
 		struct ddl_encoder_data *encoder =
 			&(ddl->codec_data.encoder);
 		ddl_pmem_free(&encoder->seq_header);
+		ddl_pmem_free(&encoder->batch_frame.slice_batch_in);
+		ddl_pmem_free(&encoder->batch_frame.slice_batch_out);
 		ddl_vidc_encode_dynamic_property(ddl, false);
 		encoder->dynamic_prop_change = 0;
 		ddl_free_enc_hw_buffers(ddl);
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 830c777..79e6c5d 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
@@ -29,7 +29,11 @@
 	enum vidc_1080p_encode_frame frame_type);
 static void ddl_get_dec_profile_level(struct ddl_decoder_data *decoder,
 	u32 profile, u32 level);
-static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl);
+static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl,
+	u32 eos_present);
+static void ddl_handle_slice_done_slice_batch(struct ddl_client_context *ddl);
+static void ddl_handle_enc_frame_done_slice_mode(
+		struct ddl_client_context *ddl, u32 eos_present);
 
 static void ddl_fw_status_done_callback(struct ddl_context *ddl_context)
 {
@@ -141,7 +145,7 @@
 {
 	struct ddl_encoder_data *encoder;
 
-	DDL_MSG_MED("ddl_encoder_seq_done_callback");
+	DDL_MSG_HIGH("ddl_encoder_seq_done_callback");
 	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) {
 		DDL_MSG_ERROR("STATE-CRITICAL-INITCODEC");
 		ddl_client_fatal_cb(ddl);
@@ -486,9 +490,9 @@
 		&(ddl->codec_data.encoder);
 	struct vcd_frame_data *output_frame =
 		&(ddl->output_frame.vcd_frm);
-	u32 bottom_frame_tag;
+	u32 eos_present = false;
 
-	DDL_MSG_MED("ddl_encoder_frame_run_callback");
+	DDL_MSG_MED("ddl_encoder_frame_run_callback\n");
 	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) &&
 		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) {
 		DDL_MSG_ERROR("STATE-CRITICAL-ENCFRMRUN");
@@ -499,47 +503,28 @@
 		DDL_MSG_LOW("ENC_FRM_RUN_DONE");
 		ddl->cmd_state = DDL_CMD_INVALID;
 		vidc_1080p_get_encode_frame_info(&encoder->enc_frame_info);
-		vidc_sm_get_frame_tags(&ddl->shared_mem
-			[ddl->command_channel],
-			&output_frame->ip_frm_tag, &bottom_frame_tag);
 
 		if (encoder->meta_data_enable_flag)
 			vidc_sm_get_metadata_status(&ddl->shared_mem
 				[ddl->command_channel],
 				&encoder->enc_frame_info.meta_data_exists);
 
+		if (VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags) {
+				DDL_MSG_LOW("%s EOS detected\n", __func__);
+				eos_present = true;
+		}
+
 		if (encoder->enc_frame_info.enc_frame_size ||
 			(encoder->enc_frame_info.enc_frame ==
 			VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED) ||
 			DDLCLIENT_STATE_IS(ddl,
 			DDL_CLIENT_WAIT_FOR_EOS_DONE)) {
-			u8 *input_buffer_address = NULL;
-			output_frame->data_len =
-				encoder->enc_frame_info.enc_frame_size;
-			output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
-			ddl_get_encoded_frame(output_frame,
-				encoder->codec.codec,
-				encoder->enc_frame_info.enc_frame);
-			ddl_process_encoder_metadata(ddl);
-			ddl_vidc_encode_dynamic_property(ddl, false);
-			ddl->input_frame.frm_trans_end = false;
-			input_buffer_address = ddl_context->dram_base_a.\
-				align_physical_addr +
-				encoder->enc_frame_info.enc_luma_address;
-			ddl_get_input_frame_from_pool(ddl,
-				input_buffer_address);
-			ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE,
-				VCD_S_SUCCESS, &(ddl->input_frame),
-				sizeof(struct ddl_frame_data_tag),
-				(u32 *)ddl, ddl->client_data);
-			ddl->output_frame.frm_trans_end =
-				DDLCLIENT_STATE_IS(ddl,
-				DDL_CLIENT_WAIT_FOR_EOS_DONE) ? false : true;
-			ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
-				VCD_S_SUCCESS, &(ddl->output_frame),
-				sizeof(struct ddl_frame_data_tag),
-				(u32 *)ddl, ddl->client_data);
-
+			if (encoder->slice_delivery_info.enable) {
+				ddl_handle_enc_frame_done_slice_mode(ddl,
+								eos_present);
+			} else {
+				ddl_handle_enc_frame_done(ddl, eos_present);
+			}
 			if (DDLCLIENT_STATE_IS(ddl,
 				DDL_CLIENT_WAIT_FOR_EOS_DONE) &&
 				encoder->i_period.b_frames) {
@@ -547,7 +532,7 @@
 					(ddl->extra_output_buf_count >
 					encoder->i_period.b_frames)) {
 					DDL_MSG_ERROR("Invalid B frame output"
-								"buffer index");
+								  "buffer index");
 				} else {
 					struct vidc_1080p_enc_frame_start_param
 						enc_param;
@@ -581,7 +566,11 @@
 					ddl_context->vidc_encode_frame_start
 						[ddl->command_channel]
 						(&enc_param);
-				} } else {
+					}
+				} else if (eos_present &&
+					encoder->slice_delivery_info.enable) {
+					ddl_vidc_encode_eos_run(ddl);
+				} else {
 				DDL_MSG_LOW("ddl_state_transition: %s ~~>"
 					"DDL_CLIENT_WAIT_FOR_FRAME",
 					ddl_get_state_string(
@@ -885,6 +874,7 @@
 	vidc_1080p_clear_returned_channel_inst_id();
 	ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
 			ddl_context->response_cmd_ch_id);
+	DDL_MSG_LOW("ddl_encoder_eos_done\n");
 	if (ddl == NULL) {
 		DDL_MSG_ERROR("NO_DDL_CONTEXT");
 	} else {
@@ -896,9 +886,11 @@
 				&(ddl->codec_data.encoder);
 			vidc_1080p_get_encode_frame_info(
 				&encoder->enc_frame_info);
-			ddl_handle_enc_frame_done(ddl);
+			if (!encoder->slice_delivery_info.enable) {
+				ddl_handle_enc_frame_done(ddl, true);
+				ddl->cmd_state = DDL_CMD_INVALID;
+			}
 			DDL_MSG_LOW("encoder_eos_done");
-			ddl->cmd_state = DDL_CMD_INVALID;
 			DDL_MSG_LOW("ddl_state_transition: %s ~~>"
 				"DDL_CLIENT_WAIT_FOR_FRAME",
 				ddl_get_state_string(ddl->client_state));
@@ -913,6 +905,35 @@
 	}
 }
 
+static u32 ddl_slice_done_callback(struct ddl_context *ddl_context)
+{
+	struct ddl_client_context *ddl;
+	u32 channel_inst_id;
+	u32 return_status = true;
+	DDL_MSG_LOW("ddl_sliceDoneCallback");
+	vidc_1080p_get_returned_channel_inst_id(&channel_inst_id);
+	vidc_1080p_clear_returned_channel_inst_id();
+	ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
+			ddl_context->response_cmd_ch_id);
+	if (ddl == NULL) {
+		DDL_MSG_ERROR("NO_DDL_CONTEXT");
+		return_status = false;
+	} else if (ddl->cmd_state == DDL_CMD_ENCODE_FRAME) {
+			ddl->cmd_state = DDL_CMD_INVALID;
+			if (DDLCLIENT_STATE_IS(ddl,
+				DDL_CLIENT_WAIT_FOR_FRAME_DONE)) {
+				ddl_handle_slice_done_slice_batch(ddl);
+			} else {
+				DDL_MSG_ERROR("STATE-CRITICAL-ENCFRMRUN : %s\n",
+					 __func__);
+				ddl_client_fatal_cb(ddl);
+			}
+	} else {
+		DDL_MSG_ERROR("UNKNOWN_SLICEDONE : %s\n", __func__);
+	}
+	return return_status;
+}
+
 static u32 ddl_process_intr_status(struct ddl_context *ddl_context,
 	u32 intr_status)
 {
@@ -931,6 +952,9 @@
 	case VIDC_1080P_RISC2HOST_CMD_FRAME_DONE_RET:
 		return_status = ddl_frame_run_callback(ddl_context);
 	break;
+	case VIDC_1080P_RISC2HOST_CMD_SLICE_DONE_RET:
+		 ddl_slice_done_callback(ddl_context);
+	break;
 	case VIDC_1080P_RISC2HOST_CMD_SYS_INIT_RET:
 		ddl_sys_init_done_callback(ddl_context,
 			ddl_context->response_cmd_ch_id);
@@ -963,6 +987,8 @@
 {
 	struct ddl_context *ddl_context;
 	struct ddl_hw_interface  *ddl_hw_response;
+	struct ddl_client_context *ddl;
+	struct ddl_encoder_data *encoder;
 
 	ddl_context = ddl_get_context();
 	if (!ddl_context->core_virtual_base_addr) {
@@ -971,12 +997,37 @@
 		ddl_hw_response = &ddl_context->ddl_hw_response;
 		vidc_1080p_get_risc2host_cmd(&ddl_hw_response->cmd,
 			&ddl_hw_response->arg1, &ddl_hw_response->arg2,
-			&ddl_hw_response->arg3, &ddl_hw_response->arg4);
+			&ddl_hw_response->arg3,
+			&ddl_hw_response->arg4);
+		DDL_MSG_LOW("%s vidc_1080p_get_risc2host_cmd cmd = %u"
+			"arg1 = %u arg2 = %u arg3 = %u"
+			"arg4 = %u\n",
+			__func__, ddl_hw_response->cmd,
+			ddl_hw_response->arg1, ddl_hw_response->arg2,
+			ddl_hw_response->arg3,
+			ddl_hw_response->arg4);
+		ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
+			ddl_context->response_cmd_ch_id);
+		if (ddl) {
+			encoder = &(ddl->codec_data.encoder);
+			if (encoder && encoder->slice_delivery_info.enable
+			&&
+			((ddl_hw_response->cmd ==
+				VIDC_1080P_RISC2HOST_CMD_SLICE_DONE_RET)
+			|| (ddl_hw_response->cmd ==
+				VIDC_1080P_RISC2HOST_CMD_FRAME_DONE_RET))) {
+				vidc_sm_set_encoder_slice_batch_int_ctrl(
+				&ddl->shared_mem[ddl->command_channel],
+				1);
+			}
+		}
 		vidc_1080p_clear_risc2host_cmd();
 		vidc_1080p_clear_interrupt();
 		vidc_1080p_get_risc2host_cmd_status(ddl_hw_response->arg2,
 			&ddl_context->cmd_err_status,
 			&ddl_context->disp_pic_err_status);
+		DDL_MSG_LOW("%s cmd_err_status = %d\n", __func__,
+				ddl_context->cmd_err_status);
 		ddl_context->response_cmd_ch_id = ddl_hw_response->arg1;
 	}
 }
@@ -1638,39 +1689,214 @@
 	decoder->level.level = level;
 }
 
-static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl)
+static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl,
+					u32 eos_present)
 {
 	struct ddl_context       *ddl_context = ddl->ddl_context;
 	struct ddl_encoder_data  *encoder = &(ddl->codec_data.encoder);
 	struct vcd_frame_data    *output_frame = &(ddl->output_frame.vcd_frm);
 	u32 bottom_frame_tag;
-	u8  *input_buffer_address = NULL;
+	u8 *input_buffer_address = NULL;
 
 	vidc_sm_get_frame_tags(&ddl->shared_mem[ddl->command_channel],
 		&output_frame->ip_frm_tag, &bottom_frame_tag);
 	output_frame->data_len = encoder->enc_frame_info.enc_frame_size;
 	output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
 	(void)ddl_get_encoded_frame(output_frame,
-		encoder->codec.codec, encoder->enc_frame_info.enc_frame);
+		encoder->codec.codec, encoder->enc_frame_info.enc_frame
+								);
 	ddl_process_encoder_metadata(ddl);
 	ddl_vidc_encode_dynamic_property(ddl, false);
 	ddl->input_frame.frm_trans_end = false;
 	input_buffer_address = ddl_context->dram_base_a.align_physical_addr +
 			encoder->enc_frame_info.enc_luma_address;
 	ddl_get_input_frame_from_pool(ddl, input_buffer_address);
-
 	ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE,
-		VCD_S_SUCCESS, &(ddl->input_frame),
-		sizeof(struct ddl_frame_data_tag),
-		(u32 *) ddl, ddl->client_data);
-
-	ddl->output_frame.frm_trans_end =
-		DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)
-			? false : true;
-
+					VCD_S_SUCCESS, &(ddl->input_frame),
+					sizeof(struct ddl_frame_data_tag),
+					(u32 *) ddl, ddl->client_data);
+	ddl->output_frame.frm_trans_end = eos_present ?
+		false : true;
 	ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
-		VCD_S_SUCCESS, &(ddl->output_frame),
-		sizeof(struct ddl_frame_data_tag),
-		(u32 *) ddl, ddl->client_data);
+				VCD_S_SUCCESS, &(ddl->output_frame),
+				sizeof(struct ddl_frame_data_tag),
+				(u32 *) ddl, ddl->client_data);
+}
 
+static void ddl_handle_slice_done_slice_batch(struct ddl_client_context *ddl)
+{
+	struct ddl_context       *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data  *encoder = &(ddl->codec_data.encoder);
+	struct vcd_frame_data    *output_frame = NULL;
+	u32 bottom_frame_tag;
+	struct vidc_1080p_enc_slice_batch_out_param *slice_output = NULL;
+	u32 num_slices_comp = 0;
+	u32 index = 0;
+	u32 start_bfr_idx = 0;
+	u32 actual_idx = 0;
+
+	DDL_MSG_LOW("%s\n", __func__);
+	vidc_sm_get_num_slices_comp(
+			&ddl->shared_mem[ddl->command_channel],
+			&num_slices_comp);
+	slice_output = (struct vidc_1080p_enc_slice_batch_out_param *)
+		(encoder->batch_frame.slice_batch_out.align_virtual_addr);
+	DDL_MSG_LOW(" after get no of slices = %d\n", num_slices_comp);
+	if (slice_output == NULL)
+		DDL_MSG_ERROR(" slice_output is NULL\n");
+	encoder->slice_delivery_info.num_slices_enc += num_slices_comp;
+	if (vidc_msg_timing) {
+		ddl_calc_core_proc_time_cnt(__func__, ENC_SLICE_OP_TIME,
+					num_slices_comp);
+		ddl_set_core_start_time(__func__, ENC_SLICE_OP_TIME);
+	}
+	DDL_MSG_LOW("%s : Slices Completed %d Total slices %d OutBfrInfo:"
+			"Cmd %d Size %d\n",
+			__func__,
+			num_slices_comp,
+			encoder->slice_delivery_info.num_slices_enc,
+			slice_output->cmd_type,
+			slice_output->output_size);
+	start_bfr_idx = encoder->batch_frame.out_frm_next_frmindex;
+	for (index = 0; index < num_slices_comp; index++) {
+		actual_idx =
+		slice_output->slice_info[start_bfr_idx+index].stream_buffer_idx;
+		DDL_MSG_LOW("Slice Info: OutBfrIndex %d SliceSize %d\n",
+			actual_idx,
+			slice_output->slice_info[start_bfr_idx+index].
+			stream_buffer_size);
+		output_frame = &(
+			encoder->batch_frame.output_frame[actual_idx].vcd_frm);
+		DDL_MSG_LOW("OutBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x"
+			"frmbfr(physical) 0x%x\n",
+			&output_frame,
+			output_frame.virtual_base_addr,
+			output_frame.physical_base_addr);
+		vidc_1080p_get_encode_frame_info(&encoder->enc_frame_info);
+		vidc_sm_get_frame_tags(&ddl->shared_mem
+			[ddl->command_channel],
+			&output_frame->ip_frm_tag, &bottom_frame_tag);
+		ddl_get_encoded_frame(output_frame,
+				encoder->codec.codec,
+				encoder->enc_frame_info.enc_frame);
+		output_frame->data_len =
+			slice_output->slice_info[actual_idx].stream_buffer_size;
+		ddl->output_frame =
+			encoder->batch_frame.output_frame[actual_idx];
+		ddl->output_frame.frm_trans_end = false;
+		ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
+				VCD_S_SUCCESS, &(ddl->output_frame),
+				sizeof(struct ddl_frame_data_tag),
+				(u32 *) ddl, ddl->client_data);
+		ddl->input_frame.frm_trans_end = false;
+		DDL_MSG_LOW("%s Set i/p o/p transactions to false\n", __func__);
+	}
+	encoder->batch_frame.out_frm_next_frmindex = start_bfr_idx + index;
+	ddl->cmd_state = DDL_CMD_ENCODE_FRAME;
+	vidc_sm_set_encoder_slice_batch_int_ctrl(
+			&ddl->shared_mem[ddl->command_channel],
+			0);
+}
+
+static void ddl_handle_enc_frame_done_slice_mode(
+		struct ddl_client_context *ddl, u32 eos_present)
+{
+	struct ddl_context       *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data  *encoder = &(ddl->codec_data.encoder);
+	struct vcd_frame_data    *output_frame = NULL;
+	u32 bottom_frame_tag;
+	u8 *input_buffer_address = NULL;
+	struct vidc_1080p_enc_slice_batch_out_param *slice_output = NULL;
+	u32 num_slices_comp = 0;
+	u32 index = 0;
+	u32 start_bfr_idx = 0;
+	u32 actual_idx = 0;
+	struct vcd_transc *transc;
+
+	DDL_MSG_LOW("%s\n", __func__);
+	vidc_sm_get_num_slices_comp(
+				&ddl->shared_mem[ddl->command_channel],
+				&num_slices_comp);
+	slice_output = (struct vidc_1080p_enc_slice_batch_out_param *)
+		encoder->batch_frame.slice_batch_out.align_virtual_addr;
+	encoder->slice_delivery_info.num_slices_enc += num_slices_comp;
+	if (vidc_msg_timing) {
+		ddl_calc_core_proc_time_cnt(__func__, ENC_OP_TIME,
+					num_slices_comp);
+	}
+	DDL_MSG_LOW("%s Slices Completed %d Total slices done = %d"
+		" OutBfrInfo: Cmd %d Size %d",
+		__func__,
+		num_slices_comp,
+		encoder->slice_delivery_info.num_slices_enc,
+		slice_output->cmd_type,
+		slice_output->output_size);
+	start_bfr_idx = encoder->batch_frame.out_frm_next_frmindex;
+	if ((encoder->slice_delivery_info.num_slices_enc %
+		encoder->batch_frame.num_output_frames) != 0) {
+		DDL_MSG_ERROR("ERROR : %d %d\n",
+		encoder->slice_delivery_info.num_slices_enc,
+		encoder->batch_frame.num_output_frames);
+	}
+	for (index = 0; index < num_slices_comp; index++) {
+		actual_idx =
+			slice_output->slice_info[start_bfr_idx+index]. \
+			stream_buffer_idx;
+		DDL_MSG_LOW("Slice Info: OutBfrIndex %d SliceSize %d",
+			actual_idx,
+			slice_output->slice_info[start_bfr_idx+index]. \
+			stream_buffer_size, 0);
+		output_frame =
+		&(encoder->batch_frame.output_frame[actual_idx].vcd_frm);
+		DDL_MSG_LOW("OutBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x"
+				"frmbfr(physical) 0x%x",
+				&output_frame,
+				output_frame.virtual_base_addr,
+				output_frame.physical_base_addr);
+		vidc_1080p_get_encode_frame_info(
+			&encoder->enc_frame_info);
+		vidc_sm_get_frame_tags(&ddl->shared_mem
+			[ddl->command_channel],
+			&output_frame->ip_frm_tag, &bottom_frame_tag);
+		ddl_get_encoded_frame(output_frame,
+				encoder->codec.codec,
+				encoder->enc_frame_info.enc_frame);
+		output_frame->data_len =
+			slice_output->slice_info[actual_idx].stream_buffer_size;
+		ddl->output_frame =
+			encoder->batch_frame.output_frame[actual_idx];
+		DDL_MSG_LOW(" %s actual_idx = %d"
+		"encoder->batch_frame.num_output_frames = %d\n", __func__,
+		actual_idx, encoder->batch_frame.num_output_frames);
+		if (encoder->batch_frame.num_output_frames == (actual_idx+1)) {
+			output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
+			ddl_vidc_encode_dynamic_property(ddl, false);
+			ddl->input_frame.frm_trans_end = true;
+			DDL_MSG_LOW("%s End of frame detected\n", __func__);
+			input_buffer_address =
+				ddl_context->dram_base_a.align_physical_addr +
+				encoder->enc_frame_info.enc_luma_address;
+			ddl_get_input_frame_from_pool(ddl,
+				input_buffer_address);
+			transc = (struct vcd_transc *)(ddl->client_data);
+			if (eos_present)
+				ddl->output_frame.frm_trans_end = false;
+			else
+				ddl->output_frame.frm_trans_end = true;
+		}
+		DDL_MSG_LOW("%s Before output done cb\n", __func__);
+		transc = (struct vcd_transc *)(ddl->client_data);
+		ddl->output_frame.vcd_frm = *output_frame;
+		ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
+				VCD_S_SUCCESS, &(ddl->output_frame),
+				sizeof(struct ddl_frame_data_tag),
+				(u32 *) ddl, ddl->client_data);
+	}
+	if (encoder->batch_frame.num_output_frames == (actual_idx+1)) {
+		DDL_MSG_LOW("%s sending input done\n", __func__);
+		ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE,
+				VCD_S_SUCCESS, &(ddl->input_frame),
+				sizeof(struct ddl_frame_data_tag),
+				(u32 *) ddl, ddl->client_data);
+	}
 }
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 7b284e9..2138c9c 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -287,6 +287,9 @@
 				ddl_set_default_decoder_buffer_req(decoder,
 					true);
 			}
+			DDL_MSG_LOW("set  VCD_I_FRAME_SIZE width = %d"
+				" height = %d\n",
+				frame_size->width, frame_size->height);
 			vcd_status = VCD_S_SUCCESS;
 		}
 	}
@@ -608,7 +611,15 @@
 		struct vcd_property_multi_slice *multi_slice =
 			(struct vcd_property_multi_slice *)
 				property_value;
-
+		DDL_MSG_HIGH("VCD_I_MULTI_SLICE eMSliceSel %d  nMSliceSize %d"
+				"Tot#of MB %d encoder->frame_size.width = %d"
+				"encoder->frame_size.height = %d",
+				(int)multi_slice->m_slice_sel,
+				multi_slice->m_slice_size,
+				DDL_NO_OF_MB(encoder->frame_size.width,
+					encoder->frame_size.height),
+				encoder->frame_size.width,
+				encoder->frame_size.height);
 		switch (multi_slice->m_slice_sel) {
 		case VCD_MSLICE_OFF:
 			vcd_status = VCD_S_SUCCESS;
@@ -618,11 +629,14 @@
 				vcd_status = VCD_S_SUCCESS;
 		break;
 		case VCD_MSLICE_BY_MB_COUNT:
-			if (multi_slice->m_slice_size >= 1 &&
+		{
+			if ((multi_slice->m_slice_size >= 1) &&
 				(multi_slice->m_slice_size <=
 				DDL_NO_OF_MB(encoder->frame_size.width,
-				encoder->frame_size.height)))
+					encoder->frame_size.height))) {
 				vcd_status = VCD_S_SUCCESS;
+			}
+		}
 		break;
 		case VCD_MSLICE_BY_BYTE_COUNT:
 			if (multi_slice->m_slice_size > 0)
@@ -850,6 +864,9 @@
 			encoder->client_output_buf_req.sz =
 				DDL_ALIGN(buffer_req->sz,
 				DDL_KILO_BYTE(4));
+			DDL_MSG_LOW("%s encoder->client_output_buf_req.sz"
+				"  = %d\n", __func__,
+				encoder->client_output_buf_req.sz);
 			vcd_status = VCD_S_SUCCESS;
 		}
 	}
@@ -920,8 +937,14 @@
 	case VCD_I_METADATA_HEADER:
 		DDL_MSG_LOW("Meta Data Interface is Requested");
 		if (!res_trk_check_for_sec_session()) {
-			vcd_status = ddl_set_metadata_params(ddl,
-				property_hdr, property_value);
+			if (!encoder->slice_delivery_info.enable) {
+				vcd_status = ddl_set_metadata_params(ddl,
+						property_hdr, property_value);
+			} else {
+				DDL_MSG_ERROR("Ignoring meta data settting in "
+					"slice mode: %s\n", __func__);
+				vcd_status = VCD_S_SUCCESS;
+			}
 		} else {
 			DDL_MSG_ERROR("Meta Data Interface is not "
 				"supported in secure session");
@@ -946,6 +969,70 @@
 		}
 		break;
 	}
+	case VCD_I_SLICE_DELIVERY_MODE:
+	{
+		size_t output_buf_size;
+		u32 num_mb, num_slices;
+		struct vcd_property_hdr slice_property_hdr;
+		struct vcd_property_meta_data_enable slice_meta_data;
+		DDL_MSG_HIGH("Set property VCD_I_SLICE_DELIVERY_MODE\n");
+		if (sizeof(u32) == property_hdr->sz &&
+			encoder->codec.codec == VCD_CODEC_H264 &&
+			encoder->multi_slice.m_slice_sel
+				 == VCD_MSLICE_BY_MB_COUNT &&
+			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
+			encoder->slice_delivery_info.enable
+				= *(u32 *)property_value;
+			DDL_MSG_HIGH("set encoder->slice_delivery_mode"
+				"  = %u\n",
+				encoder->slice_delivery_info.enable);
+			output_buf_size =
+				encoder->client_output_buf_req.sz;
+			num_mb = DDL_NO_OF_MB(encoder->frame_size.width,
+					encoder->frame_size.height);
+			num_slices = num_mb/
+				encoder->multi_slice.m_slice_size;
+			num_slices = ((num_mb - num_slices *
+				encoder->multi_slice.m_slice_size) > 0)
+				? (num_slices + 1) : num_slices;
+			encoder->slice_delivery_info.num_slices =
+				num_slices;
+			if (num_slices <= DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH) {
+				encoder->client_output_buf_req.min_count
+				= ((DDL_ENC_SLICE_BATCH_FACTOR * num_slices + 2)
+				> DDL_MAX_BUFFER_COUNT)
+				? DDL_MAX_BUFFER_COUNT :
+				(DDL_ENC_SLICE_BATCH_FACTOR * num_slices + 2);
+				output_buf_size =
+				encoder->client_output_buf_req.sz/num_slices;
+				encoder->client_output_buf_req.sz =
+				DDL_ALIGN(output_buf_size, DDL_KILO_BYTE(4));
+				encoder->output_buf_req =
+				encoder->client_output_buf_req;
+				DDL_MSG_HIGH("%s num_mb = %u num_slices = %u "
+				"output_buf_count = %u "
+				"output_buf_size = %u aligned size = %u\n",
+				__func__, num_mb, num_slices,
+				encoder->client_output_buf_req.min_count,
+				output_buf_size,
+				encoder->client_output_buf_req.sz);
+				slice_property_hdr.prop_id =
+					VCD_I_METADATA_ENABLE;
+				slice_property_hdr.sz =
+				sizeof(struct vcd_property_meta_data_enable);
+				ddl_get_metadata_params(ddl,
+						&slice_property_hdr,
+						&slice_meta_data);
+				slice_meta_data.meta_data_enable_flag
+					&= ~VCD_METADATA_ENC_SLICE;
+				ddl_set_metadata_params(ddl,
+						&slice_property_hdr,
+						&slice_meta_data);
+				vcd_status = VCD_S_SUCCESS;
+			}
+		}
+		break;
+	}
 	case VCD_REQ_PERF_LEVEL:
 		vcd_status = VCD_S_SUCCESS;
 		break;
@@ -1354,7 +1441,10 @@
 			property_hdr->sz) {
 				*(struct vcd_buffer_requirement *)
 			property_value = encoder->client_output_buf_req;
-				vcd_status = VCD_S_SUCCESS;
+			DDL_MSG_LOW("%s encoder->client_output_buf_req = %d\n",
+				 __func__,
+				encoder->client_output_buf_req.sz);
+			vcd_status = VCD_S_SUCCESS;
 		}
 	break;
 	case VCD_I_BUFFER_FORMAT:
@@ -1421,6 +1511,14 @@
 			vcd_status = VCD_S_SUCCESS;
 		}
 	break;
+	case VCD_I_SLICE_DELIVERY_MODE:
+		if (sizeof(struct vcd_property_slice_delivery_info) ==
+			property_hdr->sz) {
+			*(struct vcd_property_slice_delivery_info *)
+				property_value = encoder->slice_delivery_info;
+			vcd_status = VCD_S_SUCCESS;
+		}
+		break;
 	default:
 		vcd_status = VCD_ERR_ILLEGAL_OP;
 		break;
@@ -1579,6 +1677,9 @@
 		encoder->closed_gop = true;
 	ddl_set_default_metadata_flag(ddl);
 	ddl_set_default_encoder_buffer_req(encoder);
+	encoder->slice_delivery_info.enable = 0;
+	encoder->slice_delivery_info.num_slices = 0;
+	encoder->slice_delivery_info.num_slices_enc = 0;
 }
 
 static void ddl_set_default_enc_profile(struct ddl_encoder_data *encoder)
@@ -1725,8 +1826,7 @@
 	encoder->client_input_buf_req = encoder->input_buf_req;
 	memset(&encoder->output_buf_req , 0 ,
 		sizeof(struct vcd_buffer_requirement));
-	encoder->output_buf_req.min_count    =
-		encoder->i_period.b_frames + 2;
+	encoder->output_buf_req.min_count = encoder->i_period.b_frames + 2;
 	encoder->output_buf_req.actual_count =
 		encoder->output_buf_req.min_count + 3;
 	encoder->output_buf_req.max_count    = DDL_MAX_BUFFER_COUNT;
@@ -1737,6 +1837,8 @@
 		DDL_ALIGN(y_cb_cr_size, DDL_KILO_BYTE(4));
 	ddl_set_default_encoder_metadata_buffer_size(encoder);
 	encoder->client_output_buf_req = encoder->output_buf_req;
+	DDL_MSG_LOW("%s encoder->client_output_buf_req.sz = %d\n",
+		__func__, encoder->client_output_buf_req.sz);
 }
 
 u32 ddl_set_default_decoder_buffer_req(struct ddl_decoder_data *decoder,
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 cce779e..ac81916 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
@@ -156,6 +156,24 @@
 #define VIDC_SM_NEW_I_PERIOD_VALUE_BMASK       0xffffffff
 #define VIDC_SM_NEW_I_PERIOD_VALUE_SHFT        0
 
+#define VIDC_SM_BATCH_INPUT_ADDR                                  0x00a4
+#define VIDC_SM_BATCH_INPUT_ADDR_VALUE_BMSK                       0xffffffff
+#define VIDC_SM_BATCH_INPUT_ADDRL_VALUE_SHFT                      0
+#define VIDC_SM_BATCH_OUTPUT_ADDR                                 0x00a8
+#define VIDC_SM_BATCH_OUTPUT_ADDR_VALUE_BMSK                      0xffffffff
+#define VIDC_SM_BATCH_OUTPUT_ADDR_VALUE_SHFT                      0
+#define VIDC_SM_BATCH_OUTPUT_SIZE_ADDR                            0x00ac
+#define VIDC_SM_BATCH_OUTPUT_SIZE_VALUE_BMSK                      0xffffffff
+#define VIDC_SM_BATCH_OUTPUT_SIZE_VALUE_SHFT                      0
+#define VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_ADDR                     0x01c8
+#define VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_VALUE_BMSK               0x1
+#define VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_VALUE_SHFT               0
+#define VIDC_SM_ENC_NUM_OF_SLICE_ADDR                             0x01cc
+#define VIDC_SM_ENC_NUM_OF_SLICE_VALUE_BMSK                       0xffffffff
+#define VIDC_SM_ENC_NUM_OF_SLICE_VALUE_SHFT                       0
+#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_ADDR                        0x01d0
+#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_VALUE_BMSK                  0xffffffff
+#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_VALUE_SHFT                  0
 
 #define VIDC_SM_ALLOCATED_LUMA_DPB_SIZE_ADDR               0x0064
 #define VIDC_SM_ALLOCATED_CHROMA_DPB_SIZE_ADDR             0x0068
@@ -799,3 +817,48 @@
 			VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT);
 	}
 }
+
+void vidc_sm_set_encoder_slice_batch_int_ctrl(struct ddl_buf_addr *shared_mem,
+	u32 slice_batch_int_enable)
+{
+	u32 slice_batch_int_ctrl = VIDC_SETFIELD((slice_batch_int_enable) ?
+				1 : 0,
+				VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_SHFT,
+				VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_BMSK);
+	DDL_MEM_WRITE_32(shared_mem,
+			VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_ADDR,
+			slice_batch_int_ctrl);
+}
+
+void vidc_sm_get_num_slices_comp(struct ddl_buf_addr *shared_mem,
+	u32 *num_slices_comp)
+{
+	*num_slices_comp = DDL_MEM_READ_32(shared_mem,
+				VIDC_SM_ENC_NUM_OF_SLICE_COMP_ADDR);
+}
+
+void vidc_sm_set_encoder_batch_config(struct ddl_buf_addr *shared_mem,
+				u32 num_slices,
+				u32 input_addr, u32 output_addr,
+				u32 output_buffer_size)
+{
+	DDL_MEM_WRITE_32(shared_mem,
+			VIDC_SM_ENC_NUM_OF_SLICE_ADDR,
+			num_slices);
+	DDL_MEM_WRITE_32(shared_mem,
+			VIDC_SM_BATCH_INPUT_ADDR,
+			input_addr);
+	DDL_MEM_WRITE_32(shared_mem,
+			VIDC_SM_BATCH_OUTPUT_ADDR,
+			output_addr);
+	DDL_MEM_WRITE_32(shared_mem,
+			VIDC_SM_BATCH_OUTPUT_SIZE_ADDR,
+			output_buffer_size);
+}
+
+void vidc_sm_get_encoder_batch_output_size(struct ddl_buf_addr *shared_mem,
+	u32 *output_buffer_size)
+{
+	*output_buffer_size = DDL_MEM_READ_32(shared_mem,
+			VIDC_SM_BATCH_OUTPUT_SIZE_ADDR);
+}
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 b0e6758..7d9896f 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
@@ -181,4 +181,14 @@
 	enum vidc_sm_num_stuff_bytes_consume_info consume_info);
 void vidc_sm_get_aspect_ratio_info(struct ddl_buf_addr *shared_mem,
 	struct vcd_aspect_ratio *aspect_ratio_info);
+void vidc_sm_set_encoder_slice_batch_int_ctrl(struct ddl_buf_addr *shared_mem,
+	u32 slice_batch_int_enable);
+void vidc_sm_get_num_slices_comp(struct ddl_buf_addr *shared_mem,
+	u32 *num_slices_comp);
+void vidc_sm_set_encoder_batch_config(struct ddl_buf_addr *shared_mem,
+				u32 num_slices,
+				u32 input_addr, u32 output_addr,
+				u32 output_buffer_size);
+void vidc_sm_get_encoder_batch_output_size(struct ddl_buf_addr *shared_mem,
+	u32 *output_buffer_size);
 #endif
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
index 126698c..27d3b5b 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
@@ -385,6 +385,36 @@
 	}
 }
 
+void ddl_calc_core_proc_time_cnt(const char *func_name, u32 index, u32 count)
+{
+	struct time_data *time_data = &proc_time[index];
+	if (time_data->ddl_t1) {
+		int ddl_t2;
+		struct timeval ddl_tv;
+		do_gettimeofday(&ddl_tv);
+		ddl_t2 = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000);
+		time_data->ddl_ttotal += (ddl_t2 - time_data->ddl_t1);
+		time_data->ddl_count += count;
+		DDL_MSG_TIME("\n%s(): cnt(%u) End Time (%u) Diff(%u) Avg(%u)",
+			func_name, time_data->ddl_count, ddl_t2,
+			ddl_t2 - time_data->ddl_t1,
+			time_data->ddl_ttotal/time_data->ddl_count);
+		time_data->ddl_t1 = 0;
+	}
+}
+
+void ddl_update_core_start_time(const char *func_name, u32 index)
+{
+	u32 act_time;
+	struct timeval ddl_tv;
+	struct time_data *time_data = &proc_time[index];
+	do_gettimeofday(&ddl_tv);
+	act_time = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000);
+	time_data->ddl_t1 = act_time;
+	DDL_MSG_LOW("\n%s(): Start time updated Act(%u)",
+				func_name, act_time);
+}
+
 void ddl_reset_core_time_variables(u32 index)
 {
 	proc_time[index].ddl_t1 = 0;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
index 10b3404..13bef35 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h
@@ -24,6 +24,7 @@
 	DEC_OP_TIME,
 	DEC_IP_TIME,
 	ENC_OP_TIME,
+	ENC_SLICE_OP_TIME,
 	MAX_TIME_DATA
 };
 
@@ -65,9 +66,12 @@
 
 #define DDL_MIN(x, y)  ((x < y) ? x : y)
 #define DDL_MAX(x, y)  ((x > y) ? x : y)
+#define DDL_MEMCPY(dest, src, len)  memcpy((dest), (src), (len))
+#define DDL_MEMSET(src, value, len) memset((src), (value), (len))
 
 void ddl_set_core_start_time(const char *func_name, u32 index);
 void ddl_calc_core_proc_time(const char *func_name, u32 index);
 void ddl_reset_core_time_variables(u32 index);
-
+void ddl_calc_core_proc_time_cnt(const char *func_name, u32 index, u32 count);
+void ddl_update_core_start_time(const char *func_name, u32 index);
 #endif
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 66e129c..d288ba3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -21,6 +21,7 @@
 #else
 #define DDL_PIX_CACHE_ENABLE  true
 #endif
+static unsigned int run_cnt;
 
 void ddl_vidc_core_init(struct ddl_context *ddl_context)
 {
@@ -57,6 +58,10 @@
 		vidc_1080p_encode_frame_start_ch0;
 	ddl_context->vidc_encode_frame_start[1] =
 		vidc_1080p_encode_frame_start_ch1;
+	ddl_context->vidc_encode_slice_batch_start[0] =
+		vidc_1080p_encode_slice_batch_start_ch0;
+	ddl_context->vidc_encode_slice_batch_start[1] =
+		vidc_1080p_encode_slice_batch_start_ch1;
 	vidc_1080p_release_sw_reset();
 	ddl_context->pix_cache_enable = DDL_PIX_CACHE_ENABLE;
 	if (ddl_context->pix_cache_enable) {
@@ -515,6 +520,29 @@
 		i_multi_slice_size, i_multi_slice_byte);
 }
 
+static void ddl_vidc_encode_set_batch_slice_info(
+	struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	DDL_MSG_LOW("%s\n", __func__);
+	encoder->batch_frame.slice_batch_out.buffer_size =
+					encoder->output_buf_req.sz;
+	DDL_MSG_LOW("encoder->batch_frame.slice_batch_out.buffer_size = %d\n",
+			encoder->batch_frame.slice_batch_out.buffer_size);
+	vidc_sm_set_encoder_batch_config(
+			&ddl->shared_mem[ddl->command_channel],
+			1,
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+			encoder->batch_frame.slice_batch_in),
+			DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+			encoder->batch_frame.slice_batch_out),
+			encoder->batch_frame.slice_batch_out.buffer_size);
+	vidc_sm_set_encoder_slice_batch_int_ctrl(
+			&ddl->shared_mem[ddl->command_channel],
+			0);
+}
+
 void ddl_vidc_encode_init_codec(struct ddl_client_context *ddl)
 {
 	struct ddl_context *ddl_context = ddl->ddl_context;
@@ -724,6 +752,7 @@
 	u32 dpb_addr_y[4], dpb_addr_c[4];
 	u32 index, y_addr, c_addr;
 
+	DDL_MSG_LOW("%s\n", __func__);
 	ddl_vidc_encode_set_metadata_output_buf(ddl);
 
 	encoder->enc_frame_info.meta_data_exists = false;
@@ -769,6 +798,7 @@
 	if (encoder->intra_frame_insertion)
 		encoder->intra_frame_insertion = false;
 	enc_param.input_flush = false;
+	enc_param.slice_enable = false;
 		vidc_sm_set_encoder_vop_time(
 			&ddl->shared_mem[ddl->command_channel], true,
 			encoder->vop_timing.vop_time_resolution,
@@ -800,6 +830,142 @@
 		&enc_param);
 }
 
+void ddl_vidc_encode_frame_continue(struct ddl_client_context *ddl)
+{
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct vcd_frame_data *input_vcd_frm = &(ddl->input_frame.vcd_frm);
+	u32 address_offset;
+	address_offset = (u32)(ddl->output_frame.vcd_frm.physical -
+			ddl_context->dram_base_a.align_physical_addr) >>
+			DDL_VIDC_1080P_BASE_OFFSET_SHIFT;
+	DDL_MSG_LOW("%s\n", __func__);
+	if (VCD_FRAME_FLAG_EOS & input_vcd_frm->flags)
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE;
+	else
+		ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE;
+	ddl->cmd_state = DDL_CMD_ENCODE_CONTINUE;
+	vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_CONTINUE_ENC,
+		address_offset,
+		0, 0, 0);
+}
+
+void ddl_vidc_encode_slice_batch_run(struct ddl_client_context *ddl)
+{
+	struct vidc_1080p_enc_frame_start_param enc_param;
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data  *encoder = &(ddl->codec_data.encoder);
+	struct ddl_enc_buffers *enc_buffers = &(encoder->hw_bufs);
+	struct vcd_frame_data *input_vcd_frm =
+		&(ddl->input_frame.vcd_frm);
+	u32 dpb_addr_y[4], dpb_addr_c[4];
+	u32 index, y_addr, c_addr;
+	u32 bitstream_size;
+	struct vidc_1080p_enc_slice_batch_in_param *slice_batch_in =
+		(struct vidc_1080p_enc_slice_batch_in_param *)
+		encoder->batch_frame.slice_batch_in.align_virtual_addr;
+	DDL_MSG_LOW("%s\n", __func__);
+	DDL_MEMSET(slice_batch_in, 0,
+		sizeof(struct vidc_1080p_enc_slice_batch_in_param));
+	DDL_MEMSET(encoder->batch_frame.slice_batch_in.align_virtual_addr, 0,
+		sizeof(struct vidc_1080p_enc_slice_batch_in_param));
+	encoder->batch_frame.out_frm_next_frmindex = 0;
+	bitstream_size = encoder->batch_frame.output_frame[0].vcd_frm.alloc_len;
+	encoder->output_buf_req.sz = bitstream_size;
+	y_addr = DDL_OFFSET(ddl_context->dram_base_b.align_physical_addr,
+			input_vcd_frm->physical);
+	c_addr = (y_addr + encoder->input_buf_size.size_y);
+	enc_param.encode = VIDC_1080P_ENC_TYPE_SLICE_BATCH_START;
+	DDL_MSG_LOW("ddl_state_transition: %s ~~>"
+		"DDL_CLIENT_WAIT_FOR_FRAME_DONE",
+		ddl_get_state_string(ddl->client_state));
+	slice_batch_in->cmd_type = VIDC_1080P_ENC_TYPE_SLICE_BATCH_START;
+	ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE;
+	ddl->cmd_state = DDL_CMD_ENCODE_FRAME;
+	vidc_1080p_set_encode_circular_intra_refresh(
+		encoder->intra_refresh.cir_mb_number);
+	ddl_vidc_encode_set_multi_slice_info(encoder);
+	enc_param.cmd_seq_num = ++ddl_context->cmd_seq_num;
+	enc_param.inst_id = ddl->instance_id;
+	enc_param.shared_mem_addr_offset = DDL_ADDR_OFFSET(
+			ddl_context->dram_base_a,
+			ddl->shared_mem[ddl->command_channel]);
+	enc_param.current_y_addr_offset = y_addr;
+	enc_param.current_c_addr_offset = c_addr;
+	enc_param.stream_buffer_size = bitstream_size;
+	slice_batch_in->num_stream_buffer =
+		encoder->batch_frame.num_output_frames;
+	slice_batch_in->stream_buffer_size = bitstream_size;
+	DDL_MSG_LOW("%s slice_batch_in->num_stream_buffer = %u size = %u\n",
+			 __func__, slice_batch_in->num_stream_buffer,
+			slice_batch_in->stream_buffer_size);
+	for (index = 0; index < encoder->batch_frame.num_output_frames;
+		index++) {
+		slice_batch_in->stream_buffer_addr_offset[index] =
+		((DDL_OFFSET(ddl_context->dram_base_b.align_physical_addr,
+		encoder->batch_frame.output_frame[index].vcd_frm.physical)) >>
+			DDL_VIDC_1080P_BASE_OFFSET_SHIFT);
+	}
+	slice_batch_in->input_size = VIDC_1080P_SLICE_BATCH_IN_SIZE(index);
+	enc_param.intra_frame = encoder->intra_frame_insertion;
+	if (encoder->intra_frame_insertion)
+		encoder->intra_frame_insertion = false;
+	enc_param.input_flush = false;
+	enc_param.slice_enable =
+		encoder->slice_delivery_info.enable;
+	vidc_sm_set_encoder_vop_time(
+			&ddl->shared_mem[ddl->command_channel], true,
+			encoder->vop_timing.vop_time_resolution,
+			ddl->input_frame.frm_delta);
+	vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel],
+			ddl->input_frame.vcd_frm.ip_frm_tag);
+	DDL_MSG_LOW("%sdpb_count = %d\n", __func__, enc_buffers->dpb_count);
+	if (ddl_context->pix_cache_enable) {
+		for (index = 0; index < enc_buffers->dpb_count;
+			index++) {
+			dpb_addr_y[index] =
+				(u32) VIDC_1080P_DEC_DPB_RESET_VALUE;
+			dpb_addr_c[index] = (u32) enc_buffers->dpb_c
+				[index].align_physical_addr;
+		}
+
+		dpb_addr_y[index] = (u32) input_vcd_frm->physical;
+		dpb_addr_c[index] = (u32) input_vcd_frm->physical +
+				encoder->input_buf_size.size_y;
+
+		vidc_pix_cache_init_luma_chroma_base_addr(
+			enc_buffers->dpb_count + 1, dpb_addr_y, dpb_addr_c);
+		vidc_pix_cache_set_frame_size(encoder->frame_size.width,
+			encoder->frame_size.height);
+		vidc_pix_cache_set_frame_range(enc_buffers->sz_dpb_y,
+			enc_buffers->sz_dpb_c);
+		vidc_pix_cache_clear_cache_tags();
+	}
+	if ((!encoder->rc_level.frame_level_rc) &&
+		(!encoder->rc_level.mb_level_rc)) {
+		encoder->session_qp.p_frame_qp++;
+		if (encoder->session_qp.p_frame_qp > encoder->qp_range.max_qp)
+			encoder->session_qp.p_frame_qp =
+						encoder->qp_range.min_qp;
+		vidc_sm_set_pand_b_frame_qp(
+			&ddl->shared_mem[ddl->command_channel],
+				encoder->session_qp.b_frame_qp,
+				encoder->session_qp.p_frame_qp);
+	}
+
+	if (vidc_msg_timing) {
+		if (run_cnt < 2) {
+			ddl_reset_core_time_variables(ENC_OP_TIME);
+			ddl_reset_core_time_variables(ENC_SLICE_OP_TIME);
+			run_cnt++;
+		 }
+		ddl_update_core_start_time(__func__, ENC_SLICE_OP_TIME);
+		ddl_set_core_start_time(__func__, ENC_OP_TIME);
+	}
+	ddl_vidc_encode_set_batch_slice_info(ddl);
+	ddl_context->vidc_encode_slice_batch_start[ddl->command_channel] (
+			&enc_param);
+}
+
 u32 ddl_vidc_decode_set_buffers(struct ddl_client_context *ddl)
 {
 	struct ddl_context *ddl_context = ddl->ddl_context;
@@ -976,3 +1142,29 @@
 	ddl_context->vidc_decode_frame_start[ddl->command_channel] (
 		&dec_param);
 }
+
+void ddl_vidc_encode_eos_run(struct ddl_client_context *ddl)
+{
+	struct vidc_1080p_enc_frame_start_param enc_param;
+	struct ddl_context *ddl_context = ddl->ddl_context;
+	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
+	DDL_MSG_LOW("%s\n", __func__);
+	ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE;
+	ddl_vidc_encode_dynamic_property(ddl, true);
+	ddl->client_state = DDL_CMD_EOS;
+	DDL_MEMSET(&enc_param, 0, sizeof(enc_param));
+	enc_param.encode = VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA;
+	enc_param.cmd_seq_num = ++ddl_context->cmd_seq_num;
+	enc_param.inst_id = ddl->instance_id;
+	enc_param.shared_mem_addr_offset =
+		DDL_ADDR_OFFSET(ddl_context->dram_base_a,
+		ddl->shared_mem[ddl->command_channel]);
+	enc_param.current_y_addr_offset = 0;
+	enc_param.current_c_addr_offset = 0;
+	enc_param.stream_buffer_size = 0;
+	enc_param.intra_frame = encoder->intra_frame_insertion;
+	vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel],
+				ddl->input_frame.vcd_frm.ip_frm_tag);
+	ddl_context->vidc_encode_frame_start[ddl->command_channel](
+						&enc_param);
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.c b/drivers/video/msm/vidc/1080p/ddl/vidc.c
index 75014cc..d399847 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, 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
@@ -77,6 +77,10 @@
 #define VIDC_1080P_ENC_TYPE_FRAME_DATA       0x00020000
 #define VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA  0x00030000
 
+#define VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK   0x00004000
+#define VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT   14
+#define VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK      0x80000000
+#define VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT      31
 #define VIDC_1080P_MAX_INTRA_PERIOD 0xffff
 
 u8 *VIDC_BASE_PTR;
@@ -779,6 +783,7 @@
 void vidc_1080p_encode_frame_start_ch0(
 	struct vidc_1080p_enc_frame_start_param *param)
 {
+	u32 input_flush;
 	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
 	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
 	VIDC_HWIO_OUT(REG_117192,
@@ -791,8 +796,15 @@
 		VIDC_1080P_BASE_OFFSET_SHIFT);
 	VIDC_HWIO_OUT(REG_190381, param->intra_frame);
 	VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset);
-	VIDC_HWIO_OUT(REG_404623, param->input_flush);
+	input_flush = VIDC_SETFIELD(param->input_flush,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK);
+	input_flush |= VIDC_SETFIELD(param->slice_enable,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK);
+	VIDC_HWIO_OUT(REG_404623, input_flush);
 	VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num);
+
 	VIDC_HWIO_OUT(REG_666957, (u32)param->encode |
 		param->inst_id);
 }
@@ -800,7 +812,7 @@
 void vidc_1080p_encode_frame_start_ch1(
 	struct vidc_1080p_enc_frame_start_param *param)
 {
-
+	u32 input_flush;
 	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
 	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID);
 	VIDC_HWIO_OUT(REG_980194,
@@ -813,12 +825,71 @@
 		VIDC_1080P_BASE_OFFSET_SHIFT);
 	VIDC_HWIO_OUT(REG_887095, param->intra_frame);
 	VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset);
-	VIDC_HWIO_OUT(REG_404623, param->input_flush);
+	input_flush = VIDC_SETFIELD(param->input_flush,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK);
+	input_flush |= VIDC_SETFIELD(param->slice_enable,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK);
+
+	VIDC_HWIO_OUT(REG_404623, input_flush);
 	VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num);
 	VIDC_HWIO_OUT(REG_313350, (u32)param->encode |
 		param->inst_id);
 }
 
+void vidc_1080p_encode_slice_batch_start_ch0(
+	struct vidc_1080p_enc_frame_start_param *param)
+{
+	u32 input_flush;
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_612810, param->current_y_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_175608, param->current_c_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_190381, param->intra_frame);
+	VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset);
+	input_flush = VIDC_SETFIELD(param->input_flush,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK);
+	input_flush |= VIDC_SETFIELD(param->slice_enable,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK);
+	VIDC_HWIO_OUT(REG_404623, input_flush);
+	VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num);
+
+	VIDC_HWIO_OUT(REG_666957, (u32)param->encode |
+		param->inst_id);
+
+}
+
+void vidc_1080p_encode_slice_batch_start_ch1(
+	struct vidc_1080p_enc_frame_start_param *param)
+{
+	u32 input_flush;
+	VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);
+	VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID);
+	VIDC_HWIO_OUT(REG_655721, param->current_y_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_548308,  param->current_c_addr_offset >>
+		VIDC_1080P_BASE_OFFSET_SHIFT);
+	VIDC_HWIO_OUT(REG_887095, param->intra_frame);
+	VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset);
+	input_flush = VIDC_SETFIELD(param->input_flush,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK);
+	input_flush |= VIDC_SETFIELD(param->slice_enable,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT,
+			VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK);
+
+	VIDC_HWIO_OUT(REG_404623, input_flush);
+	VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num);
+	VIDC_HWIO_OUT(REG_313350, (u32)param->encode |
+		param->inst_id);
+
+}
+
 void vidc_1080p_set_encode_picture(u32 number_p, u32 number_b)
 {
 	u32 picture, ifrm_ctrl;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.h b/drivers/video/msm/vidc/1080p/ddl/vidc.h
index 7573ee8..7460ef3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc.h
@@ -21,11 +21,13 @@
 #define VIDC_1080P_RISC2HOST_CMD_CLOSE_CH_RET        2
 #define VIDC_1080P_RISC2HOST_CMD_SEQ_DONE_RET        4
 #define VIDC_1080P_RISC2HOST_CMD_FRAME_DONE_RET      5
+#define VIDC_1080P_RISC2HOST_CMD_SLICE_DONE_RET      6
 #define VIDC_1080P_RISC2HOST_CMD_ENC_COMPLETE_RET    7
 #define VIDC_1080P_RISC2HOST_CMD_SYS_INIT_RET        8
 #define VIDC_1080P_RISC2HOST_CMD_FW_STATUS_RET       9
 #define VIDC_1080P_RISC2HOST_CMD_FLUSH_COMMAND_RET  12
 #define VIDC_1080P_RISC2HOST_CMD_ABORT_RET          13
+#define VIDC_1080P_RISC2HOST_CMD_BATCH_ENC_RET      14
 #define VIDC_1080P_RISC2HOST_CMD_INIT_BUFFERS_RET   15
 #define VIDC_1080P_RISC2HOST_CMD_EDFU_INT_RET       16
 #define VIDC_1080P_RISC2HOST_CMD_ERROR_RET          32
@@ -188,7 +190,9 @@
 #define VIDC_1080P_ITLB_MISS_EXCEPTION_HANDLER        0x100
 #define VIDC_1080P_DATA_PAGE_FAULT_EXCEPTION_HANDLER  0x200
 #define VIDC_1080P_INST_PAGE_FAULT_EXCEPTION_HANDLER  0x400
-
+#define VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR           8
+#define VIDC_1080P_SLICE_BATCH_IN_SIZE(idx)           (4 * sizeof(u32) + \
+							idx * sizeof(u32))
 enum vidc_1080p_reset{
 	VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE   = 0x0,
 	VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE  = 0x1,
@@ -318,10 +322,11 @@
 	VIDC_1080P_DEC_TYPE_32BIT            = 0x7FFFFFFF
 };
 enum vidc_1080p_encode{
-	VIDC_1080P_ENC_TYPE_SEQ_HEADER       = 0x00010000,
-	VIDC_1080P_ENC_TYPE_FRAME_DATA       = 0x00020000,
-	VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA  = 0x00030000,
-	VIDC_1080P_ENC_TYPE_32BIT            = 0x7FFFFFFF
+	VIDC_1080P_ENC_TYPE_SEQ_HEADER        = 0x00010000,
+	VIDC_1080P_ENC_TYPE_FRAME_DATA        = 0x00020000,
+	VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA   = 0x00030000,
+	VIDC_1080P_ENC_TYPE_SLICE_BATCH_START = 0x00070000,
+	VIDC_1080P_ENC_TYPE_32BIT             = 0x7FFFFFFF
 };
 struct vidc_1080p_dec_seq_start_param{
 	u32 cmd_seq_num;
@@ -391,6 +396,7 @@
 	u32 stream_buffer_size;
 	u32 intra_frame;
 	u32 input_flush;
+	u32 slice_enable;
 	enum vidc_1080p_encode encode;
 };
 struct vidc_1080p_enc_frame_info{
@@ -402,6 +408,23 @@
 	enum vidc_1080p_encode_frame enc_frame;
 	u32 meta_data_exists;
 };
+struct vidc_1080p_enc_slice_batch_in_param {
+	u32 cmd_type;
+	u32 input_size;
+	u32 num_stream_buffer;
+	u32 stream_buffer_size;
+	u32 stream_buffer_addr_offset[VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR];
+};
+struct vidc_1080p_enc_slice_info {
+	u32 stream_buffer_idx;
+	u32 stream_buffer_size;
+};
+struct vidc_1080p_enc_slice_batch_out_param {
+	u32 cmd_type;
+	u32 output_size;
+	struct vidc_1080p_enc_slice_info slice_info
+		[VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR];
+};
 struct vidc_1080p_dec_disp_info{
 	u32 disp_resl_change;
 	u32 dec_resl_change;
@@ -519,6 +542,10 @@
 	struct vidc_1080p_enc_frame_start_param *param);
 void vidc_1080p_encode_frame_start_ch1(
 	struct vidc_1080p_enc_frame_start_param *param);
+void vidc_1080p_encode_slice_batch_start_ch0(
+	struct vidc_1080p_enc_frame_start_param *param);
+void vidc_1080p_encode_slice_batch_start_ch1(
+	struct vidc_1080p_enc_frame_start_param *param);
 void vidc_1080p_set_encode_picture(u32 ifrm_ctrl, u32 number_b);
 void vidc_1080p_set_encode_multi_slice_control(
 	enum vidc_1080p_MSlice_selection multiple_slice_selection,
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
index 9dc495b..7e201cf 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h
@@ -57,6 +57,12 @@
 	u32 activity_region_flag;
 };
 
+struct vcd_property_slice_delivery_info {
+	u32  enable;
+	u32  num_slices;
+	u32  num_slices_enc;
+};
+
 struct ddl_frame_data_tag;
 
 struct ddl_property_dec_pic_buffers {
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index d93d07e..5542856 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1604,6 +1604,20 @@
 		}
 		if (!result) {
 			ERR("setting VEN_IOCTL_(G)SET_LIVE_MODE failed\n");
+		}
+		break;
+	}
+	case VEN_IOCTL_SET_SLICE_DELIVERY_MODE:
+	{
+		struct vcd_property_hdr vcd_property_hdr;
+		u32 vcd_status = VCD_ERR_FAIL;
+		u32 enable = true;
+		vcd_property_hdr.prop_id = VCD_I_SLICE_DELIVERY_MODE;
+		vcd_property_hdr.sz = sizeof(u32);
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+						&vcd_property_hdr, &enable);
+		if (vcd_status) {
+			pr_err(" Setting slice delivery mode failed");
 			return -EIO;
 		}
 		break;
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index 6fdb1c6..55bbe00b 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -63,7 +63,7 @@
 static irqreturn_t vidc_isr(int irq, void *dev);
 static spinlock_t vidc_spin_lock;
 
-u32 vidc_msg_timing, vidc_msg_pmem;
+u32 vidc_msg_timing, vidc_msg_pmem, vidc_msg_register;
 
 #ifdef VIDC_ENABLE_DBGFS
 struct dentry *vidc_debugfs_root;
@@ -311,6 +311,8 @@
 				(u32 *) &vidc_msg_timing);
 		vidc_debugfs_file_create(root, "vidc_msg_pmem",
 				(u32 *) &vidc_msg_pmem);
+		vidc_debugfs_file_create(root, "vidc_msg_register",
+				(u32 *) &vidc_msg_register);
 	}
 #endif
 	return 0;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd.h b/drivers/video/msm/vidc/common/vcd/vcd.h
index 0d1ff7e..e557dab 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd.h
@@ -393,4 +393,6 @@
 u32 vcd_req_perf_level(struct vcd_clnt_ctxt *cctxt,
 	struct vcd_property_perf_level *);
 
+u32 vcd_set_num_slices(struct vcd_clnt_ctxt *cctxt);
+
 #endif
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_core.h b/drivers/video/msm/vidc/common/vcd/vcd_core.h
index e33c8cd..d228146 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_core.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_core.h
@@ -185,6 +185,7 @@
 	u32 live;
 	u32 decoding;
 	u32 bframe;
+	u32 num_slices;
 
 	struct vcd_property_frame_rate frm_rate;
 	u32 frm_p_units;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index fd8d02a..d49f233 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -19,6 +19,7 @@
 
 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
 #define MAP_TABLE_SZ 64
+#define VCD_ENC_MAX_OUTBFRS_PER_FRAME 8
 
 struct vcd_msm_map_buffer {
 	phys_addr_t phy_addr;
@@ -942,7 +943,6 @@
 		list_del(&entry->list);
 		pool->q_len--;
 	}
-
 	return entry;
 }
 
@@ -1122,6 +1122,7 @@
 	cctxt->bframe = 0;
 	cctxt->cmd_q.pending_cmd = VCD_CMD_NONE;
 	cctxt->status.last_evt = VCD_EVT_RESP_BASE;
+	cctxt->num_slices = 1;
 	return rc;
 }
 
@@ -1293,6 +1294,7 @@
 		}
 
 	} else {
+		vcd_set_num_slices(transc->cctxt);
 		rc = ddl_encode_start(transc->cctxt->ddl_handle,
 					  (void *)transc);
 	}
@@ -1492,7 +1494,8 @@
 	u32 rc = VCD_S_SUCCESS;
 	u32 evcode = 0;
 	struct ddl_frame_data_tag ddl_ip_frm;
-	struct ddl_frame_data_tag ddl_op_frm;
+	struct ddl_frame_data_tag *ddl_op_frm;
+	u32 out_buf_cnt = 0;
 
 	VCD_MSG_LOW("vcd_submit_frame:");
 	cctxt = transc->cctxt;
@@ -1504,34 +1507,52 @@
 	transc->flags = ip_frm_entry->flags;
 	ip_frm_entry->ip_frm_tag = (u32) transc;
 	memset(&ddl_ip_frm, 0, sizeof(ddl_ip_frm));
-	memset(&ddl_op_frm, 0, sizeof(ddl_op_frm));
 	if (cctxt->decoding) {
 		evcode = CLIENT_STATE_EVENT_NUMBER(decode_frame);
 		ddl_ip_frm.vcd_frm = *ip_frm_entry;
 		rc = ddl_decode_frame(cctxt->ddl_handle, &ddl_ip_frm,
-							   (void *) transc);
+							(void *) transc);
 	} else {
-		op_buf_entry = vcd_buffer_pool_entry_de_q(
-			&cctxt->out_buf_pool);
-		if (!op_buf_entry) {
-			VCD_MSG_ERROR("Sched provided frame when no"
-				"op buffer was present");
-			rc = VCD_ERR_FAIL;
-		} else {
+		ddl_op_frm = (struct ddl_frame_data_tag *)
+			kmalloc((sizeof(struct ddl_frame_data_tag) *
+			VCD_ENC_MAX_OUTBFRS_PER_FRAME), GFP_KERNEL);
+		if (!ddl_op_frm) {
+			VCD_MSG_ERROR("Memory allocation failure");
+			return VCD_ERR_ALLOC_FAIL;
+		}
+		memset(ddl_op_frm, 0, (sizeof(struct ddl_frame_data_tag) *
+			VCD_ENC_MAX_OUTBFRS_PER_FRAME));
+		for (out_buf_cnt = 0; out_buf_cnt < cctxt->num_slices ;
+				out_buf_cnt++) {
+			op_buf_entry = vcd_buffer_pool_entry_de_q(
+				&cctxt->out_buf_pool);
+			if (!op_buf_entry) {
+				VCD_MSG_ERROR("Sched provided frame when no"
+					"op buffer was present");
+				rc = VCD_ERR_FAIL;
+				break;
+			}
 			op_buf_entry->in_use = true;
 			cctxt->out_buf_pool.in_use++;
-			ddl_ip_frm.vcd_frm = *ip_frm_entry;
-			ddl_ip_frm.frm_delta =
-				vcd_calculate_frame_delta(cctxt,
-					ip_frm_entry);
-
-			ddl_op_frm.vcd_frm = op_buf_entry->frame;
-
-			evcode = CLIENT_STATE_EVENT_NUMBER(encode_frame);
-
-			rc = ddl_encode_frame(cctxt->ddl_handle,
-				&ddl_ip_frm, &ddl_op_frm, (void *) transc);
+			ddl_op_frm[out_buf_cnt].vcd_frm = op_buf_entry->frame;
+			VCD_MSG_LOW("%s : buffer_cnt = %d framebfr(virtual)"
+				" 0x%p", __func__, out_buf_cnt,
+				op_buf_entry->frame.virtual);
+			VCD_MSG_LOW("framebfr(physical) 0x%p bfrlength %d",
+				op_buf_entry->frame.physical,
+				op_buf_entry->frame.alloc_len);
 		}
+		ddl_ip_frm.vcd_frm = *ip_frm_entry;
+		ddl_ip_frm.frm_delta =
+			vcd_calculate_frame_delta(cctxt,
+				ip_frm_entry);
+		evcode = CLIENT_STATE_EVENT_NUMBER(encode_frame);
+
+		if (!VCD_FAILED(rc)) {
+			rc = ddl_encode_frame(cctxt->ddl_handle,
+				&ddl_ip_frm, &ddl_op_frm[0], (void *) transc);
+		}
+		kfree(ddl_op_frm);
 	}
 	ip_frm_entry->ip_frm_tag = transc->ip_frm_tag;
 	if (!VCD_FAILED(rc)) {
@@ -1875,8 +1896,10 @@
 
 void vcd_release_trans_tbl_entry(struct vcd_transc *trans_entry)
 {
-	if (trans_entry)
+	if (trans_entry) {
 		trans_entry->in_use = false;
+		VCD_MSG_LOW("%s in_use set to false\n", __func__);
+	}
 }
 
 u32 vcd_handle_input_done(
@@ -1888,6 +1911,7 @@
 		(struct ddl_frame_data_tag *) payload;
 	struct vcd_buffer_entry *orig_frame = NULL;
 	u32 rc;
+	VCD_MSG_LOW("%s\n", __func__);
 
 	if (!cctxt->status.frame_submitted &&
 		!cctxt->status.frame_delayed) {
@@ -1935,8 +1959,11 @@
 	transc->ip_buf_entry = NULL;
 	transc->input_done = true;
 
-	if (transc->input_done && transc->frame_done)
+	if (transc->input_done && transc->frame_done) {
+		VCD_MSG_LOW("%s Calling vcd_release_trans_tbl_entry\n",
+		__func__);
 		vcd_release_trans_tbl_entry(transc);
+	}
 
 	if (VCD_FAILED(status)) {
 		VCD_MSG_ERROR("INPUT_DONE returned err = 0x%x", status);
@@ -1975,6 +2002,7 @@
 		(struct ddl_frame_data_tag *) payload;
 	u32 rc = VCD_ERR_FAIL, codec_config = false;
 	u32 core_type = res_trk_get_core_type();
+	VCD_MSG_LOW("%s\n", __func__);
 	rc = vcd_validate_io_done_pyld(cctxt, payload, status);
 	if (rc == VCD_ERR_CLIENT_FATAL)
 		vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end);
@@ -2080,6 +2108,7 @@
 	struct ddl_frame_data_tag *frame =
 		(struct ddl_frame_data_tag *)payload;
 	u32 rc = VCD_S_SUCCESS;
+	VCD_MSG_LOW("%s\n", __func__);
 
 	if (!cctxt->status.frame_submitted &&
 		!cctxt->status.frame_delayed) {
@@ -2140,6 +2169,7 @@
 	struct vcd_transc *transc;
 	struct ddl_frame_data_tag *frame =
 		(struct ddl_frame_data_tag *)payload;
+	VCD_MSG_LOW("%s\n", __func__);
 
 	rc = vcd_validate_io_done_pyld(cctxt, payload, VCD_S_SUCCESS);
 	if (rc == VCD_ERR_CLIENT_FATAL)
@@ -2173,6 +2203,7 @@
 	struct vcd_transc *transc;
 	u32 rc;
 	s64 time_stamp;
+	VCD_MSG_LOW("%s\n", __func__);
 
 	rc = vcd_validate_io_done_pyld(cctxt, payload, status);
 	if (rc == VCD_ERR_CLIENT_FATAL)
@@ -2262,7 +2293,7 @@
 	struct ddl_frame_data_tag *frame =
 		(struct ddl_frame_data_tag *) payload;
 	u32 rc = VCD_S_SUCCESS;
-	VCD_MSG_LOW("vcd_handle_frame_done_in_eos:");
+	VCD_MSG_LOW("%s\n", __func__);
 	rc = vcd_validate_io_done_pyld(cctxt, payload, status);
 	if (rc == VCD_ERR_CLIENT_FATAL)
 		vcd_handle_clnt_fatal(cctxt, frame->frm_trans_end);
@@ -3326,3 +3357,24 @@
 		 0, cctxt, cctxt->client_data);
 	}
 }
+
+u32 vcd_set_num_slices(struct vcd_clnt_ctxt *cctxt)
+{
+	struct vcd_property_hdr prop_hdr;
+	struct vcd_property_slice_delivery_info slice_delivery_info;
+	u32 rc = VCD_S_SUCCESS;
+	prop_hdr.prop_id = VCD_I_SLICE_DELIVERY_MODE;
+	prop_hdr.sz = prop_hdr.sz =
+		sizeof(struct vcd_property_slice_delivery_info);
+	rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr,
+				&slice_delivery_info);
+	VCD_FAILED_RETURN(rc, "Failed: Get VCD_I_SLICE_DELIVERY_MODE");
+	if (slice_delivery_info.enable) {
+		cctxt->num_slices = slice_delivery_info.num_slices;
+		VCD_MSG_LOW("%s slice delivery mode num_slices = %u\n",
+					__func__, cctxt->num_slices);
+	} else {
+		cctxt->num_slices = 1;
+	}
+	return rc;
+}
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index bf149eb..519c537 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -454,6 +454,10 @@
 #define VEN_IOCTL_GET_EXTRADATA \
 	_IOR(VEN_IOCTLBASE_ENC, 49, struct venc_ioctl_msg)
 
+/*IOCTL params:SET: InputData - NULL, OutputData - NULL.*/
+#define VEN_IOCTL_SET_SLICE_DELIVERY_MODE \
+	_IO(VEN_IOCTLBASE_ENC, 50)
+
 struct venc_switch{
 	unsigned char	status;
 };
diff --git a/include/media/msm/vcd_property.h b/include/media/msm/vcd_property.h
index 51cc78f..e776d41 100644
--- a/include/media/msm/vcd_property.h
+++ b/include/media/msm/vcd_property.h
@@ -52,6 +52,7 @@
 #define VCD_I_DISABLE_DMX_SUPPORT (VCD_START_BASE + 0x24)
 #define VCD_I_ENABLE_SPS_PPS_FOR_IDR (VCD_START_BASE + 0x25)
 #define VCD_REQ_PERF_LEVEL (VCD_START_BASE + 0x26)
+#define VCD_I_SLICE_DELIVERY_MODE (VCD_START_BASE + 0x27)
 
 #define VCD_START_REQ      (VCD_START_BASE + 0x1000)
 #define VCD_I_REQ_IFRAME   (VCD_START_REQ + 0x1)