mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
msm: vidc: Separate meta buffers support in secure mode
Extradata is appended at the end of each output buffer in non secure video use case but in secure video playback, the client/CPU don't have access to the output buffer to parse the extradata. This change allows the client/CPU to parse the extradata by allocating separate buffers for video hardware to store extradata. Change-Id: I12927ea3d142b9cecd6fb1ae1086c5624d0e08d6 Signed-off-by: Deepak Verma <dverma@codeaurora.org>
This commit is contained in:
parent
0567450fbf
commit
f84beb65e4
10 changed files with 517 additions and 19 deletions
|
@ -88,7 +88,7 @@ u32 ddl_device_init(struct ddl_init_config *ddl_init_config,
|
|||
ddl_context->dram_base_a.align_virtual_addr;
|
||||
}
|
||||
if (!status) {
|
||||
ddl_context->metadata_shared_input.mem_type = DDL_FW_MEM;
|
||||
ddl_context->metadata_shared_input.mem_type = DDL_CMD_MEM;
|
||||
ptr = ddl_pmem_alloc(&ddl_context->metadata_shared_input,
|
||||
DDL_METADATA_TOTAL_INPUTBUFSIZE,
|
||||
DDL_LINEAR_BUFFER_ALIGN_BYTES);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
|
||||
/* Copyright (c) 2010-2013, The Linux Foundation. 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
|
||||
|
@ -188,6 +188,7 @@ struct ddl_dec_buffers{
|
|||
struct ddl_buf_addr h264_nb_ip;
|
||||
struct ddl_buf_addr context;
|
||||
struct ddl_buf_addr extnuserdata;
|
||||
struct ddl_buf_addr meta_hdr[DDL_MAX_BUFFER_COUNT];
|
||||
};
|
||||
struct ddl_enc_buffer_size{
|
||||
u32 sz_cur_y;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
|
||||
/* Copyright (c) 2010-2013, The Linux Foundation. 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
|
||||
|
@ -780,7 +780,7 @@ u32 ddl_allocate_dec_hw_buffers(struct ddl_client_context *ddl)
|
|||
}
|
||||
}
|
||||
if (buf_size.sz_extnuserdata > 0) {
|
||||
dec_bufs->extnuserdata.mem_type = DDL_FW_MEM;
|
||||
dec_bufs->extnuserdata.mem_type = DDL_CMD_MEM;
|
||||
ptr = ddl_pmem_alloc(&dec_bufs->extnuserdata,
|
||||
buf_size.sz_extnuserdata, DDL_KILO_BYTE(2));
|
||||
if (!ptr)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
|
||||
/* Copyright (c) 2010-2013, The Linux Foundation. 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
|
||||
|
@ -158,7 +158,8 @@ static u32 ddl_supported_metadata_flag(struct ddl_client_context *ddl)
|
|||
ddl->codec_data.decoder.codec.codec;
|
||||
|
||||
flag |= (VCD_METADATA_CONCEALMB | VCD_METADATA_PASSTHROUGH |
|
||||
VCD_METADATA_QPARRAY);
|
||||
VCD_METADATA_QPARRAY |
|
||||
VCD_METADATA_SEPARATE_BUF);
|
||||
if (codec == VCD_CODEC_H264)
|
||||
flag |= (VCD_METADATA_SEI | VCD_METADATA_VUI);
|
||||
else if (codec == VCD_CODEC_VC1 ||
|
||||
|
@ -249,6 +250,9 @@ void ddl_set_default_decoder_metadata_buffer_size(struct ddl_decoder_data
|
|||
DDL_METADATA_ALIGNSIZE(suffix);
|
||||
decoder->suffix = suffix;
|
||||
output_buf_req->sz += suffix;
|
||||
output_buf_req->meta_buffer_size = suffix;
|
||||
output_buf_req->meta_buffer_size =
|
||||
(output_buf_req->meta_buffer_size + 8191) & (~8191);
|
||||
decoder->meta_data_offset = 0;
|
||||
DDL_MSG_LOW("metadata output buf size : %d", suffix);
|
||||
}
|
||||
|
@ -464,13 +468,14 @@ u32 ddl_vidc_encode_set_metadata_output_buf(struct ddl_client_context *ddl)
|
|||
void ddl_vidc_decode_set_metadata_output(struct ddl_decoder_data *decoder)
|
||||
{
|
||||
struct ddl_context *ddl_context;
|
||||
u32 loopc, yuv_size;
|
||||
u32 loopc, yuv_size, dpb;
|
||||
u32 *buffer;
|
||||
|
||||
struct ddl_dec_buffers *dec_buffers = &decoder->hw_bufs;
|
||||
if (!decoder->meta_data_enable_flag) {
|
||||
decoder->meta_data_offset = 0;
|
||||
return;
|
||||
}
|
||||
dpb = decoder->dp_buf.no_of_dec_pic_buf;
|
||||
ddl_context = ddl_get_context();
|
||||
yuv_size = ddl_get_yuv_buffer_size(&decoder->client_frame_size,
|
||||
&decoder->buf_format, !decoder->progressive_only,
|
||||
|
@ -478,15 +483,22 @@ void ddl_vidc_decode_set_metadata_output(struct ddl_decoder_data *decoder)
|
|||
decoder->meta_data_offset = DDL_ALIGN_SIZE(yuv_size,
|
||||
DDL_LINEAR_BUF_ALIGN_GUARD_BYTES, DDL_LINEAR_BUF_ALIGN_MASK);
|
||||
buffer = (u32 *) decoder->meta_data_input.align_virtual_addr;
|
||||
*buffer++ = decoder->suffix;
|
||||
DDL_MSG_LOW("Metadata offset & size : %d/%d",
|
||||
decoder->meta_data_offset, decoder->suffix);
|
||||
for (loopc = 0; loopc < decoder->dp_buf.no_of_dec_pic_buf;
|
||||
++loopc) {
|
||||
*buffer++ = (u32)(decoder->meta_data_offset + (u8 *)
|
||||
if (!(decoder->meta_data_enable_flag & VCD_METADATA_SEPARATE_BUF)) {
|
||||
*buffer++ = decoder->suffix;
|
||||
for (loopc = 0; loopc < dpb; ++loopc) {
|
||||
*buffer++ = (u32)(decoder->meta_data_offset + (u8 *)
|
||||
DDL_OFFSET(ddl_context->dram_base_a.
|
||||
align_physical_addr, decoder->dp_buf.
|
||||
dec_pic_buffers[loopc].vcd_frm.physical));
|
||||
}
|
||||
} else {
|
||||
*buffer++ = decoder->actual_output_buf_req.meta_buffer_size;
|
||||
for (loopc = 0; loopc < dpb; ++loopc) {
|
||||
*buffer++ = DDL_ADDR_OFFSET(ddl_context->dram_base_a,
|
||||
dec_buffers->meta_hdr[loopc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,7 +557,8 @@ void ddl_process_decoder_metadata(struct ddl_client_context *ddl)
|
|||
DDL_MSG_LOW("data_len/metadata_offset : %d/%d",
|
||||
output_frame->data_len, decoder->meta_data_offset);
|
||||
output_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
|
||||
if (output_frame->data_len != decoder->meta_data_offset) {
|
||||
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);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
|
||||
/* Copyright (c) 2010-2013, The Linux Foundation. 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
|
||||
|
@ -319,6 +319,61 @@ static u32 ddl_set_dec_property(struct ddl_client_context *ddl,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case VCD_I_SET_EXT_METABUFFER:
|
||||
{
|
||||
int index, buffer_size;
|
||||
u8 *phys_addr;
|
||||
u8 *virt_addr;
|
||||
struct vcd_property_meta_buffer *meta_buffer =
|
||||
(struct vcd_property_meta_buffer *) property_value;
|
||||
DDL_MSG_LOW("Entered VCD_I_SET_EXT_METABUFFER Virt: %p,"\
|
||||
"Phys %p, fd: %d size: %d count: %d",
|
||||
meta_buffer->kernel_virtual_addr,
|
||||
meta_buffer->physical_addr,
|
||||
meta_buffer->pmem_fd,
|
||||
meta_buffer->size, meta_buffer->count);
|
||||
if ((property_hdr->sz == sizeof(struct
|
||||
vcd_property_meta_buffer)) &&
|
||||
(DDLCLIENT_STATE_IS(ddl,
|
||||
DDL_CLIENT_WAIT_FOR_INITCODEC) ||
|
||||
DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) ||
|
||||
DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN))) {
|
||||
phys_addr = meta_buffer->dev_addr;
|
||||
virt_addr = meta_buffer->kernel_virtual_addr;
|
||||
buffer_size = meta_buffer->size/meta_buffer->count;
|
||||
|
||||
for (index = 0; index < meta_buffer->count; index++) {
|
||||
ddl->codec_data.decoder.hw_bufs.
|
||||
meta_hdr[index].align_physical_addr
|
||||
= phys_addr;
|
||||
ddl->codec_data.decoder.hw_bufs.
|
||||
meta_hdr[index].align_virtual_addr
|
||||
= virt_addr;
|
||||
ddl->codec_data.decoder.hw_bufs.
|
||||
meta_hdr[index].buffer_size
|
||||
= buffer_size;
|
||||
ddl->codec_data.decoder.hw_bufs.
|
||||
meta_hdr[index].physical_base_addr
|
||||
= phys_addr;
|
||||
ddl->codec_data.decoder.hw_bufs.
|
||||
meta_hdr[index].virtual_base_addr
|
||||
= virt_addr;
|
||||
|
||||
DDL_MSG_LOW("Meta Buffer: "\
|
||||
"Assigned %d buffer for "
|
||||
"virt: %p, phys %p for "
|
||||
"meta_buffers "
|
||||
"of size: %d\n",
|
||||
index, virt_addr,
|
||||
phys_addr, buffer_size);
|
||||
|
||||
phys_addr += buffer_size;
|
||||
virt_addr += buffer_size;
|
||||
}
|
||||
vcd_status = VCD_S_SUCCESS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VCD_I_H264_MV_BUFFER:
|
||||
{
|
||||
int index, buffer_size;
|
||||
|
@ -379,6 +434,13 @@ static u32 ddl_set_dec_property(struct ddl_client_context *ddl,
|
|||
vcd_status = VCD_S_SUCCESS;
|
||||
}
|
||||
break;
|
||||
case VCD_I_FREE_EXT_METABUFFER:
|
||||
{
|
||||
memset(&decoder->hw_bufs.meta_hdr, 0, sizeof(struct
|
||||
ddl_buf_addr) * DDL_MAX_BUFFER_COUNT);
|
||||
vcd_status = VCD_S_SUCCESS;
|
||||
}
|
||||
break;
|
||||
case VCD_I_OUTPUT_ORDER:
|
||||
{
|
||||
if (sizeof(u32) == property_hdr->sz &&
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
|
||||
/* Copyright (c) 2010-2013, The Linux Foundation. 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
|
||||
|
@ -271,6 +271,38 @@ static void vid_dec_output_frame_done(struct video_client_ctx *client_ctx,
|
|||
&phy_addr, &pmem_fd, &file,
|
||||
&buffer_index) ||
|
||||
(vcd_frame_data->flags & VCD_FRAME_FLAG_EOS)) {
|
||||
|
||||
if (res_trk_check_for_sec_session() &&
|
||||
event == VCD_EVT_RESP_OUTPUT_DONE) {
|
||||
DBG("Buffer Index = %d", buffer_index);
|
||||
if (buffer_index != -1) {
|
||||
if (client_ctx->meta_addr_table[buffer_index].
|
||||
kernel_vir_addr_iommu &&
|
||||
client_ctx->
|
||||
meta_addr_table[buffer_index].
|
||||
kernel_vir_addr) {
|
||||
|
||||
memcpy(client_ctx->
|
||||
meta_addr_table[buffer_index].
|
||||
kernel_vir_addr_iommu,
|
||||
client_ctx->
|
||||
meta_addr_table[buffer_index].
|
||||
kernel_vir_addr,
|
||||
client_ctx->meta_buf_size);
|
||||
DBG("Copying Meta Buffer from "\
|
||||
"secure memory"
|
||||
"kernel_virt_iommu = %p "
|
||||
"kernel_virt = %p",
|
||||
client_ctx->
|
||||
meta_addr_table[buffer_index].
|
||||
kernel_vir_addr_iommu,
|
||||
client_ctx->
|
||||
meta_addr_table[buffer_index].
|
||||
kernel_vir_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Buffer address in user space */
|
||||
vdec_msg->vdec_msg_info.msgdata.output_frame.bufferaddr =
|
||||
(u8 *) user_vaddr;
|
||||
|
@ -838,7 +870,263 @@ static u32 vid_dec_set_idr_only_decoding(struct video_client_ctx *client_ctx)
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
static u32 vid_dec_set_meta_buffers(struct video_client_ctx *client_ctx,
|
||||
struct vdec_meta_buffers *meta_buffers)
|
||||
{
|
||||
struct vcd_property_hdr vcd_property_hdr;
|
||||
struct vcd_property_meta_buffer *vcd_meta_buffer = NULL;
|
||||
struct msm_mapped_buffer *mapped_buffer = NULL;
|
||||
struct msm_mapped_buffer *mapped_buffer_iommu = NULL;
|
||||
u32 vcd_status = VCD_ERR_FAIL;
|
||||
u32 len = 0, flags = 0, len_iommu = 0, flags_iommu = 0, buf_size = 0;
|
||||
struct file *file, *file_iommu;
|
||||
int rc = 0;
|
||||
unsigned long ionflag = 0, ionflag_iommu = 0;
|
||||
unsigned long buffer_size = 0, buffer_size_iommu = 0;
|
||||
unsigned long iova = 0, iova_iommu = 0;
|
||||
int index = -1, num_buffers = 0;
|
||||
u8 *ker_vir_addr = NULL, *ker_vir_addr_iommu = NULL;
|
||||
|
||||
if (!client_ctx || !meta_buffers)
|
||||
return false;
|
||||
|
||||
vcd_property_hdr.prop_id = VCD_I_SET_EXT_METABUFFER;
|
||||
vcd_property_hdr.sz = sizeof(struct vcd_property_meta_buffer);
|
||||
vcd_meta_buffer = &client_ctx->vcd_meta_buffer;
|
||||
|
||||
memset(&client_ctx->vcd_meta_buffer, 0,
|
||||
sizeof(struct vcd_property_meta_buffer));
|
||||
vcd_meta_buffer->size = meta_buffers->size;
|
||||
vcd_meta_buffer->count = meta_buffers->count;
|
||||
vcd_meta_buffer->pmem_fd = meta_buffers->pmem_fd;
|
||||
vcd_meta_buffer->offset = meta_buffers->offset;
|
||||
vcd_meta_buffer->pmem_fd_iommu = meta_buffers->pmem_fd_iommu;
|
||||
|
||||
if (!vcd_get_ion_status()) {
|
||||
if (get_pmem_file(vcd_meta_buffer->pmem_fd,
|
||||
(unsigned long *) (&(vcd_meta_buffer->
|
||||
physical_addr)),
|
||||
(unsigned long *) (&vcd_meta_buffer->
|
||||
kernel_virtual_addr),
|
||||
(unsigned long *) (&len), &file)) {
|
||||
ERR("%s(): get_pmem_file failed\n", __func__);
|
||||
return false;
|
||||
}
|
||||
put_pmem_file(file);
|
||||
flags = MSM_SUBSYSTEM_MAP_IOVA;
|
||||
mapped_buffer = msm_subsystem_map_buffer(
|
||||
(unsigned long)vcd_meta_buffer->physical_addr,
|
||||
len, flags, vidc_mmu_subsystem,
|
||||
sizeof(vidc_mmu_subsystem)/
|
||||
sizeof(unsigned int));
|
||||
if (IS_ERR(mapped_buffer)) {
|
||||
pr_err("buffer map failed");
|
||||
return false;
|
||||
}
|
||||
vcd_meta_buffer->client_data = (void *) mapped_buffer;
|
||||
vcd_meta_buffer->dev_addr =
|
||||
(u8 *)mapped_buffer->iova[0];
|
||||
|
||||
if (get_pmem_file(vcd_meta_buffer->pmem_fd_iommu,
|
||||
(unsigned long *) (&(vcd_meta_buffer->
|
||||
physical_addr_iommu)),
|
||||
(unsigned long *) (&vcd_meta_buffer->
|
||||
kernel_virt_addr_iommu),
|
||||
(unsigned long *) (&len_iommu), &file_iommu)) {
|
||||
ERR("%s(): get_pmem_file failed\n", __func__);
|
||||
return false;
|
||||
}
|
||||
put_pmem_file(file_iommu);
|
||||
flags_iommu = MSM_SUBSYSTEM_MAP_IOVA;
|
||||
mapped_buffer_iommu = msm_subsystem_map_buffer(
|
||||
(unsigned long)vcd_meta_buffer->physical_addr_iommu,
|
||||
len_iommu, flags_iommu, vidc_mmu_subsystem,
|
||||
sizeof(vidc_mmu_subsystem)/
|
||||
sizeof(unsigned int));
|
||||
if (IS_ERR(mapped_buffer_iommu)) {
|
||||
pr_err("buffer map failed");
|
||||
return false;
|
||||
}
|
||||
vcd_meta_buffer->client_data_iommu =
|
||||
(void *) mapped_buffer_iommu;
|
||||
vcd_meta_buffer->dev_addr_iommu =
|
||||
(u8 *)mapped_buffer_iommu->iova[0];
|
||||
} else {
|
||||
client_ctx->meta_buffer_ion_handle = ion_import_dma_buf(
|
||||
client_ctx->user_ion_client,
|
||||
vcd_meta_buffer->pmem_fd);
|
||||
if (IS_ERR_OR_NULL(client_ctx->meta_buffer_ion_handle)) {
|
||||
ERR("%s(): get_ION_handle failed\n", __func__);
|
||||
goto import_ion_error;
|
||||
}
|
||||
rc = ion_handle_get_flags(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_ion_handle,
|
||||
&ionflag);
|
||||
if (rc) {
|
||||
ERR("%s():get_ION_flags fail\n",
|
||||
__func__);
|
||||
goto import_ion_error;
|
||||
}
|
||||
vcd_meta_buffer->kernel_virtual_addr =
|
||||
(u8 *) ion_map_kernel(
|
||||
client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_ion_handle);
|
||||
if (!vcd_meta_buffer->kernel_virtual_addr) {
|
||||
ERR("%s(): get_ION_kernel virtual addr failed\n",
|
||||
__func__);
|
||||
goto import_ion_error;
|
||||
}
|
||||
if (res_trk_check_for_sec_session() ||
|
||||
(res_trk_get_core_type() == (u32)VCD_CORE_720P)) {
|
||||
rc = ion_phys(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_ion_handle,
|
||||
(unsigned long *) (&(vcd_meta_buffer->
|
||||
physical_addr)), &len);
|
||||
if (rc) {
|
||||
ERR("%s():get_ION_kernel physical addr fail\n",
|
||||
__func__);
|
||||
goto ion_map_error;
|
||||
}
|
||||
vcd_meta_buffer->client_data = NULL;
|
||||
vcd_meta_buffer->dev_addr = (u8 *)
|
||||
vcd_meta_buffer->physical_addr;
|
||||
} else {
|
||||
rc = ion_map_iommu(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_ion_handle,
|
||||
VIDEO_DOMAIN, VIDEO_MAIN_POOL,
|
||||
SZ_4K, 0, (unsigned long *)&iova,
|
||||
(unsigned long *)&buffer_size,
|
||||
0, 0);
|
||||
if (rc || !iova) {
|
||||
ERR("%s():get_ION_kernel physical addr fail,"\
|
||||
" rc = %d iova = 0x%lx\n",
|
||||
__func__, rc, iova);
|
||||
goto ion_map_error;
|
||||
}
|
||||
vcd_meta_buffer->physical_addr = (u8 *) iova;
|
||||
vcd_meta_buffer->client_data = NULL;
|
||||
vcd_meta_buffer->dev_addr = (u8 *) iova;
|
||||
}
|
||||
|
||||
client_ctx->meta_buffer_iommu_ion_handle = ion_import_dma_buf(
|
||||
client_ctx->user_ion_client,
|
||||
vcd_meta_buffer->pmem_fd_iommu);
|
||||
if (IS_ERR_OR_NULL(client_ctx->meta_buffer_iommu_ion_handle)) {
|
||||
ERR("%s(): get_ION_handle failed\n", __func__);
|
||||
goto import_ion_error;
|
||||
}
|
||||
rc = ion_handle_get_flags(client_ctx->user_ion_client,
|
||||
client_ctx->
|
||||
meta_buffer_iommu_ion_handle,
|
||||
&ionflag_iommu);
|
||||
if (rc) {
|
||||
ERR("%s():get_ION_flags fail\n",
|
||||
__func__);
|
||||
goto import_ion_error;
|
||||
}
|
||||
vcd_meta_buffer->kernel_virt_addr_iommu =
|
||||
(u8 *) ion_map_kernel(
|
||||
client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_iommu_ion_handle);
|
||||
if (!vcd_meta_buffer->kernel_virt_addr_iommu) {
|
||||
ERR("%s(): get_ION_kernel virtual addr failed\n",
|
||||
__func__);
|
||||
goto import_ion_error;
|
||||
}
|
||||
if (res_trk_get_core_type() == (u32)VCD_CORE_720P) {
|
||||
rc = ion_phys(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_iommu_ion_handle,
|
||||
(unsigned long *) (&(vcd_meta_buffer->
|
||||
physical_addr_iommu)), &len_iommu);
|
||||
if (rc) {
|
||||
ERR("%s():get_ION_kernel physical addr fail\n",
|
||||
__func__);
|
||||
goto ion_map_error_iommu;
|
||||
}
|
||||
vcd_meta_buffer->client_data_iommu = NULL;
|
||||
vcd_meta_buffer->dev_addr_iommu = (u8 *)
|
||||
vcd_meta_buffer->physical_addr_iommu;
|
||||
} else {
|
||||
rc = ion_map_iommu(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_iommu_ion_handle,
|
||||
VIDEO_DOMAIN, VIDEO_MAIN_POOL,
|
||||
SZ_4K, 0, (unsigned long *)&iova_iommu,
|
||||
(unsigned long *)&buffer_size_iommu,
|
||||
0, 0);
|
||||
if (rc || !iova_iommu) {
|
||||
ERR("%s():get_ION_kernel physical addr fail, "\
|
||||
"rc = %d iova = 0x%lx\n",
|
||||
__func__, rc, iova);
|
||||
goto ion_map_error_iommu;
|
||||
}
|
||||
vcd_meta_buffer->physical_addr_iommu =
|
||||
(u8 *) iova_iommu;
|
||||
vcd_meta_buffer->client_data_iommu = NULL;
|
||||
vcd_meta_buffer->dev_addr_iommu = (u8 *) iova_iommu;
|
||||
}
|
||||
}
|
||||
|
||||
/*fill the meta addr table*/
|
||||
num_buffers = vcd_meta_buffer->count;
|
||||
buf_size = vcd_meta_buffer->size/num_buffers;
|
||||
ker_vir_addr = vcd_meta_buffer->kernel_virtual_addr;
|
||||
ker_vir_addr_iommu = vcd_meta_buffer->kernel_virt_addr_iommu;
|
||||
client_ctx->meta_buf_size = buf_size;
|
||||
for (index = 0; index < num_buffers; index++) {
|
||||
client_ctx->meta_addr_table[index].kernel_vir_addr =
|
||||
ker_vir_addr;
|
||||
client_ctx->meta_addr_table[index].kernel_vir_addr_iommu =
|
||||
ker_vir_addr_iommu;
|
||||
DBG("[%d] kernel_virtual = %p kernel_vir_iommu = %p",
|
||||
index, ker_vir_addr, ker_vir_addr_iommu);
|
||||
ker_vir_addr += buf_size;
|
||||
ker_vir_addr_iommu += buf_size;
|
||||
}
|
||||
|
||||
DBG("Meta Buffer: Virt: %p, Phys %p, fd: %d",
|
||||
vcd_meta_buffer->kernel_virtual_addr,
|
||||
vcd_meta_buffer->physical_addr,
|
||||
vcd_meta_buffer->pmem_fd);
|
||||
DBG("IOMMU Meta Buffer: Virt: %p, Phys %p, fd: %d",
|
||||
vcd_meta_buffer->kernel_virt_addr_iommu,
|
||||
vcd_meta_buffer->physical_addr_iommu,
|
||||
vcd_meta_buffer->pmem_fd_iommu);
|
||||
DBG("Meta_buffer: Dev addr %p", vcd_meta_buffer->dev_addr);
|
||||
DBG("IOMMU Meta_buffer: Dev addr %p",
|
||||
vcd_meta_buffer->dev_addr_iommu);
|
||||
vcd_status = vcd_set_property(client_ctx->vcd_handle,
|
||||
&vcd_property_hdr,
|
||||
vcd_meta_buffer);
|
||||
|
||||
if (vcd_status)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
ion_map_error_iommu:
|
||||
if (vcd_meta_buffer->kernel_virt_addr_iommu) {
|
||||
ion_unmap_kernel(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_iommu_ion_handle);
|
||||
vcd_meta_buffer->kernel_virt_addr_iommu = NULL;
|
||||
}
|
||||
if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_iommu_ion_handle)) {
|
||||
ion_free(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_iommu_ion_handle);
|
||||
client_ctx->meta_buffer_iommu_ion_handle = NULL;
|
||||
}
|
||||
ion_map_error:
|
||||
if (vcd_meta_buffer->kernel_virtual_addr) {
|
||||
ion_unmap_kernel(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_ion_handle);
|
||||
vcd_meta_buffer->kernel_virtual_addr = NULL;
|
||||
}
|
||||
if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_ion_handle)) {
|
||||
ion_free(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_ion_handle);
|
||||
client_ctx->meta_buffer_ion_handle = NULL;
|
||||
}
|
||||
import_ion_error:
|
||||
return false;
|
||||
}
|
||||
static u32 vid_dec_set_h264_mv_buffers(struct video_client_ctx *client_ctx,
|
||||
struct vdec_h264_mv *mv_data)
|
||||
{
|
||||
|
@ -1018,6 +1306,65 @@ static u32 vid_dec_get_h264_mv_buffer_size(struct video_client_ctx *client_ctx,
|
|||
return true;
|
||||
}
|
||||
|
||||
static u32 vid_dec_free_meta_buffers(struct video_client_ctx *client_ctx)
|
||||
{
|
||||
struct vcd_property_hdr vcd_property_hdr;
|
||||
struct vcd_property_buffer_size meta_buffer_size;
|
||||
u32 vcd_status = VCD_ERR_FAIL;
|
||||
|
||||
if (!client_ctx)
|
||||
return false;
|
||||
if (client_ctx->vcd_meta_buffer.client_data)
|
||||
msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
|
||||
client_ctx->vcd_meta_buffer.client_data);
|
||||
|
||||
if (client_ctx->vcd_meta_buffer.client_data_iommu)
|
||||
msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
|
||||
client_ctx->vcd_meta_buffer.client_data_iommu);
|
||||
|
||||
vcd_property_hdr.prop_id = VCD_I_FREE_EXT_METABUFFER;
|
||||
vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
|
||||
|
||||
vcd_status = vcd_set_property(client_ctx->vcd_handle,
|
||||
&vcd_property_hdr, &meta_buffer_size);
|
||||
|
||||
if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_ion_handle)) {
|
||||
ion_unmap_kernel(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_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,
|
||||
client_ctx->meta_buffer_ion_handle,
|
||||
VIDEO_DOMAIN,
|
||||
VIDEO_MAIN_POOL);
|
||||
}
|
||||
ion_free(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_ion_handle);
|
||||
client_ctx->meta_buffer_ion_handle = NULL;
|
||||
}
|
||||
|
||||
if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_iommu_ion_handle)) {
|
||||
ion_unmap_kernel(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_iommu_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,
|
||||
client_ctx->meta_buffer_iommu_ion_handle,
|
||||
VIDEO_DOMAIN,
|
||||
VIDEO_MAIN_POOL);
|
||||
}
|
||||
ion_free(client_ctx->user_ion_client,
|
||||
client_ctx->meta_buffer_iommu_ion_handle);
|
||||
client_ctx->meta_buffer_iommu_ion_handle = NULL;
|
||||
}
|
||||
|
||||
if (vcd_status)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static u32 vid_dec_free_h264_mv_buffers(struct video_client_ctx *client_ctx)
|
||||
{
|
||||
struct vcd_property_hdr vcd_property_hdr;
|
||||
|
@ -1085,6 +1432,7 @@ static u32 vid_dec_get_buffer_req(struct video_client_ctx *client_ctx,
|
|||
vdec_buf_req->buffer_size = vcd_buf_req.sz;
|
||||
vdec_buf_req->alignment = vcd_buf_req.align;
|
||||
vdec_buf_req->buf_poolid = vcd_buf_req.buf_pool_id;
|
||||
vdec_buf_req->meta_buffer_size = vcd_buf_req.meta_buffer_size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1977,6 +2325,29 @@ static long vid_dec_ioctl(struct file *file,
|
|||
return -EIO;
|
||||
break;
|
||||
}
|
||||
case VDEC_IOCTL_SET_META_BUFFERS:
|
||||
{
|
||||
struct vdec_meta_buffers meta_buffers;
|
||||
DBG("VDEC_IOCTL_SET_META_BUFFERS\n");
|
||||
if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
|
||||
return -EFAULT;
|
||||
if (copy_from_user(&meta_buffers, vdec_msg.in,
|
||||
sizeof(meta_buffers)))
|
||||
return -EFAULT;
|
||||
result = vid_dec_set_meta_buffers(client_ctx, &meta_buffers);
|
||||
|
||||
if (!result)
|
||||
return -EIO;
|
||||
break;
|
||||
}
|
||||
case VDEC_IOCTL_FREE_META_BUFFERS:
|
||||
{
|
||||
DBG("VDEC_IOCTL_FREE_META_BUFFERS\n");
|
||||
result = vid_dec_free_meta_buffers(client_ctx);
|
||||
if (!result)
|
||||
return -EIO;
|
||||
break;
|
||||
}
|
||||
case VDEC_IOCTL_SET_H264_MV_BUFFER:
|
||||
{
|
||||
struct vdec_h264_mv mv_data;
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
|
||||
#define VDEC_EXTRADATA_EXT_DATA 0x0800
|
||||
#define VDEC_EXTRADATA_USER_DATA 0x1000
|
||||
#define VDEC_EXTRADATA_EXT_BUFFER 0x2000
|
||||
|
||||
#define VDEC_CMDBASE 0x800
|
||||
#define VDEC_CMD_SET_INTF_VERSION (VDEC_CMDBASE)
|
||||
|
@ -213,6 +214,12 @@ struct vdec_ioctl_msg {
|
|||
#define VDEC_IOCTL_SET_PERF_CLK \
|
||||
_IOR(VDEC_IOCTL_MAGIC, 38, struct vdec_ioctl_msg)
|
||||
|
||||
#define VDEC_IOCTL_SET_META_BUFFERS \
|
||||
_IOW(VDEC_IOCTL_MAGIC, 39, struct vdec_ioctl_msg)
|
||||
|
||||
#define VDEC_IOCTL_FREE_META_BUFFERS \
|
||||
_IO(VDEC_IOCTL_MAGIC, 40)
|
||||
|
||||
enum vdec_picture {
|
||||
PICTURE_TYPE_I,
|
||||
PICTURE_TYPE_P,
|
||||
|
@ -236,6 +243,7 @@ struct vdec_allocatorproperty {
|
|||
size_t buffer_size;
|
||||
uint32_t alignment;
|
||||
uint32_t buf_poolid;
|
||||
size_t meta_buffer_size;
|
||||
};
|
||||
|
||||
struct vdec_bufferpayload {
|
||||
|
@ -526,6 +534,11 @@ struct vdec_aspectratioinfo {
|
|||
uint32_t par_height;
|
||||
};
|
||||
|
||||
struct vdec_sep_metadatainfo {
|
||||
void __user *metabufaddr;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct vdec_output_frameinfo {
|
||||
void __user *bufferaddr;
|
||||
size_t offset;
|
||||
|
@ -538,6 +551,7 @@ struct vdec_output_frameinfo {
|
|||
struct vdec_framesize framesize;
|
||||
enum vdec_interlaced_format interlaced_format;
|
||||
struct vdec_aspectratioinfo aspect_ratio_info;
|
||||
struct vdec_sep_metadatainfo metadata_info;
|
||||
};
|
||||
|
||||
union vdec_msgdata {
|
||||
|
@ -571,4 +585,12 @@ struct vdec_mv_buff_size{
|
|||
int alignment;
|
||||
};
|
||||
|
||||
struct vdec_meta_buffers {
|
||||
size_t size;
|
||||
int count;
|
||||
int pmem_fd;
|
||||
int pmem_fd_iommu;
|
||||
int offset;
|
||||
};
|
||||
|
||||
#endif /* end of macro _VDECDECODER_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
|
||||
/* Copyright (c) 2010-2013, The Linux Foundation. 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
|
||||
|
@ -100,6 +100,7 @@ struct vcd_buffer_requirement {
|
|||
size_t sz;
|
||||
u32 align;
|
||||
u32 buf_pool_id;
|
||||
size_t meta_buffer_size;
|
||||
};
|
||||
|
||||
struct vcd_init_config {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
|
||||
/* Copyright (c) 2010-2013, The Linux Foundation. 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
|
||||
|
@ -57,7 +57,8 @@
|
|||
#define VCD_I_SET_TURBO_CLK (VCD_START_BASE + 0x29)
|
||||
#define VCD_I_ENABLE_DELIMITER_FLAG (VCD_START_BASE + 0x2A)
|
||||
#define VCD_I_ENABLE_VUI_TIMING_INFO (VCD_START_BASE + 0x2B)
|
||||
|
||||
#define VCD_I_SET_EXT_METABUFFER (VCD_START_BASE + 0x2C)
|
||||
#define VCD_I_FREE_EXT_METABUFFER (VCD_START_BASE + 0x2D)
|
||||
|
||||
#define VCD_START_REQ (VCD_START_BASE + 0x1000)
|
||||
#define VCD_I_REQ_IFRAME (VCD_START_REQ + 0x1)
|
||||
|
@ -118,6 +119,7 @@ enum vcd_perf_level {
|
|||
|
||||
#define VCD_METADATA_EXT_DATA 0x0800
|
||||
#define VCD_METADATA_USER_DATA 0x1000
|
||||
#define VCD_METADATA_SEPARATE_BUF 0x2000
|
||||
|
||||
struct vcd_property_meta_data_enable {
|
||||
u32 meta_data_enable_flag;
|
||||
|
@ -384,4 +386,19 @@ struct vcd_property_vui_timing_info_enable {
|
|||
u32 vui_timing_info;
|
||||
};
|
||||
|
||||
struct vcd_property_meta_buffer {
|
||||
u8 *kernel_virtual_addr;
|
||||
u8 *physical_addr;
|
||||
u32 size;
|
||||
u32 count;
|
||||
int pmem_fd;
|
||||
u32 offset;
|
||||
u8 *dev_addr;
|
||||
void *client_data;
|
||||
u8 *kernel_virt_addr_iommu;
|
||||
u8 *physical_addr_iommu;
|
||||
int pmem_fd_iommu;
|
||||
u8 *dev_addr_iommu;
|
||||
void *client_data_iommu;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
|
||||
/* Copyright (c) 2010-2013, The Linux Foundation. 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
|
||||
|
@ -19,6 +19,7 @@
|
|||
|
||||
#define VIDC_MAX_NUM_CLIENTS 4
|
||||
#define MAX_VIDEO_NUM_OF_BUFF 100
|
||||
#define MAX_META_BUFFERS 32
|
||||
|
||||
enum buffer_dir {
|
||||
BUFFER_TYPE_INPUT,
|
||||
|
@ -37,6 +38,11 @@ struct buf_addr_table {
|
|||
void *client_data;
|
||||
};
|
||||
|
||||
struct meta_buffer_addr_table {
|
||||
u8 *kernel_vir_addr;
|
||||
u8 *kernel_vir_addr_iommu;
|
||||
};
|
||||
|
||||
struct video_client_ctx {
|
||||
void *vcd_handle;
|
||||
u32 num_of_input_buffers;
|
||||
|
@ -49,17 +55,22 @@ struct video_client_ctx {
|
|||
wait_queue_head_t msg_wait;
|
||||
struct completion event;
|
||||
struct vcd_property_h264_mv_buffer vcd_h264_mv_buffer;
|
||||
struct vcd_property_meta_buffer vcd_meta_buffer;
|
||||
struct vcd_property_enc_recon_buffer recon_buffer[4];
|
||||
u32 event_status;
|
||||
u32 seq_header_set;
|
||||
u32 stop_msg;
|
||||
u32 stop_called;
|
||||
u32 stop_sync_cb;
|
||||
size_t meta_buf_size;
|
||||
struct ion_client *user_ion_client;
|
||||
struct ion_handle *seq_hdr_ion_handle;
|
||||
struct ion_handle *h264_mv_ion_handle;
|
||||
struct ion_handle *recon_buffer_ion_handle[4];
|
||||
struct ion_handle *meta_buffer_ion_handle;
|
||||
struct ion_handle *meta_buffer_iommu_ion_handle;
|
||||
u32 dmx_disable;
|
||||
struct meta_buffer_addr_table meta_addr_table[MAX_META_BUFFERS];
|
||||
};
|
||||
|
||||
void __iomem *vidc_get_ioaddr(void);
|
||||
|
|
Loading…
Reference in a new issue