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>
This commit is contained in:
Maheshwar Ajja 2013-04-17 16:47:22 +05:30 committed by Artem Borisov
parent 92533119a9
commit a094b332dc
11 changed files with 116 additions and 95 deletions

View file

@ -172,22 +172,16 @@ u32 ddl_decoder_dpb_transact(struct ddl_decoder_data *decoder,
(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 @@ u32 ddl_decoder_dpb_init(struct ddl_client_context *ddl)
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) {

View file

@ -1769,7 +1769,7 @@ static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl,
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);
}

View file

@ -510,8 +510,8 @@ void ddl_process_encoder_metadata(struct ddl_client_context *ddl)
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 @@ void ddl_process_encoder_metadata(struct ddl_client_context *ddl)
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 @@ void ddl_process_decoder_metadata(struct ddl_client_context *ddl)
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 @@ void ddl_process_decoder_metadata(struct ddl_client_context *ddl)
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)

View file

@ -312,6 +312,12 @@ static void vid_dec_output_frame_done(struct video_client_ctx *client_ctx,
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 @@ static void vid_dec_output_frame_done(struct video_client_ctx *client_ctx,
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);
@ -1679,7 +1683,7 @@ static u32 vid_dec_decode_frame(struct video_client_ctx *client_ctx,
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);
}
@ -2051,6 +2055,7 @@ static long vid_dec_ioctl(struct file *file,
}
case VDEC_IOCTL_CMD_PAUSE:
{
DBG("VDEC_IOCTL_CMD_PAUSE\n");
result = vid_dec_pause_resume(client_ctx, true);
if (!result)
return -EIO;
@ -2106,6 +2111,7 @@ static long vid_dec_ioctl(struct file *file,
}
case VDEC_IOCTL_SET_PERF_CLK:
{
DBG("VDEC_IOCTL_SET_PERF_CLK\n");
vid_dec_set_turbo_clk(client_ctx);
break;
}
@ -2481,6 +2487,7 @@ static long vid_dec_ioctl(struct file *file,
}
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;
@ -2488,6 +2495,7 @@ static long vid_dec_ioctl(struct file *file,
}
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;

View file

@ -254,6 +254,12 @@ static void vid_enc_output_frame_done(struct video_client_ctx *client_ctx,
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 @@ static void vid_enc_output_frame_done(struct video_client_ctx *client_ctx,
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);
}

View file

@ -1737,7 +1737,7 @@ u32 vid_enc_encode_frame(struct video_client_ctx *client_ctx,
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);
}

View file

@ -644,16 +644,6 @@ u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx,
__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,
@ -692,6 +682,7 @@ u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx,
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;
@ -712,9 +703,6 @@ u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx,
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:
@ -835,8 +823,6 @@ u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx,
}
*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,

View file

@ -2490,6 +2490,7 @@ u32 vcd_handle_first_fill_output_buffer_for_enc(
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);
@ -2517,7 +2518,26 @@ u32 vcd_handle_first_fill_output_buffer_for_enc(
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,
@ -2528,6 +2548,8 @@ u32 vcd_handle_first_fill_output_buffer_for_enc(
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",
@ -2569,6 +2591,16 @@ u32 vcd_handle_first_fill_output_buffer_for_enc(
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;
}

View file

@ -555,6 +555,8 @@ struct vdec_output_frameinfo {
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 {

View file

@ -499,6 +499,8 @@ struct venc_buffer{
long long timestamp;
unsigned long flags;
void *clientdata;
unsigned long metadata_len;
unsigned long metadata_offset;
};
struct venc_basecfg{

View file

@ -78,6 +78,8 @@ struct vcd_frame_data {
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 {