msm: vidc: Remove kernel mapping on input/output buffers

This change will remove the kernel mapping of input and
output buffers for both video encoder and decoder to
avoid the errors resulting from ion_map_kernel() for
high resolution video concurrency use cases due to the
limited vmalloc space. It also removed the metadata
processing in kerner video driver as kernel virtual
address is removed. The metadata processing can be
done in user space video component.

Change-Id: I3f2c9b7c13b3e09097ce07ca7b59154b97401052
CRs-fixed: 471135
Signed-off-by: Maheshwar Ajja <majja@codeaurora.org>
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 fda795c..360a85a 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -172,22 +172,16 @@
 				    (in_out_frame->vcd_frm.buff_ion_handle)) {
 					struct ddl_context *ddl_context =
 						ddl_get_context();
-					unsigned long *vaddr =
-						(unsigned long *)((u32)
-						in_out_frame->vcd_frm.virtual +
-						decoder->meta_data_offset);
-					DDL_MSG_LOW("%s: Cache clean: vaddr"\
-						" (%p), offset %u, size %u",
-						__func__,
-						in_out_frame->vcd_frm.virtual,
-						decoder->meta_data_offset,
-						decoder->suffix);
+					DDL_MSG_LOW("%s: Cache clean: size %u",
+						__func__, in_out_frame->vcd_frm.
+						alloc_len);
 					msm_ion_do_cache_op(
 						ddl_context->video_ion_client,
 						in_out_frame->vcd_frm.\
 						buff_ion_handle,
-						vaddr,
-						(unsigned long)decoder->suffix,
+						NULL,
+						(unsigned long)in_out_frame->
+						vcd_frm.alloc_len,
 						ION_IOC_CLEAN_CACHES);
 				}
 			}
@@ -258,47 +252,60 @@
 	struct ddl_context *ddl_context = ddl->ddl_context;
 	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
 	struct ddl_dec_buffers *dec_buffers = &decoder->hw_bufs;
-	struct ddl_frame_data_tag *frame;
+	struct vcd_frame_data *vcd_frm;
 	u32 luma[DDL_MAX_BUFFER_COUNT], chroma[DDL_MAX_BUFFER_COUNT];
 	u32 mv[DDL_MAX_BUFFER_COUNT], luma_size, i, dpb;
-	frame = &decoder->dp_buf.dec_pic_buffers[0];
 	luma_size = ddl_get_yuv_buf_size(decoder->frame_size.width,
 			decoder->frame_size.height, DDL_YUV_BUF_TYPE_TILE);
 	dpb = decoder->dp_buf.no_of_dec_pic_buf;
-	DDL_MSG_LOW("%s Decoder num DPB buffers = %u Luma Size = %u"
+	DDL_MSG_LOW("%s: Decoder num DPB buffers = %u Luma Size = %u",
 				 __func__, dpb, luma_size);
 	if (dpb > DDL_MAX_BUFFER_COUNT)
 		dpb = DDL_MAX_BUFFER_COUNT;
 	for (i = 0; i < dpb; i++) {
-		if (!(res_trk_check_for_sec_session()) &&
-			frame[i].vcd_frm.virtual) {
-			if (luma_size <= frame[i].vcd_frm.alloc_len) {
-				memset(frame[i].vcd_frm.virtual,
-					 0x10101010, luma_size);
-				memset(frame[i].vcd_frm.virtual + luma_size,
-					 0x80808080,
-					frame[i].vcd_frm.alloc_len - luma_size);
-				if (frame[i].vcd_frm.ion_flag
-					== ION_FLAG_CACHED) {
-					msm_ion_do_cache_op(
-					ddl_context->video_ion_client,
-					frame[i].vcd_frm.buff_ion_handle,
-					(unsigned long *)frame[i].
-					vcd_frm.virtual,
-					(unsigned long)frame[i].
-					vcd_frm.alloc_len,
-					ION_IOC_CLEAN_INV_CACHES);
+		vcd_frm = &decoder->dp_buf.dec_pic_buffers[i].vcd_frm;
+		if (!res_trk_check_for_sec_session()) {
+			u8 *kernel_vaddr = NULL;
+			if (luma_size <= vcd_frm->alloc_len) {
+				kernel_vaddr = (u8 *)ion_map_kernel(
+						ddl_context->video_ion_client,
+						vcd_frm->buff_ion_handle);
+				if (IS_ERR_OR_NULL(kernel_vaddr)) {
+					DDL_MSG_ERROR("%s(): ION_MAP for "\
+					"DPB[%u] failed\n", __func__, i);
+				} else {
+					memset(kernel_vaddr, 0x10101010,
+						luma_size);
+					memset(kernel_vaddr + luma_size,
+						0x80808080,
+						vcd_frm->alloc_len - luma_size);
+					if (vcd_frm->ion_flag ==
+						ION_FLAG_CACHED) {
+						msm_ion_do_cache_op(
+						ddl_context->video_ion_client,
+						vcd_frm->buff_ion_handle,
+						(unsigned long *)kernel_vaddr,
+						(unsigned long)vcd_frm->
+						alloc_len,
+						ION_IOC_CLEAN_INV_CACHES);
+					}
+					ion_unmap_kernel(
+						ddl_context->video_ion_client,
+						vcd_frm->buff_ion_handle);
+					kernel_vaddr = NULL;
 				}
 			} else {
-				DDL_MSG_ERROR("luma size error");
+				DDL_MSG_ERROR("%s: err: luma_size (%u), "\
+					"alloc_len (%u)", __func__,
+					luma_size, vcd_frm->alloc_len);
 				return VCD_ERR_FAIL;
 			}
 		}
 
 		luma[i] = DDL_OFFSET(ddl_context->dram_base_a.
-			align_physical_addr, frame[i].vcd_frm.physical);
+			align_physical_addr, vcd_frm->physical);
 		chroma[i] = luma[i] + luma_size;
-		DDL_MSG_LOW("%s Decoder Luma address = %x Chroma address = %x"
+		DDL_MSG_LOW("%s: Decoder Luma address = %x Chroma address = %x",
 					__func__, luma[i], chroma[i]);
 	}
 	switch (decoder->codec.codec) {
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 819c32e..0bb7c3b 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
@@ -1773,7 +1773,7 @@
 	if (!IS_ERR_OR_NULL(output_frame->buff_ion_handle)) {
 		msm_ion_do_cache_op(ddl_context->video_ion_client,
 			output_frame->buff_ion_handle,
-			(unsigned long *) output_frame->virtual,
+			(unsigned long *)NULL,
 			(unsigned long) output_frame->alloc_len,
 			ION_IOC_INV_CACHES);
 	}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
index 7449a4a..6a26c13 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c
@@ -510,8 +510,8 @@
 	struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder);
 	struct vcd_frame_data *out_frame =
 		&(ddl->output_frame.vcd_frm);
-	u32 *qfiller_hdr, *qfiller, start_addr;
-	u32 qfiller_size;
+	out_frame->metadata_offset = 0;
+	out_frame->metadata_len = 0;
 	if (!encoder->meta_data_enable_flag) {
 		out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
 		return;
@@ -520,19 +520,11 @@
 		out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
 		return;
 	}
+	DDL_MSG_LOW("%s: data_len/metadata_offset : %d/%d", __func__,
+		out_frame->data_len, encoder->meta_data_offset);
+	out_frame->metadata_offset = encoder->meta_data_offset;
+	out_frame->metadata_len = encoder->suffix;
 	out_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
-	DDL_MSG_LOW("processing metadata for encoder");
-	start_addr = (u32) ((u8 *)out_frame->virtual + out_frame->offset);
-	qfiller = (u32 *)((out_frame->data_len +
-				start_addr + 3) & ~3);
-	qfiller_size = (u32)((encoder->meta_data_offset +
-		(u8 *) out_frame->virtual) - (u8 *) qfiller);
-	qfiller_hdr = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QCOMFILLER);
-	*qfiller++ = qfiller_size;
-	*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_VERSION_INDEX];
-	*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_PORT_INDEX];
-	*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_TYPE_INDEX];
-	*qfiller = (u32)(qfiller_size - DDL_METADATA_HDR_SIZE);
 }
 
 void ddl_process_decoder_metadata(struct ddl_client_context *ddl)
@@ -540,9 +532,8 @@
 	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
 	struct vcd_frame_data *output_frame =
 		&(ddl->output_frame.vcd_frm);
-	u32 *qfiller_hdr, *qfiller;
-	u32 qfiller_size;
-
+	output_frame->metadata_offset = 0;
+	output_frame->metadata_len = 0;
 	if (!decoder->meta_data_enable_flag) {
 		output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
 		return;
@@ -556,26 +547,11 @@
 		output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA);
 		return;
 	}
-	DDL_MSG_LOW("processing metadata for decoder");
-	DDL_MSG_LOW("data_len/metadata_offset : %d/%d",
+	DDL_MSG_LOW("%s: data_len/metadata_offset : %d/%d", __func__,
 		output_frame->data_len, decoder->meta_data_offset);
+	output_frame->metadata_offset = decoder->meta_data_offset;
+	output_frame->metadata_len = decoder->suffix;
 	output_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
-	if (!(decoder->meta_data_enable_flag & VCD_METADATA_SEPARATE_BUF)
-		&& (output_frame->data_len != decoder->meta_data_offset)) {
-		qfiller = (u32 *)((u32)((output_frame->data_len +
-			output_frame->offset  +
-				(u8 *) output_frame->virtual) + 3) & ~3);
-		qfiller_size = (u32)((decoder->meta_data_offset +
-				(u8 *) output_frame->virtual) -
-				(u8 *) qfiller);
-		qfiller_hdr = ddl_metadata_hdr_entry(ddl,
-				VCD_METADATA_QCOMFILLER);
-		*qfiller++ = qfiller_size;
-		*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_VERSION_INDEX];
-		*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_PORT_INDEX];
-		*qfiller++ = qfiller_hdr[DDL_METADATA_HDR_TYPE_INDEX];
-		*qfiller = (u32)(qfiller_size - DDL_METADATA_HDR_SIZE);
-	}
 }
 
 void ddl_set_mp2_dump_default(struct ddl_decoder_data *decoder, u32 flag)
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index a978593..92fa3ed 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -312,6 +312,12 @@
 		    vcd_frame_data->data_len;
 		vdec_msg->vdec_msg_info.msgdata.output_frame.flags =
 		    vcd_frame_data->flags;
+		/* metadata offset in output buffer for non-secure mode */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.metadata_len =
+			(size_t)vcd_frame_data->metadata_len;
+		/* metadata offset in output buffer for non-secure mode */
+		vdec_msg->vdec_msg_info.msgdata.output_frame.metadata_offset =
+			(size_t)vcd_frame_data->metadata_offset;
 		/* Timestamp pass-through from input frame */
 		vdec_msg->vdec_msg_info.msgdata.output_frame.time_stamp =
 		    vcd_frame_data->time_stamp;
@@ -381,13 +387,11 @@
 				pmem_fd, kernel_vaddr, buffer_index,
 				&buff_handle);
 		if (ion_flag == ION_FLAG_CACHED && buff_handle) {
-			DBG("%s: Cache invalidate: vaddr (%p), "\
-				"size %u\n", __func__,
-				(void *)kernel_vaddr,
+			DBG("%s: Cache invalidate: size %u", __func__,
 				vcd_frame_data->alloc_len);
 			msm_ion_do_cache_op(client_ctx->user_ion_client,
 					buff_handle,
-					(unsigned long *) kernel_vaddr,
+					(unsigned long *) NULL,
 					(unsigned long)vcd_frame_data->\
 					alloc_len,
 					ION_IOC_INV_CACHES);
@@ -1665,7 +1669,7 @@
 			if (ion_flag == ION_FLAG_CACHED && buff_handle) {
 				msm_ion_do_cache_op(client_ctx->user_ion_client,
 				buff_handle,
-				(unsigned long *)kernel_vaddr,
+				(unsigned long *) NULL,
 				(unsigned long) vcd_input_buffer.data_len,
 				ION_IOC_CLEAN_CACHES);
 			}
@@ -2023,6 +2027,7 @@
 	}
 	case VDEC_IOCTL_CMD_PAUSE:
 	{
+		DBG("VDEC_IOCTL_CMD_PAUSE\n");
 		result = vid_dec_pause_resume(client_ctx, true);
 		if (!result)
 			return -EIO;
@@ -2076,6 +2081,7 @@
 	}
 	case VDEC_IOCTL_SET_PERF_CLK:
 	{
+		DBG("VDEC_IOCTL_SET_PERF_CLK\n");
 		vid_dec_set_turbo_clk(client_ctx);
 		break;
 	}
@@ -2435,6 +2441,7 @@
 	}
 	case VDEC_IOCTL_SET_IDR_ONLY_DECODING:
 	{
+		DBG("VDEC_IOCTL_SET_IDR_ONLY_DECODING\n");
 		result = vid_dec_set_idr_only_decoding(client_ctx);
 		if (!result)
 			return -EIO;
@@ -2442,6 +2449,7 @@
 	}
 	case VDEC_IOCTL_SET_CONT_ON_RECONFIG:
 	{
+		DBG("VDEC_IOCTL_SET_CONT_ON_RECONFIG\n");
 		result = vid_dec_set_cont_on_reconfig(client_ctx);
 		if (!result)
 			return -EIO;
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 2353553..1722972 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -254,6 +254,12 @@
 			vcd_frame_data->time_stamp;
 		venc_msg->venc_msg_info.buf.sz =
 			vcd_frame_data->alloc_len;
+		/* Metadata length */
+		venc_msg->venc_msg_info.buf.metadata_len =
+			vcd_frame_data->metadata_len;
+		/* Metadata offset */
+		venc_msg->venc_msg_info.buf.metadata_offset =
+			vcd_frame_data->metadata_offset;
 
 		/* Decoded picture width and height */
 		venc_msg->venc_msg_info.msgdata_size =
@@ -270,7 +276,7 @@
 		if (ion_flag == ION_FLAG_CACHED && buff_handle) {
 			msm_ion_do_cache_op(client_ctx->user_ion_client,
 				buff_handle,
-				(unsigned long *) kernel_vaddr,
+				(unsigned long *) NULL,
 				(unsigned long)venc_msg->venc_msg_info.buf.sz,
 				ION_IOC_CLEAN_INV_CACHES);
 		}
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index 808ba79..e60fc46 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -1699,7 +1699,7 @@
 				msm_ion_do_cache_op(
 				client_ctx->user_ion_client,
 				buff_handle,
-				(unsigned long *) vcd_input_buffer.virtual,
+				(unsigned long *) NULL,
 				(unsigned long) vcd_input_buffer.data_len,
 				ION_IOC_CLEAN_CACHES);
 			}
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index d67c9e9..fd1d4c1 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -680,16 +680,6 @@
 				 __func__);
 				goto bail_out_add;
 			}
-			*kernel_vaddr = (unsigned long)
-				ion_map_kernel(
-				client_ctx->user_ion_client,
-				buff_ion_handle);
-			if (IS_ERR_OR_NULL((void *)*kernel_vaddr)) {
-				ERR("%s():ION virtual addr fail\n",
-				 __func__);
-				*kernel_vaddr = (unsigned long)NULL;
-				goto ion_free_error;
-			}
 			if (res_trk_check_for_sec_session() ||
 			   (res_trk_get_core_type() == (u32)VCD_CORE_720P)) {
 				if (ion_phys(client_ctx->user_ion_client,
@@ -727,6 +717,7 @@
 						 iova;
 			}
 		}
+		(*kernel_vaddr) = phys_addr;
 		phys_addr += buffer_addr_offset;
 		(*kernel_vaddr) += buffer_addr_offset;
 		buf_addr_table[*num_of_buffers].user_vaddr = user_vaddr;
@@ -747,9 +738,6 @@
 	mutex_unlock(&client_ctx->enrty_queue_lock);
 	return true;
 ion_map_error:
-	if (*kernel_vaddr && buff_ion_handle)
-		ion_unmap_kernel(client_ctx->user_ion_client, buff_ion_handle);
-ion_free_error:
 	if (!IS_ERR_OR_NULL(buff_ion_handle))
 		ion_free(client_ctx->user_ion_client, buff_ion_handle);
 bail_out_add:
@@ -870,8 +858,6 @@
 	}
 	*kernel_vaddr = buf_addr_table[i].kernel_vaddr;
 	if (buf_addr_table[i].buff_ion_handle) {
-		ion_unmap_kernel(client_ctx->user_ion_client,
-				buf_addr_table[i].buff_ion_handle);
 		if (!res_trk_check_for_sec_session() &&
 		   (res_trk_get_core_type() != (u32)VCD_CORE_720P)) {
 			ion_unmap_iommu(client_ctx->user_ion_client,
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index 46f2bae..3e20fbc 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -2454,6 +2454,7 @@
 	struct vcd_sequence_hdr seq_hdr;
 	struct vcd_property_sps_pps_for_idr_enable idr_enable;
 	struct vcd_property_codec codec;
+	u8 *kernel_vaddr = NULL;
 	*handled = true;
 	prop_hdr.prop_id = DDL_I_SEQHDR_PRESENT;
 	prop_hdr.sz = sizeof(seqhdr_present);
@@ -2481,7 +2482,26 @@
 			if (!cctxt->secure) {
 				prop_hdr.prop_id = VCD_I_SEQ_HEADER;
 				prop_hdr.sz = sizeof(struct vcd_sequence_hdr);
-				seq_hdr.sequence_header = frm_entry->virtual;
+				if (vcd_get_ion_status()) {
+					kernel_vaddr = (u8 *)ion_map_kernel(
+						cctxt->vcd_ion_client,
+						frm_entry->buff_ion_handle);
+					if (IS_ERR_OR_NULL(kernel_vaddr)) {
+						VCD_MSG_ERROR("%s: 0x%x = "\
+						"ion_map_kernel(0x%x, 0x%x) fail",
+						__func__,
+						(u32)kernel_vaddr,
+						(u32)cctxt->vcd_ion_client,
+						(u32)frm_entry->
+						buff_ion_handle);
+						return VCD_ERR_FAIL;
+					}
+				} else {
+					VCD_MSG_ERROR("%s: ION status is NULL",
+						__func__);
+					return VCD_ERR_FAIL;
+				}
+				seq_hdr.sequence_header = kernel_vaddr;
 				seq_hdr.sequence_header_len =
 					frm_entry->alloc_len;
 				rc = ddl_get_property(cctxt->ddl_handle,
@@ -2492,6 +2512,8 @@
 					frm_entry->time_stamp = 0;
 					frm_entry->flags |=
 						VCD_FRAME_FLAG_CODECCONFIG;
+					VCD_MSG_LOW("%s: header len = %u",
+						__func__, frm_entry->data_len);
 				} else
 					VCD_MSG_ERROR("rc = 0x%x. Failed:"
 							"ddl_get_property: VCD_I_SEQ_HEADER",
@@ -2533,6 +2555,16 @@
 		VCD_MSG_ERROR(
 			"rc = 0x%x. Failed: ddl_get_property:VCD_I_CODEC",
 			rc);
+	if (kernel_vaddr) {
+		if (!IS_ERR_OR_NULL(frm_entry->buff_ion_handle)) {
+			ion_map_kernel(cctxt->vcd_ion_client,
+				frm_entry->buff_ion_handle);
+		} else {
+			VCD_MSG_ERROR("%s: Invalid ion_handle (0x%x)",
+				__func__, (u32)frm_entry->buff_ion_handle);
+			rc = VCD_ERR_FAIL;
+		}
+	}
 	return rc;
 }
 
diff --git a/include/linux/msm_vidc_dec.h b/include/linux/msm_vidc_dec.h
index cd363c5..7edf6cf 100644
--- a/include/linux/msm_vidc_dec.h
+++ b/include/linux/msm_vidc_dec.h
@@ -555,6 +555,8 @@
 	enum vdec_interlaced_format interlaced_format;
 	struct vdec_aspectratioinfo aspect_ratio_info;
 	struct vdec_sep_metadatainfo metadata_info;
+	size_t metadata_len;
+	size_t metadata_offset;
 };
 
 union vdec_msgdata {
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index 9d714f0..7914723 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -495,6 +495,8 @@
  long long	timestamp;
  unsigned long	flags;
  void	*clientdata;
+	unsigned long	metadata_len;
+	unsigned long	metadata_offset;
 };
 
 struct venc_basecfg{
diff --git a/include/media/msm/vcd_api.h b/include/media/msm/vcd_api.h
index 7472fb2..ec535ce5 100644
--- a/include/media/msm/vcd_api.h
+++ b/include/media/msm/vcd_api.h
@@ -78,6 +78,8 @@
 	u32 desc_size;
 	struct ion_handle *buff_ion_handle;
 	struct vcd_aspect_ratio aspect_ratio_info;
+	u32 metadata_len;
+	u32 metadata_offset;
 };
 
 struct vcd_sequence_hdr {