diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index da4766b456f00435c618f75a68f80e4d7e0bcf10..a0afc6ebb05927289930d91f01724eaad4353f3e 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2349,13 +2349,6 @@ config FB_PRE_INIT_FB Select this option if display contents should be inherited as set by the bootloader. -config FB_MSM - tristate "MSM Framebuffer support" - depends on FB && ARCH_MSM - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - config FB_MX3 tristate "MX3 Framebuffer support" depends on FB && MX3_IPU @@ -2472,6 +2465,7 @@ config FB_SIMPLE through device tree, or potentially plain old platform data in the future. +source "drivers/video/msm/Kconfig" source "drivers/video/omap/Kconfig" source "drivers/video/omap2/Kconfig" source "drivers/video/exynos/Kconfig" diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig index f5e3093ffeb155f6a43fd72137e928783e65232d..b8d1df8d29bfdd61063d1989c15915af9a49a833 100644 --- a/drivers/video/msm/Kconfig +++ b/drivers/video/msm/Kconfig @@ -1,3 +1,6 @@ + +source "drivers/video/msm/vidc/Kconfig" + config FB_MSM tristate "MSM Framebuffer support" depends on FB && ARCH_MSM diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile index 0a37cf3a78aefd5157c44dd60e247073de38ba92..b2ecb083b9f254df15bab0ffccf55e370d147b9c 100644 --- a/drivers/video/msm/Makefile +++ b/drivers/video/msm/Makefile @@ -181,6 +181,9 @@ obj-$(CONFIG_FB_MSM_EXTMDDI_SVGA) += mddi_ext_lcd.o obj-$(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL) += mdp4_wfd_writeback_panel.o obj-$(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL) += mdp4_wfd_writeback.o obj-$(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL) += mdp4_overlay_writeback.o + +obj-$(CONFIG_MSM_VIDC_1080P) += vidc/ +obj-$(CONFIG_MSM_VIDC_720P) += vidc/ else obj-$(CONFIG_FB_MSM_EBI2) += ebi2_host.o obj-$(CONFIG_FB_MSM_EBI2) += ebi2_lcd.o diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c new file mode 100644 index 0000000000000000000000000000000000000000..ac002e12685c6da510e169538dbbf33f65c08e6f --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c @@ -0,0 +1,718 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include "vcd_ddl.h" +#include "vcd_ddl_metadata.h" +#include "vcd_res_tracker_api.h" + +static unsigned int first_time; + +u32 ddl_device_init(struct ddl_init_config *ddl_init_config, + void *client_data) +{ + struct ddl_context *ddl_context; + u32 status = VCD_S_SUCCESS; + void *ptr = NULL; + DDL_MSG_HIGH("ddl_device_init"); + + if ((!ddl_init_config) || (!ddl_init_config->ddl_callback) || + (!ddl_init_config->core_virtual_base_addr)) { + DDL_MSG_ERROR("ddl_dev_init:Bad_argument"); + return VCD_ERR_ILLEGAL_PARM; + } + ddl_context = ddl_get_context(); + if (DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_dev_init:Multiple_init"); + return VCD_ERR_ILLEGAL_OP; + } + if (!DDL_IS_IDLE(ddl_context)) { + DDL_MSG_ERROR("ddl_dev_init:Ddl_busy"); + return VCD_ERR_BUSY; + } + memset(ddl_context, 0, sizeof(struct ddl_context)); + DDL_BUSY(ddl_context); + if (res_trk_get_enable_ion()) { + DDL_MSG_LOW("ddl_dev_init:ION framework enabled"); + ddl_context->video_ion_client = + res_trk_get_ion_client(); + if (!ddl_context->video_ion_client) { + DDL_MSG_ERROR("ION client create failed"); + return VCD_ERR_ILLEGAL_OP; + } + } + ddl_context->ddl_callback = ddl_init_config->ddl_callback; + if (ddl_init_config->interrupt_clr) + ddl_context->interrupt_clr = + ddl_init_config->interrupt_clr; + ddl_context->core_virtual_base_addr = + ddl_init_config->core_virtual_base_addr; + ddl_context->client_data = client_data; + ddl_context->ddl_hw_response.arg1 = DDL_INVALID_INTR_STATUS; + + ddl_context->frame_channel_depth = VCD_FRAME_COMMAND_DEPTH; + + DDL_MSG_LOW("%s() : virtual address of core(%x)\n", __func__, + (u32) ddl_init_config->core_virtual_base_addr); + vidc_1080p_set_device_base_addr( + ddl_context->core_virtual_base_addr); + ddl_context->cmd_state = DDL_CMD_INVALID; + ddl_client_transact(DDL_INIT_CLIENTS, NULL); + ddl_context->fw_memory_size = + DDL_FW_INST_GLOBAL_CONTEXT_SPACE_SIZE; + if (res_trk_get_firmware_addr(&ddl_context->dram_base_a)) { + DDL_MSG_ERROR("firmware allocation failed"); + ptr = NULL; + } else { + ptr = (void *)ddl_context->dram_base_a.virtual_base_addr; + } + if (!ptr) { + DDL_MSG_ERROR("Memory Aocation Failed for FW Base"); + status = VCD_ERR_ALLOC_FAIL; + } else { + DDL_MSG_LOW("%s() : physical address of base(%x)\n", + __func__, (u32) ddl_context->dram_base_a.\ + align_physical_addr); + ddl_context->dram_base_b.align_physical_addr = + ddl_context->dram_base_a.align_physical_addr; + ddl_context->dram_base_b.align_virtual_addr = + ddl_context->dram_base_a.align_virtual_addr; + } + if (!status) { + ddl_context->metadata_shared_input.mem_type = DDL_FW_MEM; + ptr = ddl_pmem_alloc(&ddl_context->metadata_shared_input, + DDL_METADATA_TOTAL_INPUTBUFSIZE, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!ptr) { + DDL_MSG_ERROR("ddl_device_init: metadata alloc fail"); + status = VCD_ERR_ALLOC_FAIL; + } + } + if (!status && !ddl_fw_init(&ddl_context->dram_base_a)) { + DDL_MSG_ERROR("ddl_dev_init:fw_init_failed"); + status = VCD_ERR_ALLOC_FAIL; + } + if (!status) { + ddl_context->cmd_state = DDL_CMD_DMA_INIT; + ddl_vidc_core_init(ddl_context); + } else { + ddl_release_context_buffers(ddl_context); + DDL_IDLE(ddl_context); + } + return status; +} + +u32 ddl_device_release(void *client_data) +{ + struct ddl_context *ddl_context; + + DDL_MSG_HIGH("ddl_device_release"); + ddl_context = ddl_get_context(); + if (!DDL_IS_IDLE(ddl_context)) { + DDL_MSG_ERROR("ddl_dev_rel:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_dev_rel:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl_client_transact(DDL_ACTIVE_CLIENT, NULL)) { + DDL_MSG_ERROR("ddl_dev_rel:Client_present_err"); + return VCD_ERR_CLIENT_PRESENT; + } + DDL_BUSY(ddl_context); + ddl_context->device_state = DDL_DEVICE_NOTINIT; + ddl_context->client_data = client_data; + ddl_context->cmd_state = DDL_CMD_INVALID; + ddl_vidc_core_term(ddl_context); + DDL_MSG_LOW("FW_ENDDONE"); + ddl_context->core_virtual_base_addr = NULL; + ddl_release_context_buffers(ddl_context); + ddl_context->video_ion_client = NULL; + DDL_IDLE(ddl_context); + return VCD_S_SUCCESS; +} + +u32 ddl_open(u32 **ddl_handle, u32 decoding) +{ + struct ddl_context *ddl_context; + struct ddl_client_context *ddl; + void *ptr; + u32 status; + + DDL_MSG_HIGH("ddl_open"); + if (!ddl_handle) { + DDL_MSG_ERROR("ddl_open:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_open:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + status = ddl_client_transact(DDL_GET_CLIENT, &ddl); + if (status) { + DDL_MSG_ERROR("ddl_open:Client_trasac_failed"); + return status; + } + if (res_trk_check_for_sec_session()) + ddl->shared_mem[0].mem_type = DDL_CMD_MEM; + else + ddl->shared_mem[0].mem_type = DDL_FW_MEM; + ptr = ddl_pmem_alloc(&ddl->shared_mem[0], + DDL_FW_AUX_HOST_CMD_SPACE_SIZE, 0); + if (!ptr) + status = VCD_ERR_ALLOC_FAIL; + if (!status && ddl_context->frame_channel_depth + == VCD_DUAL_FRAME_COMMAND_CHANNEL) { + if (res_trk_check_for_sec_session()) + ddl->shared_mem[1].mem_type = DDL_CMD_MEM; + else + ddl->shared_mem[1].mem_type = DDL_FW_MEM; + ptr = ddl_pmem_alloc(&ddl->shared_mem[1], + DDL_FW_AUX_HOST_CMD_SPACE_SIZE, 0); + if (!ptr) { + ddl_pmem_free(&ddl->shared_mem[0]); + status = VCD_ERR_ALLOC_FAIL; + } + } + if (!status) { + memset(ddl->shared_mem[0].align_virtual_addr, 0, + DDL_FW_AUX_HOST_CMD_SPACE_SIZE); + if (ddl_context->frame_channel_depth == + VCD_DUAL_FRAME_COMMAND_CHANNEL) { + memset(ddl->shared_mem[1].align_virtual_addr, 0, + DDL_FW_AUX_HOST_CMD_SPACE_SIZE); + } + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_OPEN", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_OPEN; + ddl->codec_data.hdr.decoding = decoding; + ddl->decoding = decoding; + ddl_set_default_meta_data_hdr(ddl); + ddl_set_initial_default_values(ddl); + *ddl_handle = (u32 *) ddl; + } else { + ddl_pmem_free(&ddl->shared_mem[0]); + if (ddl_context->frame_channel_depth + == VCD_DUAL_FRAME_COMMAND_CHANNEL) + ddl_pmem_free(&ddl->shared_mem[1]); + ddl_client_transact(DDL_FREE_CLIENT, &ddl); + } + return status; +} + +u32 ddl_close(u32 **ddl_handle) +{ + struct ddl_context *ddl_context; + struct ddl_client_context **pp_ddl = + (struct ddl_client_context **)ddl_handle; + + DDL_MSG_HIGH("ddl_close"); + if (!pp_ddl || !*pp_ddl) { + DDL_MSG_ERROR("ddl_close:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_close:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (!DDLCLIENT_STATE_IS(*pp_ddl, DDL_CLIENT_OPEN)) { + DDL_MSG_ERROR("ddl_close:Not_in_open_state"); + return VCD_ERR_ILLEGAL_OP; + } + ddl_pmem_free(&(*pp_ddl)->shared_mem[0]); + if (ddl_context->frame_channel_depth == + VCD_DUAL_FRAME_COMMAND_CHANNEL) + ddl_pmem_free(&(*pp_ddl)->shared_mem[1]); + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_INVALID", + ddl_get_state_string((*pp_ddl)->client_state)); + (*pp_ddl)->client_state = DDL_CLIENT_INVALID; + ddl_codec_type_transact(*pp_ddl, true, (enum vcd_codec)0); + ddl_client_transact(DDL_FREE_CLIENT, pp_ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_encode_start(u32 *ddl_handle, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + struct ddl_context *ddl_context; + struct ddl_encoder_data *encoder; + void *ptr; + u32 status = VCD_S_SUCCESS; + DDL_MSG_HIGH("ddl_encode_start"); + if (first_time < 2) { + ddl_reset_core_time_variables(ENC_OP_TIME); + first_time++; + } + ddl_set_core_start_time(__func__, ENC_OP_TIME); + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_enc_start:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + DDL_MSG_ERROR("ddl_enc_start:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || ddl->decoding) { + DDL_MSG_ERROR("ddl_enc_start:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + DDL_MSG_ERROR("ddl_enc_start:Not_opened"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl_encoder_ready_to_start(ddl)) { + DDL_MSG_ERROR("ddl_enc_start:Err_param_settings"); + return VCD_ERR_ILLEGAL_OP; + } + encoder = &ddl->codec_data.encoder; + status = ddl_allocate_enc_hw_buffers(ddl); + if (status) + return status; +#ifdef DDL_BUF_LOG + ddl_list_buffers(ddl); +#endif + encoder->seq_header.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&encoder->seq_header, + DDL_ENC_SEQHEADER_SIZE, DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!ptr) { + ddl_free_enc_hw_buffers(ddl); + DDL_MSG_ERROR("ddl_enc_start:Seq_hdr_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + msm_ion_do_cache_op(ddl_context->video_ion_client, + encoder->seq_header.alloc_handle, + 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); + return status; +} + +u32 ddl_decode_start(u32 *ddl_handle, struct vcd_sequence_hdr *header, + void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + struct ddl_context *ddl_context; + struct ddl_decoder_data *decoder; + u32 status = VCD_S_SUCCESS; + + DDL_MSG_HIGH("ddl_decode_start"); + ddl_reset_core_time_variables(DEC_OP_TIME); + ddl_reset_core_time_variables(DEC_IP_TIME); + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_dec_start:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + DDL_MSG_ERROR("ddl_dec_start:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || !ddl->decoding) { + DDL_MSG_ERROR("ddl_dec_start:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + DDL_MSG_ERROR("ddl_dec_start:Not_in_opened_state"); + return VCD_ERR_ILLEGAL_OP; + } + + if ((header) && ((!header->sequence_header_len) || + (!header->sequence_header))) { + DDL_MSG_ERROR("ddl_dec_start:Bad_param_seq_header"); + return VCD_ERR_ILLEGAL_PARM; + } + if (!ddl_decoder_ready_to_start(ddl, header)) { + DDL_MSG_ERROR("ddl_dec_start:Err_param_settings"); + return VCD_ERR_ILLEGAL_OP; + } + decoder = &ddl->codec_data.decoder; + status = ddl_allocate_dec_hw_buffers(ddl); + if (status) + return status; +#ifdef DDL_BUF_LOG + ddl_list_buffers(ddl); +#endif + if (!ddl_take_command_channel(ddl_context, ddl, client_data)) + return VCD_ERR_BUSY; + if (header) { + decoder->header_in_start = true; + decoder->decode_config = *header; + } else { + decoder->header_in_start = false; + decoder->decode_config.sequence_header_len = 0; + } + ddl_vidc_channel_set(ddl); + return status; +} + +u32 ddl_decode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_bits, void *client_data) +{ + u32 vcd_status = VCD_S_SUCCESS; + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + struct ddl_context *ddl_context; + struct ddl_decoder_data *decoder; + DDL_MSG_HIGH("ddl_decode_frame"); + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_dec_frame:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + DDL_MSG_ERROR("ddl_dec_frame:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || !ddl->decoding) { + DDL_MSG_ERROR("ddl_dec_frame:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!input_bits || ((!input_bits->vcd_frm.physical || + !input_bits->vcd_frm.data_len) && + (!(VCD_FRAME_FLAG_EOS & input_bits->vcd_frm.flags)))) { + DDL_MSG_ERROR("ddl_dec_frame:Bad_input_param"); + return VCD_ERR_ILLEGAL_PARM; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) { + DDL_MSG_ERROR("Dec_frame:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + decoder = &(ddl->codec_data.decoder); + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && + !ddl->codec_data.decoder.dp_buf.no_of_dec_pic_buf) { + DDL_MSG_ERROR("ddl_dec_frame:Dpbs_requied"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl_take_command_channel(ddl_context, ddl, client_data)) + return VCD_ERR_BUSY; + + ddl->input_frame = *input_bits; + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) + ddl_vidc_decode_frame_run(ddl); + else { + if (!ddl->codec_data.decoder.dp_buf.no_of_dec_pic_buf) { + DDL_MSG_ERROR("ddl_dec_frame:Dpbs_requied"); + vcd_status = VCD_ERR_ILLEGAL_OP; + } else if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) { + vcd_status = ddl_vidc_decode_set_buffers(ddl); + if (vcd_status) + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } else if (DDLCLIENT_STATE_IS(ddl, + DDL_CLIENT_WAIT_FOR_INITCODEC)) { + if (decoder->codec.codec == VCD_CODEC_DIVX_3) { + if ((!decoder->client_frame_size.width) || + (!decoder->client_frame_size.height)) + return VCD_ERR_ILLEGAL_OP; + } + ddl->codec_data.decoder.decode_config.sequence_header = + ddl->input_frame.vcd_frm.physical; + ddl->codec_data.decoder.decode_config.sequence_header_len = + ddl->input_frame.vcd_frm.data_len; + ddl_vidc_decode_init_codec(ddl); + } else { + DDL_MSG_ERROR("Dec_frame:Wrong_state"); + vcd_status = VCD_ERR_ILLEGAL_OP; + } + if (vcd_status) + DDL_IDLE(ddl_context); + } + return vcd_status; +} + +u32 ddl_encode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_frame, + struct ddl_frame_data_tag *output_bit, void *client_data) +{ + 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; + struct vcd_transc *transc; + transc = (struct vcd_transc *)(ddl->client_data); + DDL_MSG_LOW("%s: transc = 0x%x", __func__, (u32)ddl->client_data); + 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_set_core_start_time(__func__, ENC_OP_TIME); + 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; + + ddl->input_frame = *input_frame; + ddl->output_frame = *output_bit; + if (ddl->codec_data.encoder.i_period.b_frames > 0) { + if (!ddl->b_count) { + ddl->first_output_frame = *output_bit; + ddl->b_count++; + } else if (ddl->codec_data.encoder.i_period.b_frames >= + ddl->b_count) { + ddl->extra_output_frame[ddl->b_count-1] = + *output_bit; + ddl->output_frame = ddl->first_output_frame; + ddl->b_count++; + } + } + ddl_insert_input_frame_to_pool(ddl, input_frame); + if (!vcd_status) + ddl_vidc_encode_frame_run(ddl); + else + DDL_MSG_ERROR("insert to frame pool failed %u", vcd_status); + 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 = + (struct ddl_client_context *) ddl_handle; + struct ddl_context *ddl_context; + + DDL_MSG_HIGH("ddl_decode_end"); + ddl_reset_core_time_variables(DEC_OP_TIME); + ddl_reset_core_time_variables(DEC_IP_TIME); + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_dec_end:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + DDL_MSG_ERROR("ddl_dec_end:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || !ddl->decoding) { + DDL_MSG_ERROR("ddl_dec_end:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_FAVIDC_ERROR)) { + DDL_MSG_ERROR("ddl_dec_end:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl_take_command_channel(ddl_context, ddl, client_data)) + return VCD_ERR_BUSY; + ddl_vidc_channel_end(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_encode_end(u32 *ddl_handle, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + struct ddl_context *ddl_context; + + DDL_MSG_HIGH("ddl_encode_end"); + ddl_reset_core_time_variables(ENC_OP_TIME); + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_enc_end:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + DDL_MSG_ERROR("ddl_enc_end:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || ddl->decoding) { + DDL_MSG_ERROR("ddl_enc_end:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_FAVIDC_ERROR)) { + DDL_MSG_ERROR("ddl_enc_end:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl_take_command_channel(ddl_context, ddl, client_data)) + return VCD_ERR_BUSY; + ddl_vidc_channel_end(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_reset_hw(u32 mode) +{ + struct ddl_context *ddl_context; + struct ddl_client_context *ddl; + u32 i; + + DDL_MSG_HIGH("ddl_reset_hw"); + DDL_MSG_LOW("ddl_reset_hw:called"); + ddl_context = ddl_get_context(); + ddl_context->cmd_state = DDL_CMD_INVALID; + DDL_BUSY(ddl_context); + if (ddl_context->core_virtual_base_addr) { + vidc_1080p_do_sw_reset(VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE); + msleep(DDL_SW_RESET_SLEEP); + vidc_1080p_do_sw_reset(VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE); + msleep(DDL_SW_RESET_SLEEP); + ddl_context->core_virtual_base_addr = NULL; + } + ddl_context->device_state = DDL_DEVICE_NOTINIT; + for (i = 0; i < VCD_MAX_NO_CLIENT; i++) { + ddl = ddl_context->ddl_clients[i]; + ddl_context->ddl_clients[i] = NULL; + if (ddl) { + ddl_release_client_internal_buffers(ddl); + ddl_client_transact(DDL_FREE_CLIENT, &ddl); + } + } + ddl_release_context_buffers(ddl_context); + memset(ddl_context, 0, sizeof(struct ddl_context)); + return true; +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h new file mode 100644 index 0000000000000000000000000000000000000000..a7b19f9a812d3b9cf0a54c5da942ecdaf82f9ffc --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h @@ -0,0 +1,493 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VCD_DDL_H_ +#define _VCD_DDL_H_ + +#include +#include "vcd_ddl_api.h" +#include "vcd_ddl_core.h" +#include "vcd_ddl_utils.h" +#include "vidc.h" +#include "vidc_hwio.h" +#include "vidc_pix_cache.h" +#include "vidc.h" + +#define DDL_IDLE_STATE 0 +#define DDL_BUSY_STATE 1 +#define DDL_ERROR_STATE 2 +#define DDL_RUN_STATE 3 + +#define DDL_IS_BUSY(ddl_context) \ + ((ddl_context)->ddl_busy == DDL_BUSY_STATE) +#define DDL_IS_IDLE(ddl_context) \ + ((ddl_context)->ddl_busy == DDL_IDLE_STATE) +#define DDL_BUSY(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_BUSY_STATE) +#define DDL_IDLE(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_IDLE_STATE) +#define DDL_ERROR(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_ERROR_STATE) +#define DDL_RUN(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_RUN_STATE) + +#define DDL_DEVICE_NOTINIT 0 +#define DDL_DEVICE_INITED 1 +#define DDL_DEVICE_HWFATAL 2 + +#define DDL_IS_INITIALIZED(ddl_context) \ + (ddl_context->device_state == DDL_DEVICE_INITED) +#define DDLCOMMAND_STATE_IS(ddl_context, command_state) \ + (command_state == (ddl_context)->cmd_state) +#define DDLCLIENT_STATE_IS(ddl, state) \ + (state == (ddl)->client_state) + +#define DDL_DPB_OP_INIT 1 +#define DDL_DPB_OP_MARK_FREE 2 +#define DDL_DPB_OP_MARK_BUSY 3 +#define DDL_DPB_OP_SET_MASK 4 +#define DDL_DPB_OP_RETRIEVE 5 + +#define DDL_INIT_CLIENTS 0 +#define DDL_GET_CLIENT 1 +#define DDL_FREE_CLIENT 2 +#define DDL_ACTIVE_CLIENT 3 + +#define DDL_INVALID_CHANNEL_ID ((u32)~0) +#define DDL_INVALID_CODEC_TYPE ((u32)~0) +#define DDL_INVALID_INTR_STATUS ((u32)~0) + +#define DDL_ENC_REQ_IFRAME 0x01 +#define DDL_ENC_CHANGE_IPERIOD 0x02 +#define DDL_ENC_CHANGE_BITRATE 0x04 +#define DDL_ENC_CHANGE_FRAMERATE 0x08 +#define DDL_ENC_CHANGE_CIR 0x10 + +#define DDL_DEC_REQ_OUTPUT_FLUSH 0x1 + +#define DDL_MIN_NUM_OF_B_FRAME 0 +#define DDL_MAX_NUM_OF_B_FRAME 1 +#define DDL_DEFAULT_NUM_OF_B_FRAME DDL_MIN_NUM_OF_B_FRAME + +#define DDL_MIN_NUM_REF_FOR_P_FRAME 1 +#define DDL_MAX_NUM_REF_FOR_P_FRAME 2 + +#define DDL_MAX_NUM_IN_INPUTFRAME_POOL (DDL_MAX_NUM_OF_B_FRAME + 1) + +#define MDP_MIN_TILE_HEIGHT 96 + +enum ddl_mem_area { + DDL_FW_MEM = 0x0, + DDL_MM_MEM = 0x1, + DDL_CMD_MEM = 0x2 +}; + +struct ddl_buf_addr{ + u8 *virtual_base_addr; + u8 *physical_base_addr; + u8 *align_physical_addr; + u8 *align_virtual_addr; + phys_addr_t alloced_phys_addr; + struct msm_mapped_buffer *mapped_buffer; + struct ion_handle *alloc_handle; + u32 buffer_size; + enum ddl_mem_area mem_type; + void *pil_cookie; +}; +enum ddl_cmd_state{ + DDL_CMD_INVALID = 0x0, + DDL_CMD_DMA_INIT = 0x1, + DDL_CMD_CPU_RESET = 0x2, + DDL_CMD_CHANNEL_SET = 0x3, + DDL_CMD_INIT_CODEC = 0x4, + DDL_CMD_HEADER_PARSE = 0x5, + DDL_CMD_DECODE_SET_DPB = 0x6, + DDL_CMD_DECODE_FRAME = 0x7, + 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{ + DDL_CLIENT_INVALID = 0x0, + DDL_CLIENT_OPEN = 0x1, + DDL_CLIENT_WAIT_FOR_CHDONE = 0x2, + DDL_CLIENT_WAIT_FOR_INITCODEC = 0x3, + DDL_CLIENT_WAIT_FOR_INITCODECDONE = 0x4, + DDL_CLIENT_WAIT_FOR_DPB = 0x5, + DDL_CLIENT_WAIT_FOR_DPBDONE = 0x6, + DDL_CLIENT_WAIT_FOR_FRAME = 0x7, + DDL_CLIENT_WAIT_FOR_FRAME_DONE = 0x8, + DDL_CLIENT_WAIT_FOR_EOS_DONE = 0x9, + 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{ + u32 cmd; + u32 arg1; + u32 arg2; + u32 arg3; + u32 arg4; +}; +struct ddl_mask{ + u32 client_mask; + u32 hw_mask; +}; +struct ddl_yuv_buffer_size{ + u32 size_yuv; + u32 size_y; + u32 size_c; +}; +struct ddl_dec_buffer_size{ + u32 sz_dpb0; + u32 sz_dpb1; + u32 sz_mv; + u32 sz_vert_nb_mv; + u32 sz_nb_ip; + u32 sz_luma; + u32 sz_chroma; + u32 sz_nb_dcac; + u32 sz_upnb_mv; + u32 sz_sub_anchor_mv; + u32 sz_overlap_xform; + u32 sz_bit_plane3; + u32 sz_bit_plane2; + u32 sz_bit_plane1; + u32 sz_stx_parser; + u32 sz_desc; + u32 sz_cpb; + u32 sz_context; +}; +struct ddl_dec_buffers{ + struct ddl_buf_addr desc; + struct ddl_buf_addr nb_dcac; + struct ddl_buf_addr upnb_mv; + struct ddl_buf_addr sub_anchor_mv; + struct ddl_buf_addr overlay_xform; + struct ddl_buf_addr bit_plane3; + struct ddl_buf_addr bit_plane2; + struct ddl_buf_addr bit_plane1; + struct ddl_buf_addr stx_parser; + struct ddl_buf_addr h264_mv[DDL_MAX_BUFFER_COUNT]; + struct ddl_buf_addr h264_vert_nb_mv; + struct ddl_buf_addr h264_nb_ip; + struct ddl_buf_addr context; +}; +struct ddl_enc_buffer_size{ + u32 sz_cur_y; + u32 sz_cur_c; + u32 sz_dpb_y; + u32 sz_dpb_c; + u32 sz_strm; + u32 sz_mv; + u32 sz_col_zero; + u32 sz_md; + u32 sz_pred; + u32 sz_nbor_info; + u32 sz_acdc_coef; + u32 sz_mb_info; + u32 sz_context; +}; +struct ddl_enc_buffers{ + struct ddl_buf_addr dpb_y[4]; + struct ddl_buf_addr dpb_c[4]; + struct ddl_buf_addr mv; + struct ddl_buf_addr col_zero; + struct ddl_buf_addr md; + struct ddl_buf_addr pred; + struct ddl_buf_addr nbor_info; + struct ddl_buf_addr acdc_coef; + struct ddl_buf_addr mb_info; + struct ddl_buf_addr context; + u32 dpb_count; + u32 sz_dpb_y; + u32 sz_dpb_c; +}; +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; + u32 first_output_frame_tag; +}; +struct ddl_encoder_data{ + struct ddl_codec_data_hdr hdr; + struct vcd_property_codec codec; + struct vcd_property_frame_size frame_size; + struct vcd_property_frame_rate frame_rate; + struct vcd_property_target_bitrate target_bit_rate; + struct vcd_property_profile profile; + struct vcd_property_level level; + struct vcd_property_rate_control rc; + struct vcd_property_multi_slice multi_slice; + struct ddl_buf_addr meta_data_input; + struct vcd_property_short_header short_header; + struct vcd_property_vop_timing vop_timing; + struct vcd_property_db_config db_control; + struct vcd_property_entropy_control entropy_control; + struct vcd_property_i_period i_period; + struct vcd_property_session_qp session_qp; + struct vcd_property_qp_range qp_range; + struct vcd_property_rc_level rc_level; + struct vcd_property_frame_level_rc_params frame_level_rc; + struct vcd_property_adaptive_rc_params adaptive_rc; + struct vcd_property_intra_refresh_mb_number intra_refresh; + struct vcd_property_buffer_format buf_format; + struct vcd_property_buffer_format recon_buf_format; + struct vcd_property_sps_pps_for_idr_enable sps_pps; + struct ddl_buf_addr seq_header; + struct vcd_buffer_requirement input_buf_req; + struct vcd_buffer_requirement output_buf_req; + struct vcd_buffer_requirement client_input_buf_req; + struct vcd_buffer_requirement client_output_buf_req; + struct ddl_enc_buffers hw_bufs; + struct ddl_yuv_buffer_size input_buf_size; + struct vidc_1080p_enc_frame_info enc_frame_info; + u32 meta_data_enable_flag; + u32 suffix; + u32 meta_data_offset; + u32 hdr_ext_control; + u32 r_cframe_skip; + u32 vb_vbuffer_size; + u32 dynamic_prop_change; + u32 dynmic_prop_change_req; + u32 seq_header_length; + u32 intra_frame_insertion; + u32 mb_info_enable; + 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; + struct vcd_property_codec codec; + struct vcd_property_buffer_format buf_format; + struct vcd_property_frame_size frame_size; + struct vcd_property_frame_size client_frame_size; + struct vcd_property_profile profile; + struct vcd_property_level level; + struct ddl_buf_addr meta_data_input; + struct vcd_property_post_filter post_filter; + struct vcd_sequence_hdr decode_config; + struct ddl_property_dec_pic_buffers dp_buf; + struct ddl_mask dpb_mask; + struct vcd_buffer_requirement actual_input_buf_req; + struct vcd_buffer_requirement min_input_buf_req; + struct vcd_buffer_requirement client_input_buf_req; + struct vcd_buffer_requirement actual_output_buf_req; + struct vcd_buffer_requirement min_output_buf_req; + struct vcd_buffer_requirement client_output_buf_req; + struct ddl_dec_buffers hw_bufs; + struct ddl_yuv_buffer_size dpb_buf_size; + struct vidc_1080p_dec_disp_info dec_disp_info; + u32 progressive_only; + u32 output_order; + u32 meta_data_enable_flag; + u32 suffix; + u32 meta_data_offset; + u32 header_in_start; + u32 min_dpb_num; + u32 y_cb_cr_size; + u32 dynamic_prop_change; + u32 dynmic_prop_change_req; + u32 flush_pending; + u32 meta_data_exists; + u32 idr_only_decoding; + u32 field_needed_for_prev_ip; + u32 prev_ip_frm_tag; + u32 cont_mode; + u32 reconfig_detected; + u32 dmx_disable; + int avg_dec_time; + int dec_time_sum; +}; +union ddl_codec_data{ + struct ddl_codec_data_hdr hdr; + struct ddl_decoder_data decoder; + struct ddl_encoder_data encoder; +}; +struct ddl_context{ + u8 *core_virtual_base_addr; + void *client_data; + u32 device_state; + u32 ddl_busy; + u32 cmd_err_status; + u32 disp_pic_err_status; + u32 pix_cache_enable; + u32 fw_version; + u32 fw_memory_size; + u32 cmd_seq_num; + u32 response_cmd_ch_id; + enum ddl_cmd_state cmd_state; + struct ddl_client_context *current_ddl[2]; + struct ddl_buf_addr metadata_shared_input; + struct ddl_client_context *ddl_clients[VCD_MAX_NO_CLIENT]; + struct ddl_buf_addr dram_base_a; + struct ddl_buf_addr dram_base_b; + struct ddl_hw_interface ddl_hw_response; + struct ion_client *video_ion_client; + void (*ddl_callback) (u32 event, u32 status, void *payload, + size_t sz, u32 *ddl_handle, void *const client_data); + void (*interrupt_clr) (void); + void (*vidc_decode_seq_start[2]) + (struct vidc_1080p_dec_seq_start_param *param); + void (*vidc_set_dec_resolution[2]) + (u32 width, u32 height); + void(*vidc_decode_init_buffers[2]) + (struct vidc_1080p_dec_init_buffers_param *param); + void(*vidc_decode_frame_start[2]) + (struct vidc_1080p_dec_frame_start_param *param); + void(*vidc_encode_seq_start[2]) + (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{ + struct ddl_context *ddl_context; + enum ddl_client_state client_state; + struct ddl_frame_data_tag first_output_frame; + struct ddl_frame_data_tag + extra_output_frame[DDL_MAX_NUM_OF_B_FRAME]; + struct ddl_frame_data_tag input_frame; + struct ddl_frame_data_tag output_frame; + struct ddl_frame_data_tag + input_frame_pool[DDL_MAX_NUM_IN_INPUTFRAME_POOL]; + union ddl_codec_data codec_data; + enum ddl_cmd_state cmd_state; + struct ddl_buf_addr shared_mem[2]; + void *client_data; + u32 decoding; + u32 channel_id; + u32 command_channel; + u32 b_count; + s32 extra_output_buf_count; + u32 instance_id; +}; + +struct ddl_context *ddl_get_context(void); +void ddl_vidc_core_init(struct ddl_context *); +void ddl_vidc_core_term(struct ddl_context *); +void ddl_vidc_channel_set(struct ddl_client_context *); +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 *); +u32 ddl_decoder_dpb_transact(struct ddl_decoder_data *decoder, + struct ddl_frame_data_tag *in_out_frame, u32 operation); +u32 ddl_decoder_dpb_init(struct ddl_client_context *ddl); +u32 ddl_client_transact(u32 , struct ddl_client_context **); +u32 ddl_set_default_decoder_buffer_req(struct ddl_decoder_data *decoder, + u32 estimate); +void ddl_set_default_encoder_buffer_req(struct ddl_encoder_data + *encoder); +void ddl_set_default_dec_property(struct ddl_client_context *); +u32 ddl_encoder_ready_to_start(struct ddl_client_context *); +u32 ddl_decoder_ready_to_start(struct ddl_client_context *, + struct vcd_sequence_hdr *); +u32 ddl_get_yuv_buffer_size(struct vcd_property_frame_size *frame_size, + struct vcd_property_buffer_format *buf_format, u32 interlace, + u32 decoding, u32 *pn_c_offset); +void ddl_calculate_stride(struct vcd_property_frame_size *frame_size, + u32 interlace); +u32 ddl_codec_type_transact(struct ddl_client_context *ddl, + u32 remove, enum vcd_codec requested_codec); +void ddl_vidc_encode_dynamic_property(struct ddl_client_context *ddl, + u32 enable); +void ddl_vidc_decode_dynamic_property(struct ddl_client_context *ddl, + u32 enable); +void ddl_set_initial_default_values(struct ddl_client_context *ddl); + +u32 ddl_take_command_channel(struct ddl_context *ddl_context, + struct ddl_client_context *ddl, void *client_data); +void ddl_release_command_channel(struct ddl_context *ddl_context, + u32 command_channel); +struct ddl_client_context *ddl_get_current_ddl_client_for_channel_id( + struct ddl_context *ddl_context, u32 channel_id); +struct ddl_client_context *ddl_get_current_ddl_client_for_command( + struct ddl_context *ddl_context, + enum ddl_cmd_state cmd_state); + +u32 ddl_get_yuv_buf_size(u32 width, u32 height, u32 format); +void ddl_free_dec_hw_buffers(struct ddl_client_context *ddl); +void ddl_free_enc_hw_buffers(struct ddl_client_context *ddl); +void ddl_calc_dec_hw_buffers_size(enum vcd_codec codec, u32 width, + u32 height, u32 h264_dpb, + struct ddl_dec_buffer_size *buf_size); +u32 ddl_allocate_dec_hw_buffers(struct ddl_client_context *ddl); +u32 ddl_calc_enc_hw_buffers_size(enum vcd_codec codec, u32 width, + u32 height, enum vcd_yuv_buffer_format input_format, + struct ddl_client_context *ddl, + struct ddl_enc_buffer_size *buf_size); +u32 ddl_allocate_enc_hw_buffers(struct ddl_client_context *ddl); + +u32 ddl_handle_core_errors(struct ddl_context *ddl_context); +void ddl_client_fatal_cb(struct ddl_client_context *ddl); +void ddl_hw_fatal_cb(struct ddl_client_context *ddl); + +void *ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment); +void ddl_pmem_free(struct ddl_buf_addr *addr); + +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); +void ddl_fill_dec_desc_buffer(struct ddl_client_context *ddl); +void ddl_set_vidc_timeout(struct ddl_client_context *ddl); + + +#ifdef DDL_BUF_LOG +void ddl_list_buffers(struct ddl_client_context *ddl); +#endif +#ifdef DDL_MSG_LOG +s8 *ddl_get_state_string(enum ddl_client_state client_state); +#endif +extern unsigned char *vidc_video_codec_fw; +extern u32 vidc_video_codec_fw_size; + +u32 ddl_fw_init(struct ddl_buf_addr *dram_base); +void ddl_get_fw_info(const unsigned char **fw_array_addr, + unsigned int *fw_size); +void ddl_fw_release(struct ddl_buf_addr *); +int ddl_vidc_decode_get_avg_time(struct ddl_client_context *ddl); +void ddl_vidc_decode_reset_avg_time(struct ddl_client_context *ddl); +void ddl_calc_core_proc_time(const char *func_name, u32 index, + struct ddl_client_context *ddl); +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h new file mode 100644 index 0000000000000000000000000000000000000000..3a7e443eb769e1fe78724f9b4b3d564da851ac40 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h @@ -0,0 +1,120 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VCD_DDL_API_H_ +#define _VCD_DDL_API_H_ + +#include +#include "vidc.h" + +#define VCD_EVT_RESP_DDL_BASE 0x3000 +#define VCD_EVT_RESP_DEVICE_INIT (VCD_EVT_RESP_DDL_BASE + 0x1) +#define VCD_EVT_RESP_OUTPUT_REQ (VCD_EVT_RESP_DDL_BASE + 0x2) +#define VCD_EVT_RESP_EOS_DONE (VCD_EVT_RESP_DDL_BASE + 0x3) +#define VCD_EVT_RESP_TRANSACTION_PENDING (VCD_EVT_RESP_DDL_BASE + 0x4) + +#define VCD_S_DDL_ERR_BASE 0x90000000 +#define VCD_ERR_MAX_NO_CODEC (VCD_S_DDL_ERR_BASE + 0x1) +#define VCD_ERR_CLIENT_PRESENT (VCD_S_DDL_ERR_BASE + 0x2) +#define VCD_ERR_CLIENT_FATAL (VCD_S_DDL_ERR_BASE + 0x3) +#define VCD_ERR_NO_SEQ_HDR (VCD_S_DDL_ERR_BASE + 0x4) + +#define VCD_I_CUSTOM_BASE (VCD_I_RESERVED_BASE) +#define VCD_I_RC_LEVEL_CONFIG (VCD_I_CUSTOM_BASE + 0x1) +#define VCD_I_FRAME_LEVEL_RC (VCD_I_CUSTOM_BASE + 0x2) +#define VCD_I_ADAPTIVE_RC (VCD_I_CUSTOM_BASE + 0x3) +#define VCD_I_CUSTOM_DDL_BASE (VCD_I_RESERVED_BASE + 0x100) +#define DDL_I_INPUT_BUF_REQ (VCD_I_CUSTOM_DDL_BASE + 0x1) +#define DDL_I_OUTPUT_BUF_REQ (VCD_I_CUSTOM_DDL_BASE + 0x2) +#define DDL_I_DPB (VCD_I_CUSTOM_DDL_BASE + 0x3) +#define DDL_I_DPB_RELEASE (VCD_I_CUSTOM_DDL_BASE + 0x4) +#define DDL_I_DPB_RETRIEVE (VCD_I_CUSTOM_DDL_BASE + 0x5) +#define DDL_I_REQ_OUTPUT_FLUSH (VCD_I_CUSTOM_DDL_BASE + 0x6) +#define DDL_I_SEQHDR_ALIGN_BYTES (VCD_I_CUSTOM_DDL_BASE + 0x7) +#define DDL_I_CAPABILITY (VCD_I_CUSTOM_DDL_BASE + 0x8) +#define DDL_I_FRAME_PROC_UNITS (VCD_I_CUSTOM_DDL_BASE + 0x9) +#define DDL_I_SEQHDR_PRESENT (VCD_I_CUSTOM_DDL_BASE + 0xA) + +#define DDL_FRAME_VGA_SIZE (640*480) +#define DDL_FRAME_720P_WIDTH 1280 +#define DDL_FRAME_720P_HEIGHT 720 + +struct vcd_property_rc_level{ + u32 frame_level_rc; + u32 mb_level_rc; +}; +struct vcd_property_frame_level_rc_params{ + u32 reaction_coeff; +}; +struct vcd_property_adaptive_rc_params{ + u32 disable_dark_region_as_flag; + u32 disable_smooth_region_as_flag; + 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; +}; +struct ddl_property_capability{ + u32 max_num_client; + u32 general_command_depth; + u32 exclusive; + u32 frame_command_depth; + u32 ddl_time_out_in_ms; +}; +struct ddl_init_config{ + int memtype; + u8 *core_virtual_base_addr; + void (*interrupt_clr) (void); + void (*ddl_callback) (u32 event, u32 status, void *payload, size_t sz, + u32 *ddl_handle, void *const client_data); +}; +struct ddl_frame_data_tag{ + struct vcd_frame_data vcd_frm; + u32 frm_trans_end; + u32 frm_delta; +}; +u32 ddl_device_init(struct ddl_init_config *ddl_init_config, + void *client_data); +u32 ddl_device_release(void *client_data); +u32 ddl_open(u32 **ddl_handle, u32 decoding); +u32 ddl_close(u32 **ddl_handle); +u32 ddl_encode_start(u32 *ddl_handle, void *client_data); +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); +u32 ddl_decode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_bits, void *client_data); +u32 ddl_decode_end(u32 *ddl_handle, void *client_data); +u32 ddl_set_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value); +u32 ddl_get_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value); +u32 ddl_process_core_response(void); +u32 ddl_reset_hw(u32 mode); +void ddl_read_and_clear_interrupt(void); +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h new file mode 100644 index 0000000000000000000000000000000000000000..e65a94d78ed8541b93893b5ae0a388a730a25d52 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h @@ -0,0 +1,156 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VCD_DDL_CORE_H_ +#define _VCD_DDL_CORE_H_ + +#define DDL_LINEAR_BUF_ALIGN_MASK 0xFFFFF800U +#define DDL_LINEAR_BUF_ALIGN_GUARD_BYTES 0x7FF +#define DDL_LINEAR_BUFFER_ALIGN_BYTES 2048 +#define DDL_TILE_BUF_ALIGN_MASK 0xFFFFE000U +#define DDL_TILE_BUF_ALIGN_GUARD_BYTES 0x1FFF +#define DDL_TILE_BUFFER_ALIGN_BYTES 8192 + +#define DDL_YUV_BUF_TYPE_LINEAR 0 +#define DDL_YUV_BUF_TYPE_TILE 1 + +#define DDL_NO_OF_MB(nWidth, nHeight) \ + ((((nWidth) + 15) >> 4) * (((nHeight) + 15) >> 4)) + +#define DDL_MAX_FRAME_WIDTH 1920 +#define DDL_MAX_FRAME_HEIGHT 1088 + +#define DDL_MAX_VC1_FRAME_WIDTH (DDL_MAX_FRAME_WIDTH) +#define DDL_MAX_VC1_FRAME_HEIGHT (1280) + +#define MAX_DPB_SIZE_L4PT0_MBS DDL_KILO_BYTE(32) +#define MAX_FRAME_SIZE_L4PT0_MBS DDL_KILO_BYTE(8) + +#define DDL_MAX_MB_PER_FRAME (DDL_NO_OF_MB(DDL_MAX_FRAME_WIDTH,\ + DDL_MAX_FRAME_HEIGHT)) + +#define DDL_DB_LINE_BUF_SIZE\ + (((((DDL_MAX_FRAME_WIDTH * 4) - 1) / 256) + 1) * 8 * 1024) + +#define DDL_MAX_FRAME_RATE 120 +#define DDL_INITIAL_FRAME_RATE 30 + +#define DDL_MAX_BIT_RATE (20*1024*1024) +#define DDL_MAX_MB_PER_SEC (DDL_MAX_MB_PER_FRAME * DDL_INITIAL_FRAME_RATE) + +#define DDL_SW_RESET_SLEEP 1 +#define VCD_MAX_NO_CLIENT 4 +#define VCD_SINGLE_FRAME_COMMAND_CHANNEL 1 +#define VCD_DUAL_FRAME_COMMAND_CHANNEL 2 +#define VCD_FRAME_COMMAND_DEPTH VCD_SINGLE_FRAME_COMMAND_CHANNEL +#define VCD_GENEVIDC_COMMAND_DEPTH 1 +#define VCD_COMMAND_EXCLUSIVE true +#define DDL_HW_TIMEOUT_IN_MS 1000 +#define DDL_STREAMBUF_ALIGN_GUARD_BYTES 0x7FF + +#define DDL_VIDC_1080P_48MHZ (48000000) +#define DDL_VIDC_1080P_133MHZ (133330000) +#define DDL_VIDC_1080P_200MHZ (200000000) +#define DDL_VIDC_1080P_48MHZ_TIMEOUT_VALUE (0xCB8) +#define DDL_VIDC_1080P_133MHZ_TIMEOUT_VALUE (0x2355) +#define DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE (0x3500) + +#define DDL_CONTEXT_MEMORY (1024 * 15 * (VCD_MAX_NO_CLIENT + 1)) + +#define DDL_ENC_MIN_DPB_BUFFERS 2 +#define DDL_ENC_MAX_DPB_BUFFERS 4 + +#define DDL_FW_AUX_HOST_CMD_SPACE_SIZE (DDL_KILO_BYTE(4)) +#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(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 + +#define DDL_MPEG_REFBUF_COUNT 2 +#define DDL_MPEG_COMV_BUF_NO 2 +#define DDL_H263_COMV_BUF_NO 0 +#define DDL_COMV_BUFLINE_NO 128 +#define DDL_VC1_COMV_BUFLINE_NO 32 + +#define DDL_MAX_H264_QP 51 +#define DDL_MAX_MPEG4_QP 31 + +#define DDL_CONCEALMENT_Y_COLOR 16 +#define DDL_CONCEALMENT_C_COLOR 128 + +#define DDL_ALLOW_DEC_FRAMESIZE(width, height) \ + ((DDL_NO_OF_MB(width, height) <= \ + MAX_FRAME_SIZE_L4PT0_MBS) && \ + (width <= DDL_MAX_FRAME_WIDTH) && \ + (height <= DDL_MAX_FRAME_WIDTH) && \ + ((width >= 32 && height >= 16) || \ + (width >= 16 && height >= 32))) + +#define DDL_ALLOW_ENC_FRAMESIZE(width, height) \ + ((DDL_NO_OF_MB(width, height) <= \ + MAX_FRAME_SIZE_L4PT0_MBS) && \ + (width <= DDL_MAX_FRAME_WIDTH) && \ + (height <= DDL_MAX_FRAME_WIDTH) && \ + ((width >= 32 && height >= 32))) + +#define DDL_LINEAR_ALIGN_WIDTH 16 +#define DDL_LINEAR_ALIGN_HEIGHT 16 +#define DDL_LINEAR_MULTIPLY_FACTOR 2048 +#define DDL_TILE_ALIGN_WIDTH 128 +#define DDL_TILE_ALIGN_HEIGHT 32 +#define DDL_TILE_MULTIPLY_FACTOR 8192 +#define DDL_TILE_ALIGN(val, grid) \ + (((val) + (grid) - 1) / (grid) * (grid)) + +#define VCD_DDL_720P_YUV_BUF_SIZE ((1280*720*3) >> 1) +#define VCD_DDL_WVGA_BUF_SIZE (800*480) + +#define VCD_DDL_TEST_MAX_WIDTH (DDL_MAX_FRAME_WIDTH) +#define VCD_DDL_TEST_MAX_HEIGHT (DDL_MAX_FRAME_HEIGHT) + +#define VCD_DDL_TEST_MAX_NUM_H264_DPB 8 + +#define VCD_DDL_TEST_NUM_ENC_INPUT_BUFS 6 +#define VCD_DDL_TEST_NUM_ENC_OUTPUT_BUFS 4 + +#define VCD_DDL_TEST_DEFAULT_WIDTH 176 +#define VCD_DDL_TEST_DEFAULT_HEIGHT 144 + +#define DDL_PIXEL_CACHE_NOT_IDLE 0x4000 +#define DDL_PIXEL_CACHE_STATUS_READ_RETRY 10 +#define DDL_PIXEL_CACHE_STATUS_READ_SLEEP 200 + +#define DDL_RESL_CHANGE_NO_CHANGE 0 +#define DDL_RESL_CHANGE_INCREASED 1 +#define DDL_RESL_CHANGE_DECREASED 2 + +#define VIDC_SM_ERR_CONCEALMENT_ENABLE 1 +#define VIDC_SM_ERR_CONCEALMENT_INTER_SLICE_MB_COPY 2 +#define VIDC_SM_ERR_CONCEALMENT_INTRA_SLICE_COLOR_CONCEALMENT 1 + +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c new file mode 100644 index 0000000000000000000000000000000000000000..d9e73fb8b1282365d12460ad8f24d38a7c45f521 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c @@ -0,0 +1,771 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "vcd_ddl.h" +#include "vcd_ddl_shared_mem.h" +#include "vidc.h" + +static u32 ddl_handle_hw_fatal_errors(struct ddl_client_context *ddl); +static u32 ddl_handle_client_fatal_errors( + struct ddl_client_context *ddl); +static void ddl_input_failed_cb(struct ddl_client_context *ddl, + u32 vcd_event, u32 vcd_status); +static u32 ddl_handle_core_recoverable_errors( + struct ddl_client_context *ddl); +static u32 ddl_handle_core_warnings(u32 error_code); +static void ddl_release_prev_field( + struct ddl_client_context *ddl); +static u32 ddl_handle_dec_seq_hdr_fail_error(struct ddl_client_context *ddl); +static void print_core_errors(u32 error_code); +static void print_core_recoverable_errors(u32 error_code); + +void ddl_hw_fatal_cb(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + u32 error_code = ddl_context->cmd_err_status; + + DDL_MSG_FATAL("VIDC_HW_FATAL"); + ddl->cmd_state = DDL_CMD_INVALID; + ddl_context->device_state = DDL_DEVICE_HWFATAL; + + ddl_context->ddl_callback(VCD_EVT_IND_HWERRFATAL, VCD_ERR_HW_FATAL, + &error_code, sizeof(error_code), + (u32 *)ddl, ddl->client_data); + + ddl_release_command_channel(ddl_context, ddl->command_channel); +} + +static u32 ddl_handle_hw_fatal_errors(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + u32 status = false, error_code = ddl_context->cmd_err_status; + + switch (error_code) { + case VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER: + case VIDC_1080P_ERROR_INVALID_COMMAND_ID: + case VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE: + case VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE: + case VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START: + case VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED: + case VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS: + case VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS: + case VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED: + case VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START: + case VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START: + case VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START: + case VIDC_1080P_ERROR_RESOLUTION_CHANGED: + case VIDC_1080P_ERROR_INVALID_COMMAND_LAST_FRAME: + case VIDC_1080P_ERROR_INVALID_COMMAND: + case VIDC_1080P_ERROR_INVALID_CODEC_TYPE: + case VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED: + case VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE: + case VIDC_1080P_ERROR_DIVIDE_BY_ZERO: + case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY: + case VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE: + case VIDC_1080P_ERROR_VSP_NOT_READY: + case VIDC_1080P_ERROR_BUFFER_FULL_STATE: + ddl_hw_fatal_cb(ddl); + status = true; + break; + default: + break; + } + return status; +} + +void ddl_client_fatal_cb(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + + if (ddl->cmd_state == DDL_CMD_DECODE_FRAME) + ddl_vidc_decode_dynamic_property(ddl, false); + else if (ddl->cmd_state == DDL_CMD_ENCODE_FRAME) + ddl_vidc_encode_dynamic_property(ddl, false); + ddl->cmd_state = DDL_CMD_INVALID; + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_FAVIDC_ERROR", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_FAVIDC_ERROR; + ddl_context->ddl_callback(VCD_EVT_IND_HWERRFATAL, + VCD_ERR_CLIENT_FATAL, NULL, 0, (u32 *)ddl, + ddl->client_data); + ddl_release_command_channel(ddl_context, ddl->command_channel); +} + +static u32 ddl_handle_client_fatal_errors( + struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + u32 status = false; + + switch (ddl_context->cmd_err_status) { + case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE: + case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED: + case VIDC_1080P_ERROR_VOS_END_CODE_RECEIVED: + case VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED: + case VIDC_1080P_ERROR_INVALID_QP_VALUE: + case VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT: + case VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL: + case VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED: + case VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT: + case VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE: + case VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER: + case VIDC_1080P_ERROR_NULL_DPB_POINTER: + case VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR: + case VIDC_1080P_ERROR_NULL_MV_POINTER: + status = true; + DDL_MSG_ERROR("VIDC_CLIENT_FATAL!!"); + break; + default: + break; + } + if (!status) + DDL_MSG_ERROR("VIDC_UNKNOWN_OP_FAILED %d", + ddl_context->cmd_err_status); + ddl_client_fatal_cb(ddl); + return true; +} + +static void ddl_input_failed_cb(struct ddl_client_context *ddl, + u32 vcd_event, u32 vcd_status) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + u32 payload_size = sizeof(struct ddl_frame_data_tag); + + ddl->cmd_state = DDL_CMD_INVALID; + if (ddl->decoding) + ddl_vidc_decode_dynamic_property(ddl, false); + else + ddl_vidc_encode_dynamic_property(ddl, false); + if (ddl->client_state == DDL_CLIENT_WAIT_FOR_INITCODECDONE) { + payload_size = 0; + DDL_MSG_LOW("ddl_state_transition: %s ~~> " + "DDL_CLIENT_WAIT_FOR_INITCODEC", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODEC; + } else { + DDL_MSG_LOW("ddl_state_transition: %s ~~> " + "DDL_CLIENT_WAIT_FOR_FRAME", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; + } + if (vcd_status == VCD_ERR_IFRAME_EXPECTED) + vcd_status = VCD_S_SUCCESS; + ddl_context->ddl_callback(vcd_event, vcd_status, &ddl->input_frame, + payload_size, (u32 *)ddl, ddl->client_data); +} + +static u32 ddl_handle_core_recoverable_errors( + struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + u32 vcd_status = VCD_S_SUCCESS; + u32 vcd_event = VCD_EVT_RESP_INPUT_DONE; + u32 eos = false, status = false; + + if (ddl->decoding) { + if (ddl_handle_dec_seq_hdr_fail_error(ddl)) + return true; + } + + if ((ddl->cmd_state != DDL_CMD_DECODE_FRAME) && + (ddl->cmd_state != DDL_CMD_ENCODE_FRAME)) + return false; + + if (ddl->decoding && + (ddl->codec_data.decoder.field_needed_for_prev_ip == 1)) { + ddl->codec_data.decoder.field_needed_for_prev_ip = 0; + ddl_release_prev_field(ddl); + if (ddl_context->cmd_err_status == + VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED) { + ddl_vidc_decode_frame_run(ddl); + return true; + } + } + + switch (ddl_context->cmd_err_status) { + case VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED: + vcd_status = VCD_ERR_IFRAME_EXPECTED; + break; + case VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST: + { + u32 pending_display = 0, release_mask; + + release_mask = + ddl->codec_data.decoder.\ + dpb_mask.hw_mask; + while (release_mask > 0) { + if (release_mask & 0x1) + pending_display++; + release_mask >>= 1; + } + if (pending_display >= ddl->codec_data.\ + decoder.min_dpb_num) { + DDL_MSG_ERROR("VIDC_FW_ISSUE_REQ_BUF"); + ddl_client_fatal_cb(ddl); + status = true; + } else { + vcd_event = VCD_EVT_RESP_OUTPUT_REQ; + DDL_MSG_LOW("VIDC_OUTPUT_BUF_REQ!!"); + } + break; + } + case VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST: + case VIDC_1080P_ERROR_DESCRIPTOR_TABLE_ENTRY_INVALID: + case VIDC_1080P_ERROR_MB_COEFF_NOT_DONE: + case VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE: + case VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT: + case VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR: + case VIDC_1080P_ERROR_RESOLUTION_MISMATCH: + case VIDC_1080P_ERROR_NV_QUANT_ERR: + case VIDC_1080P_ERROR_SYNC_MARKER_ERR: + case VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED: + case VIDC_1080P_ERROR_MEM_CORRUPTION: + case VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME: + case VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR: + case VIDC_1080P_ERROR_MV_RANGE_ERR: + case VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR: + case VIDC_1080P_ERROR_SLICE_ADDR_INVALID: + case VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED: + case VIDC_1080P_ERROR_NALU_HEADER_ERROR: + case VIDC_1080P_ERROR_SPS_PARSE_ERROR: + case VIDC_1080P_ERROR_PPS_PARSE_ERROR: + case VIDC_1080P_ERROR_HEADER_NOT_FOUND: + case VIDC_1080P_ERROR_SLICE_PARSE_ERROR: + case VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED: + vcd_status = VCD_ERR_BITSTREAM_ERR; + DDL_MSG_ERROR("VIDC_BIT_STREAM_ERR"); + break; + case VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED: + case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE: + case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED: + if (ddl->decoding) { + vcd_status = VCD_ERR_BITSTREAM_ERR; + DDL_MSG_ERROR("VIDC_BIT_STREAM_ERR"); + } + break; + default: + break; + } + + if (((vcd_status) || (vcd_event != VCD_EVT_RESP_INPUT_DONE)) && + !status) { + ddl->input_frame.frm_trans_end = true; + eos = ((vcd_event == VCD_EVT_RESP_INPUT_DONE) && + (ddl->input_frame.vcd_frm.flags & VCD_FRAME_FLAG_EOS)); + if (((ddl->decoding) && (eos)) || !ddl->decoding) + ddl->input_frame.frm_trans_end = false; + ddl_input_failed_cb(ddl, vcd_event, vcd_status); + if (!ddl->decoding) { + ddl->output_frame.frm_trans_end = !eos; + ddl->output_frame.vcd_frm.data_len = 0; + ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_ERR_FAIL, &ddl->output_frame, + sizeof(struct ddl_frame_data_tag), (u32 *)ddl, + ddl->client_data); + if (eos) { + DDL_MSG_LOW("VIDC_ENC_EOS_DONE"); + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, + ddl->client_data); + } + } + if ((ddl->decoding) && (eos)) + ddl_vidc_decode_eos_run(ddl); + else + ddl_release_command_channel(ddl_context, + ddl->command_channel); + status = true; + } + return status; +} + +static u32 ddl_handle_core_warnings(u32 err_status) +{ + u32 status = false; + + switch (err_status) { + case VIDC_1080P_WARN_COMMAND_FLUSHED: + case VIDC_1080P_WARN_FRAME_RATE_UNKNOWN: + case VIDC_1080P_WARN_ASPECT_RATIO_UNKNOWN: + case VIDC_1080P_WARN_COLOR_PRIMARIES_UNKNOWN: + case VIDC_1080P_WARN_TRANSFER_CHAR_UNKNOWN: + case VIDC_1080P_WARN_MATRIX_COEFF_UNKNOWN: + case VIDC_1080P_WARN_NON_SEQ_SLICE_ADDR: + case VIDC_1080P_WARN_BROKEN_LINK: + case VIDC_1080P_WARN_FRAME_CONCEALED: + case VIDC_1080P_WARN_PROFILE_UNKNOWN: + case VIDC_1080P_WARN_LEVEL_UNKNOWN: + case VIDC_1080P_WARN_BIT_RATE_NOT_SUPPORTED: + case VIDC_1080P_WARN_COLOR_DIFF_FORMAT_NOT_SUPPORTED: + case VIDC_1080P_WARN_NULL_EXTRA_METADATA_POINTER: + case VIDC_1080P_WARN_DEBLOCKING_NOT_DONE: + case VIDC_1080P_WARN_INCOMPLETE_FRAME: + case VIDC_1080P_ERROR_NULL_FW_DEBUG_INFO_POINTER: + case VIDC_1080P_ERROR_ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT: + case VIDC_1080P_WARN_METADATA_NO_SPACE_NUM_CONCEAL_MB: + case VIDC_1080P_WARN_METADATA_NO_SPACE_QP: + case VIDC_1080P_WARN_METADATA_NO_SPACE_CONCEAL_MB: + case VIDC_1080P_WARN_METADATA_NO_SPACE_VC1_PARAM: + case VIDC_1080P_WARN_METADATA_NO_SPACE_SEI: + case VIDC_1080P_WARN_METADATA_NO_SPACE_VUI: + case VIDC_1080P_WARN_METADATA_NO_SPACE_EXTRA: + case VIDC_1080P_WARN_METADATA_NO_SPACE_DATA_NONE: + case VIDC_1080P_WARN_METADATA_NO_SPACE_MB_INFO: + case VIDC_1080P_WARN_METADATA_NO_SPACE_SLICE_SIZE: + case VIDC_1080P_WARN_RESOLUTION_WARNING: + case VIDC_1080P_WARN_NO_LONG_TERM_REFERENCE: + case VIDC_1080P_WARN_NO_SPACE_MPEG2_DATA_DUMP: + case VIDC_1080P_WARN_METADATA_NO_SPACE_MISSING_MB: + status = true; + DDL_MSG_ERROR("VIDC_WARNING_IGNORED"); + break; + default: + break; + } + return status; +} + +u32 ddl_handle_core_errors(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id, status = false; + u32 disp_status; + + if (!ddl_context->cmd_err_status && + !ddl_context->disp_pic_err_status) { + DDL_MSG_ERROR("VIDC_NO_ERROR"); + return false; + } + 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) { + DDL_MSG_ERROR("VIDC_SPURIOUS_INTERRUPT_ERROR"); + return true; + } + if (ddl_context->cmd_err_status) { + print_core_errors(ddl_context->cmd_err_status); + print_core_recoverable_errors(ddl_context->cmd_err_status); + } + if (ddl_context->disp_pic_err_status) + print_core_errors(ddl_context->disp_pic_err_status); + status = ddl_handle_core_warnings(ddl_context->cmd_err_status); + disp_status = ddl_handle_core_warnings( + ddl_context->disp_pic_err_status); + if (!status && !disp_status) { + DDL_MSG_ERROR("ddl_warning:Unknown"); + status = ddl_handle_hw_fatal_errors(ddl); + if (!status) + status = ddl_handle_core_recoverable_errors(ddl); + if (!status) + status = ddl_handle_client_fatal_errors(ddl); + } + return status; +} + +static void ddl_release_prev_field(struct ddl_client_context *ddl) +{ + ddl->output_frame.vcd_frm.ip_frm_tag = + ddl->codec_data.decoder.prev_ip_frm_tag; + ddl->output_frame.vcd_frm.physical = NULL; + ddl->output_frame.vcd_frm.virtual = NULL; + ddl->output_frame.frm_trans_end = false; + ddl->ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_ERR_INTRLCD_FIELD_DROP, &(ddl->output_frame), + sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, ddl->client_data); +} + +static u32 ddl_handle_dec_seq_hdr_fail_error(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + u32 status = false; + + if ((ddl->cmd_state != DDL_CMD_HEADER_PARSE) || + (ddl->client_state != DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-HDDONE"); + return false; + } + + switch (ddl_context->cmd_err_status) { + case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE: + case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED: + case VIDC_1080P_ERROR_HEADER_NOT_FOUND: + case VIDC_1080P_ERROR_SPS_PARSE_ERROR: + case VIDC_1080P_ERROR_PPS_PARSE_ERROR: + { + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + if (ddl_context->cmd_err_status == + VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE + && decoder->codec.codec == VCD_CODEC_H264) { + DDL_MSG_ERROR("Unsupported Feature for H264"); + ddl_client_fatal_cb(ddl); + return true; + } + if ((ddl_context->cmd_err_status == + VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED) + && (decoder->codec.codec == VCD_CODEC_H263 + || decoder->codec.codec == VCD_CODEC_H264 + || decoder->codec.codec == VCD_CODEC_MPEG4 + || decoder->codec.codec == VCD_CODEC_VC1 + || decoder->codec.codec == VCD_CODEC_VC1_RCV)) { + DDL_MSG_ERROR("Unsupported resolution"); + ddl_client_fatal_cb(ddl); + return true; + } + + DDL_MSG_ERROR("SEQHDR-FAILED"); + if (decoder->header_in_start) { + decoder->header_in_start = false; + ddl_context->ddl_callback(VCD_EVT_RESP_START, + VCD_ERR_SEQHDR_PARSE_FAIL, NULL, 0, + (u32 *) ddl, ddl->client_data); + } else { + ddl->input_frame.frm_trans_end = true; + if ((ddl->input_frame.vcd_frm.flags & + VCD_FRAME_FLAG_EOS)) { + ddl->input_frame.frm_trans_end = false; + } + ddl_vidc_decode_dynamic_property(ddl, false); + ddl_context->ddl_callback( + VCD_EVT_RESP_INPUT_DONE, + VCD_ERR_SEQHDR_PARSE_FAIL, &ddl->input_frame, + sizeof(struct ddl_frame_data_tag), (u32 *)ddl, + ddl->client_data); + if ((ddl->input_frame.vcd_frm.flags & + VCD_FRAME_FLAG_EOS)) { + DDL_MSG_HIGH("EOS_DONE-fromDDL"); + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, 0, (u32 *) ddl, + ddl->client_data); + } + } + DDL_MSG_LOW("ddl_state_transition: %s ~~> " + "DDL_CLIENT_WAIT_FOR_INITCODEC", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODEC; + ddl_release_command_channel(ddl_context, ddl->command_channel); + status = true; + break; + } + default: + break; + } + return status; +} + +void print_core_errors(u32 error_code) +{ + s8 *string = NULL; + + switch (error_code) { + case VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER: + string = "VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER"; + break; + case VIDC_1080P_ERROR_INVALID_COMMAND_ID: + string = "VIDC_1080P_ERROR_INVALID_COMMAND_ID"; + break; + case VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE: + string = "VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE"; + break; + case VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE: + string = + "VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE"; + break; + case VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START: + string = "VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START"; + break; + case VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED: + string = "VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED"; + break; + case VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS: + string = "VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS"; + break; + case VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS: + string = "VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS"; + break; + case VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED: + string = "VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED"; + break; + case VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START: + string = "VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START"; + break; + case VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START: + string = "VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START"; + break; + case VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START: + string = "VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START"; + break; + case VIDC_1080P_ERROR_RESOLUTION_CHANGED: + string = "VIDC_1080P_ERROR_RESOLUTION_CHANGED"; + break; + case VIDC_1080P_ERROR_INVALID_COMMAND_LAST_FRAME: + string = "VIDC_1080P_ERROR_INVALID_COMMAND_LAST_FRAME"; + break; + case VIDC_1080P_ERROR_INVALID_COMMAND: + string = "VIDC_1080P_ERROR_INVALID_COMMAND"; + break; + case VIDC_1080P_ERROR_INVALID_CODEC_TYPE: + string = "VIDC_1080P_ERROR_INVALID_CODEC_TYPE"; + break; + case VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED: + string = "VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED"; + break; + case VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE: + string = "VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE"; + break; + case VIDC_1080P_ERROR_DIVIDE_BY_ZERO: + string = "VIDC_1080P_ERROR_DIVIDE_BY_ZERO"; + break; + case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY: + string = "VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY"; + break; + case VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE: + string = "VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE"; + break; + case VIDC_1080P_ERROR_VSP_NOT_READY: + string = "VIDC_1080P_ERROR_VSP_NOT_READY"; + break; + case VIDC_1080P_ERROR_BUFFER_FULL_STATE: + string = "VIDC_1080P_ERROR_BUFFER_FULL_STATE"; + break; + case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE: + string = "VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE"; + break; + case VIDC_1080P_ERROR_HEADER_NOT_FOUND: + string = "VIDC_1080P_ERROR_HEADER_NOT_FOUND"; + break; + case VIDC_1080P_ERROR_VOS_END_CODE_RECEIVED: + string = "VIDC_1080P_ERROR_VOS_END_CODE_RECEIVED"; + break; + case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED: + string = "VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED"; + break; + case VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED: + string = "VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED"; + break; + case VIDC_1080P_ERROR_INVALID_QP_VALUE: + string = "VIDC_1080P_ERROR_INVALID_QP_VALUE"; + break; + case VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT: + string = "VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT"; + break; + case VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL: + string = "VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL"; + break; + case VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED: + string = "VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED"; + break; + case VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT: + string = "VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT"; + break; + case VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE: + string = "VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE"; + break; + case VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER: + string = "VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER"; + break; + case VIDC_1080P_ERROR_NULL_DPB_POINTER: + string = "VIDC_1080P_ERROR_NULL_DPB_POINTER"; + break; + case VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR: + string = "VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR"; + break; + case VIDC_1080P_ERROR_NULL_MV_POINTER: + string = "VIDC_1080P_ERROR_NULL_MV_POINTER"; + break; + case VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED: + string = "VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED"; + break; + case VIDC_1080P_WARN_COMMAND_FLUSHED: + string = "VIDC_1080P_WARN_COMMAND_FLUSHED"; + break; + case VIDC_1080P_WARN_FRAME_RATE_UNKNOWN: + string = "VIDC_1080P_WARN_FRAME_RATE_UNKNOWN"; + break; + case VIDC_1080P_WARN_ASPECT_RATIO_UNKNOWN: + string = "VIDC_1080P_WARN_ASPECT_RATIO_UNKNOWN"; + break; + case VIDC_1080P_WARN_COLOR_PRIMARIES_UNKNOWN: + string = "VIDC_1080P_WARN_COLOR_PRIMARIES_UNKNOWN"; + break; + case VIDC_1080P_WARN_TRANSFER_CHAR_UNKNOWN: + string = "VIDC_1080P_WARN_TRANSFER_CHAR_UNKNOWN"; + break; + case VIDC_1080P_WARN_MATRIX_COEFF_UNKNOWN: + string = "VIDC_1080P_WARN_MATRIX_COEFF_UNKNOWN"; + break; + case VIDC_1080P_WARN_NON_SEQ_SLICE_ADDR: + string = "VIDC_1080P_WARN_NON_SEQ_SLICE_ADDR"; + break; + case VIDC_1080P_WARN_BROKEN_LINK: + string = "VIDC_1080P_WARN_BROKEN_LINK"; + break; + case VIDC_1080P_WARN_FRAME_CONCEALED: + string = "VIDC_1080P_WARN_FRAME_CONCEALED"; + break; + case VIDC_1080P_WARN_PROFILE_UNKNOWN: + string = "VIDC_1080P_WARN_PROFILE_UNKNOWN"; + break; + case VIDC_1080P_WARN_LEVEL_UNKNOWN: + string = "VIDC_1080P_WARN_LEVEL_UNKNOWN"; + break; + case VIDC_1080P_WARN_BIT_RATE_NOT_SUPPORTED: + string = "VIDC_1080P_WARN_BIT_RATE_NOT_SUPPORTED"; + break; + case VIDC_1080P_WARN_COLOR_DIFF_FORMAT_NOT_SUPPORTED: + string = "VIDC_1080P_WARN_COLOR_DIFF_FORMAT_NOT_SUPPORTED"; + break; + case VIDC_1080P_WARN_NULL_EXTRA_METADATA_POINTER: + string = "VIDC_1080P_WARN_NULL_EXTRA_METADATA_POINTER"; + break; + case VIDC_1080P_WARN_DEBLOCKING_NOT_DONE: + string = "VIDC_1080P_WARN_DEBLOCKING_NOT_DONE"; + break; + case VIDC_1080P_WARN_INCOMPLETE_FRAME: + string = "VIDC_1080P_WARN_INCOMPLETE_FRAME"; + break; + case VIDC_1080P_ERROR_NULL_FW_DEBUG_INFO_POINTER: + string = "VIDC_1080P_ERROR_NULL_FW_DEBUG_INFO_POINTER"; + break; + case VIDC_1080P_ERROR_ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT: + string = + "VIDC_1080P_ERROR_ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_NUM_CONCEAL_MB: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_NUM_CONCEAL_MB"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_QP: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_QP"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_CONCEAL_MB: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_CONCEAL_MB"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_VC1_PARAM: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_VC1_PARAM"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_SEI: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_SEI"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_VUI: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_VUI"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_EXTRA: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_EXTRA"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_DATA_NONE: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_DATA_NONE"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_MB_INFO: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_MB_INFO"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_SLICE_SIZE: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_SLICE_SIZE"; + break; + case VIDC_1080P_WARN_RESOLUTION_WARNING: + string = "VIDC_1080P_WARN_RESOLUTION_WARNING"; + break; + case VIDC_1080P_WARN_NO_LONG_TERM_REFERENCE: + string = "VIDC_1080P_WARN_NO_LONG_TERM_REFERENCE"; + break; + case VIDC_1080P_WARN_NO_SPACE_MPEG2_DATA_DUMP: + string = "VIDC_1080P_WARN_NO_SPACE_MPEG2_DATA_DUMP"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_MISSING_MB: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_MISSING_MB"; + break; + } + if (string) + DDL_MSG_ERROR("Error code = 0x%x : %s", error_code, string); +} + +void print_core_recoverable_errors(u32 error_code) +{ + s8 *string = NULL; + + switch (error_code) { + case VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED: + string = "VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED"; + break; + case VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST: + string = "VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST"; + break; + case VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST: + string = "VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST"; + break; + case VIDC_1080P_ERROR_DESCRIPTOR_TABLE_ENTRY_INVALID: + string = "VIDC_1080P_ERROR_DESCRIPTOR_TABLE_ENTRY_INVALID"; + break; + case VIDC_1080P_ERROR_MB_COEFF_NOT_DONE: + string = "VIDC_1080P_ERROR_MB_COEFF_NOT_DONE"; + break; + case VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE: + string = "VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE"; + break; + case VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT: + string = "VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT"; + break; + case VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR: + string = "VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR"; + break; + case VIDC_1080P_ERROR_RESOLUTION_MISMATCH: + string = "VIDC_1080P_ERROR_RESOLUTION_MISMATCH"; + break; + case VIDC_1080P_ERROR_NV_QUANT_ERR: + string = "VIDC_1080P_ERROR_NV_QUANT_ERR"; + break; + case VIDC_1080P_ERROR_SYNC_MARKER_ERR: + string = "VIDC_1080P_ERROR_SYNC_MARKER_ERR"; + break; + case VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED: + string = "VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED"; + break; + case VIDC_1080P_ERROR_MEM_CORRUPTION: + string = "VIDC_1080P_ERROR_MEM_CORRUPTION"; + break; + case VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME: + string = "VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME"; + break; + case VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR: + string = "VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR"; + break; + case VIDC_1080P_ERROR_MV_RANGE_ERR: + string = "VIDC_1080P_ERROR_MV_RANGE_ERR"; + break; + case VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR: + string = "VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR"; + break; + case VIDC_1080P_ERROR_SLICE_ADDR_INVALID: + string = "VIDC_1080P_ERROR_SLICE_ADDR_INVALID"; + break; + case VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED: + string = "VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED"; + break; + case VIDC_1080P_ERROR_NALU_HEADER_ERROR: + string = "VIDC_1080P_ERROR_NALU_HEADER_ERROR"; + break; + case VIDC_1080P_ERROR_SPS_PARSE_ERROR: + string = "VIDC_1080P_ERROR_SPS_PARSE_ERROR"; + break; + case VIDC_1080P_ERROR_PPS_PARSE_ERROR: + string = "VIDC_1080P_ERROR_PPS_PARSE_ERROR"; + break; + case VIDC_1080P_ERROR_SLICE_PARSE_ERROR: + string = "VIDC_1080P_ERROR_SLICE_PARSE_ERROR"; + break; + } + if (string) + DDL_MSG_ERROR("Recoverable Error code = 0x%x : %s", + error_code, string); +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c new file mode 100644 index 0000000000000000000000000000000000000000..aaa6edc629d1630f0e310c3ce1010b65b63b8c6e --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c @@ -0,0 +1,1074 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include "vcd_ddl.h" +#include "vcd_ddl_shared_mem.h" +#include "vcd_res_tracker_api.h" + +struct ddl_context *ddl_get_context(void) +{ + static struct ddl_context ddl_context; + return &ddl_context; +} + +#ifdef DDL_MSG_LOG +s8 *ddl_get_state_string(enum ddl_client_state client_state) +{ + s8 *ptr; + + switch (client_state) { + case DDL_CLIENT_INVALID: + ptr = "INVALID "; + break; + case DDL_CLIENT_OPEN: + ptr = "OPEN "; + break; + case DDL_CLIENT_WAIT_FOR_CHDONE: + ptr = "WAIT_FOR_CHDONE "; + break; + case DDL_CLIENT_WAIT_FOR_INITCODEC: + ptr = "WAIT_FOR_INITCODEC "; + break; + case DDL_CLIENT_WAIT_FOR_INITCODECDONE: + ptr = "WAIT_FOR_INITCODECDONE"; + break; + case DDL_CLIENT_WAIT_FOR_DPB: + ptr = "WAIT_FOR_DPB "; + break; + case DDL_CLIENT_WAIT_FOR_DPBDONE: + ptr = "WAIT_FOR_DPBDONE"; + break; + case DDL_CLIENT_WAIT_FOR_FRAME: + ptr = "WAIT_FOR_FRAME "; + break; + case DDL_CLIENT_WAIT_FOR_FRAME_DONE: + ptr = "WAIT_FOR_FRAME_DONE "; + break; + case DDL_CLIENT_WAIT_FOR_EOS_DONE: + ptr = "WAIT_FOR_EOS_DONE "; + break; + case DDL_CLIENT_WAIT_FOR_CHEND: + ptr = "WAIT_FOR_CHEND "; + break; + case DDL_CLIENT_FATAL_ERROR: + ptr = "FATAL_ERROR"; + break; + default: + ptr = "UNKNOWN "; + break; + } + return ptr; +} +#endif + +u32 ddl_client_transact(u32 operation, + struct ddl_client_context **pddl_client) +{ + struct ddl_context *ddl_context; + u32 ret_status = VCD_ERR_FAIL; + s32 counter; + + ddl_context = ddl_get_context(); + switch (operation) { + case DDL_FREE_CLIENT: + ret_status = VCD_ERR_MAX_CLIENT; + for (counter = 0; (counter < VCD_MAX_NO_CLIENT) && + (ret_status == VCD_ERR_MAX_CLIENT); ++counter) { + if (*pddl_client == ddl_context->ddl_clients + [counter]) { + kfree(*pddl_client); + *pddl_client = NULL; + ddl_context->ddl_clients[counter] + = NULL; + ret_status = VCD_S_SUCCESS; + } + } + break; + case DDL_GET_CLIENT: + ret_status = VCD_ERR_MAX_CLIENT; + for (counter = (VCD_MAX_NO_CLIENT - 1); (counter >= 0) && + (ret_status == VCD_ERR_MAX_CLIENT); --counter) { + if (!ddl_context->ddl_clients[counter]) { + *pddl_client = + (struct ddl_client_context *) + kmalloc(sizeof(struct + ddl_client_context), GFP_KERNEL); + if (!*pddl_client) + ret_status = VCD_ERR_ALLOC_FAIL; + else { + memset(*pddl_client, 0, + sizeof(struct + ddl_client_context)); + ddl_context->ddl_clients + [counter] = *pddl_client; + (*pddl_client)->ddl_context = + ddl_context; + ret_status = VCD_S_SUCCESS; + } + } + } + break; + case DDL_INIT_CLIENTS: + for (counter = 0; counter < VCD_MAX_NO_CLIENT; ++counter) + ddl_context->ddl_clients[counter] = NULL; + ret_status = VCD_S_SUCCESS; + break; + case DDL_ACTIVE_CLIENT: + for (counter = 0; counter < VCD_MAX_NO_CLIENT; + ++counter) { + if (ddl_context->ddl_clients[counter]) { + ret_status = VCD_S_SUCCESS; + break; + } + } + break; + default: + ret_status = VCD_ERR_ILLEGAL_PARM; + break; + } + return ret_status; +} + +u32 ddl_decoder_dpb_transact(struct ddl_decoder_data *decoder, + struct ddl_frame_data_tag *in_out_frame, u32 operation) +{ + struct ddl_frame_data_tag *found_frame = NULL; + struct ddl_mask *dpb_mask = &decoder->dpb_mask; + u32 vcd_status = VCD_S_SUCCESS, loopc; + + switch (operation) { + case DDL_DPB_OP_MARK_BUSY: + case DDL_DPB_OP_MARK_FREE: + for (loopc = 0; !found_frame && loopc < + decoder->dp_buf.no_of_dec_pic_buf; ++loopc) { + if (in_out_frame->vcd_frm.physical == + decoder->dp_buf.dec_pic_buffers[loopc]. + vcd_frm.physical) { + found_frame = &(decoder->dp_buf. + dec_pic_buffers[loopc]); + break; + } + } + if (found_frame) { + if (operation == DDL_DPB_OP_MARK_BUSY) { + dpb_mask->hw_mask &= + (~(u32)(0x1 << loopc)); + *in_out_frame = *found_frame; + } else if (operation == DDL_DPB_OP_MARK_FREE) { + dpb_mask->client_mask |= (0x1 << loopc); + *found_frame = *in_out_frame; + } + } else { + in_out_frame->vcd_frm.physical = NULL; + in_out_frame->vcd_frm.virtual = NULL; + vcd_status = VCD_ERR_BAD_POINTER; + DDL_MSG_ERROR("BUF_NOT_FOUND"); + } + break; + case DDL_DPB_OP_SET_MASK: + dpb_mask->hw_mask |= dpb_mask->client_mask; + dpb_mask->client_mask = 0; + break; + case DDL_DPB_OP_INIT: + { + u32 dpb_size; + dpb_size = (!decoder->meta_data_offset) ? + decoder->dp_buf.dec_pic_buffers[0].vcd_frm.alloc_len : + decoder->meta_data_offset; + } + break; + case DDL_DPB_OP_RETRIEVE: + { + u32 position; + if (dpb_mask->client_mask) { + position = 0x1; + for (loopc = 0; loopc < + decoder->dp_buf.no_of_dec_pic_buf && + !found_frame; ++loopc) { + if (dpb_mask->client_mask & position) { + found_frame = &decoder->dp_buf. + dec_pic_buffers[loopc]; + dpb_mask->client_mask &= + ~(position); + } + position <<= 1; + } + } else if (dpb_mask->hw_mask) { + position = 0x1; + for (loopc = 0; loopc < + decoder->dp_buf.no_of_dec_pic_buf && + !found_frame; ++loopc) { + if (dpb_mask->hw_mask & position) { + found_frame = &decoder->dp_buf. + dec_pic_buffers[loopc]; + dpb_mask->hw_mask &= ~(position); + } + position <<= 1; + } + } + if (found_frame) + *in_out_frame = *found_frame; + else { + in_out_frame->vcd_frm.physical = NULL; + in_out_frame->vcd_frm.virtual = NULL; + } + } + break; + default: + break; + } + return vcd_status; +} + +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; + 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" + __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 == 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); + } + } else { + DDL_MSG_ERROR("luma size error"); + return VCD_ERR_FAIL; + } + } + + luma[i] = DDL_OFFSET(ddl_context->dram_base_a. + align_physical_addr, frame[i].vcd_frm.physical); + chroma[i] = luma[i] + luma_size; + DDL_MSG_LOW("%s Decoder Luma address = %x Chroma address = %x" + __func__, luma[i], chroma[i]); + } + switch (decoder->codec.codec) { + case VCD_CODEC_MPEG1: + case VCD_CODEC_MPEG2: + vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma); + break; + case VCD_CODEC_DIVX_3: + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + case VCD_CODEC_MPEG4: + vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma); + vidc_1080p_set_mpeg4_divx_decode_work_buffers( + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->nb_dcac), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->upnb_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->sub_anchor_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->overlay_xform), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->stx_parser)); + break; + case VCD_CODEC_H263: + vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma); + vidc_1080p_set_h263_decode_work_buffers( + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->nb_dcac), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->upnb_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->sub_anchor_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->overlay_xform)); + break; + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma); + vidc_1080p_set_vc1_decode_work_buffers( + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->nb_dcac), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->upnb_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->sub_anchor_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->overlay_xform), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->bit_plane1), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->bit_plane2), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->bit_plane3)); + break; + case VCD_CODEC_H264: + for (i = 0; i < dpb; i++) + mv[i] = DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->h264_mv[i]); + vidc_1080p_set_h264_decode_buffers(dpb, + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->h264_vert_nb_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->h264_nb_ip), + luma, chroma, mv); + break; + default: + break; + } + return VCD_S_SUCCESS; +} + +void ddl_release_context_buffers(struct ddl_context *ddl_context) +{ + ddl_pmem_free(&ddl_context->metadata_shared_input); + ddl_fw_release(&ddl_context->dram_base_a); +} + +void ddl_release_client_internal_buffers(struct ddl_client_context *ddl) +{ + if (ddl->decoding) { + struct ddl_decoder_data *decoder = + &(ddl->codec_data.decoder); + kfree(decoder->dp_buf.dec_pic_buffers); + decoder->dp_buf.dec_pic_buffers = NULL; + ddl_vidc_decode_dynamic_property(ddl, false); + decoder->decode_config.sequence_header_len = 0; + decoder->decode_config.sequence_header = NULL; + decoder->dpb_mask.client_mask = 0; + decoder->dpb_mask.hw_mask = 0; + decoder->dp_buf.no_of_dec_pic_buf = 0; + decoder->dynamic_prop_change = 0; + ddl_free_dec_hw_buffers(ddl); + } else { + 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); + } + ddl_pmem_free(&ddl->shared_mem[0]); + ddl_pmem_free(&ddl->shared_mem[1]); +} + +u32 ddl_codec_type_transact(struct ddl_client_context *ddl, + u32 remove, enum vcd_codec requested_codec) +{ + if (requested_codec > VCD_CODEC_VC1_RCV || + requested_codec < VCD_CODEC_H264) + return false; + if (!ddl->decoding && requested_codec != VCD_CODEC_MPEG4 && + requested_codec != VCD_CODEC_H264 && + requested_codec != VCD_CODEC_H263) + return false; + + return true; +} + +u32 ddl_take_command_channel(struct ddl_context *ddl_context, + struct ddl_client_context *ddl, void *client_data) +{ + u32 status = true; + + if (!ddl_context->current_ddl[0]) { + ddl_context->current_ddl[0] = ddl; + ddl->client_data = client_data; + ddl->command_channel = 0; + } else if (!ddl_context->current_ddl[1]) { + ddl_context->current_ddl[1] = ddl; + ddl->client_data = client_data; + ddl->command_channel = 1; + } else + status = false; + if (status) { + if (ddl_context->current_ddl[0] && + ddl_context->current_ddl[1]) + DDL_BUSY(ddl_context); + else + DDL_RUN(ddl_context); + } + return status; +} + +void ddl_release_command_channel(struct ddl_context *ddl_context, + u32 command_channel) +{ + ddl_context->current_ddl[command_channel]->client_data = NULL; + ddl_context->current_ddl[command_channel] = NULL; + if (!ddl_context->current_ddl[0] && + !ddl_context->current_ddl[1]) + DDL_IDLE(ddl_context); + else + DDL_RUN(ddl_context); +} + +struct ddl_client_context *ddl_get_current_ddl_client_for_channel_id( + struct ddl_context *ddl_context, u32 channel_id) +{ + struct ddl_client_context *ddl; + + if (ddl_context->current_ddl[0] && channel_id == + ddl_context->current_ddl[0]->command_channel) + ddl = ddl_context->current_ddl[0]; + else if (ddl_context->current_ddl[1] && channel_id == + ddl_context->current_ddl[1]->command_channel) + ddl = ddl_context->current_ddl[1]; + else { + DDL_MSG_LOW("STATE-CRITICAL-FRMRUN"); + DDL_MSG_ERROR("Unexpected channel ID = %d", channel_id); + ddl = NULL; + } + return ddl; +} + +struct ddl_client_context *ddl_get_current_ddl_client_for_command( + struct ddl_context *ddl_context, + enum ddl_cmd_state cmd_state) +{ + struct ddl_client_context *ddl; + + if (ddl_context->current_ddl[0] && + cmd_state == ddl_context->current_ddl[0]->cmd_state) + ddl = ddl_context->current_ddl[0]; + else if (ddl_context->current_ddl[1] && + cmd_state == ddl_context->current_ddl[1]->cmd_state) + ddl = ddl_context->current_ddl[1]; + else { + DDL_MSG_LOW("STATE-CRITICAL-FRMRUN"); + DDL_MSG_ERROR("Error: Unexpected cmd_state = %d", + cmd_state); + ddl = NULL; + } + return ddl; +} + +u32 ddl_get_yuv_buf_size(u32 width, u32 height, u32 format) +{ + u32 mem_size, width_round_up, height_round_up, align; + + width_round_up = width; + height_round_up = height; + if (format == DDL_YUV_BUF_TYPE_TILE) { + width_round_up = DDL_ALIGN(width, DDL_TILE_ALIGN_WIDTH); + height_round_up = DDL_ALIGN(height, DDL_TILE_ALIGN_HEIGHT); + align = DDL_TILE_MULTIPLY_FACTOR; + } + if (format == DDL_YUV_BUF_TYPE_LINEAR) { + width_round_up = DDL_ALIGN(width, DDL_LINEAR_ALIGN_WIDTH); + align = DDL_LINEAR_MULTIPLY_FACTOR; + } + mem_size = (width_round_up * height_round_up); + mem_size = DDL_ALIGN(mem_size, align); + return mem_size; +} +void ddl_free_dec_hw_buffers(struct ddl_client_context *ddl) +{ + struct ddl_dec_buffers *dec_bufs = + &ddl->codec_data.decoder.hw_bufs; + ddl_pmem_free(&dec_bufs->h264_nb_ip); + ddl_pmem_free(&dec_bufs->h264_vert_nb_mv); + ddl_pmem_free(&dec_bufs->nb_dcac); + ddl_pmem_free(&dec_bufs->upnb_mv); + ddl_pmem_free(&dec_bufs->sub_anchor_mv); + ddl_pmem_free(&dec_bufs->overlay_xform); + ddl_pmem_free(&dec_bufs->bit_plane3); + ddl_pmem_free(&dec_bufs->bit_plane2); + ddl_pmem_free(&dec_bufs->bit_plane1); + ddl_pmem_free(&dec_bufs->stx_parser); + ddl_pmem_free(&dec_bufs->desc); + ddl_pmem_free(&dec_bufs->context); + memset(dec_bufs, 0, sizeof(struct ddl_dec_buffers)); +} + +void ddl_free_enc_hw_buffers(struct ddl_client_context *ddl) +{ + struct ddl_enc_buffers *enc_bufs = + &ddl->codec_data.encoder.hw_bufs; + u32 i; + + for (i = 0; i < enc_bufs->dpb_count; i++) { + ddl_pmem_free(&enc_bufs->dpb_y[i]); + ddl_pmem_free(&enc_bufs->dpb_c[i]); + } + ddl_pmem_free(&enc_bufs->mv); + ddl_pmem_free(&enc_bufs->col_zero); + ddl_pmem_free(&enc_bufs->md); + ddl_pmem_free(&enc_bufs->pred); + ddl_pmem_free(&enc_bufs->nbor_info); + ddl_pmem_free(&enc_bufs->acdc_coef); + ddl_pmem_free(&enc_bufs->context); + memset(enc_bufs, 0, sizeof(struct ddl_enc_buffers)); +} + +u32 ddl_get_input_frame_from_pool(struct ddl_client_context *ddl, + u8 *input_buffer_address) +{ + u32 vcd_status = VCD_S_SUCCESS, i, found = false; + + for (i = 0; i < DDL_MAX_NUM_IN_INPUTFRAME_POOL && !found; i++) { + if (input_buffer_address == + ddl->input_frame_pool[i].vcd_frm.physical) { + found = true; + ddl->input_frame = ddl->input_frame_pool[i]; + memset(&ddl->input_frame_pool[i], 0, + sizeof(struct ddl_frame_data_tag)); + } + } + if (!found) + vcd_status = VCD_ERR_FAIL; + + return vcd_status; +} + +u32 ddl_insert_input_frame_to_pool(struct ddl_client_context *ddl, + struct ddl_frame_data_tag *ddl_input_frame) +{ + u32 vcd_status = VCD_S_SUCCESS, i, found = false; + + for (i = 0; i < DDL_MAX_NUM_IN_INPUTFRAME_POOL && !found; i++) { + if (!ddl->input_frame_pool[i].vcd_frm.physical) { + found = true; + ddl->input_frame_pool[i] = *ddl_input_frame; + } + } + if (!found) + vcd_status = VCD_ERR_FAIL; + + return vcd_status; +} + +void ddl_calc_dec_hw_buffers_size(enum vcd_codec codec, u32 width, + u32 height, u32 dpb, struct ddl_dec_buffer_size *buf_size) +{ + u32 sz_dpb0 = 0, sz_dpb1 = 0, sz_mv = 0; + u32 sz_luma = 0, sz_chroma = 0, sz_nb_dcac = 0, sz_upnb_mv = 0; + u32 sz_sub_anchor_mv = 0, sz_overlap_xform = 0, sz_bit_plane3 = 0; + u32 sz_bit_plane2 = 0, sz_bit_plane1 = 0, sz_stx_parser = 0; + u32 sz_desc, sz_cpb, sz_context, sz_vert_nb_mv = 0, sz_nb_ip = 0; + + if (codec == VCD_CODEC_H264) { + sz_mv = ddl_get_yuv_buf_size(width, + height>>2, DDL_YUV_BUF_TYPE_TILE); + sz_nb_ip = DDL_KILO_BYTE(32); + sz_vert_nb_mv = DDL_KILO_BYTE(16); + } else { + if ((codec == VCD_CODEC_MPEG4) || + (codec == VCD_CODEC_DIVX_3) || + (codec == VCD_CODEC_DIVX_4) || + (codec == VCD_CODEC_DIVX_5) || + (codec == VCD_CODEC_DIVX_6) || + (codec == VCD_CODEC_XVID) || + (codec == VCD_CODEC_H263)) { + sz_nb_dcac = DDL_KILO_BYTE(16); + sz_upnb_mv = DDL_KILO_BYTE(68); + sz_sub_anchor_mv = DDL_KILO_BYTE(136); + sz_overlap_xform = DDL_KILO_BYTE(32); + if (codec != VCD_CODEC_H263) + sz_stx_parser = DDL_KILO_BYTE(68); + } else if ((codec == VCD_CODEC_VC1) || + (codec == VCD_CODEC_VC1_RCV)) { + sz_nb_dcac = DDL_KILO_BYTE(16); + sz_upnb_mv = DDL_KILO_BYTE(68); + sz_sub_anchor_mv = DDL_KILO_BYTE(136); + sz_overlap_xform = DDL_KILO_BYTE(32); + sz_bit_plane3 = DDL_KILO_BYTE(2); + sz_bit_plane2 = DDL_KILO_BYTE(2); + sz_bit_plane1 = DDL_KILO_BYTE(2); + } + } + sz_desc = DDL_KILO_BYTE(128); + sz_cpb = VCD_DEC_CPB_SIZE; + if (codec == VCD_CODEC_H264) + sz_context = DDL_FW_H264DEC_CONTEXT_SPACE_SIZE; + else + sz_context = DDL_FW_OTHER_CONTEXT_SPACE_SIZE; + if (buf_size) { + buf_size->sz_dpb0 = sz_dpb0; + buf_size->sz_dpb1 = sz_dpb1; + buf_size->sz_mv = sz_mv; + buf_size->sz_vert_nb_mv = sz_vert_nb_mv; + buf_size->sz_nb_ip = sz_nb_ip; + buf_size->sz_luma = sz_luma; + buf_size->sz_chroma = sz_chroma; + buf_size->sz_nb_dcac = sz_nb_dcac; + buf_size->sz_upnb_mv = sz_upnb_mv; + buf_size->sz_sub_anchor_mv = sz_sub_anchor_mv; + buf_size->sz_overlap_xform = sz_overlap_xform; + buf_size->sz_bit_plane3 = sz_bit_plane3; + buf_size->sz_bit_plane2 = sz_bit_plane2; + buf_size->sz_bit_plane1 = sz_bit_plane1; + buf_size->sz_stx_parser = sz_stx_parser; + buf_size->sz_desc = sz_desc; + buf_size->sz_cpb = sz_cpb; + buf_size->sz_context = sz_context; + } +} + +u32 ddl_allocate_dec_hw_buffers(struct ddl_client_context *ddl) +{ + struct ddl_dec_buffers *dec_bufs; + struct ddl_dec_buffer_size buf_size; + u32 status = VCD_S_SUCCESS, dpb = 0; + u32 width = 0, height = 0; + u8 *ptr; + struct ddl_context *ddl_context = ddl->ddl_context; + + dec_bufs = &ddl->codec_data.decoder.hw_bufs; + ddl_calc_dec_hw_buffers_size(ddl->codec_data.decoder. + codec.codec, width, height, dpb, &buf_size); + if (buf_size.sz_context > 0) { + dec_bufs->context.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->context, buf_size.sz_context, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + else + msm_ion_do_cache_op(ddl_context->video_ion_client, + dec_bufs->context.alloc_handle, + dec_bufs->context.virtual_base_addr, + dec_bufs->context.buffer_size, + ION_IOC_CLEAN_INV_CACHES); + } + if (buf_size.sz_nb_ip > 0) { + dec_bufs->h264_nb_ip.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->h264_nb_ip, buf_size.sz_nb_ip, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_vert_nb_mv > 0) { + dec_bufs->h264_vert_nb_mv.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->h264_vert_nb_mv, + buf_size.sz_vert_nb_mv, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_nb_dcac > 0) { + dec_bufs->nb_dcac.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->nb_dcac, buf_size.sz_nb_dcac, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_upnb_mv > 0) { + dec_bufs->upnb_mv.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->upnb_mv, buf_size.sz_upnb_mv, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_sub_anchor_mv > 0) { + dec_bufs->sub_anchor_mv.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->sub_anchor_mv, + buf_size.sz_sub_anchor_mv, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_overlap_xform > 0) { + dec_bufs->overlay_xform.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->overlay_xform, + buf_size.sz_overlap_xform, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_bit_plane3 > 0) { + dec_bufs->bit_plane3.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->bit_plane3, + buf_size.sz_bit_plane3, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_bit_plane2 > 0) { + dec_bufs->bit_plane2.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->bit_plane2, + buf_size.sz_bit_plane2, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_bit_plane1 > 0) { + dec_bufs->bit_plane1.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->bit_plane1, + buf_size.sz_bit_plane1, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_stx_parser > 0) { + dec_bufs->stx_parser.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->stx_parser, + buf_size.sz_stx_parser, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_desc > 0) { + dec_bufs->desc.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->desc, buf_size.sz_desc, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + else { + if (!res_trk_check_for_sec_session()) { + memset(dec_bufs->desc.align_virtual_addr, + 0, buf_size.sz_desc); + msm_ion_do_cache_op( + ddl_context->video_ion_client, + dec_bufs->desc.alloc_handle, + dec_bufs->desc.virtual_base_addr, + dec_bufs->desc.buffer_size, + ION_IOC_CLEAN_INV_CACHES); + } + } + } + return status; +fail_free_exit: + status = VCD_ERR_ALLOC_FAIL; + ddl_free_dec_hw_buffers(ddl); + return status; +} + +u32 ddl_calc_enc_hw_buffers_size(enum vcd_codec codec, u32 width, + u32 height, enum vcd_yuv_buffer_format input_format, + struct ddl_client_context *ddl, + struct ddl_enc_buffer_size *buf_size) +{ + u32 status = VCD_S_SUCCESS, mb_x, mb_y; + u32 sz_cur_y, sz_cur_c, sz_dpb_y, sz_dpb_c, sz_strm = 0, sz_mv; + u32 sz_md = 0, sz_pred = 0, sz_nbor_info = 0 , sz_acdc_coef = 0; + u32 sz_mb_info = 0, sz_context, sz_col_zero = 0; + + mb_x = (width + 15) / 16; + mb_y = (height + 15) / 16; + sz_dpb_y = ddl_get_yuv_buf_size(width, + height, DDL_YUV_BUF_TYPE_TILE); + sz_dpb_c = ddl_get_yuv_buf_size(width, height>>1, + DDL_YUV_BUF_TYPE_TILE); + if (input_format == + VCD_BUFFER_FORMAT_NV12_16M2KA) { + sz_cur_y = ddl_get_yuv_buf_size(width, height, + DDL_YUV_BUF_TYPE_LINEAR); + sz_cur_c = ddl_get_yuv_buf_size(width, height>>1, + DDL_YUV_BUF_TYPE_LINEAR); + } else if (VCD_BUFFER_FORMAT_TILE_4x2 == input_format) { + sz_cur_y = sz_dpb_y; + sz_cur_c = sz_dpb_c; + } else + status = VCD_ERR_NOT_SUPPORTED; + sz_context = DDL_FW_OTHER_CONTEXT_SPACE_SIZE; + if (!status) { + sz_strm = DDL_ALIGN(ddl_get_yuv_buf_size(width, height, + DDL_YUV_BUF_TYPE_LINEAR) + ddl_get_yuv_buf_size(width, + height/2, DDL_YUV_BUF_TYPE_LINEAR), DDL_KILO_BYTE(4)); + sz_mv = DDL_ALIGN(2 * mb_x * mb_y * 8, DDL_KILO_BYTE(2)); + if ((codec == VCD_CODEC_MPEG4) || + (codec == VCD_CODEC_H264)) { + sz_col_zero = DDL_ALIGN(((mb_x * mb_y + 7) / 8) * + 8, DDL_KILO_BYTE(2)); + } + if ((codec == VCD_CODEC_MPEG4) || + (codec == VCD_CODEC_H263)) { + sz_acdc_coef = DDL_ALIGN((width / 2) * 8, + DDL_KILO_BYTE(2)); + } else if (codec == VCD_CODEC_H264) { + sz_md = DDL_ALIGN(mb_x * 48, DDL_KILO_BYTE(2)); + sz_pred = DDL_ALIGN(2 * 8 * 1024, DDL_KILO_BYTE(2)); + sz_context = DDL_FW_H264ENC_CONTEXT_SPACE_SIZE; + if (ddl) { + if (ddl->codec_data.encoder. + entropy_control.entropy_sel == + VCD_ENTROPY_SEL_CAVLC) + sz_nbor_info = DDL_ALIGN(8 * 8 * mb_x, + DDL_KILO_BYTE(2)); + else if (ddl->codec_data.encoder. + entropy_control.entropy_sel == + VCD_ENTROPY_SEL_CABAC) + sz_nbor_info = DDL_ALIGN(8 * 24 * + mb_x, DDL_KILO_BYTE(2)); + if ((ddl->codec_data.encoder. + mb_info_enable) && + (codec == VCD_CODEC_H264)) { + sz_mb_info = DDL_ALIGN(mb_x * mb_y * + 6 * 8, DDL_KILO_BYTE(2)); + } + } + } else { + sz_nbor_info = DDL_ALIGN(8 * 24 * mb_x, + DDL_KILO_BYTE(2)); + sz_mb_info = DDL_ALIGN(mb_x * mb_y * 6 * 8, + DDL_KILO_BYTE(2)); + } + if (buf_size) { + buf_size->sz_cur_y = sz_cur_y; + buf_size->sz_cur_c = sz_cur_c; + buf_size->sz_dpb_y = sz_dpb_y; + buf_size->sz_dpb_c = sz_dpb_c; + buf_size->sz_strm = sz_strm; + buf_size->sz_mv = sz_mv; + buf_size->sz_col_zero = sz_col_zero; + buf_size->sz_md = sz_md; + buf_size->sz_pred = sz_pred; + buf_size->sz_nbor_info = sz_nbor_info; + buf_size->sz_acdc_coef = sz_acdc_coef; + buf_size->sz_mb_info = sz_mb_info; + buf_size->sz_context = sz_context; + } + } + return status; +} + +u32 ddl_allocate_enc_hw_buffers(struct ddl_client_context *ddl) +{ + struct ddl_enc_buffers *enc_bufs; + struct ddl_enc_buffer_size buf_size; + void *ptr; + u32 status = VCD_S_SUCCESS; + struct ddl_context *ddl_context = ddl->ddl_context; + + enc_bufs = &ddl->codec_data.encoder.hw_bufs; + enc_bufs->dpb_count = DDL_ENC_MIN_DPB_BUFFERS; + + if ((ddl->codec_data.encoder.i_period.b_frames > + DDL_MIN_NUM_OF_B_FRAME) || + (ddl->codec_data.encoder.num_references_for_p_frame + > DDL_MIN_NUM_REF_FOR_P_FRAME)) + enc_bufs->dpb_count = DDL_ENC_MAX_DPB_BUFFERS; + DDL_MSG_HIGH("Encoder num DPB buffers allocated = %d", + enc_bufs->dpb_count); + + status = ddl_calc_enc_hw_buffers_size( + ddl->codec_data.encoder.codec.codec, + ddl->codec_data.encoder.frame_size.width, + ddl->codec_data.encoder.frame_size.height, + ddl->codec_data.encoder.buf_format.buffer_format, + ddl, &buf_size); + buf_size.sz_strm = ddl->codec_data.encoder. + client_output_buf_req.sz; + if (!status) { + enc_bufs->sz_dpb_y = buf_size.sz_dpb_y; + enc_bufs->sz_dpb_c = buf_size.sz_dpb_c; + if (buf_size.sz_mv > 0) { + enc_bufs->mv.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->mv, buf_size.sz_mv, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_col_zero > 0) { + enc_bufs->col_zero.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->col_zero, + buf_size.sz_col_zero, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_md > 0) { + enc_bufs->md.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->md, buf_size.sz_md, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_pred > 0) { + enc_bufs->pred.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->pred, + buf_size.sz_pred, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_nbor_info > 0) { + enc_bufs->nbor_info.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->nbor_info, + buf_size.sz_nbor_info, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_acdc_coef > 0) { + enc_bufs->acdc_coef.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->acdc_coef, + buf_size.sz_acdc_coef, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_mb_info > 0) { + enc_bufs->mb_info.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->mb_info, + buf_size.sz_mb_info, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_context > 0) { + enc_bufs->context.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->context, + buf_size.sz_context, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + else + msm_ion_do_cache_op( + ddl_context->video_ion_client, + enc_bufs->context.alloc_handle, + enc_bufs->context.virtual_base_addr, + enc_bufs->context.buffer_size, + ION_IOC_CLEAN_INV_CACHES); + } + } + return status; +fail_enc_free_exit: + status = VCD_ERR_ALLOC_FAIL; + ddl_free_enc_hw_buffers(ddl); + return status; +} + +void ddl_decoder_chroma_dpb_change(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct ddl_frame_data_tag *frame = + &(decoder->dp_buf.dec_pic_buffers[0]); + u32 luma[DDL_MAX_BUFFER_COUNT]; + u32 chroma[DDL_MAX_BUFFER_COUNT]; + u32 luma_size, i, dpb; + luma_size = decoder->dpb_buf_size.size_y; + dpb = decoder->dp_buf.no_of_dec_pic_buf; + DDL_MSG_HIGH("%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++) { + luma[i] = DDL_OFFSET( + ddl_context->dram_base_a.align_physical_addr, + frame[i].vcd_frm.physical); + chroma[i] = luma[i] + luma_size; + DDL_MSG_LOW("%s Decoder Luma address = %x" + "Chroma address = %x", __func__, luma[i], chroma[i]); + } + vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma); +} + +u32 ddl_check_reconfig(struct ddl_client_context *ddl) +{ + u32 need_reconfig = true; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + if (decoder->cont_mode) { + if ((decoder->actual_output_buf_req.sz <= + decoder->client_output_buf_req.sz) && + (decoder->actual_output_buf_req.actual_count <= + decoder->client_output_buf_req.actual_count)) { + need_reconfig = false; + if (decoder->min_dpb_num > + decoder->min_output_buf_req.min_count) { + decoder->min_output_buf_req = + decoder->actual_output_buf_req; + } + DDL_MSG_LOW("%s Decoder width = %u height = %u " + "Client width = %u height = %u\n", + __func__, decoder->frame_size.width, + decoder->frame_size.height, + decoder->client_frame_size.width, + decoder->client_frame_size.height); + } + } else { + if ((decoder->frame_size.width == + decoder->client_frame_size.width) && + (decoder->frame_size.height == + decoder->client_frame_size.height) && + (decoder->actual_output_buf_req.sz <= + decoder->client_output_buf_req.sz) && + (decoder->actual_output_buf_req.min_count == + decoder->client_output_buf_req.min_count) && + (decoder->actual_output_buf_req.actual_count == + decoder->client_output_buf_req.actual_count) && + (decoder->frame_size.scan_lines == + decoder->client_frame_size.scan_lines) && + (decoder->frame_size.stride == + decoder->client_frame_size.stride) && + decoder->progressive_only) + need_reconfig = false; + } + return need_reconfig; +} + +void ddl_handle_reconfig(u32 res_change, struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + if ((decoder->cont_mode) && + (res_change == DDL_RESL_CHANGE_DECREASED)) { + DDL_MSG_LOW("%s Resolution decreased, continue decoding\n", + __func__); + vidc_sm_get_min_yc_dpb_sizes( + &ddl->shared_mem[ddl->command_channel], + &decoder->dpb_buf_size.size_y, + &decoder->dpb_buf_size.size_c); + DDL_MSG_LOW(" %s Resolution decreased, size_y = %u" + " size_c = %u\n", + __func__, + decoder->dpb_buf_size.size_y, + decoder->dpb_buf_size.size_c); + ddl_decoder_chroma_dpb_change(ddl); + vidc_sm_set_chroma_addr_change( + &ddl->shared_mem[ddl->command_channel], + true); + ddl_vidc_decode_frame_run(ddl); + } else { + DDL_MSG_LOW("%s Resolution change, start realloc\n", + __func__); + decoder->reconfig_detected = true; + ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE; + ddl->cmd_state = DDL_CMD_EOS; + vidc_1080p_frame_start_realloc(ddl->instance_id); + } +} + +void ddl_fill_dec_desc_buffer(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct vcd_frame_data *ip_bitstream = &(ddl->input_frame.vcd_frm); + struct ddl_buf_addr *dec_desc_buf = &(decoder->hw_bufs.desc); + + if (ip_bitstream->desc_buf && + ip_bitstream->desc_size < DDL_KILO_BYTE(128)) + memcpy(dec_desc_buf->align_virtual_addr, + ip_bitstream->desc_buf, + ip_bitstream->desc_size); +} + +void ddl_set_vidc_timeout(struct ddl_client_context *ddl) +{ + u32 vidc_time_out = 0; + if (ddl->codec_data.decoder.idr_only_decoding) + vidc_time_out = 2 * DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE; + DDL_MSG_HIGH("%s Video core time out value = 0x%x", + __func__, vidc_time_out); + vidc_sm_set_video_core_timeout_value( + &ddl->shared_mem[ddl->command_channel], vidc_time_out); +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..f18f8a9ec7fddb31de8945a96cd0d78d426b6586 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c @@ -0,0 +1,2042 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + + +#include "vcd_ddl.h" +#include "vcd_ddl_shared_mem.h" +#include "vcd_ddl_metadata.h" +#include "vcd_res_tracker_api.h" +#include + +static void ddl_decoder_input_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end); +static u32 ddl_decoder_output_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end); +static u32 ddl_get_decoded_frame(struct vcd_frame_data *frame, + enum vidc_1080p_decode_frame frame_type); +static u32 ddl_get_encoded_frame(struct vcd_frame_data *frame, + enum vcd_codec codec, + 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, + 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_handle_enc_skipframe_slice_mode( + struct ddl_client_context *ddl, u32 eos_present); + +static void ddl_fw_status_done_callback(struct ddl_context *ddl_context) +{ + DDL_MSG_MED("ddl_fw_status_done_callback"); + if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_DMA_INIT)) { + DDL_MSG_ERROR("UNKWN_DMADONE"); + } else { + DDL_MSG_LOW("FW_STATUS_DONE"); + vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_SYS_INIT, + ddl_context->fw_memory_size, 0, 0, 0); + } +} + +static void ddl_sys_init_done_callback(struct ddl_context *ddl_context, + u32 fw_size) +{ + u32 vcd_status = VCD_S_SUCCESS; + u8 *fw_ver; + + DDL_MSG_MED("ddl_sys_init_done_callback"); + if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_DMA_INIT)) { + DDL_MSG_ERROR("UNKNOWN_SYS_INIT_DONE"); + } else { + ddl_context->cmd_state = DDL_CMD_INVALID; + DDL_MSG_LOW("SYS_INIT_DONE"); + vidc_1080p_get_fw_version(&ddl_context->fw_version); + fw_ver = (u8 *)&ddl_context->fw_version; + DDL_MSG_ERROR("fw_version %x:%x:20%x", + fw_ver[1]&0xFF, fw_ver[0]&0xFF, fw_ver[2]&0xFF); + if (ddl_context->fw_memory_size >= fw_size) { + ddl_context->device_state = DDL_DEVICE_INITED; + vcd_status = VCD_S_SUCCESS; + } else + vcd_status = VCD_ERR_FAIL; + ddl_context->ddl_callback(VCD_EVT_RESP_DEVICE_INIT, + vcd_status, NULL, 0, NULL, + ddl_context->client_data); + DDL_IDLE(ddl_context); + } +} + +static void ddl_decoder_eos_done_callback( + struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + + if (!ddl->decoding) { + DDL_MSG_ERROR("STATE-CRITICAL-EOSDONE"); + ddl_client_fatal_cb(ddl); + } else { + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; + DDL_MSG_LOW("EOS_DONE"); + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, + ddl->client_data); + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } +} + +static u32 ddl_channel_set_callback(struct ddl_context *ddl_context, + u32 instance_id) +{ + struct ddl_client_context *ddl; + u32 ret = false; + + DDL_MSG_MED("ddl_channel_open_callback"); + ddl = ddl_get_current_ddl_client_for_command(ddl_context, + DDL_CMD_CHANNEL_SET); + if (ddl) { + ddl->cmd_state = DDL_CMD_INVALID; + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHDONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-CHSET"); + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } else { + DDL_MSG_LOW("CH_SET_DONE"); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_INITCODEC", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODEC; + ddl->instance_id = instance_id; + if (ddl->decoding) { + ddl_calc_core_proc_time(__func__, + DEC_OP_TIME, ddl); + if (ddl->codec_data.decoder.header_in_start) + ddl_vidc_decode_init_codec(ddl); + else { + ddl_context->ddl_callback( + VCD_EVT_RESP_START, + VCD_S_SUCCESS, NULL, 0, + (u32 *)ddl, + ddl->client_data); + ddl_release_command_channel( + ddl_context, + ddl->command_channel); + ret = true; + } + } else + ddl_vidc_encode_init_codec(ddl); + } + } + return ret; +} + +static u32 ddl_encoder_seq_done_callback(struct ddl_context *ddl_context, + struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder; + + 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); + return true; + } + ddl_calc_core_proc_time(__func__, ENC_OP_TIME, ddl); + 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)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; + DDL_MSG_LOW("INIT_CODEC_DONE"); + encoder = &ddl->codec_data.encoder; + vidc_1080p_get_encoder_sequence_header_size( + &encoder->seq_header_length); + if ((encoder->codec.codec == VCD_CODEC_H264) && + (encoder->profile.profile == VCD_PROFILE_H264_BASELINE)) + if ((encoder->seq_header.align_virtual_addr) && + (encoder->seq_header_length > 6)) + encoder->seq_header.align_virtual_addr[6] = 0xC0; + ddl_context->ddl_callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, + NULL, 0, (u32 *) ddl, ddl->client_data); + ddl_release_command_channel(ddl_context, + ddl->command_channel); + return true; +} + +static void parse_hdr_size_data(struct ddl_client_context *ddl, + struct vidc_1080p_seq_hdr_info *seq_hdr_info) +{ + u32 progressive; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) { + decoder->frame_size.width = seq_hdr_info->img_size_x; + decoder->frame_size.height = seq_hdr_info->img_size_y; + progressive = seq_hdr_info->disp_progressive; + } else { + vidc_sm_get_dec_order_resl( + &ddl->shared_mem[ddl->command_channel], + &decoder->frame_size.width, + &decoder->frame_size.height); + progressive = seq_hdr_info->dec_progressive; + } + decoder->min_dpb_num = seq_hdr_info->min_num_dpb; + vidc_sm_get_min_yc_dpb_sizes( + &ddl->shared_mem[ddl->command_channel], + &seq_hdr_info->min_luma_dpb_size, + &seq_hdr_info->min_chroma_dpb_size); + decoder->y_cb_cr_size = seq_hdr_info->min_luma_dpb_size + + seq_hdr_info->min_chroma_dpb_size; + decoder->dpb_buf_size.size_yuv = decoder->y_cb_cr_size; + decoder->dpb_buf_size.size_y = + seq_hdr_info->min_luma_dpb_size; + decoder->dpb_buf_size.size_c = + seq_hdr_info->min_chroma_dpb_size; + decoder->progressive_only = progressive ? false : true; +} + +static void parse_hdr_crop_data(struct ddl_client_context *ddl, + struct vidc_1080p_seq_hdr_info *seq_hdr_info) +{ + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + u32 crop_exists = (decoder->output_order == VCD_DEC_ORDER_DISPLAY) ? + seq_hdr_info->disp_crop_exists : seq_hdr_info->dec_crop_exists; + if (crop_exists) { + if (decoder->output_order == + VCD_DEC_ORDER_DISPLAY) + vidc_sm_get_crop_info( + &ddl->shared_mem[ddl->command_channel], + &seq_hdr_info->crop_left_offset, + &seq_hdr_info->crop_right_offset, + &seq_hdr_info->crop_top_offset, + &seq_hdr_info->crop_bottom_offset); + else + vidc_sm_get_dec_order_crop_info( + &ddl->shared_mem[ddl->command_channel], + &seq_hdr_info->crop_left_offset, + &seq_hdr_info->crop_right_offset, + &seq_hdr_info->crop_top_offset, + &seq_hdr_info->crop_bottom_offset); + decoder->frame_size.width -= + seq_hdr_info->crop_right_offset + + seq_hdr_info->crop_left_offset; + decoder->frame_size.height -= + seq_hdr_info->crop_top_offset + + seq_hdr_info->crop_bottom_offset; + } +} + +static u32 ddl_decoder_seq_done_callback(struct ddl_context *ddl_context, + struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct vidc_1080p_seq_hdr_info seq_hdr_info; + u32 process_further = true; + struct ddl_profile_info_type disp_profile_info; + + DDL_MSG_MED("ddl_decoder_seq_done_callback"); + if (!ddl->decoding || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-HDDONE"); + ddl_client_fatal_cb(ddl); + } else { + ddl_calc_core_proc_time(__func__, DEC_OP_TIME, ddl); + ddl->cmd_state = DDL_CMD_INVALID; + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_DPB", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_DPB; + DDL_MSG_LOW("HEADER_DONE"); + vidc_1080p_get_decode_seq_start_result(&seq_hdr_info); + parse_hdr_size_data(ddl, &seq_hdr_info); + if (res_trk_get_disable_fullhd() && + (seq_hdr_info.img_size_x * seq_hdr_info.img_size_y > + 1280 * 720)) { + DDL_MSG_ERROR("FATAL:Resolution greater than 720P HD"); + ddl_client_fatal_cb(ddl); + return process_further; + } + if (!seq_hdr_info.img_size_x || !seq_hdr_info.img_size_y) { + DDL_MSG_ERROR("FATAL:ZeroImageSize"); + ddl_client_fatal_cb(ddl); + return process_further; + } + vidc_sm_get_profile_info(&ddl->shared_mem + [ddl->command_channel], &disp_profile_info); + disp_profile_info.pic_profile = seq_hdr_info.profile; + disp_profile_info.pic_level = seq_hdr_info.level; + ddl_get_dec_profile_level(decoder, seq_hdr_info.profile, + seq_hdr_info.level); + switch (decoder->codec.codec) { + case VCD_CODEC_H264: + if (decoder->profile.profile == VCD_PROFILE_H264_HIGH || + decoder->profile.profile == + VCD_PROFILE_UNKNOWN) { + if ((disp_profile_info.chroma_format_idc > + VIDC_1080P_IDCFORMAT_420) || + (disp_profile_info.bit_depth_luma_minus8 + || disp_profile_info. + bit_depth_chroma_minus8)) { + DDL_MSG_ERROR("Unsupported H.264 " + "feature: IDC format : %d, Bitdepth: %d", + disp_profile_info. + chroma_format_idc, + (disp_profile_info. + bit_depth_luma_minus8 + || disp_profile_info. + bit_depth_chroma_minus8)); + ddl_client_fatal_cb(ddl); + return process_further; + } + } + break; + case VCD_CODEC_MPEG4: + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + if (seq_hdr_info.data_partition) + if ((seq_hdr_info.img_size_x * + seq_hdr_info.img_size_y) > (720 * 576)) { + DDL_MSG_ERROR("Unsupported DP clip"); + ddl_client_fatal_cb(ddl); + return process_further; + } + break; + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + if ((seq_hdr_info.img_size_x > + DDL_MAX_VC1_FRAME_WIDTH) || + (seq_hdr_info.img_size_y > + DDL_MAX_VC1_FRAME_HEIGHT)) { + DDL_MSG_ERROR("Unsupported VC1 clip: " + "Resolution X=%d and Y=%d", + seq_hdr_info.img_size_x, + seq_hdr_info.img_size_y); + ddl_client_fatal_cb(ddl); + return process_further; + } + break; + default: + break; + } + ddl_calculate_stride(&decoder->frame_size, + !decoder->progressive_only); + decoder->frame_size.scan_lines = + DDL_ALIGN(decoder->frame_size.height, DDL_TILE_ALIGN_HEIGHT); + decoder->frame_size.stride = + DDL_ALIGN(decoder->frame_size.width, DDL_TILE_ALIGN_WIDTH); + parse_hdr_crop_data(ddl, &seq_hdr_info); + if (decoder->codec.codec == VCD_CODEC_H264 && + seq_hdr_info.level > VIDC_1080P_H264_LEVEL4) { + DDL_MSG_ERROR("WARNING: H264MaxLevelExceeded : %d", + seq_hdr_info.level); + } + ddl_set_default_decoder_buffer_req(decoder, false); + if (decoder->header_in_start) { + if (!(decoder->cont_mode) || + (decoder->min_dpb_num > + decoder->client_output_buf_req.min_count) || + (decoder->actual_output_buf_req.sz > + decoder->client_output_buf_req.sz)) { + decoder->client_frame_size = + decoder->frame_size; + decoder->client_output_buf_req = + decoder->actual_output_buf_req; + decoder->client_input_buf_req = + decoder->actual_input_buf_req; + } + ddl_context->ddl_callback(VCD_EVT_RESP_START, + VCD_S_SUCCESS, NULL, 0, (u32 *) ddl, + ddl->client_data); + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } else { + u32 seq_hdr_only_frame = false; + u32 need_reconfig = false; + struct vcd_frame_data *input_vcd_frm = + &ddl->input_frame.vcd_frm; + need_reconfig = ddl_check_reconfig(ddl); + DDL_MSG_HIGH("%s : need_reconfig = %u\n", __func__, + need_reconfig); + if (input_vcd_frm->flags & + VCD_FRAME_FLAG_EOS) { + need_reconfig = false; + } + if (((input_vcd_frm->flags & + VCD_FRAME_FLAG_CODECCONFIG) && + (!(input_vcd_frm->flags & + VCD_FRAME_FLAG_SYNCFRAME))) || + input_vcd_frm->data_len <= + seq_hdr_info.dec_frm_size) { + seq_hdr_only_frame = true; + input_vcd_frm->offset += + seq_hdr_info.dec_frm_size; + input_vcd_frm->data_len = 0; + input_vcd_frm->flags |= + VCD_FRAME_FLAG_CODECCONFIG; + ddl->input_frame.frm_trans_end = + !need_reconfig; + 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); + } else { + if (decoder->codec.codec == + VCD_CODEC_VC1_RCV) { + vidc_sm_set_start_byte_number( + &ddl->shared_mem + [ddl->command_channel], + seq_hdr_info.dec_frm_size); + } + } + if (need_reconfig) { + struct ddl_frame_data_tag *payload = + &ddl->input_frame; + u32 payload_size = + sizeof(struct ddl_frame_data_tag); + decoder->client_frame_size = + decoder->frame_size; + decoder->client_output_buf_req = + decoder->actual_output_buf_req; + decoder->client_input_buf_req = + decoder->actual_input_buf_req; + if (seq_hdr_only_frame) { + payload = NULL; + payload_size = 0; + } + DDL_MSG_HIGH("%s : sending port reconfig\n", + __func__); + ddl_context->ddl_callback( + VCD_EVT_IND_OUTPUT_RECONFIG, + VCD_S_SUCCESS, payload, + payload_size, (u32 *) ddl, + ddl->client_data); + } + if (!need_reconfig && !seq_hdr_only_frame) { + if (!ddl_vidc_decode_set_buffers(ddl)) + process_further = false; + else { + DDL_MSG_ERROR("ddl_vidc_decode_set_" + "buffers failed"); + ddl_client_fatal_cb(ddl); + } + } else + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } + } + return process_further; +} + +static u32 ddl_sequence_done_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id, ret; + + 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) { + DDL_MSG_ERROR("UNKWN_SEQ_DONE"); + ret = true; + } else { + if (ddl->decoding) + ret = ddl_decoder_seq_done_callback(ddl_context, + ddl); + else + ret = ddl_encoder_seq_done_callback(ddl_context, + ddl); + } + return ret; +} + +static u32 ddl_dpb_buffers_set_done_callback( + struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id, ret_status = true; + + DDL_MSG_MED("ddl_dpb_buffers_set_done_callback"); + vidc_1080p_get_returned_channel_inst_id(&channel_inst_id); + vidc_1080p_clear_returned_channel_inst_id(); + ddl = ddl_get_current_ddl_client_for_command(ddl_context, + DDL_CMD_DECODE_SET_DPB); + if (ddl) { + ddl->cmd_state = DDL_CMD_INVALID; + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPBDONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-DPBDONE"); + ddl_client_fatal_cb(ddl); + } else { + DDL_MSG_LOW("INTR_DPBDONE"); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_FRAME", + ddl_get_state_string(ddl->client_state)); + ddl_calc_core_proc_time(__func__, DEC_OP_TIME, ddl); + ddl_reset_core_time_variables(DEC_OP_TIME); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; + ddl_vidc_decode_frame_run(ddl); + ret_status = false; + } + } + return ret_status; +} + +static void ddl_encoder_frame_run_callback( + 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 = + &(ddl->output_frame.vcd_frm); + u32 eos_present = false; + + 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"); + ddl_client_fatal_cb(ddl); + } else { + ddl_calc_core_proc_time(__func__, ENC_OP_TIME, ddl); + DDL_MSG_LOW("ENC_FRM_RUN_DONE"); + ddl->cmd_state = DDL_CMD_INVALID; + vidc_1080p_get_encode_frame_info(&encoder->enc_frame_info); + + 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)) { + if (encoder->slice_delivery_info.enable) { + if (encoder->enc_frame_info.enc_frame == + VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED) + ddl_handle_enc_skipframe_slice_mode( + ddl, eos_present); + else + 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) { + if ((ddl->extra_output_buf_count < 0) || + (ddl->extra_output_buf_count > + encoder->i_period.b_frames)) { + DDL_MSG_ERROR("Invalid B frame output" + "buffer index"); + } else { + struct vidc_1080p_enc_frame_start_param + enc_param; + ddl->output_frame = ddl->\ + extra_output_frame[ddl->\ + extra_output_buf_count]; + ddl->\ + extra_output_buf_count--; + output_frame = + &ddl->output_frame.\ + vcd_frm; + memset(&enc_param, 0, + sizeof(enc_param)); + 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.stream_buffer_addr_offset = + DDL_OFFSET(ddl_context->\ + dram_base_a.\ + align_physical_addr, + output_frame->physical); + enc_param.stream_buffer_size = + encoder->client_output_buf_req.sz; + enc_param.encode = + VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA; + ddl->cmd_state = DDL_CMD_ENCODE_FRAME; + ddl_context->vidc_encode_frame_start + [ddl->command_channel] + (&enc_param); + } + } 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( + ddl->client_state)); + ddl->client_state = + DDL_CLIENT_WAIT_FOR_FRAME; + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } + } else { + ddl_context->ddl_callback( + VCD_EVT_RESP_TRANSACTION_PENDING, + VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, + ddl->client_data); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_FRAME", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } + } +} + +static void get_dec_status(struct ddl_client_context *ddl, + struct vidc_1080p_dec_disp_info *dec_disp_info, + u32 output_order, u32 *status, u32 *rsl_chg) +{ + if (output_order == VCD_DEC_ORDER_DISPLAY) { + vidc_1080p_get_display_frame_result(dec_disp_info); + *status = dec_disp_info->display_status; + *rsl_chg = dec_disp_info->disp_resl_change; + } else { + vidc_1080p_get_decode_frame_result(dec_disp_info); + vidc_sm_get_dec_order_resl( + &ddl->shared_mem[ddl->command_channel], + &dec_disp_info->img_size_x, + &dec_disp_info->img_size_y); + *status = dec_disp_info->decode_status; + *rsl_chg = dec_disp_info->dec_resl_change; + } +} + +static u32 ddl_decoder_frame_run_callback(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + u32 callback_end = false, ret_status = false; + u32 eos_present = false, rsl_chg; + u32 more_field_needed, extended_rsl_chg; + enum vidc_1080p_display_status disp_status; + DDL_MSG_MED("ddl_decoder_frame_run_callback"); + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-DECFRMRUN"); + ddl_client_fatal_cb(ddl); + ret_status = true; + } else { + DDL_MSG_LOW("DEC_FRM_RUN_DONE"); + ddl->cmd_state = DDL_CMD_INVALID; + get_dec_status(ddl, &ddl->codec_data.decoder.dec_disp_info, + ddl->codec_data.decoder.output_order, + &disp_status, &rsl_chg); + + vidc_sm_get_extended_decode_status( + &ddl->shared_mem[ddl->command_channel], + &more_field_needed, + &extended_rsl_chg); + decoder->field_needed_for_prev_ip = + more_field_needed; + decoder->prev_ip_frm_tag = + ddl->input_frame.vcd_frm.ip_frm_tag; + + ddl_vidc_decode_dynamic_property(ddl, false); + if (rsl_chg != DDL_RESL_CHANGE_NO_CHANGE) { + ddl_handle_reconfig(rsl_chg, ddl); + ret_status = false; + } else { + if ((VCD_FRAME_FLAG_EOS & + ddl->input_frame.vcd_frm.flags)) { + callback_end = false; + eos_present = true; + } + if (disp_status == + VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY || + disp_status == + VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY) { + if (!eos_present) + callback_end = + (disp_status == + VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY); + ddl_decoder_input_done_callback(ddl, + callback_end); + } + if (disp_status == + VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY || + disp_status == + VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY) { + if (!eos_present) + callback_end = (disp_status == + VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY); + if (ddl_decoder_output_done_callback( + ddl, callback_end)) + ret_status = true; + } + if (!ret_status) { + if (disp_status == + VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY + || disp_status == + VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY || + disp_status == + VIDC_1080P_DISPLAY_STATUS_NOOP) { + ddl_vidc_decode_frame_run(ddl); + } else if (eos_present) + ddl_vidc_decode_eos_run(ddl); + else { + ddl->client_state = + DDL_CLIENT_WAIT_FOR_FRAME; + ddl_release_command_channel(ddl_context, + ddl->command_channel); + ret_status = true; + } + } + } + } + return ret_status; +} + +static u32 ddl_eos_frame_done_callback( + struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct ddl_mask *dpb_mask = &decoder->dpb_mask; + u32 ret_status = true, rsl_chg, more_field_needed; + enum vidc_1080p_display_status disp_status; + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-EOSFRMRUN"); + ddl_client_fatal_cb(ddl); + } else { + DDL_MSG_LOW("EOS_FRM_RUN_DONE"); + ddl->cmd_state = DDL_CMD_INVALID; + get_dec_status(ddl, &ddl->codec_data.decoder.dec_disp_info, + ddl->codec_data.decoder.output_order, + &disp_status, &rsl_chg); + vidc_sm_get_extended_decode_status( + &ddl->shared_mem[ddl->command_channel], + &more_field_needed, &rsl_chg); + + decoder->field_needed_for_prev_ip = + more_field_needed; + decoder->prev_ip_frm_tag = + ddl->input_frame.vcd_frm.ip_frm_tag; + ddl_vidc_decode_dynamic_property(ddl, false); + if (disp_status == + VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY) { + if (rsl_chg) { + decoder->header_in_start = false; + decoder->decode_config.sequence_header = + ddl->input_frame.vcd_frm.physical; + decoder->decode_config.sequence_header_len = + ddl->input_frame.vcd_frm.data_len; + decoder->reconfig_detected = false; + ddl_vidc_decode_init_codec(ddl); + ret_status = false; + } else + ddl_decoder_eos_done_callback(ddl); + } else { + struct vidc_1080p_dec_frame_start_param dec_param; + ret_status = false; + if (disp_status == + VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY) { + if (ddl_decoder_output_done_callback( + ddl, false)) + ret_status = true; + } else if (disp_status != + VIDC_1080P_DISPLAY_STATUS_NOOP) + DDL_MSG_ERROR("EOS-STATE-CRITICAL-" + "WRONG-DISP-STATUS"); + if (!ret_status) { + ddl_decoder_dpb_transact(decoder, NULL, + DDL_DPB_OP_SET_MASK); + ddl->cmd_state = DDL_CMD_EOS; + + memset(&dec_param, 0, sizeof(dec_param)); + + dec_param.cmd_seq_num = + ++ddl_context->cmd_seq_num; + dec_param.inst_id = ddl->instance_id; + dec_param.shared_mem_addr_offset = + DDL_ADDR_OFFSET( + ddl_context->dram_base_a, + ddl->shared_mem[ddl->command_channel]); + dec_param.release_dpb_bit_mask = + dpb_mask->hw_mask; + dec_param.decode = + (decoder->reconfig_detected) ?\ + VIDC_1080P_DEC_TYPE_FRAME_DATA :\ + VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA; + + ddl_context->vidc_decode_frame_start[ddl->\ + command_channel](&dec_param); + } + } + } + return ret_status; +} + +static u32 ddl_frame_run_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id; + u32 return_status = true; + + 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) { + if (ddl_context->pix_cache_enable) { + struct vidc_1080P_pix_cache_statistics + pixel_cache_stats; + vidc_pix_cache_get_statistics(&pixel_cache_stats); + + DDL_MSG_HIGH(" pixel cache hits = %d," + "miss = %d", pixel_cache_stats.access_hit, + pixel_cache_stats.access_miss); + DDL_MSG_HIGH(" pixel cache core reqs = %d," + "axi reqs = %d", pixel_cache_stats.core_req, + pixel_cache_stats.axi_req); + DDL_MSG_HIGH(" pixel cache core bus stats = %d," + "axi bus stats = %d", pixel_cache_stats.core_bus, + pixel_cache_stats.axi_bus); + } + + if (ddl->cmd_state == DDL_CMD_DECODE_FRAME) + return_status = ddl_decoder_frame_run_callback(ddl); + else if (ddl->cmd_state == DDL_CMD_ENCODE_FRAME) + ddl_encoder_frame_run_callback(ddl); + else if (ddl->cmd_state == DDL_CMD_EOS) + return_status = ddl_eos_frame_done_callback(ddl); + else { + DDL_MSG_ERROR("UNKWN_FRAME_DONE"); + return_status = false; + } + } else + return_status = false; + + return return_status; +} + +static void ddl_channel_end_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + + DDL_MSG_MED("ddl_channel_end_callback"); + ddl = ddl_get_current_ddl_client_for_command(ddl_context, + DDL_CMD_CHANNEL_END); + if (ddl) { + ddl->cmd_state = DDL_CMD_INVALID; + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHEND)) { + DDL_MSG_LOW("STATE-CRITICAL-CHEND"); + } else { + DDL_MSG_LOW("CH_END_DONE"); + ddl_release_client_internal_buffers(ddl); + ddl_context->ddl_callback(VCD_EVT_RESP_STOP, + VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, + ddl->client_data); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_OPEN", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_OPEN; + } + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } +} + +static void ddl_edfu_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id; + + DDL_MSG_MED("ddl_edfu_callback"); + 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) { + if (ddl->cmd_state != DDL_CMD_ENCODE_FRAME) + DDL_MSG_LOW("UNKWN_EDFU"); + } +} + +static void ddl_encoder_eos_done(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id; + + 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); + DDL_MSG_LOW("ddl_encoder_eos_done\n"); + if (ddl == NULL) { + DDL_MSG_ERROR("NO_DDL_CONTEXT"); + } else { + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-EOSFRMDONE"); + ddl_client_fatal_cb(ddl); + } else { + struct ddl_encoder_data *encoder = + &(ddl->codec_data.encoder); + vidc_1080p_get_encode_frame_info( + &encoder->enc_frame_info); + 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_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_FRAME", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; + DDL_MSG_LOW("eos_done"); + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, 0, + (u32 *)ddl, ddl->client_data); + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } + } +} + +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) +{ + u32 return_status = true; + switch (intr_status) { + case VIDC_1080P_RISC2HOST_CMD_OPEN_CH_RET: + return_status = ddl_channel_set_callback(ddl_context, + ddl_context->response_cmd_ch_id); + break; + case VIDC_1080P_RISC2HOST_CMD_CLOSE_CH_RET: + ddl_channel_end_callback(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_SEQ_DONE_RET: + return_status = ddl_sequence_done_callback(ddl_context); + break; + 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); + break; + case VIDC_1080P_RISC2HOST_CMD_FW_STATUS_RET: + ddl_fw_status_done_callback(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_EDFU_INT_RET: + ddl_edfu_callback(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_ENC_COMPLETE_RET: + ddl_encoder_eos_done(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_ERROR_RET: + DDL_MSG_ERROR("CMD_ERROR_INTR"); + return_status = ddl_handle_core_errors(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_INIT_BUFFERS_RET: + return_status = + ddl_dpb_buffers_set_done_callback(ddl_context); + break; + default: + DDL_MSG_LOW("UNKWN_INTR"); + break; + } + return return_status; +} + +void ddl_read_and_clear_interrupt(void) +{ + 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) { + DDL_MSG_LOW("SPURIOUS_INTERRUPT"); + } else { + 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_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; + } +} + +u32 ddl_process_core_response(void) +{ + struct ddl_context *ddl_context; + struct ddl_hw_interface *ddl_hw_response; + u32 status = false; + + ddl_context = ddl_get_context(); + if (!ddl_context->core_virtual_base_addr) { + DDL_MSG_LOW("SPURIOUS_INTERRUPT"); + return status; + } + ddl_hw_response = &ddl_context->ddl_hw_response; + status = ddl_process_intr_status(ddl_context, ddl_hw_response->cmd); + if (ddl_context->interrupt_clr) + (*ddl_context->interrupt_clr)(); + return status; +} + +static void ddl_decoder_input_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vidc_1080p_dec_disp_info *dec_disp_info = + &decoder->dec_disp_info; + struct vcd_frame_data *input_vcd_frm = &(ddl->input_frame.vcd_frm); + u32 is_interlaced; + vidc_1080p_get_decoded_frame_size( + &dec_disp_info->input_bytes_consumed); + vidc_sm_set_start_byte_number(&ddl->shared_mem + [ddl->command_channel], 0); + vidc_1080p_get_decode_frame(&dec_disp_info->input_frame); + ddl_get_decoded_frame(input_vcd_frm, + dec_disp_info->input_frame); + vidc_1080p_get_decode_frame_result(dec_disp_info); + is_interlaced = (dec_disp_info->decode_coding == + VIDC_1080P_DISPLAY_CODING_INTERLACED); + if (decoder->output_order == VCD_DEC_ORDER_DECODE) { + dec_disp_info->tag_bottom = is_interlaced ? + dec_disp_info->tag_top : + VCD_FRAMETAG_INVALID; + dec_disp_info->tag_top = input_vcd_frm->ip_frm_tag; + } + input_vcd_frm->interlaced = is_interlaced; + input_vcd_frm->offset += dec_disp_info->input_bytes_consumed; + input_vcd_frm->data_len -= dec_disp_info->input_bytes_consumed; + ddl->input_frame.frm_trans_end = frame_transact_end; + ddl_calc_core_proc_time(__func__, DEC_IP_TIME, ddl); + 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); +} + +static void get_dec_op_done_data(struct vidc_1080p_dec_disp_info *dec_disp_info, + u32 output_order, u8 **physical, u32 *is_interlaced) +{ + enum vidc_1080p_display_coding disp_coding; + if (output_order == VCD_DEC_ORDER_DECODE) { + *physical = (u8 *)(dec_disp_info->decode_y_addr << 11); + disp_coding = dec_disp_info->decode_coding; + } else { + *physical = (u8 *)(dec_disp_info->display_y_addr << 11); + disp_coding = dec_disp_info->display_coding; + } + *is_interlaced = (disp_coding == + VIDC_1080P_DISPLAY_CODING_INTERLACED); +} + +static void get_dec_op_done_crop(u32 output_order, + struct vidc_1080p_dec_disp_info *dec_disp_info, + struct vcd_frame_rect *crop_data, + struct vcd_property_frame_size *op_frame_sz, + struct vcd_property_frame_size *frame_sz, + struct ddl_buf_addr *shared_mem) +{ + u32 crop_exists = + (output_order == VCD_DEC_ORDER_DECODE) ? + dec_disp_info->dec_crop_exists : + dec_disp_info->disp_crop_exists; + crop_data->left = 0; + crop_data->top = 0; + crop_data->right = dec_disp_info->img_size_x; + crop_data->bottom = dec_disp_info->img_size_y; + op_frame_sz->width = dec_disp_info->img_size_x; + op_frame_sz->height = dec_disp_info->img_size_y; + ddl_calculate_stride(op_frame_sz, false); + op_frame_sz->stride = DDL_ALIGN(op_frame_sz->width, + DDL_TILE_ALIGN_WIDTH); + op_frame_sz->scan_lines = DDL_ALIGN(op_frame_sz->height, + DDL_TILE_ALIGN_HEIGHT); + DDL_MSG_LOW("%s img_size_x = %u img_size_y = %u\n", + __func__, dec_disp_info->img_size_x, + dec_disp_info->img_size_y); + if (crop_exists) { + if (output_order == VCD_DEC_ORDER_DECODE) + vidc_sm_get_dec_order_crop_info(shared_mem, + &dec_disp_info->crop_left_offset, + &dec_disp_info->crop_right_offset, + &dec_disp_info->crop_top_offset, + &dec_disp_info->crop_bottom_offset); + else + vidc_sm_get_crop_info(shared_mem, + &dec_disp_info->crop_left_offset, + &dec_disp_info->crop_right_offset, + &dec_disp_info->crop_top_offset, + &dec_disp_info->crop_bottom_offset); + crop_data->left = dec_disp_info->crop_left_offset; + crop_data->top = dec_disp_info->crop_top_offset; + crop_data->right -= dec_disp_info->crop_right_offset; + crop_data->bottom -= dec_disp_info->crop_bottom_offset; + op_frame_sz->width = crop_data->right - crop_data->left; + op_frame_sz->height = crop_data->bottom - crop_data->top; + } +} + +static u32 ddl_decoder_output_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vidc_1080p_dec_disp_info *dec_disp_info = + &(decoder->dec_disp_info); + struct ddl_frame_data_tag *output_frame = &(ddl->output_frame); + struct vcd_frame_data *output_vcd_frm = &(output_frame->vcd_frm); + u32 vcd_status, free_luma_dpb = 0, disp_pict = 0, is_interlaced; + get_dec_op_done_data(dec_disp_info, decoder->output_order, + &output_vcd_frm->physical, &is_interlaced); + decoder->progressive_only = !(is_interlaced); + output_vcd_frm->frame = VCD_FRAME_YUV; + if (decoder->codec.codec == VCD_CODEC_MPEG4 || + decoder->codec.codec == VCD_CODEC_VC1 || + decoder->codec.codec == VCD_CODEC_VC1_RCV || + (decoder->codec.codec >= VCD_CODEC_DIVX_3 && + decoder->codec.codec <= VCD_CODEC_XVID)) { + vidc_sm_get_displayed_picture_frame(&ddl->shared_mem + [ddl->command_channel], &disp_pict); + if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) { + if (!disp_pict) { + output_vcd_frm->frame = VCD_FRAME_NOTCODED; + vidc_sm_get_available_luma_dpb_address( + &ddl->shared_mem[ddl->command_channel], + &free_luma_dpb); + } + } else { + if (dec_disp_info->input_frame == + VIDC_1080P_DECODE_FRAMETYPE_NOT_CODED) { + output_vcd_frm->frame = VCD_FRAME_NOTCODED; + vidc_sm_get_available_luma_dpb_dec_order_address( + &ddl->shared_mem[ddl->command_channel], + &free_luma_dpb); + } + } + if (free_luma_dpb) + output_vcd_frm->physical = + (u8 *)(free_luma_dpb << 11); + } + vcd_status = ddl_decoder_dpb_transact(decoder, output_frame, + DDL_DPB_OP_MARK_BUSY); + if (vcd_status) { + DDL_MSG_ERROR("CORRUPTED_OUTPUT_BUFFER_ADDRESS"); + ddl_hw_fatal_cb(ddl); + } else { + vidc_sm_get_metadata_status(&ddl->shared_mem + [ddl->command_channel], + &decoder->meta_data_exists); + if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) { + vidc_sm_get_frame_tags(&ddl->shared_mem + [ddl->command_channel], + &dec_disp_info->tag_top, + &dec_disp_info->tag_bottom); + if (dec_disp_info->display_correct == + VIDC_1080P_DECODE_NOT_CORRECT || + dec_disp_info->display_correct == + VIDC_1080P_DECODE_APPROX_CORRECT) + output_vcd_frm->flags |= + VCD_FRAME_FLAG_DATACORRUPT; + } else { + if (dec_disp_info->decode_correct == + VIDC_1080P_DECODE_NOT_CORRECT || + dec_disp_info->decode_correct == + VIDC_1080P_DECODE_APPROX_CORRECT) + output_vcd_frm->flags |= + VCD_FRAME_FLAG_DATACORRUPT; + } + output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top; + vidc_sm_get_picture_times(&ddl->shared_mem + [ddl->command_channel], + &dec_disp_info->pic_time_top, + &dec_disp_info->pic_time_bottom); + get_dec_op_done_crop(decoder->output_order, dec_disp_info, + &output_vcd_frm->dec_op_prop.disp_frm, + &output_vcd_frm->dec_op_prop.frm_size, + &decoder->frame_size, + &ddl->shared_mem[ddl_context->response_cmd_ch_id]); + if ((decoder->cont_mode) && + ((output_vcd_frm->dec_op_prop.frm_size.width != + decoder->frame_size.width) || + (output_vcd_frm->dec_op_prop.frm_size.height != + decoder->frame_size.height) || + (decoder->frame_size.width != + decoder->client_frame_size.width) || + (decoder->frame_size.height != + decoder->client_frame_size.height))) { + DDL_MSG_LOW("%s o/p width = %u o/p height = %u" + "decoder width = %u decoder height = %u ", + __func__, + output_vcd_frm->dec_op_prop.frm_size.width, + output_vcd_frm->dec_op_prop.frm_size.height, + decoder->frame_size.width, + decoder->frame_size.height); + DDL_MSG_HIGH("%s Sending INFO_OP_RECONFIG event\n", + __func__); + ddl_context->ddl_callback( + VCD_EVT_IND_INFO_OUTPUT_RECONFIG, + VCD_S_SUCCESS, NULL, 0, + (u32 *)ddl, + ddl->client_data); + decoder->frame_size = + output_vcd_frm->dec_op_prop.frm_size; + decoder->client_frame_size = decoder->frame_size; + decoder->y_cb_cr_size = + ddl_get_yuv_buffer_size(&decoder->frame_size, + &decoder->buf_format, + (!decoder->progressive_only), + decoder->codec.codec, NULL); + decoder->actual_output_buf_req.sz = + decoder->y_cb_cr_size + decoder->suffix; + decoder->min_output_buf_req = + decoder->actual_output_buf_req; + DDL_MSG_LOW("%s y_cb_cr_size = %u " + "actual_output_buf_req.sz = %u" + "min_output_buf_req.sz = %u\n", + decoder->y_cb_cr_size, + decoder->actual_output_buf_req.sz, + decoder->min_output_buf_req.sz); + vidc_sm_set_chroma_addr_change( + &ddl->shared_mem[ddl->command_channel], + false); + } + output_vcd_frm->interlaced = is_interlaced; + output_vcd_frm->intrlcd_ip_frm_tag = + (!is_interlaced || !dec_disp_info->tag_bottom) ? + VCD_FRAMETAG_INVALID : dec_disp_info->tag_bottom; + output_vcd_frm->offset = 0; + output_vcd_frm->data_len = decoder->y_cb_cr_size; + if (free_luma_dpb) { + output_vcd_frm->data_len = 0; + output_vcd_frm->flags |= VCD_FRAME_FLAG_DECODEONLY; + } + output_vcd_frm->flags |= VCD_FRAME_FLAG_ENDOFFRAME; + output_frame->frm_trans_end = frame_transact_end; + ddl_calc_core_proc_time(__func__, DEC_OP_TIME, ddl); + ddl_process_decoder_metadata(ddl); + vidc_sm_get_aspect_ratio_info( + &ddl->shared_mem[ddl->command_channel], + &output_vcd_frm->aspect_ratio_info); + ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, + vcd_status, output_frame, + sizeof(struct ddl_frame_data_tag), + (u32 *)ddl, ddl->client_data); + } + return vcd_status; +} + +static u32 ddl_get_decoded_frame(struct vcd_frame_data *frame, + enum vidc_1080p_decode_frame frame_type) +{ + u32 status = true; + + switch (frame_type) { + case VIDC_1080P_DECODE_FRAMETYPE_I: + frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; + frame->frame = VCD_FRAME_I; + break; + case VIDC_1080P_DECODE_FRAMETYPE_P: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_DECODE_FRAMETYPE_B: + frame->frame = VCD_FRAME_B; + break; + case VIDC_1080P_DECODE_FRAMETYPE_NOT_CODED: + frame->frame = VCD_FRAME_NOTCODED; + frame->data_len = 0; + DDL_MSG_HIGH("DDL_INFO:Decoder:NotCodedFrame>"); + break; + case VIDC_1080P_DECODE_FRAMETYPE_OTHERS: + frame->frame = VCD_FRAME_YUV; + break; + case VIDC_1080P_DECODE_FRAMETYPE_32BIT: + default: + DDL_MSG_ERROR("UNKNOWN-FRAMETYPE"); + status = false; + break; + } + return status; +} + +static u32 ddl_get_encoded_frame(struct vcd_frame_data *frame, + enum vcd_codec codec, + enum vidc_1080p_encode_frame frame_type) +{ + u32 status = true; + + if (codec == VCD_CODEC_H264) { + switch (frame_type) { + case VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_I: + frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; + frame->frame = VCD_FRAME_I; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_P: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_B: + frame->frame = VCD_FRAME_B; + frame->flags |= VCD_FRAME_FLAG_BFRAME; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED: + frame->frame = VCD_FRAME_NOTCODED; + frame->data_len = 0; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_OTHERS: + DDL_MSG_LOW("FRAMETYPE-OTHERS"); + break; + case VIDC_1080P_ENCODE_FRAMETYPE_32BIT: + default: + DDL_MSG_LOW("UNKNOWN-FRAMETYPE"); + status = false; + break; + } + } else if (codec == VCD_CODEC_MPEG4) { + switch (frame_type) { + case VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_I: + frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; + frame->frame = VCD_FRAME_I; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_P: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_B: + frame->frame = VCD_FRAME_B; + frame->flags |= VCD_FRAME_FLAG_BFRAME; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED: + frame->frame = VCD_FRAME_NOTCODED; + frame->data_len = 0; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_OTHERS: + DDL_MSG_LOW("FRAMETYPE-OTHERS"); + break; + case VIDC_1080P_ENCODE_FRAMETYPE_32BIT: + default: + DDL_MSG_LOW("UNKNOWN-FRAMETYPE"); + status = false; + break; + } + } else if (codec == VCD_CODEC_H263) { + switch (frame_type) { + case VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_I: + frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; + frame->frame = VCD_FRAME_I; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_P: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED: + frame->frame = VCD_FRAME_NOTCODED; + frame->data_len = 0; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_OTHERS: + DDL_MSG_LOW("FRAMETYPE-OTHERS"); + break; + case VIDC_1080P_ENCODE_FRAMETYPE_32BIT: + default: + DDL_MSG_LOW("UNKNOWN-FRAMETYPE"); + status = false; + break; + } + } else + status = false; + DDL_MSG_HIGH("Enc Frame Type %u", (u32)frame->frame); + return status; +} + +static void ddl_get_mpeg4_dec_level(enum vcd_codec_level *level, + u32 level_codec, enum vcd_codec_profile mpeg4_profile) +{ + switch (level_codec) { + case VIDC_1080P_MPEG4_LEVEL0: + *level = VCD_LEVEL_MPEG4_0; + break; + case VIDC_1080P_MPEG4_LEVEL0b: + *level = VCD_LEVEL_MPEG4_0b; + break; + case VIDC_1080P_MPEG4_LEVEL1: + *level = VCD_LEVEL_MPEG4_1; + break; + case VIDC_1080P_MPEG4_LEVEL2: + *level = VCD_LEVEL_MPEG4_2; + break; + case VIDC_1080P_MPEG4_LEVEL3: + *level = VCD_LEVEL_MPEG4_3; + break; + case VIDC_1080P_MPEG4_LEVEL3b: + if (mpeg4_profile == VCD_PROFILE_MPEG4_SP) + *level = VCD_LEVEL_MPEG4_7; + else + *level = VCD_LEVEL_MPEG4_3b; + break; + case VIDC_1080P_MPEG4_LEVEL4a: + *level = VCD_LEVEL_MPEG4_4a; + break; + case VIDC_1080P_MPEG4_LEVEL5: + *level = VCD_LEVEL_MPEG4_5; + break; + case VIDC_1080P_MPEG4_LEVEL6: + *level = VCD_LEVEL_MPEG4_6; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } +} + +static void ddl_get_h264_dec_level(enum vcd_codec_level *level, + u32 level_codec) +{ + switch (level_codec) { + case VIDC_1080P_H264_LEVEL1: + *level = VCD_LEVEL_H264_1; + break; + case VIDC_1080P_H264_LEVEL1b: + *level = VCD_LEVEL_H264_1b; + break; + case VIDC_1080P_H264_LEVEL1p1: + *level = VCD_LEVEL_H264_1p1; + break; + case VIDC_1080P_H264_LEVEL1p2: + *level = VCD_LEVEL_H264_1p2; + break; + case VIDC_1080P_H264_LEVEL1p3: + *level = VCD_LEVEL_H264_1p3; + break; + case VIDC_1080P_H264_LEVEL2: + *level = VCD_LEVEL_H264_2; + break; + case VIDC_1080P_H264_LEVEL2p1: + *level = VCD_LEVEL_H264_2p1; + break; + case VIDC_1080P_H264_LEVEL2p2: + *level = VCD_LEVEL_H264_2p2; + break; + case VIDC_1080P_H264_LEVEL3: + *level = VCD_LEVEL_H264_3; + break; + case VIDC_1080P_H264_LEVEL3p1: + *level = VCD_LEVEL_H264_3p1; + break; + case VIDC_1080P_H264_LEVEL3p2: + *level = VCD_LEVEL_H264_3p2; + break; + case VIDC_1080P_H264_LEVEL4: + *level = VCD_LEVEL_H264_4; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } +} + +static void ddl_get_h263_dec_level(enum vcd_codec_level *level, + u32 level_codec) +{ + switch (level_codec) { + case VIDC_1080P_H263_LEVEL10: + *level = VCD_LEVEL_H263_10; + break; + case VIDC_1080P_H263_LEVEL20: + *level = VCD_LEVEL_H263_20; + break; + case VIDC_1080P_H263_LEVEL30: + *level = VCD_LEVEL_H263_30; + break; + case VIDC_1080P_H263_LEVEL40: + *level = VCD_LEVEL_H263_40; + break; + case VIDC_1080P_H263_LEVEL45: + *level = VCD_LEVEL_H263_45; + break; + case VIDC_1080P_H263_LEVEL50: + *level = VCD_LEVEL_H263_50; + break; + case VIDC_1080P_H263_LEVEL60: + *level = VCD_LEVEL_H263_60; + break; + case VIDC_1080P_H263_LEVEL70: + *level = VCD_LEVEL_H263_70; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } +} + +static void ddl_get_vc1_dec_level(enum vcd_codec_level *level, + u32 level_codec, enum vcd_codec_profile vc1_profile) +{ + if (vc1_profile == VCD_PROFILE_VC1_ADVANCE) { + switch (level_codec) { + case VIDC_SM_LEVEL_VC1_ADV_0: + *level = VCD_LEVEL_VC1_A_0; + break; + case VIDC_SM_LEVEL_VC1_ADV_1: + *level = VCD_LEVEL_VC1_A_1; + break; + case VIDC_SM_LEVEL_VC1_ADV_2: + *level = VCD_LEVEL_VC1_A_2; + break; + case VIDC_SM_LEVEL_VC1_ADV_3: + *level = VCD_LEVEL_VC1_A_3; + break; + case VIDC_SM_LEVEL_VC1_ADV_4: + *level = VCD_LEVEL_VC1_A_4; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } + } else if (vc1_profile == VCD_PROFILE_VC1_MAIN) { + switch (level_codec) { + case VIDC_SM_LEVEL_VC1_LOW: + *level = VCD_LEVEL_VC1_M_LOW; + break; + case VIDC_SM_LEVEL_VC1_MEDIUM: + *level = VCD_LEVEL_VC1_M_MEDIUM; + break; + case VIDC_SM_LEVEL_VC1_HIGH: + *level = VCD_LEVEL_VC1_M_HIGH; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } + } else if (vc1_profile == VCD_PROFILE_VC1_SIMPLE) { + switch (level_codec) { + case VIDC_SM_LEVEL_VC1_LOW: + *level = VCD_LEVEL_VC1_S_LOW; + break; + case VIDC_SM_LEVEL_VC1_MEDIUM: + *level = VCD_LEVEL_VC1_S_MEDIUM; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } + } +} + +static void ddl_get_mpeg2_dec_level(enum vcd_codec_level *level, + u32 level_codec) +{ + switch (level_codec) { + case VIDC_SM_LEVEL_MPEG2_LOW: + *level = VCD_LEVEL_MPEG2_LOW; + break; + case VIDC_SM_LEVEL_MPEG2_MAIN: + *level = VCD_LEVEL_MPEG2_MAIN; + break; + case VIDC_SM_LEVEL_MPEG2_HIGH_1440: + *level = VCD_LEVEL_MPEG2_HIGH_14; + break; + case VIDC_SM_LEVEL_MPEG2_HIGH: + *level = VCD_LEVEL_MPEG2_HIGH; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } +} + +static void ddl_get_dec_profile_level(struct ddl_decoder_data *decoder, + u32 profile_codec, u32 level_codec) +{ + enum vcd_codec_profile profile = VCD_PROFILE_UNKNOWN; + enum vcd_codec_level level = VCD_LEVEL_UNKNOWN; + + switch (decoder->codec.codec) { + case VCD_CODEC_MPEG4: + case VCD_CODEC_XVID: + if (profile_codec == VIDC_SM_PROFILE_MPEG4_SIMPLE) + profile = VCD_PROFILE_MPEG4_SP; + else if (profile_codec == VIDC_SM_PROFILE_MPEG4_ADV_SIMPLE) + profile = VCD_PROFILE_MPEG4_ASP; + else + profile = VCD_PROFILE_UNKNOWN; + ddl_get_mpeg4_dec_level(&level, level_codec, profile); + break; + case VCD_CODEC_H264: + if (profile_codec == VIDC_SM_PROFILE_H264_BASELINE) + profile = VCD_PROFILE_H264_BASELINE; + else if (profile_codec == VIDC_SM_PROFILE_H264_MAIN) + profile = VCD_PROFILE_H264_MAIN; + else if (profile_codec == VIDC_SM_PROFILE_H264_HIGH) + profile = VCD_PROFILE_H264_HIGH; + else + profile = VCD_PROFILE_UNKNOWN; + ddl_get_h264_dec_level(&level, level_codec); + break; + case VCD_CODEC_H263: + if (profile_codec == VIDC_SM_PROFILE_H263_BASELINE) + profile = VCD_PROFILE_H263_BASELINE; + else + profile = VCD_PROFILE_UNKNOWN; + ddl_get_h263_dec_level(&level, level_codec); + break; + case VCD_CODEC_MPEG2: + if (profile_codec == VIDC_SM_PROFILE_MPEG2_MAIN) + profile = VCD_PROFILE_MPEG2_MAIN; + else if (profile_codec == VIDC_SM_PROFILE_MPEG2_SIMPLE) + profile = VCD_PROFILE_MPEG2_SIMPLE; + else + profile = VCD_PROFILE_UNKNOWN; + ddl_get_mpeg2_dec_level(&level, level_codec); + break; + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + if (profile_codec == VIDC_SM_PROFILE_VC1_SIMPLE) + profile = VCD_PROFILE_VC1_SIMPLE; + else if (profile_codec == VIDC_SM_PROFILE_VC1_MAIN) + profile = VCD_PROFILE_VC1_MAIN; + else if (profile_codec == VIDC_SM_PROFILE_VC1_ADVANCED) + profile = VCD_PROFILE_VC1_ADVANCE; + else + profile = VCD_PROFILE_UNKNOWN; + ddl_get_vc1_dec_level(&level, level_codec, profile); + break; + default: + if (!profile_codec) + profile = VCD_PROFILE_UNKNOWN; + if (!level) + level = VCD_LEVEL_UNKNOWN; + break; + } + decoder->profile.profile = profile; + decoder->level.level = level; +} + +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; + + 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 + ); + 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) output_frame->alloc_len, + ION_IOC_INV_CACHES); + } + 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 = 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); +} + +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); + + if (start_bfr_idx == 0) { + encoder->batch_frame.first_output_frame_tag = + output_frame->ip_frm_tag; + DDL_MSG_LOW("%s: first_output_frame_tag[0x%x]", + __func__, output_frame->ip_frm_tag); + if (!output_frame->ip_frm_tag) { + DDL_MSG_ERROR("%s: first_output_frame_tag "\ + "is zero", __func__); + } + } + if (output_frame->ip_frm_tag != + encoder->batch_frame.first_output_frame_tag) { + DDL_MSG_ERROR("%s: output_frame->ip_frm_tag[0x%x] is "\ + "not equal to the first_output_frame_tag[0x%x]\n", + __func__, output_frame->ip_frm_tag, + encoder->batch_frame.first_output_frame_tag); + output_frame->ip_frm_tag = + encoder->batch_frame.first_output_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); + + if (start_bfr_idx == 0) { + encoder->batch_frame.first_output_frame_tag = + output_frame->ip_frm_tag; + DDL_MSG_LOW("%s: first_output_frame_tag[0x%x]", + __func__, output_frame->ip_frm_tag); + if (!output_frame->ip_frm_tag) { + DDL_MSG_ERROR("%s: first_output_frame_tag "\ + "is zero", __func__); + } + } + if (output_frame->ip_frm_tag != + encoder->batch_frame.first_output_frame_tag) { + DDL_MSG_ERROR("%s: output_frame->ip_frm_tag[0x%x] is "\ + "not equal to the first_output_frame_tag[0x%x]\n", + __func__, output_frame->ip_frm_tag, + encoder->batch_frame.first_output_frame_tag); + output_frame->ip_frm_tag = + encoder->batch_frame.first_output_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); + } +} + +static void ddl_handle_enc_skipframe_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; + u32 index = 0; + DDL_MSG_HIGH("ddl_handle_enc_skipframe_slice_mode: frame skipped"); + vidc_sm_set_encoder_slice_batch_int_ctrl( + &ddl->shared_mem[ddl->command_channel], + 1); + for (index = 0; + index < encoder->batch_frame.num_output_frames; + index++) { + output_frame = + &(encoder->batch_frame.output_frame[index].vcd_frm); + DDL_MSG_MED("output buffer: vcd_frm = 0x%x " + "frmbfr(virtual) = 0x%x frmbfr(physical) = 0x%x", + (u32)output_frame, (u32)output_frame->virtual, + (u32)output_frame->physical); + vidc_sm_get_frame_tags( + &ddl->shared_mem[ddl->command_channel], + &output_frame->ip_frm_tag, + &bottom_frame_tag); + if (!output_frame->ip_frm_tag) { + DDL_MSG_ERROR("%s: output frame tag is zero", + __func__); + } + ddl_get_encoded_frame( + output_frame, + encoder->codec.codec, + encoder->enc_frame_info.enc_frame); + output_frame->data_len = 0; + ddl->output_frame.frm_trans_end = false; + if (encoder->batch_frame.num_output_frames == + (index + 1)) { + DDL_MSG_MED("last output bfr for skip frame, set EOF"); + output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME; + ddl_vidc_encode_dynamic_property(ddl, false); + if (eos_present) + ddl->output_frame.frm_trans_end = false; + else + ddl->output_frame.frm_trans_end = true; + } + 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 == + (index + 1)) { + ddl->input_frame.frm_trans_end = false; + input_buffer_address = + ddl_context->dram_base_a.physical_base_addr + + (encoder->enc_frame_info.enc_luma_address); + ddl_get_input_frame_from_pool(ddl, + input_buffer_address); + DDL_MSG_MED("InpBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x" + " frmbfr(physical) 0x%x", + (u32)&(ddl->input_frame.vcd_frm), + (u32)ddl->input_frame.vcd_frm.virtual, + (u32)ddl->input_frame.vcd_frm.physical); + 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_metadata.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c new file mode 100644 index 0000000000000000000000000000000000000000..aa28276160428edc0815307c1c5ef4e7ee9964cb --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c @@ -0,0 +1,508 @@ +/* Copyright (c) 2010, 2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "vcd_ddl.h" +#include "vcd_ddl_shared_mem.h" +#include "vcd_ddl_metadata.h" + +static u32 *ddl_metadata_hdr_entry(struct ddl_client_context *ddl, + u32 meta_data) +{ + u32 skip_words = 0; + u32 *buffer; + + if (ddl->decoding) { + buffer = (u32 *) ddl->codec_data.decoder.meta_data_input. + align_virtual_addr; + skip_words = 32 + 1; + buffer += skip_words; + switch (meta_data) { + default: + case VCD_METADATA_DATANONE: + skip_words = 0; + break; + case VCD_METADATA_QPARRAY: + skip_words = 3; + break; + case VCD_METADATA_CONCEALMB: + skip_words = 6; + break; + case VCD_METADATA_VC1: + skip_words = 9; + break; + case VCD_METADATA_SEI: + skip_words = 12; + break; + case VCD_METADATA_VUI: + skip_words = 15; + break; + case VCD_METADATA_PASSTHROUGH: + skip_words = 18; + break; + case VCD_METADATA_QCOMFILLER: + skip_words = 21; + break; + } + } else { + buffer = (u32 *) ddl->codec_data.encoder.meta_data_input. + align_virtual_addr; + skip_words = 2; + buffer += skip_words; + switch (meta_data) { + default: + case VCD_METADATA_DATANONE: + skip_words = 0; + break; + case VCD_METADATA_ENC_SLICE: + skip_words = 3; + break; + case VCD_METADATA_QCOMFILLER: + skip_words = 6; + break; + } + } + buffer += skip_words; + return buffer; +} + +void ddl_set_default_meta_data_hdr(struct ddl_client_context *ddl) +{ + struct ddl_buf_addr *main_buffer = + &ddl->ddl_context->metadata_shared_input; + struct ddl_buf_addr *client_buffer; + u32 *hdr_entry; + + if (ddl->decoding) + client_buffer = &(ddl->codec_data.decoder.meta_data_input); + else + client_buffer = &(ddl->codec_data.encoder.meta_data_input); + DDL_METADATA_CLIENT_INPUTBUF(main_buffer, client_buffer, + ddl->instance_id); + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QCOMFILLER); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_QCOMFILLER; + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_DATANONE); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_DATANONE; + if (ddl->decoding) { + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QPARRAY); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_QPARRAY; + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_CONCEALMB); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_CONCEALMB; + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_SEI); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_SEI; + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_VUI); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_VUI; + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_VC1); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_VC1; + hdr_entry = ddl_metadata_hdr_entry(ddl, + VCD_METADATA_PASSTHROUGH); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = + VCD_METADATA_PASSTHROUGH; + } else { + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_ENC_SLICE); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_ENC_SLICE; + } +} + +static u32 ddl_supported_metadata_flag(struct ddl_client_context *ddl) +{ + u32 flag = 0; + + if (ddl->decoding) { + enum vcd_codec codec = + ddl->codec_data.decoder.codec.codec; + + flag |= (VCD_METADATA_CONCEALMB | VCD_METADATA_PASSTHROUGH | + VCD_METADATA_QPARRAY); + if (codec == VCD_CODEC_H264) + flag |= (VCD_METADATA_SEI | VCD_METADATA_VUI); + else if (codec == VCD_CODEC_VC1 || + codec == VCD_CODEC_VC1_RCV) + flag |= VCD_METADATA_VC1; + } else + flag |= VCD_METADATA_ENC_SLICE; + return flag; +} + +void ddl_set_default_metadata_flag(struct ddl_client_context *ddl) +{ + if (ddl->decoding) + ddl->codec_data.decoder.meta_data_enable_flag = 0; + else + ddl->codec_data.encoder.meta_data_enable_flag = 0; +} + +void ddl_set_default_decoder_metadata_buffer_size(struct ddl_decoder_data + *decoder, struct vcd_property_frame_size *frame_size, + struct vcd_buffer_requirement *output_buf_req) +{ + u32 flag = decoder->meta_data_enable_flag; + u32 suffix = 0, size = 0; + + if (!flag) { + decoder->suffix = 0; + return; + } + if (flag & VCD_METADATA_QPARRAY) { + u32 num_of_mb = DDL_NO_OF_MB(frame_size->width, + frame_size->height); + + size = DDL_METADATA_HDR_SIZE; + size += num_of_mb; + DDL_METADATA_ALIGNSIZE(size); + suffix += size; + } + if (flag & VCD_METADATA_CONCEALMB) { + u32 num_of_mb = DDL_NO_OF_MB(frame_size->width, + frame_size->height); + size = DDL_METADATA_HDR_SIZE + (num_of_mb >> 3); + DDL_METADATA_ALIGNSIZE(size); + suffix += size; + } + if (flag & VCD_METADATA_VC1) { + size = DDL_METADATA_HDR_SIZE; + size += DDL_METADATA_VC1_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(size); + suffix += size; + } + if (flag & VCD_METADATA_SEI) { + size = DDL_METADATA_HDR_SIZE; + size += DDL_METADATA_SEI_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(size); + suffix += (size * DDL_METADATA_SEI_MAX); + } + if (flag & VCD_METADATA_VUI) { + size = DDL_METADATA_HDR_SIZE; + size += DDL_METADATA_VUI_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(size); + suffix += (size); + } + if (flag & VCD_METADATA_PASSTHROUGH) { + size = DDL_METADATA_HDR_SIZE; + size += DDL_METADATA_PASSTHROUGH_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(size); + suffix += (size); + } + size = DDL_METADATA_EXTRADATANONE_SIZE; + DDL_METADATA_ALIGNSIZE(size); + suffix += (size); + suffix += DDL_METADATA_EXTRAPAD_SIZE; + DDL_METADATA_ALIGNSIZE(suffix); + decoder->suffix = suffix; + output_buf_req->sz += suffix; + DDL_MSG_LOW("metadata output buf size : %d", suffix); +} + +void ddl_set_default_encoder_metadata_buffer_size(struct ddl_encoder_data + *encoder) +{ + u32 flag = encoder->meta_data_enable_flag; + u32 suffix = 0, size = 0; + + if (!flag) { + encoder->suffix = 0; + return; + } + if (flag & VCD_METADATA_ENC_SLICE) { + u32 num_of_mb = DDL_NO_OF_MB(encoder->frame_size.width, + encoder->frame_size.height); + size = DDL_METADATA_HDR_SIZE; + size += 4; + size += (num_of_mb << 3); + DDL_METADATA_ALIGNSIZE(size); + suffix += size; + } + size = DDL_METADATA_EXTRADATANONE_SIZE; + DDL_METADATA_ALIGNSIZE(size); + suffix += (size); + suffix += DDL_METADATA_EXTRAPAD_SIZE; + DDL_METADATA_ALIGNSIZE(suffix); + encoder->suffix = suffix; + encoder->output_buf_req.sz += suffix; + encoder->output_buf_req.sz = + DDL_ALIGN(encoder->output_buf_req.sz, DDL_KILO_BYTE(4)); +} + +u32 ddl_set_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + if (property_hdr->prop_id == VCD_I_METADATA_ENABLE) { + struct vcd_property_meta_data_enable *meta_data_enable = + (struct vcd_property_meta_data_enable *) property_value; + u32 *meta_data_enable_flag; + enum vcd_codec codec; + + if (ddl->decoding) { + meta_data_enable_flag = + &(ddl->codec_data.decoder.meta_data_enable_flag); + codec = ddl->codec_data.decoder.codec.codec; + } else { + meta_data_enable_flag = + &ddl->codec_data.encoder.meta_data_enable_flag; + codec = ddl->codec_data.encoder.codec.codec; + } + if (sizeof(struct vcd_property_meta_data_enable) == + property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && codec) { + u32 flag = ddl_supported_metadata_flag(ddl); + flag &= (meta_data_enable->meta_data_enable_flag); + if (flag) + flag |= DDL_METADATA_MANDATORY; + if (*meta_data_enable_flag != flag) { + *meta_data_enable_flag = flag; + if (ddl->decoding) + ddl_set_default_decoder_buffer_req( + &ddl->codec_data.decoder, true); + else + ddl_set_default_encoder_buffer_req( + &ddl->codec_data.encoder); + } + vcd_status = VCD_S_SUCCESS; + } + } else if (property_hdr->prop_id == VCD_I_METADATA_HEADER) { + struct vcd_property_metadata_hdr *hdr = + (struct vcd_property_metadata_hdr *) property_value; + + if (sizeof(struct vcd_property_metadata_hdr) == + property_hdr->sz) { + u32 flag = ddl_supported_metadata_flag(ddl); + + flag |= DDL_METADATA_MANDATORY; + flag &= hdr->meta_data_id; + if (!(flag & (flag - 1))) { + u32 *hdr_entry = ddl_metadata_hdr_entry(ddl, + flag); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = + hdr->version; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = + hdr->port_index; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = + hdr->type; + vcd_status = VCD_S_SUCCESS; + } + } + } + return vcd_status; +} + +u32 ddl_get_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + if (property_hdr->prop_id == VCD_I_METADATA_ENABLE && + sizeof(struct vcd_property_meta_data_enable) == + property_hdr->sz) { + struct vcd_property_meta_data_enable *meta_data_enable = + (struct vcd_property_meta_data_enable *) property_value; + + meta_data_enable->meta_data_enable_flag = + ((ddl->decoding) ? + (ddl->codec_data.decoder.meta_data_enable_flag) : + (ddl->codec_data.encoder.meta_data_enable_flag)); + vcd_status = VCD_S_SUCCESS; + } else if (property_hdr->prop_id == VCD_I_METADATA_HEADER && + sizeof(struct vcd_property_metadata_hdr) == + property_hdr->sz) { + struct vcd_property_metadata_hdr *hdr = + (struct vcd_property_metadata_hdr *) property_value; + u32 flag = ddl_supported_metadata_flag(ddl); + + flag |= DDL_METADATA_MANDATORY; + flag &= hdr->meta_data_id; + if (!(flag & (flag - 1))) { + u32 *hdr_entry = ddl_metadata_hdr_entry(ddl, flag); + hdr->version = + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX]; + hdr->port_index = + hdr_entry[DDL_METADATA_HDR_PORT_INDEX]; + hdr->type = hdr_entry[DDL_METADATA_HDR_TYPE_INDEX]; + vcd_status = VCD_S_SUCCESS; + } + } + return vcd_status; +} + +void ddl_vidc_metadata_enable(struct ddl_client_context *ddl) +{ + u32 flag, extradata_enable = false; + u32 qp_enable = false, concealed_mb_enable = false; + u32 vc1_param_enable = false, sei_nal_enable = false; + u32 vui_enable = false, enc_slice_size_enable = false; + + if (ddl->decoding) + flag = ddl->codec_data.decoder.meta_data_enable_flag; + else + flag = ddl->codec_data.encoder.meta_data_enable_flag; + if (flag) { + if (flag & VCD_METADATA_QPARRAY) + qp_enable = true; + if (flag & VCD_METADATA_CONCEALMB) + concealed_mb_enable = true; + if (flag & VCD_METADATA_VC1) + vc1_param_enable = true; + if (flag & VCD_METADATA_SEI) + sei_nal_enable = true; + if (flag & VCD_METADATA_VUI) + vui_enable = true; + if (flag & VCD_METADATA_ENC_SLICE) + enc_slice_size_enable = true; + if (flag & VCD_METADATA_PASSTHROUGH) + extradata_enable = true; + } + + DDL_MSG_LOW("metadata enable flag : %d", sei_nal_enable); + vidc_sm_set_metadata_enable(&ddl->shared_mem + [ddl->command_channel], extradata_enable, qp_enable, + concealed_mb_enable, vc1_param_enable, sei_nal_enable, + vui_enable, enc_slice_size_enable); +} + +u32 ddl_vidc_encode_set_metadata_output_buf(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &ddl->codec_data.encoder; + struct vcd_frame_data *stream = &ddl->output_frame.vcd_frm; + struct ddl_context *ddl_context; + u32 ext_buffer_end, hw_metadata_start; + u32 *buffer; + + ddl_context = ddl_get_context(); + ext_buffer_end = (u32) stream->physical + stream->alloc_len; + if (!encoder->meta_data_enable_flag) { + ext_buffer_end &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + return ext_buffer_end; + } + hw_metadata_start = (ext_buffer_end - encoder->suffix) & + ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + ext_buffer_end = (hw_metadata_start - 1) & + ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + buffer = (u32 *) encoder->meta_data_input.align_virtual_addr; + *buffer++ = encoder->suffix; + *buffer = DDL_OFFSET(ddl_context->dram_base_a.align_physical_addr, + hw_metadata_start); + encoder->meta_data_offset = hw_metadata_start - (u32) stream->physical; + return ext_buffer_end; +} + +void ddl_vidc_decode_set_metadata_output(struct ddl_decoder_data *decoder) +{ + struct ddl_context *ddl_context; + u32 loopc, yuv_size; + u32 *buffer; + + if (!decoder->meta_data_enable_flag) { + decoder->meta_data_offset = 0; + return; + } + ddl_context = ddl_get_context(); + yuv_size = ddl_get_yuv_buffer_size(&decoder->client_frame_size, + &decoder->buf_format, !decoder->progressive_only, + decoder->hdr.decoding, NULL); + 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 *) + DDL_OFFSET(ddl_context->dram_base_a. + align_physical_addr, decoder->dp_buf. + dec_pic_buffers[loopc].vcd_frm.physical)); + } +} + +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; + if (!encoder->meta_data_enable_flag) { + out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + if (!encoder->enc_frame_info.meta_data_exists) { + out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + 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) +{ + 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; + + if (!decoder->meta_data_enable_flag) { + output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + if (!decoder->meta_data_exists) { + output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + DDL_MSG_LOW("processing metadata for decoder"); + 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) { + 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); + } +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h new file mode 100644 index 0000000000000000000000000000000000000000..11283932a78d1a859c57baa41bea9a197bf9ee24 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h @@ -0,0 +1,66 @@ +/* Copyright (c) 2010, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VCD_DDL_METADATA_H_ +#define _VCD_DDL_METADATA_H_ + +#define DDL_MAX_DEC_METADATATYPE 8 +#define DDL_MAX_ENC_METADATATYPE 3 +#define DDL_METADATA_EXTRAPAD_SIZE 256 +#define DDL_METADATA_HDR_SIZE 20 +#define DDL_METADATA_EXTRADATANONE_SIZE 24 +#define DDL_METADATA_ALIGNSIZE(x) ((x) = (((x) + 0x7) & ~0x7)) +#define DDL_METADATA_MANDATORY \ + (VCD_METADATA_DATANONE | VCD_METADATA_QCOMFILLER) +#define DDL_METADATA_VC1_PAYLOAD_SIZE (38*4) +#define DDL_METADATA_SEI_PAYLOAD_SIZE 100 +#define DDL_METADATA_SEI_MAX 5 +#define DDL_METADATA_VUI_PAYLOAD_SIZE 256 +#define DDL_METADATA_PASSTHROUGH_PAYLOAD_SIZE 68 +#define DDL_METADATA_CLIENT_INPUTBUFSIZE 256 +#define DDL_METADATA_TOTAL_INPUTBUFSIZE \ + (DDL_METADATA_CLIENT_INPUTBUFSIZE * VCD_MAX_NO_CLIENT) + +#define DDL_METADATA_CLIENT_INPUTBUF(main_buffer, client_buffer,\ + channel_id) { \ + (client_buffer)->align_physical_addr = (u8 *) \ + ((u8 *)(main_buffer)->align_physical_addr + \ + (DDL_METADATA_CLIENT_INPUTBUFSIZE * channel_id)); \ + (client_buffer)->align_virtual_addr = (u8 *) \ + ((u8 *)(main_buffer)->align_virtual_addr + \ + (DDL_METADATA_CLIENT_INPUTBUFSIZE * channel_id)); \ + (client_buffer)->virtual_base_addr = 0; \ + } + +#define DDL_METADATA_HDR_VERSION_INDEX 0 +#define DDL_METADATA_HDR_PORT_INDEX 1 +#define DDL_METADATA_HDR_TYPE_INDEX 2 + +void ddl_set_default_meta_data_hdr(struct ddl_client_context *ddl); +u32 ddl_get_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value); +u32 ddl_set_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value); +void ddl_set_default_metadata_flag(struct ddl_client_context *ddl); +void ddl_set_default_decoder_metadata_buffer_size(struct ddl_decoder_data + *decoder, struct vcd_property_frame_size *frame_size, + struct vcd_buffer_requirement *output_buf_req); +void ddl_set_default_encoder_metadata_buffer_size( + struct ddl_encoder_data *encoder); +void ddl_vidc_metadata_enable(struct ddl_client_context *ddl); +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); +void ddl_process_encoder_metadata(struct ddl_client_context *ddl); +void ddl_process_decoder_metadata(struct ddl_client_context *ddl); + +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c new file mode 100644 index 0000000000000000000000000000000000000000..e1959a1ba3cb2b374aa846bb3176c3a91a9de20f --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c @@ -0,0 +1,2113 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "vcd_ddl.h" +#include "vcd_ddl_metadata.h" +#include "vcd_res_tracker_api.h" + +static u32 ddl_set_dec_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, void *property_value); +static u32 ddl_set_enc_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, void *property_value); +static u32 ddl_get_dec_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, void *property_value); +static u32 ddl_get_enc_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, void *property_value); +static u32 ddl_set_enc_dynamic_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value); +static void ddl_set_default_enc_property(struct ddl_client_context *ddl); +static void ddl_set_default_enc_profile( + struct ddl_encoder_data *encoder); +static void ddl_set_default_enc_level(struct ddl_encoder_data *encoder); +static void ddl_set_default_enc_vop_timing( + struct ddl_encoder_data *encoder); +static void ddl_set_default_enc_intra_period( + struct ddl_encoder_data *encoder); +static void ddl_set_default_enc_rc_params( + struct ddl_encoder_data *encoder); +static u32 ddl_valid_buffer_requirement( + struct vcd_buffer_requirement *original_buf_req, + struct vcd_buffer_requirement *req_buf_req); +static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *decoder); +static u32 ddl_set_dec_buffers(struct ddl_decoder_data *decoder, + struct ddl_property_dec_pic_buffers *dpb); + +u32 ddl_set_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + struct ddl_context *ddl_context; + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + u32 vcd_status; + + DDL_MSG_HIGH("ddl_set_property"); + if (!property_hdr || !property_value) { + DDL_MSG_ERROR("ddl_set_prop:Bad_argument"); + return VCD_ERR_ILLEGAL_PARM; + } + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_set_prop:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl) { + DDL_MSG_ERROR("ddl_set_prop:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (ddl->decoding) + vcd_status = ddl_set_dec_property(ddl, property_hdr, + property_value); + else + vcd_status = ddl_set_enc_property(ddl, property_hdr, + property_value); + if (vcd_status) + DDL_MSG_ERROR("ddl_set_prop:FAILED"); + return vcd_status; +} + +u32 ddl_get_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + struct ddl_context *ddl_context; + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + + DDL_MSG_HIGH("ddl_get_property"); + if (!property_hdr || !property_value) + return VCD_ERR_ILLEGAL_PARM; + if (property_hdr->prop_id == DDL_I_CAPABILITY) { + if (sizeof(struct ddl_property_capability) == + property_hdr->sz) { + struct ddl_property_capability *ddl_capability = + (struct ddl_property_capability *) + property_value; + + ddl_capability->max_num_client = VCD_MAX_NO_CLIENT; + ddl_capability->exclusive = VCD_COMMAND_EXCLUSIVE; + ddl_capability->frame_command_depth = + VCD_FRAME_COMMAND_DEPTH; + ddl_capability->general_command_depth = + VCD_GENEVIDC_COMMAND_DEPTH; + ddl_capability->ddl_time_out_in_ms = + DDL_HW_TIMEOUT_IN_MS; + vcd_status = VCD_S_SUCCESS; + } + return vcd_status; + } + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) + return VCD_ERR_ILLEGAL_OP; + if (!ddl) + return VCD_ERR_BAD_HANDLE; + if (ddl->decoding) + vcd_status = ddl_get_dec_property(ddl, property_hdr, + property_value); + else + vcd_status = ddl_get_enc_property(ddl, property_hdr, + property_value); + if (vcd_status) + DDL_MSG_ERROR("ddl_get_prop:FAILED"); + else + DDL_MSG_MED("ddl_get_prop:SUCCESS"); + return vcd_status; +} + +u32 ddl_decoder_ready_to_start(struct ddl_client_context *ddl, + struct vcd_sequence_hdr *header) +{ + struct ddl_decoder_data *decoder = + &(ddl->codec_data.decoder); + + if (!decoder->codec.codec) { + DDL_MSG_ERROR("ddl_dec_start_check:Codec_not_set"); + return false; + } + if ((!header) && (!decoder->client_frame_size.height || + !decoder->client_frame_size.width)) { + DDL_MSG_ERROR("ddl_dec_start_check:" + "Client_height_width_default"); + return false; + } + return true; +} + +u32 ddl_encoder_ready_to_start(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + + if (!encoder->codec.codec || !encoder->frame_size.height || + !encoder->frame_size.width || + !encoder->frame_rate.fps_denominator || + !encoder->frame_rate.fps_numerator || + !encoder->target_bit_rate.target_bitrate) + return false; + if (encoder->frame_rate.fps_numerator > + (encoder->frame_rate.fps_denominator * + encoder->vop_timing.vop_time_resolution)) { + DDL_MSG_ERROR("ResVsFrameRateFailed!"); + return false; + } + if (encoder->profile.profile == VCD_PROFILE_H264_BASELINE && + encoder->entropy_control.entropy_sel == VCD_ENTROPY_SEL_CABAC) { + DDL_MSG_ERROR("H264BaseLineCABAC!!"); + return false; + } + return true; +} + +static u32 ddl_set_dec_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + u32 vcd_status = VCD_ERR_ILLEGAL_PARM ; + + switch (property_hdr->prop_id) { + case DDL_I_DPB_RELEASE: + if ((sizeof(struct ddl_frame_data_tag) == + property_hdr->sz) && + (decoder->dp_buf.no_of_dec_pic_buf)) + vcd_status = ddl_decoder_dpb_transact(decoder, + (struct ddl_frame_data_tag *) + property_value, DDL_DPB_OP_MARK_FREE); + break; + case DDL_I_DPB: + { + struct ddl_property_dec_pic_buffers *dpb = + (struct ddl_property_dec_pic_buffers *) property_value; + + if ((sizeof(struct ddl_property_dec_pic_buffers) == + property_hdr->sz) && + (DDLCLIENT_STATE_IS(ddl, + DDL_CLIENT_WAIT_FOR_INITCODEC) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) && + (dpb->no_of_dec_pic_buf == + decoder->client_output_buf_req.actual_count)) + vcd_status = ddl_set_dec_buffers(decoder, dpb); + } + break; + case DDL_I_REQ_OUTPUT_FLUSH: + if (sizeof(u32) == property_hdr->sz) { + decoder->dynamic_prop_change |= + DDL_DEC_REQ_OUTPUT_FLUSH; + decoder->dpb_mask.client_mask = 0; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_INPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *)property_value; + + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && + (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)) && + (ddl_valid_buffer_requirement( + &decoder->min_input_buf_req, buffer_req))) { + decoder->client_input_buf_req = *buffer_req; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case DDL_I_OUTPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *)property_value; + + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && + (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)) && + (ddl_valid_buffer_requirement( + &decoder->min_output_buf_req, buffer_req))) { + decoder->client_output_buf_req = + *buffer_req; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_CODEC: + { + struct vcd_property_codec *codec = + (struct vcd_property_codec *)property_value; + if (sizeof(struct vcd_property_codec) == + property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + ddl_codec_type_transact(ddl, false, + codec->codec)) { + if (decoder->codec.codec != codec->codec) { + decoder->codec = *codec; + ddl_set_default_dec_property(ddl); + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_POST_FILTER: + if (sizeof(struct vcd_property_post_filter) == + property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && ( + decoder->codec.codec == VCD_CODEC_MPEG4 || + decoder->codec.codec == VCD_CODEC_MPEG2)) { + decoder->post_filter = + *(struct vcd_property_post_filter *) + property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_FRAME_SIZE: + { + struct vcd_property_frame_size *frame_size = + (struct vcd_property_frame_size *) property_value; + if ((sizeof(struct vcd_property_frame_size) == + property_hdr->sz) && + (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) && + (DDL_ALLOW_DEC_FRAMESIZE(frame_size->width, + frame_size->height))) { + if (decoder->client_frame_size.height != + frame_size->height || + decoder->client_frame_size.width != + frame_size->width) { + decoder->client_frame_size = *frame_size; + 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; + } + } + break; + case VCD_I_BUFFER_FORMAT: + { + struct vcd_property_buffer_format *tile = + (struct vcd_property_buffer_format *) + property_value; + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + tile->buffer_format == VCD_BUFFER_FORMAT_TILE_4x2) { + if (tile->buffer_format != + decoder->buf_format.buffer_format) { + decoder->buf_format = *tile; + ddl_set_default_decoder_buffer_req( + decoder, true); + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_H264_MV_BUFFER: + { + int index, buffer_size; + u8 *phys_addr; + u8 *virt_addr; + struct vcd_property_h264_mv_buffer *mv_buff = + (struct vcd_property_h264_mv_buffer *) + property_value; + DDL_MSG_LOW("Entered VCD_I_H264_MV_BUFFER Virt: %p, Phys %p," + "fd: %d size: %d count: %d\n", + mv_buff->kernel_virtual_addr, + mv_buff->physical_addr, + mv_buff->pmem_fd, + mv_buff->size, mv_buff->count); + if ((property_hdr->sz == sizeof(struct + vcd_property_h264_mv_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 = mv_buff->dev_addr; + virt_addr = mv_buff->kernel_virtual_addr; + buffer_size = mv_buff->size/mv_buff->count; + + for (index = 0; index < mv_buff->count; index++) { + ddl->codec_data.decoder.hw_bufs. + h264_mv[index].align_physical_addr + = phys_addr; + ddl->codec_data.decoder.hw_bufs. + h264_mv[index].align_virtual_addr + = virt_addr; + ddl->codec_data.decoder.hw_bufs. + h264_mv[index].buffer_size + = buffer_size; + ddl->codec_data.decoder.hw_bufs. + h264_mv[index].physical_base_addr + = phys_addr; + ddl->codec_data.decoder.hw_bufs. + h264_mv[index].virtual_base_addr + = virt_addr; + DDL_MSG_LOW("Assigned %d buffer for " + "virt: %p, phys %p for " + "h264_mv_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_FREE_H264_MV_BUFFER: + { + memset(&decoder->hw_bufs.h264_mv, 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 && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + decoder->output_order = + *(u32 *)property_value; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_DEC_PICTYPE: + { + if ((sizeof(u32) == property_hdr->sz) && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + decoder->idr_only_decoding = + *(u32 *)property_value; + ddl_set_default_decoder_buffer_req( + decoder, true); + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + DDL_MSG_MED("Meta Data Interface is Requested"); + vcd_status = ddl_set_metadata_params(ddl, property_hdr, + property_value); + vcd_status = VCD_S_SUCCESS; + break; + case VCD_I_FRAME_RATE: + vcd_status = VCD_S_SUCCESS; + break; + case VCD_I_CONT_ON_RECONFIG: + { + DDL_MSG_LOW("Set property VCD_I_CONT_ON_RECONFIG\n"); + if (sizeof(u32) == property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + decoder->cont_mode = *(u32 *)property_value; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_DISABLE_DMX: + { + int disable_dmx_allowed = 0; + DDL_MSG_LOW("Set property VCD_I_DISABLE_DMX\n"); + if (res_trk_get_disable_dmx() && + ((decoder->codec.codec == VCD_CODEC_H264) || + (decoder->codec.codec == VCD_CODEC_VC1) || + (decoder->codec.codec == VCD_CODEC_VC1_RCV))) + disable_dmx_allowed = 1; + + if (sizeof(u32) == property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + disable_dmx_allowed) { + decoder->dmx_disable = *(u32 *)property_value; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_REQ_PERF_LEVEL: + vcd_status = VCD_S_SUCCESS; + break; + default: + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + return vcd_status; +} + +static u32 ddl_check_valid_enc_level(struct vcd_property_codec *codec, + struct vcd_property_profile *profile, + struct vcd_property_level *level) +{ + u32 status = false; + + if (codec && profile && level) { + switch (codec->codec) { + case VCD_CODEC_MPEG4: + status = (profile->profile == + VCD_PROFILE_MPEG4_SP) && + (level->level >= VCD_LEVEL_MPEG4_0) && + (level->level <= VCD_LEVEL_MPEG4_6) && + (VCD_LEVEL_MPEG4_3b != level->level); + status = status || + ((profile->profile == + VCD_PROFILE_MPEG4_ASP) && + (level->level >= VCD_LEVEL_MPEG4_0) && + (level->level <= VCD_LEVEL_MPEG4_5)); + break; + case VCD_CODEC_H264: + status = (level->level >= VCD_LEVEL_H264_1) && + (level->level <= VCD_LEVEL_H264_4); + break; + case VCD_CODEC_H263: + status = (level->level >= VCD_LEVEL_H263_10) && + (level->level <= VCD_LEVEL_H263_70); + break; + default: + break; + } + } + return status; +} + +static u32 ddl_set_enc_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, + void *property_value) +{ + struct ddl_encoder_data *encoder = + &(ddl->codec_data.encoder); + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + vcd_status = ddl_set_enc_dynamic_property(ddl, + property_hdr, property_value); + } + if (vcd_status) { + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) || + vcd_status != VCD_ERR_ILLEGAL_OP) { + DDL_MSG_ERROR("ddl_set_enc_property:" + "Fails_as_not_in_open_state"); + return VCD_ERR_ILLEGAL_OP; + } + } else + return vcd_status; + + switch (property_hdr->prop_id) { + case VCD_I_FRAME_SIZE: + { + struct vcd_property_frame_size *frame_size = + (struct vcd_property_frame_size *) property_value; + if ((sizeof(struct vcd_property_frame_size) == + property_hdr->sz) && + (DDL_ALLOW_ENC_FRAMESIZE(frame_size->width, + frame_size->height))) { + if (encoder->frame_size.height != frame_size->height || + encoder->frame_size.width != + frame_size->width) { + ddl_calculate_stride(frame_size, false); + encoder->frame_size = *frame_size; + ddl_set_default_encoder_buffer_req(encoder); + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_CODEC: + { + struct vcd_property_codec *codec = + (struct vcd_property_codec *) property_value; + if ((sizeof(struct vcd_property_codec) == + property_hdr->sz) && + (ddl_codec_type_transact(ddl, false, codec->codec))) { + if (codec->codec != encoder->codec.codec) { + encoder->codec = *codec; + ddl_set_default_enc_property(ddl); + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_REQ_IFRAME: + vcd_status = VCD_S_SUCCESS; + break; + case VCD_I_INTRA_PERIOD: + { + struct vcd_property_i_period *i_period = + (struct vcd_property_i_period *)property_value; + if (sizeof(struct vcd_property_i_period) == + property_hdr->sz && + i_period->b_frames <= DDL_MAX_NUM_OF_B_FRAME) { + encoder->i_period = *i_period; + encoder->client_input_buf_req.min_count = + i_period->b_frames + 1; + encoder->client_input_buf_req.actual_count = + DDL_MAX(encoder->client_input_buf_req.\ + actual_count, encoder->\ + client_input_buf_req.min_count); + encoder->client_output_buf_req.min_count = + i_period->b_frames + 2; + encoder->client_output_buf_req.actual_count = + DDL_MAX(encoder->client_output_buf_req.\ + actual_count, encoder->\ + client_output_buf_req.min_count); + ddl->extra_output_buf_count = + i_period->b_frames - 1; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_PROFILE: + { + struct vcd_property_profile *profile = + (struct vcd_property_profile *)property_value; + + if ((sizeof(struct vcd_property_profile) == + property_hdr->sz) && (( + (encoder->codec.codec == VCD_CODEC_MPEG4) && ( + profile->profile == VCD_PROFILE_MPEG4_SP || + profile->profile == VCD_PROFILE_MPEG4_ASP)) || + ((encoder->codec.codec == VCD_CODEC_H264) && + (profile->profile >= VCD_PROFILE_H264_BASELINE) && + (profile->profile <= VCD_PROFILE_H264_HIGH)) || + ((encoder->codec.codec == VCD_CODEC_H263) && + (profile->profile == VCD_PROFILE_H263_BASELINE)))) { + encoder->profile = *profile; + vcd_status = VCD_S_SUCCESS; + if (profile->profile == VCD_PROFILE_H264_BASELINE) + encoder->entropy_control.entropy_sel = + VCD_ENTROPY_SEL_CAVLC; + else + encoder->entropy_control.entropy_sel = + VCD_ENTROPY_SEL_CABAC; + } + } + break; + case VCD_I_LEVEL: + { + struct vcd_property_level *level = + (struct vcd_property_level *) property_value; + + if ((sizeof(struct vcd_property_level) == + property_hdr->sz) && (ddl_check_valid_enc_level + (&encoder->codec, + &encoder->profile, level))) { + encoder->level = *level; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_MULTI_SLICE: + { + 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; + break; + case VCD_MSLICE_BY_GOB: + if (encoder->codec.codec == VCD_CODEC_H263) + vcd_status = VCD_S_SUCCESS; + break; + case VCD_MSLICE_BY_MB_COUNT: + { + if ((multi_slice->m_slice_size >= 1) && + (multi_slice->m_slice_size <= + DDL_NO_OF_MB(encoder->frame_size.width, + encoder->frame_size.height))) { + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_MSLICE_BY_BYTE_COUNT: + if (multi_slice->m_slice_size > 0) + vcd_status = VCD_S_SUCCESS; + break; + default: + break; + } + if (sizeof(struct vcd_property_multi_slice) == + property_hdr->sz && !vcd_status) { + encoder->multi_slice = *multi_slice; + if (multi_slice->m_slice_sel == VCD_MSLICE_OFF) + encoder->multi_slice.m_slice_size = 0; + } + } + break; + case VCD_I_RATE_CONTROL: + { + struct vcd_property_rate_control *rate_control = + (struct vcd_property_rate_control *) + property_value; + if (sizeof(struct vcd_property_rate_control) == + property_hdr->sz && + rate_control->rate_control >= + VCD_RATE_CONTROL_OFF && + rate_control->rate_control <= + VCD_RATE_CONTROL_CBR_CFR) { + encoder->rc = *rate_control; + ddl_set_default_enc_rc_params(encoder); + vcd_status = VCD_S_SUCCESS; + } + + } + break; + case VCD_I_SHORT_HEADER: + if (sizeof(struct vcd_property_short_header) == + property_hdr->sz && + encoder->codec.codec == + VCD_CODEC_MPEG4) { + encoder->short_header = + *(struct vcd_property_short_header *) + property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_VOP_TIMING: + { + struct vcd_property_vop_timing *vop_time = + (struct vcd_property_vop_timing *) + property_value; + + if ((sizeof(struct vcd_property_vop_timing) == + property_hdr->sz) && + (encoder->frame_rate.fps_numerator <= + vop_time->vop_time_resolution) && + (encoder->codec.codec == VCD_CODEC_MPEG4)) { + encoder->vop_timing = *vop_time; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_HEADER_EXTENSION: + if (sizeof(u32) == property_hdr->sz && + encoder->codec.codec == VCD_CODEC_MPEG4) { + encoder->hdr_ext_control = *(u32 *)property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_ENTROPY_CTRL: + { + struct vcd_property_entropy_control *entropy_control = + (struct vcd_property_entropy_control *) + property_value; + if (sizeof(struct vcd_property_entropy_control) == + property_hdr->sz && + encoder->codec.codec == VCD_CODEC_H264 && + entropy_control->entropy_sel >= + VCD_ENTROPY_SEL_CAVLC && + entropy_control->entropy_sel <= + VCD_ENTROPY_SEL_CABAC) { + if ((entropy_control->entropy_sel == + VCD_ENTROPY_SEL_CABAC) && + (encoder->entropy_control.cabac_model == + VCD_CABAC_MODEL_NUMBER_1 || + encoder->entropy_control.cabac_model == + VCD_CABAC_MODEL_NUMBER_2)) { + vcd_status = VCD_ERR_ILLEGAL_PARM; + } else { + encoder->entropy_control = *entropy_control; + vcd_status = VCD_S_SUCCESS; + } + } + } + break; + case VCD_I_DEBLOCKING: + { + struct vcd_property_db_config *db_config = + (struct vcd_property_db_config *) property_value; + if (sizeof(struct vcd_property_db_config) == + property_hdr->sz && + encoder->codec.codec == VCD_CODEC_H264 && + db_config->db_config >= + VCD_DB_ALL_BLOCKING_BOUNDARY && + db_config->db_config <= + VCD_DB_SKIP_SLICE_BOUNDARY) { + encoder->db_control = *db_config; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_QP_RANGE: + { + struct vcd_property_qp_range *qp = + (struct vcd_property_qp_range *)property_value; + + if ((sizeof(struct vcd_property_qp_range) == + property_hdr->sz) && (qp->min_qp <= + qp->max_qp) && ((encoder->codec.codec == + VCD_CODEC_H264 && qp->max_qp <= DDL_MAX_H264_QP) || + (qp->max_qp <= DDL_MAX_MPEG4_QP))) { + encoder->qp_range = *qp; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_SESSION_QP: + { + struct vcd_property_session_qp *qp = + (struct vcd_property_session_qp *)property_value; + if ((sizeof(struct vcd_property_session_qp) == + property_hdr->sz) && + (qp->i_frame_qp >= encoder->qp_range.min_qp) && + (qp->i_frame_qp <= encoder->qp_range.max_qp) && + (qp->p_frame_qp >= encoder->qp_range.min_qp) && + (qp->p_frame_qp <= encoder->qp_range.max_qp)) { + encoder->session_qp = *qp; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_RC_LEVEL_CONFIG: + { + struct vcd_property_rc_level *rc_level = + (struct vcd_property_rc_level *) property_value; + if (sizeof(struct vcd_property_rc_level) == + property_hdr->sz && + (encoder->rc.rate_control >= + VCD_RATE_CONTROL_VBR_VFR || + encoder->rc.rate_control <= + VCD_RATE_CONTROL_CBR_VFR) && + (!rc_level->mb_level_rc || + encoder->codec.codec == VCD_CODEC_H264)) { + encoder->rc_level = *rc_level; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_FRAME_LEVEL_RC: + { + struct vcd_property_frame_level_rc_params + *frame_level_rc = + (struct vcd_property_frame_level_rc_params *) + property_value; + if ((sizeof(struct vcd_property_frame_level_rc_params) == + property_hdr->sz) && + (frame_level_rc->reaction_coeff) && + (encoder->rc_level.frame_level_rc)) { + encoder->frame_level_rc = *frame_level_rc; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_ADAPTIVE_RC: + if ((sizeof(struct vcd_property_adaptive_rc_params) == + property_hdr->sz) && + (encoder->codec.codec == VCD_CODEC_H264) && + (encoder->rc_level.mb_level_rc)) { + encoder->adaptive_rc = + *(struct vcd_property_adaptive_rc_params *) + property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_BUFFER_FORMAT: + { + struct vcd_property_buffer_format *buffer_format = + (struct vcd_property_buffer_format *) + property_value; + + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz && + ((buffer_format->buffer_format == + VCD_BUFFER_FORMAT_NV12_16M2KA) || + (VCD_BUFFER_FORMAT_TILE_4x2 == + buffer_format->buffer_format))) { + if (buffer_format->buffer_format != + encoder->buf_format.buffer_format) { + encoder->buf_format = *buffer_format; + ddl_set_default_encoder_buffer_req(encoder); + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case DDL_I_INPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *)property_value; + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && (ddl_valid_buffer_requirement( + &encoder->input_buf_req, buffer_req))) { + encoder->client_input_buf_req = *buffer_req; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case DDL_I_OUTPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *)property_value; + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && (ddl_valid_buffer_requirement( + &encoder->output_buf_req, buffer_req))) { + encoder->client_output_buf_req = *buffer_req; + 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; + } + } + break; + case VCD_I_RECON_BUFFERS: + { + int index, index_hw_bufs = -1; + struct vcd_property_enc_recon_buffer *recon_buffers = + (struct vcd_property_enc_recon_buffer *)property_value; + for (index = 0; index < 4; index++) { + if (!encoder->hw_bufs.dpb_y[index]. + align_physical_addr) { + index_hw_bufs = index; + break; + } else + continue; + } + if (index_hw_bufs == -1) { + DDL_MSG_HIGH("ERROR: value of index_hw_bufs"); + vcd_status = VCD_ERR_ILLEGAL_PARM; + } else { + if (property_hdr->sz == sizeof(struct + vcd_property_enc_recon_buffer)) { + encoder->hw_bufs.dpb_y[index_hw_bufs]. + align_physical_addr = + recon_buffers->dev_addr; + encoder->hw_bufs.dpb_y[index_hw_bufs]. + align_virtual_addr = + recon_buffers->kernel_virtual_addr; + encoder->hw_bufs.dpb_y[index_hw_bufs]. + buffer_size = recon_buffers->buffer_size; + encoder->hw_bufs.dpb_c[index_hw_bufs]. + align_physical_addr = + recon_buffers->dev_addr + + ddl_get_yuv_buf_size( + encoder->frame_size.width, + encoder->frame_size.height, + DDL_YUV_BUF_TYPE_TILE); + encoder->hw_bufs.dpb_c[index_hw_bufs]. + align_virtual_addr = + recon_buffers->kernel_virtual_addr + + recon_buffers->ysize; + DDL_MSG_LOW("Y::KVirt: %p,KPhys: %p" + "UV::KVirt: %p,KPhys: %p\n", + encoder->hw_bufs.dpb_y[index_hw_bufs]. + align_virtual_addr, + encoder->hw_bufs.dpb_y[index_hw_bufs]. + align_physical_addr, + encoder->hw_bufs.dpb_c[index_hw_bufs]. + align_virtual_addr, + encoder->hw_bufs.dpb_c[index_hw_bufs]. + align_physical_addr); + vcd_status = VCD_S_SUCCESS; + } + } + } + break; + case VCD_I_FREE_RECON_BUFFERS: + { + memset(&encoder->hw_bufs.dpb_y, 0, + sizeof(struct ddl_buf_addr) * 4); + memset(&encoder->hw_bufs.dpb_c, 0, + sizeof(struct ddl_buf_addr) * 4); + vcd_status = VCD_S_SUCCESS; + break; + } + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + DDL_MSG_LOW("Meta Data Interface is Requested"); + if (!res_trk_check_for_sec_session()) { + 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"); + vcd_status = VCD_ERR_ILLEGAL_OP; + } + break; + case VCD_I_META_BUFFER_MODE: + vcd_status = VCD_S_SUCCESS; + break; + case VCD_I_ENABLE_SPS_PPS_FOR_IDR: + { + struct vcd_property_sps_pps_for_idr_enable *sps_pps = + (struct vcd_property_sps_pps_for_idr_enable *) property_value; + + if ((sizeof(struct vcd_property_sps_pps_for_idr_enable)) == + property_hdr->sz) { + DDL_MSG_LOW("SPS PPS generation for IDR Encode " + "is Requested"); + encoder->sps_pps.sps_pps_for_idr_enable_flag = + sps_pps->sps_pps_for_idr_enable_flag; + vcd_status = VCD_S_SUCCESS; + } + 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) { + DDL_MSG_HIGH("%s: currently slice info " + "metadata is not supported when slice " + "delivery mode is enabled. hence " + "disabling slice info metadata.\n", + __func__); + 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); + 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); + vcd_status = VCD_S_SUCCESS; + } + } + break; + } + case VCD_REQ_PERF_LEVEL: + vcd_status = VCD_S_SUCCESS; + break; + default: + DDL_MSG_ERROR("INVALID ID %d\n", (int)property_hdr->prop_id); + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + return vcd_status; +} + +static u32 ddl_get_dec_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct vcd_property_frame_size *fz_size; + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + DDL_MSG_HIGH("property_hdr->prop_id:%x\n", property_hdr->prop_id); + switch (property_hdr->prop_id) { + case VCD_I_FRAME_SIZE: + if (sizeof(struct vcd_property_frame_size) == + property_hdr->sz) { + ddl_calculate_stride(&decoder->client_frame_size, + !decoder->progressive_only); + fz_size = + &decoder->client_frame_size; + fz_size->stride = + DDL_TILE_ALIGN(fz_size->width, + DDL_TILE_ALIGN_WIDTH); + fz_size->scan_lines = + DDL_TILE_ALIGN(fz_size->height, + DDL_TILE_ALIGN_HEIGHT); + *(struct vcd_property_frame_size *) + property_value = + decoder->client_frame_size; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_PROFILE: + if (sizeof(struct vcd_property_profile) == + property_hdr->sz) { + *(struct vcd_property_profile *)property_value = + decoder->profile; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_LEVEL: + if (sizeof(struct vcd_property_level) == + property_hdr->sz) { + *(struct vcd_property_level *)property_value = + decoder->level; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_PROGRESSIVE_ONLY: + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = + decoder->progressive_only; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_INPUT_BUF_REQ: + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = + decoder->client_input_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_OUTPUT_BUF_REQ: + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = decoder->client_output_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_CODEC: + if (sizeof(struct vcd_property_codec) == + property_hdr->sz) { + *(struct vcd_property_codec *) property_value = + decoder->codec; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_BUFFER_FORMAT: + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz) { + *(struct vcd_property_buffer_format *) + property_value = decoder->buf_format; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_POST_FILTER: + if (sizeof(struct vcd_property_post_filter) == + property_hdr->sz) { + *(struct vcd_property_post_filter *) + property_value = + decoder->post_filter; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_SEQHDR_ALIGN_BYTES: + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = + DDL_LINEAR_BUFFER_ALIGN_BYTES; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_FRAME_PROC_UNITS: + if (sizeof(u32) == property_hdr->sz) { + if (!decoder->progressive_only && + (decoder->client_frame_size.width * + decoder->client_frame_size.height) <= + DDL_FRAME_VGA_SIZE) { + *(u32 *) property_value = DDL_NO_OF_MB( + DDL_FRAME_720P_WIDTH, + DDL_FRAME_720P_HEIGHT); + } else { + *(u32 *) property_value = DDL_NO_OF_MB( + decoder->client_frame_size.width, + decoder->client_frame_size.height); + } + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_DPB_RETRIEVE: + if (sizeof(struct ddl_frame_data_tag) == + property_hdr->sz) { + vcd_status = ddl_decoder_dpb_transact(decoder, + (struct ddl_frame_data_tag *) + property_value, DDL_DPB_OP_RETRIEVE); + } + break; + case VCD_I_GET_H264_MV_SIZE: + if (property_hdr->sz == sizeof(struct + vcd_property_buffer_size)) { + struct vcd_property_buffer_size *mv_size = + (struct vcd_property_buffer_size *) property_value; + mv_size->size = ddl_get_yuv_buf_size(mv_size->width, + mv_size->height, DDL_YUV_BUF_TYPE_TILE); + mv_size->alignment = DDL_TILE_BUFFER_ALIGN_BYTES; + DDL_MSG_LOW("w: %d, h: %d, S: %d, " + "A: %d", mv_size->width, + mv_size->height, mv_size->size, + mv_size->alignment); + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_OUTPUT_ORDER: + { + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = decoder->output_order; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + DDL_MSG_ERROR("Meta Data Interface is Requested"); + vcd_status = ddl_get_metadata_params(ddl, property_hdr, + property_value); + vcd_status = VCD_S_SUCCESS; + break; + case VCD_I_CONT_ON_RECONFIG: + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = decoder->cont_mode; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_DISABLE_DMX_SUPPORT: + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = res_trk_get_disable_dmx(); + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_DISABLE_DMX: + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = decoder->dmx_disable; + vcd_status = VCD_S_SUCCESS; + } + break; + default: + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + return vcd_status; +} + +static u32 ddl_get_enc_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + struct ddl_encoder_data *encoder = &ddl->codec_data.encoder; + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + + switch (property_hdr->prop_id) { + case VCD_I_CODEC: + if (sizeof(struct vcd_property_codec) == + property_hdr->sz) { + *(struct vcd_property_codec *) property_value = + encoder->codec; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_FRAME_SIZE: + if (sizeof(struct vcd_property_frame_size) == + property_hdr->sz) { + *(struct vcd_property_frame_size *) + property_value = encoder->frame_size; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_FRAME_RATE: + if (sizeof(struct vcd_property_frame_rate) == + property_hdr->sz) { + *(struct vcd_property_frame_rate *) + property_value = encoder->frame_rate; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_TARGET_BITRATE: + if (sizeof(struct vcd_property_target_bitrate) == + property_hdr->sz) { + *(struct vcd_property_target_bitrate *) + property_value = encoder->target_bit_rate; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_RATE_CONTROL: + if (sizeof(struct vcd_property_rate_control) == + property_hdr->sz) { + *(struct vcd_property_rate_control *) + property_value = encoder->rc; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_PROFILE: + if (sizeof(struct vcd_property_profile) == + property_hdr->sz) { + *(struct vcd_property_profile *) property_value = + encoder->profile; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_LEVEL: + if (sizeof(struct vcd_property_level) == + property_hdr->sz) { + *(struct vcd_property_level *) property_value = + encoder->level; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_MULTI_SLICE: + if (sizeof(struct vcd_property_multi_slice) == + property_hdr->sz) { + *(struct vcd_property_multi_slice *) + property_value = encoder->multi_slice; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_SEQ_HEADER: + { + struct vcd_sequence_hdr *seq_hdr = + (struct vcd_sequence_hdr *) property_value; + + if (!encoder->seq_header_length) { + seq_hdr->sequence_header_len = + encoder->seq_header_length; + vcd_status = VCD_ERR_NO_SEQ_HDR; + } else if (sizeof(struct vcd_sequence_hdr) == + property_hdr->sz && + encoder->seq_header_length <= + seq_hdr->sequence_header_len) { + memcpy(seq_hdr->sequence_header, + encoder->seq_header.align_virtual_addr, + encoder->seq_header_length); + seq_hdr->sequence_header_len = + encoder->seq_header_length; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case DDL_I_SEQHDR_PRESENT: + if (sizeof(u32) == property_hdr->sz) { + if ((encoder->codec.codec == + VCD_CODEC_MPEG4 && + !encoder->short_header.short_header) || + encoder->codec.codec == VCD_CODEC_H264) + *(u32 *) property_value = 0x1; + else + *(u32 *) property_value = 0x0; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_VOP_TIMING: + if (sizeof(struct vcd_property_vop_timing) == + property_hdr->sz) { + *(struct vcd_property_vop_timing *) + property_value = encoder->vop_timing; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_SHORT_HEADER: + if (sizeof(struct vcd_property_short_header) == + property_hdr->sz) { + if (encoder->codec.codec == VCD_CODEC_MPEG4) { + *(struct vcd_property_short_header *) + property_value = + encoder->short_header; + vcd_status = VCD_S_SUCCESS; + } else + vcd_status = VCD_ERR_ILLEGAL_OP; + } + break; + case VCD_I_ENTROPY_CTRL: + if (sizeof(struct vcd_property_entropy_control) == + property_hdr->sz) { + if (encoder->codec.codec == VCD_CODEC_H264) { + *(struct vcd_property_entropy_control *) + property_value = + encoder->entropy_control; + vcd_status = VCD_S_SUCCESS; + } else + vcd_status = VCD_ERR_ILLEGAL_OP; + } + break; + case VCD_I_DEBLOCKING: + if (sizeof(struct vcd_property_db_config) == + property_hdr->sz) { + if (encoder->codec.codec == VCD_CODEC_H264) { + *(struct vcd_property_db_config *) + property_value = + encoder->db_control; + vcd_status = VCD_S_SUCCESS; + } else + vcd_status = VCD_ERR_ILLEGAL_OP; + } + break; + case VCD_I_INTRA_PERIOD: + if (sizeof(struct vcd_property_i_period) == + property_hdr->sz) { + *(struct vcd_property_i_period *) + property_value = encoder->i_period; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_QP_RANGE: + if (sizeof(struct vcd_property_qp_range) == + property_hdr->sz) { + *(struct vcd_property_qp_range *) + property_value = encoder->qp_range; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_SESSION_QP: + if (sizeof(struct vcd_property_session_qp) == + property_hdr->sz) { + *(struct vcd_property_session_qp *) + property_value = encoder->session_qp; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_RC_LEVEL_CONFIG: + if (sizeof(struct vcd_property_rc_level) == + property_hdr->sz) { + *(struct vcd_property_rc_level *) + property_value = encoder->rc_level; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_FRAME_LEVEL_RC: + if (sizeof(struct vcd_property_frame_level_rc_params) == + property_hdr->sz) { + *(struct vcd_property_frame_level_rc_params *) + property_value = encoder->frame_level_rc; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_ADAPTIVE_RC: + if (sizeof(struct vcd_property_adaptive_rc_params) == + property_hdr->sz) { + *(struct vcd_property_adaptive_rc_params *) + property_value = encoder->adaptive_rc; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_INTRA_REFRESH: + if (sizeof(struct vcd_property_intra_refresh_mb_number) == + property_hdr->sz) { + *(struct vcd_property_intra_refresh_mb_number *) + property_value = encoder->intra_refresh; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_INPUT_BUF_REQ: + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = encoder->client_input_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_OUTPUT_BUF_REQ: + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = encoder->client_output_buf_req; + 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: + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz) { + *(struct vcd_property_buffer_format *) + property_value = encoder->buf_format; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_FRAME_PROC_UNITS: + if (sizeof(u32) == property_hdr->sz && + encoder->frame_size.width && + encoder->frame_size.height) { + *(u32 *)property_value = DDL_NO_OF_MB( + encoder->frame_size.width, + encoder->frame_size.height); + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_HEADER_EXTENSION: + if (sizeof(u32) == property_hdr->sz && + encoder->codec.codec == VCD_CODEC_MPEG4) { + *(u32 *) property_value = + encoder->hdr_ext_control; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_GET_RECON_BUFFER_SIZE: + { + u32 ysize, uvsize; + if (property_hdr->sz == sizeof(struct + vcd_property_buffer_size)) { + struct vcd_property_buffer_size *recon_buff_size = + (struct vcd_property_buffer_size *) property_value; + + ysize = ddl_get_yuv_buf_size(recon_buff_size->width, + recon_buff_size->height, DDL_YUV_BUF_TYPE_TILE); + uvsize = ddl_get_yuv_buf_size(recon_buff_size->width, + recon_buff_size->height/2, + DDL_YUV_BUF_TYPE_TILE); + recon_buff_size->size = ysize + uvsize; + recon_buff_size->alignment = + DDL_TILE_BUFFER_ALIGN_BYTES; + DDL_MSG_LOW("w: %d, h: %d, S: %d, A: %d", + recon_buff_size->width, recon_buff_size->height, + recon_buff_size->size, recon_buff_size->alignment); + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + DDL_MSG_ERROR("Meta Data Interface is Requested"); + vcd_status = ddl_get_metadata_params(ddl, property_hdr, + property_value); + vcd_status = VCD_S_SUCCESS; + break; + case VCD_I_ENABLE_SPS_PPS_FOR_IDR: + if (sizeof(struct vcd_property_sps_pps_for_idr_enable) == + property_hdr->sz) { + *(struct vcd_property_sps_pps_for_idr_enable *) + property_value = encoder->sps_pps; + 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; + } + return vcd_status; +} + +static u32 ddl_set_enc_dynamic_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + struct ddl_encoder_data *encoder = &ddl->codec_data.encoder; + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + u32 dynamic_prop_change = 0x0; + + switch (property_hdr->prop_id) { + case VCD_I_REQ_IFRAME: + if (sizeof(struct vcd_property_req_i_frame) == + property_hdr->sz) { + dynamic_prop_change |= DDL_ENC_REQ_IFRAME; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_TARGET_BITRATE: + { + struct vcd_property_target_bitrate *bitrate = + (struct vcd_property_target_bitrate *)property_value; + + if (sizeof(struct vcd_property_target_bitrate) == + property_hdr->sz && bitrate->target_bitrate && + bitrate->target_bitrate <= DDL_MAX_BIT_RATE) { + encoder->target_bit_rate = *bitrate; + dynamic_prop_change = DDL_ENC_CHANGE_BITRATE; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_INTRA_PERIOD: + { + struct vcd_property_i_period *i_period = + (struct vcd_property_i_period *)property_value; + + if (sizeof(struct vcd_property_i_period) == + property_hdr->sz) { + encoder->i_period = *i_period; + dynamic_prop_change = DDL_ENC_CHANGE_IPERIOD; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_FRAME_RATE: + { + struct vcd_property_frame_rate *frame_rate = + (struct vcd_property_frame_rate *) + property_value; + if (sizeof(struct vcd_property_frame_rate) == + property_hdr->sz && + frame_rate->fps_denominator && + frame_rate->fps_numerator && + frame_rate->fps_denominator <= + frame_rate->fps_numerator) { + encoder->frame_rate = *frame_rate; + dynamic_prop_change = DDL_ENC_CHANGE_FRAMERATE; + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + (encoder->codec.codec != VCD_CODEC_MPEG4 || + encoder->short_header.short_header)) { + ddl_set_default_enc_vop_timing(encoder); + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_INTRA_REFRESH: + { + struct vcd_property_intra_refresh_mb_number + *intra_refresh_mb_num = + (struct vcd_property_intra_refresh_mb_number *) + property_value; + u32 frame_mb_num = DDL_NO_OF_MB(encoder->frame_size.width, + encoder->frame_size.height); + + if ((sizeof(struct vcd_property_intra_refresh_mb_number) == + property_hdr->sz) && + (intra_refresh_mb_num->cir_mb_number <= frame_mb_num)) { + encoder->intra_refresh = *intra_refresh_mb_num; + dynamic_prop_change = DDL_ENC_CHANGE_CIR; + vcd_status = VCD_S_SUCCESS; + } + } + break; + default: + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + + if (!vcd_status && (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) + || DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE))) + encoder->dynamic_prop_change |= dynamic_prop_change; + + return vcd_status; +} + +void ddl_set_default_dec_property(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = + &(ddl->codec_data.decoder); + + if (decoder->codec.codec >= VCD_CODEC_MPEG2 && + decoder->codec.codec <= VCD_CODEC_XVID) + decoder->post_filter.post_filter = false; + else + decoder->post_filter.post_filter = false; + decoder->buf_format.buffer_format = VCD_BUFFER_FORMAT_TILE_4x2; + decoder->client_frame_size.height = VCD_DDL_TEST_DEFAULT_HEIGHT; + decoder->client_frame_size.width = VCD_DDL_TEST_DEFAULT_WIDTH; + decoder->client_frame_size.stride = VCD_DDL_TEST_DEFAULT_WIDTH; + decoder->client_frame_size.scan_lines = VCD_DDL_TEST_DEFAULT_HEIGHT; + decoder->progressive_only = 1; + decoder->idr_only_decoding = false; + decoder->output_order = VCD_DEC_ORDER_DISPLAY; + decoder->field_needed_for_prev_ip = 0; + decoder->cont_mode = 0; + decoder->reconfig_detected = false; + decoder->dmx_disable = false; + ddl_set_default_metadata_flag(ddl); + ddl_set_default_decoder_buffer_req(decoder, true); +} + +static void ddl_set_default_enc_property(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + + ddl_set_default_enc_profile(encoder); + ddl_set_default_enc_level(encoder); + encoder->rc.rate_control = VCD_RATE_CONTROL_VBR_VFR; + ddl_set_default_enc_rc_params(encoder); + ddl_set_default_enc_intra_period(encoder); + encoder->intra_refresh.cir_mb_number = 0; + ddl_set_default_enc_vop_timing(encoder); + encoder->multi_slice.m_slice_sel = VCD_MSLICE_OFF; + encoder->multi_slice.m_slice_size = 0; + ddl->b_count = 0; + encoder->short_header.short_header = false; + encoder->entropy_control.entropy_sel = VCD_ENTROPY_SEL_CAVLC; + encoder->entropy_control.cabac_model = VCD_CABAC_MODEL_NUMBER_0; + encoder->db_control.db_config = + VCD_DB_ALL_BLOCKING_BOUNDARY; + encoder->db_control.slice_alpha_offset = 0; + encoder->db_control.slice_beta_offset = 0; + encoder->recon_buf_format.buffer_format = + VCD_BUFFER_FORMAT_TILE_1x1; + encoder->buf_format.buffer_format = VCD_BUFFER_FORMAT_NV12_16M2KA; + encoder->hdr_ext_control = 0; + encoder->mb_info_enable = false; + encoder->num_references_for_p_frame = DDL_MIN_NUM_REF_FOR_P_FRAME; + if (encoder->codec.codec == VCD_CODEC_MPEG4) + 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) +{ + enum vcd_codec codec = encoder->codec.codec; + + if (codec == VCD_CODEC_MPEG4) + encoder->profile.profile = VCD_PROFILE_MPEG4_SP; + else if (codec == VCD_CODEC_H264) + encoder->profile.profile = VCD_PROFILE_H264_BASELINE; + else + encoder->profile.profile = VCD_PROFILE_H263_BASELINE; +} + +static void ddl_set_default_enc_level(struct ddl_encoder_data *encoder) +{ + enum vcd_codec codec = encoder->codec.codec; + + if (codec == VCD_CODEC_MPEG4) + encoder->level.level = VCD_LEVEL_MPEG4_1; + else if (codec == VCD_CODEC_H264) + encoder->level.level = VCD_LEVEL_H264_1; + else + encoder->level.level = VCD_LEVEL_H263_10; +} + +static void ddl_set_default_enc_vop_timing( + struct ddl_encoder_data *encoder) +{ + if (encoder->codec.codec == VCD_CODEC_MPEG4) { + encoder->vop_timing.vop_time_resolution = + (encoder->frame_rate.fps_numerator << 1) / + encoder->frame_rate.fps_denominator; + } else + encoder->vop_timing.vop_time_resolution = + DDL_FRAMERATE_SCALE(DDL_INITIAL_FRAME_RATE); +} + +static void ddl_set_default_enc_intra_period( + struct ddl_encoder_data *encoder) +{ + switch (encoder->rc.rate_control) { + default: + case VCD_RATE_CONTROL_VBR_VFR: + case VCD_RATE_CONTROL_VBR_CFR: + case VCD_RATE_CONTROL_CBR_VFR: + case VCD_RATE_CONTROL_OFF: + encoder->i_period.p_frames = + ((encoder->frame_rate.fps_numerator << 1) / + encoder->frame_rate.fps_denominator) - 1; + break; + case VCD_RATE_CONTROL_CBR_CFR: + encoder->i_period.p_frames = + ((encoder->frame_rate.fps_numerator >> 1) / + encoder->frame_rate.fps_denominator) - 1; + break; + } + encoder->i_period.b_frames = DDL_DEFAULT_NUM_OF_B_FRAME; +} + +static void ddl_set_default_enc_rc_params( + struct ddl_encoder_data *encoder) +{ + enum vcd_codec codec = encoder->codec.codec; + encoder->rc_level.frame_level_rc = true; + encoder->qp_range.min_qp = 0x1; + if (codec == VCD_CODEC_H264) { + encoder->qp_range.min_qp = 0x1; + encoder->qp_range.max_qp = 0x33; + encoder->session_qp.i_frame_qp = 0x14; + encoder->session_qp.p_frame_qp = 0x14; + encoder->session_qp.b_frame_qp = 0x14; + encoder->rc_level.mb_level_rc = true; + encoder->adaptive_rc.disable_activity_region_flag = true; + encoder->adaptive_rc.disable_dark_region_as_flag = true; + encoder->adaptive_rc.disable_smooth_region_as_flag = true; + encoder->adaptive_rc.disable_static_region_as_flag = true; + } else { + encoder->qp_range.max_qp = 0x1f; + encoder->qp_range.min_qp = 0x1; + encoder->session_qp.i_frame_qp = 0xd; + encoder->session_qp.p_frame_qp = 0xd; + encoder->session_qp.b_frame_qp = 0xd; + encoder->rc_level.frame_level_rc = true; + encoder->rc_level.mb_level_rc = false; + } + switch (encoder->rc.rate_control) { + case VCD_RATE_CONTROL_VBR_CFR: + encoder->r_cframe_skip = 0; + encoder->frame_level_rc.reaction_coeff = 0x1f4; + break; + case VCD_RATE_CONTROL_CBR_VFR: + encoder->r_cframe_skip = 1; + if (codec != VCD_CODEC_H264) { + encoder->session_qp.i_frame_qp = 0xf; + encoder->session_qp.p_frame_qp = 0xf; + encoder->session_qp.b_frame_qp = 0xf; + } + encoder->frame_level_rc.reaction_coeff = 0x14; + break; + case VCD_RATE_CONTROL_CBR_CFR: + encoder->r_cframe_skip = 0; + encoder->frame_level_rc.reaction_coeff = 0x6; + break; + case VCD_RATE_CONTROL_OFF: + encoder->r_cframe_skip = 0; + encoder->rc_level.frame_level_rc = false; + encoder->rc_level.mb_level_rc = false; + break; + case VCD_RATE_CONTROL_VBR_VFR: + default: + encoder->r_cframe_skip = 1; + encoder->frame_level_rc.reaction_coeff = 0x1f4; + break; + } +} + +void ddl_set_default_encoder_buffer_req(struct ddl_encoder_data *encoder) +{ + u32 y_cb_cr_size, y_size; + memset(&encoder->hw_bufs.dpb_y, 0, sizeof(struct ddl_buf_addr) * 4); + memset(&encoder->hw_bufs.dpb_c, 0, sizeof(struct ddl_buf_addr) * 4); + + y_cb_cr_size = ddl_get_yuv_buffer_size(&encoder->frame_size, + &encoder->buf_format, false, + encoder->hdr.decoding, &y_size); + encoder->input_buf_size.size_yuv = y_cb_cr_size; + encoder->input_buf_size.size_y = y_size; + encoder->input_buf_size.size_c = y_cb_cr_size - y_size; + memset(&encoder->input_buf_req , 0 , + sizeof(struct vcd_buffer_requirement)); + encoder->input_buf_req.min_count = 3; + encoder->input_buf_req.actual_count = + encoder->input_buf_req.min_count; + encoder->input_buf_req.max_count = DDL_MAX_BUFFER_COUNT; + encoder->input_buf_req.sz = y_cb_cr_size; + if (encoder->buf_format.buffer_format == + VCD_BUFFER_FORMAT_NV12_16M2KA) + encoder->input_buf_req.align = + DDL_LINEAR_BUFFER_ALIGN_BYTES; + else if (VCD_BUFFER_FORMAT_TILE_4x2 == + encoder->buf_format.buffer_format) + encoder->input_buf_req.align = DDL_TILE_BUFFER_ALIGN_BYTES; + 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.actual_count = + encoder->output_buf_req.min_count + 3; + encoder->output_buf_req.max_count = DDL_MAX_BUFFER_COUNT; + encoder->output_buf_req.align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + if (y_cb_cr_size >= VCD_DDL_720P_YUV_BUF_SIZE) + y_cb_cr_size = y_cb_cr_size>>1; + encoder->output_buf_req.sz = + 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, + u32 estimate) +{ + struct vcd_property_frame_size *frame_size; + struct vcd_buffer_requirement *input_buf_req; + struct vcd_buffer_requirement *output_buf_req; + u32 min_dpb, y_cb_cr_size; + + if (!decoder->codec.codec) + return false; + if (estimate) { + if (!decoder->cont_mode) + min_dpb = ddl_decoder_min_num_dpb(decoder); + else + min_dpb = res_trk_get_min_dpb_count(); + frame_size = &decoder->client_frame_size; + output_buf_req = &decoder->client_output_buf_req; + input_buf_req = &decoder->client_input_buf_req; + y_cb_cr_size = ddl_get_yuv_buffer_size(frame_size, + &decoder->buf_format, + (!decoder->progressive_only), + decoder->hdr.decoding, NULL); + } else { + frame_size = &decoder->frame_size; + output_buf_req = &decoder->actual_output_buf_req; + input_buf_req = &decoder->actual_input_buf_req; + min_dpb = decoder->min_dpb_num; + y_cb_cr_size = decoder->y_cb_cr_size; + if ((decoder->buf_format.buffer_format == + VCD_BUFFER_FORMAT_TILE_4x2) && + (frame_size->height < MDP_MIN_TILE_HEIGHT)) { + frame_size->height = MDP_MIN_TILE_HEIGHT; + ddl_calculate_stride(frame_size, + !decoder->progressive_only); + y_cb_cr_size = ddl_get_yuv_buffer_size( + frame_size, + &decoder->buf_format, + (!decoder->progressive_only), + decoder->hdr.decoding, NULL); + } else + y_cb_cr_size = decoder->y_cb_cr_size; + } + memset(output_buf_req, 0, + sizeof(struct vcd_buffer_requirement)); + if (!decoder->idr_only_decoding && !decoder->cont_mode) + output_buf_req->actual_count = min_dpb + 4; + else + output_buf_req->actual_count = min_dpb; + output_buf_req->min_count = min_dpb; + output_buf_req->max_count = DDL_MAX_BUFFER_COUNT; + output_buf_req->sz = y_cb_cr_size; + DDL_MSG_LOW("output_buf_req->sz : %d", output_buf_req->sz); + if (decoder->buf_format.buffer_format != VCD_BUFFER_FORMAT_NV12) + output_buf_req->align = DDL_TILE_BUFFER_ALIGN_BYTES; + else + output_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + ddl_set_default_decoder_metadata_buffer_size(decoder, frame_size, + output_buf_req); + + decoder->min_output_buf_req = *output_buf_req; + memset(input_buf_req, 0, + sizeof(struct vcd_buffer_requirement)); + input_buf_req->min_count = 1; + input_buf_req->actual_count = input_buf_req->min_count + 1; + input_buf_req->max_count = DDL_MAX_BUFFER_COUNT; + input_buf_req->sz = (1024 * 1024 * 2); + input_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + decoder->min_input_buf_req = *input_buf_req; + return true; +} + +u32 ddl_get_yuv_buffer_size(struct vcd_property_frame_size *frame_size, + struct vcd_property_buffer_format *buf_format, + u32 interlace, u32 decoding, u32 *pn_c_offset) +{ + struct vcd_property_frame_size frame_sz = *frame_size; + u32 total_memory_size = 0, c_offset = 0; + ddl_calculate_stride(&frame_sz, interlace); + if (buf_format->buffer_format == VCD_BUFFER_FORMAT_TILE_4x2) { + u32 component_mem_size, width_round_up; + u32 height_round_up, height_chroma = (frame_sz.scan_lines >> 1); + + width_round_up = + DDL_ALIGN(frame_sz.stride, DDL_TILE_ALIGN_WIDTH); + height_round_up = + DDL_ALIGN(frame_sz.scan_lines, + DDL_TILE_ALIGN_HEIGHT); + component_mem_size = width_round_up * height_round_up; + component_mem_size = DDL_ALIGN(component_mem_size, + DDL_TILE_MULTIPLY_FACTOR); + c_offset = component_mem_size; + total_memory_size = ((component_mem_size + + DDL_TILE_BUF_ALIGN_GUARD_BYTES) & + DDL_TILE_BUF_ALIGN_MASK); + height_round_up = DDL_ALIGN(height_chroma, + DDL_TILE_ALIGN_HEIGHT); + component_mem_size = width_round_up * height_round_up; + component_mem_size = DDL_ALIGN(component_mem_size, + DDL_TILE_MULTIPLY_FACTOR); + total_memory_size += component_mem_size; + } else { + if (decoding) + total_memory_size = frame_sz.scan_lines * + frame_sz.stride; + else + total_memory_size = frame_sz.height * frame_sz.stride; + c_offset = DDL_ALIGN(total_memory_size, + DDL_LINEAR_MULTIPLY_FACTOR); + total_memory_size = c_offset + DDL_ALIGN( + total_memory_size >> 1, DDL_LINEAR_MULTIPLY_FACTOR); + } + if (pn_c_offset) + *pn_c_offset = c_offset; + return total_memory_size; +} + + +void ddl_calculate_stride(struct vcd_property_frame_size *frame_size, + u32 interlace) +{ + frame_size->stride = DDL_ALIGN(frame_size->width, + DDL_LINEAR_ALIGN_WIDTH); + if (interlace) + frame_size->scan_lines = DDL_ALIGN(frame_size->height, + DDL_TILE_ALIGN_HEIGHT); + else + frame_size->scan_lines = DDL_ALIGN(frame_size->height, + DDL_LINEAR_ALIGN_HEIGHT); +} + + +static u32 ddl_valid_buffer_requirement(struct vcd_buffer_requirement + *original_buf_req, struct vcd_buffer_requirement *req_buf_req) +{ + u32 status = false; + + if (original_buf_req->max_count >= req_buf_req->actual_count && + original_buf_req->min_count <= + req_buf_req->actual_count && + !((original_buf_req->align - (u32)0x1) & + req_buf_req->align) && + /*original_buf_req->align <= req_buf_req->align,*/ + original_buf_req->sz <= req_buf_req->sz) + status = true; + else { + DDL_MSG_ERROR("ddl_valid_buf_req:Failed"); + DDL_MSG_ERROR("codec_buf_req: min_cnt=%d, mx_cnt=%d, " + "align=%d, sz=%d\n", original_buf_req->min_count, + original_buf_req->max_count, original_buf_req->align, + original_buf_req->sz); + DDL_MSG_ERROR("client_buffs: actual_count=%d, align=%d, " + "sz=%d\n", req_buf_req->actual_count, + req_buf_req->align, req_buf_req->sz); + } + return status; +} + +static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *decoder) +{ + u32 min_dpb = 0; + + if (decoder->idr_only_decoding) { + min_dpb = DDL_MIN_BUFFER_COUNT; + if (decoder->post_filter.post_filter) + min_dpb *= 2; + return min_dpb; + } + + switch (decoder->codec.codec) { + case VCD_CODEC_H264: + { + u32 yuv_size_in_mb = DDL_MIN(DDL_NO_OF_MB( + decoder->client_frame_size.stride, + decoder->client_frame_size.scan_lines), + MAX_FRAME_SIZE_L4PT0_MBS); + min_dpb = DDL_MIN((MAX_DPB_SIZE_L4PT0_MBS / + yuv_size_in_mb), 16); + min_dpb += 2; + } + break; + case VCD_CODEC_H263: + min_dpb = 3; + break; + default: + case VCD_CODEC_MPEG1: + case VCD_CODEC_MPEG2: + case VCD_CODEC_MPEG4: + case VCD_CODEC_DIVX_3: + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + min_dpb = 4; + if (decoder->post_filter.post_filter) + min_dpb *= 2; + break; + } + return min_dpb; +} + +static u32 ddl_set_dec_buffers(struct ddl_decoder_data *decoder, + struct ddl_property_dec_pic_buffers *dpb) +{ + u32 vcd_status = VCD_S_SUCCESS, loopc; + + + for (loopc = 0; !vcd_status && + loopc < dpb->no_of_dec_pic_buf; ++loopc) { + if ((!DDL_ADDR_IS_ALIGNED(dpb->dec_pic_buffers[loopc]. + vcd_frm.physical, + decoder->client_output_buf_req.align)) || + (dpb->dec_pic_buffers[loopc].vcd_frm.alloc_len < + decoder->client_output_buf_req.sz)) + vcd_status = VCD_ERR_ILLEGAL_PARM; + } + if (vcd_status) { + DDL_MSG_ERROR("ddl_set_prop:" + "Dpb_align_fail_or_alloc_size_small"); + return vcd_status; + } + if (decoder->dp_buf.no_of_dec_pic_buf) { + kfree(decoder->dp_buf.dec_pic_buffers); + decoder->dp_buf.no_of_dec_pic_buf = 0; + } + decoder->dp_buf.dec_pic_buffers = + kmalloc(dpb->no_of_dec_pic_buf * + sizeof(struct ddl_frame_data_tag), GFP_KERNEL); + if (!decoder->dp_buf.dec_pic_buffers) { + DDL_MSG_ERROR("ddl_dec_set_prop:Dpb_container_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + decoder->dp_buf.no_of_dec_pic_buf = dpb->no_of_dec_pic_buf; + for (loopc = 0; loopc < dpb->no_of_dec_pic_buf; ++loopc) + decoder->dp_buf.dec_pic_buffers[loopc] = + dpb->dec_pic_buffers[loopc]; + decoder->dpb_mask.client_mask = 0; + decoder->dpb_mask.hw_mask = 0; + decoder->dynamic_prop_change = 0; + return VCD_S_SUCCESS; +} + +void ddl_set_initial_default_values(struct ddl_client_context *ddl) +{ + + if (ddl->decoding) { + ddl->codec_data.decoder.codec.codec = VCD_CODEC_MPEG4; + ddl_set_default_dec_property(ddl); + } else { + struct ddl_encoder_data *encoder = + &(ddl->codec_data.encoder); + encoder->codec.codec = VCD_CODEC_MPEG4; + encoder->target_bit_rate.target_bitrate = 64000; + encoder->frame_size.width = VCD_DDL_TEST_DEFAULT_WIDTH; + encoder->frame_size.height = VCD_DDL_TEST_DEFAULT_HEIGHT; + encoder->frame_size.scan_lines = + VCD_DDL_TEST_DEFAULT_HEIGHT; + encoder->frame_size.stride = VCD_DDL_TEST_DEFAULT_WIDTH; + encoder->frame_rate.fps_numerator = DDL_INITIAL_FRAME_RATE; + encoder->frame_rate.fps_denominator = 1; + ddl_set_default_enc_property(ddl); + encoder->sps_pps.sps_pps_for_idr_enable_flag = false; + } +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..6d8c4b91c89b1f63352dc35956aa208b28410949 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c @@ -0,0 +1,876 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "vcd_ddl_shared_mem.h" + +#define VIDC_SM_EXTENDED_DECODE_STATUS_ADDR 0x0000 +#define VIDC_SM_EXT_DEC_STATUS_RESOLUTION_CHANGE_BMSK 0x1 +#define VIDC_SM_EXT_DEC_STATUS_RESOLUTION_CHANGE_SHFT 0x0 +#define VIDC_SM_EXT_DEC_STATUS_MORE_FIELD_NEEDED_BMSK 0x4 +#define VIDC_SM_EXT_DEC_STATUS_MORE_FIELD_NEEDED_SHFT 0x2 + +#define VIDC_SM_SET_FRAME_TAG_ADDR 0x0004 +#define VIDC_SM_GET_FRAME_TAG_TOP_ADDR 0x0008 +#define VIDC_SM_GET_FRAME_TAG_BOTTOM_ADDR 0x000c +#define VIDC_SM_PIC_TIME_TOP_ADDR 0x0010 +#define VIDC_SM_PIC_TIME_BOTTOM_ADDR 0x0014 +#define VIDC_SM_START_BYTE_NUM_ADDR 0x0018 + +#define VIDC_SM_CROP_INFO1_ADDR 0x0020 +#define VIDC_SM_CROP_INFO1_RIGHT_OFFSET_BMSK 0xffff0000 +#define VIDC_SM_CROP_INFO1_RIGHT_OFFSET_SHFT 16 +#define VIDC_SM_CROP_INFO1_LEFT_OFFSET_BMSK 0x0000ffff +#define VIDC_SM_CROP_INFO1_LEFT_OFFSET_SHFT 0 + +#define VIDC_SM_CROP_INFO2_ADDR 0x0024 +#define VIDC_SM_CROP_INFO2_BOTTOM_OFFSET_BMSK 0xffff0000 +#define VIDC_SM_CROP_INFO2_BOTTOM_OFFSET_SHFT 16 +#define VIDC_SM_CROP_INFO2_TOP_OFFSET_BMSK 0x0000ffff +#define VIDC_SM_CROP_INFO2_TOP_OFFSET_SHFT 0 + +#define VIDC_SM_DISP_PIC_PROFILE_ADDR 0x007c +#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_LEVEL_BMASK 0x0000ff00 +#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_LEVEL_SHFT 8 +#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_BMASK 0x0000001f +#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_SHFT 0 + +#define VIDC_SM_DISP_PIC_FRAME_TYPE_ADDR 0x00c0 +#define VIDC_SM_DISP_PIC_FRAME_TYPE_BMSK 0x00000003 +#define VIDC_SM_DISP_PIC_FRAME_TYPE_SHFT 0 + +#define VIDC_SM_FREE_LUMA_DPB_ADDR 0x00c4 +#define VIDC_SM_FREE_LUMA_DPB_BMSK 0xffffffff +#define VIDC_SM_FREE_LUMA_DPB_SHFT 0 + +#define VIDC_SM_FREE_LUMA_DPB_DEC_ORDER_ADDR 0x00fc +#define VIDC_SM_FREE_LUMA_DPB_DEC_ORDER_BMSK 0xffffffff +#define VIDC_SM_FREE_LUMA_DPB_DEC_ORDER_SHFT 0 + +#define VIDC_SM_DEC_ORDER_WIDTH_ADDR 0x00e8 +#define VIDC_SM_DEC_ORDER_WIDTH_BMSK 0xffffffff +#define VIDC_SM_DEC_ORDER_WIDTH_SHFT 0 + +#define VIDC_SM_DEC_ORDER_HEIGHT_ADDR 0x00ec +#define VIDC_SM_DEC_ORDER_HEIGHT_BMSK 0xffffffff +#define VIDC_SM_DEC_ORDER_HEIGHT_SHFT 0 + +#define VIDC_SM_DEC_CROP_INFO1_ADDR 0x00f4 +#define VIDC_SM_DEC_CROP_INFO1_RIGHT_OFFSET_BMSK 0xffff0000 +#define VIDC_SM_DEC_CROP_INFO1_RIGHT_OFFSET_SHFT 16 +#define VIDC_SM_DEC_CROP_INFO1_LEFT_OFFSET_BMSK 0x0000ffff +#define VIDC_SM_DEC_CROP_INFO1_LEFT_OFFSET_SHFT 0 + +#define VIDC_SM_DEC_CROP_INFO2_ADDR 0x00f8 +#define VIDC_SM_DEC_CROP_INFO2_BOTTOM_OFFSET_BMSK 0xffff0000 +#define VIDC_SM_DEC_CROP_INFO2_BOTTOM_OFFSET_SHFT 16 +#define VIDC_SM_DEC_CROP_INFO2_TOP_OFFSET_BMSK 0x0000ffff +#define VIDC_SM_DEC_CROP_INFO2_TOP_OFFSET_SHFT 0 + +#define VIDC_SM_IDR_DECODING_ONLY_ADDR 0x0108 +#define VIDC_SM_IDR_DECODING_ONLY_BMSK 0x00000001 +#define VIDC_SM_IDR_DECODING_ONLY_SHIFT 0 + +#define VIDC_SM_ENC_EXT_CTRL_ADDR 0x0028 +#define VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_BMSK 0xffff0000 +#define VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_SHFT 16 +#define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_BMSK 0x80 +#define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_SHFT 7 +#define VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_BMSK 0X100 +#define VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_SHFT 8 +#define VIDC_SM_ENC_EXT_CTRL_SEQ_HDR_CTRL_BMSK 0x8 +#define VIDC_SM_ENC_EXT_CTRL_SEQ_HDR_CTRL_SHFT 3 +#define VIDC_SM_ENC_EXT_CTRL_FRAME_SKIP_ENABLE_BMSK 0x6 +#define VIDC_SM_ENC_EXT_CTRL_FRAME_SKIP_ENABLE_SHFT 1 +#define VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_BMSK 0x1 +#define VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_SHFT 0 + +#define VIDC_SM_ENC_PARAM_CHANGE_ADDR 0x002c +#define VIDC_SM_ENC_PARAM_CHANGE_RC_BIT_RATE_BMSK 0x4 +#define VIDC_SM_ENC_PARAM_CHANGE_RC_BIT_RATE_SHFT 2 +#define VIDC_SM_ENC_PARAM_CHANGE_RC_FRAME_RATE_BMSK 0x2 +#define VIDC_SM_ENC_PARAM_CHANGE_RC_FRAME_RATE_SHFT 1 +#define VIDC_SM_ENC_PARAM_CHANGE_I_PERIOD_BMSK 0x1 +#define VIDC_SM_ENC_PARAM_CHANGE_I_PERIOD_SHFT 0 + +#define VIDC_SM_ENC_VOP_TIMING_ADDR 0x0030 +#define VIDC_SM_ENC_VOP_TIMING_ENABLE_BMSK 0x80000000 +#define VIDC_SM_ENC_VOP_TIMING_ENABLE_SHFT 31 +#define VIDC_SM_ENC_VOP_TIMING_TIME_RESOLUTION_BMSK 0x7fff0000 +#define VIDC_SM_ENC_VOP_TIMING_TIME_RESOLUTION_SHFT 16 +#define VIDC_SM_ENC_VOP_TIMING_FRAME_DELTA_BMSK 0x0000ffff +#define VIDC_SM_ENC_VOP_TIMING_FRAME_DELTA_SHFT 0 + +#define VIDC_SM_ENC_HEC_PERIOD_ADDR 0x0034 + +#define VIDC_SM_H264_REF_L0_ADDR 0x005c +#define VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_1_BMSK 0x80000000 +#define VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_1_SHFT 31 +#define VIDC_SM_H264_REF_L0_CHRO_REF_1_BMSK 0x7f000000 +#define VIDC_SM_H264_REF_L0_CHRO_REF_1_SHFT 24 +#define VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_0_BMSK 0x00800000 +#define VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_0_SHFT 23 +#define VIDC_SM_H264_REF_L0_CHRO_REF_0_BMSK 0x007f0000 +#define VIDC_SM_H264_REF_L0_CHRO_REF_0_SHFT 16 +#define VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_1_BMSK 0x00008000 +#define VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_1_SHFT 15 +#define VIDC_SM_H264_REF_L0_LUMA_REF_1_BMSK 0x00007f00 +#define VIDC_SM_H264_REF_L0_LUMA_REF_1_SHFT 8 +#define VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_0_BMSK 0x00000080 +#define VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_0_SHFT 7 +#define VIDC_SM_H264_REF_L0_LUMA_REF_0_BMSK 0x0000007f +#define VIDC_SM_H264_REF_L0_LUMA_REF_0_SHFT 0 + +#define VIDC_SM_H264_REF_L1_ADDR 0x0060 +#define VIDC_SM_H264_REF_L1_CHRO_BTM_FLG_0_BMSK 0x00800000 +#define VIDC_SM_H264_REF_L1_CHRO_BTM_FLG_0_SHFT 23 +#define VIDC_SM_H264_REF_L1_CHRO_REF_0_BMSK 0x007f0000 +#define VIDC_SM_H264_REF_L1_CHRO_REF_0_SHFT 16 +#define VIDC_SM_H264_REF_L1_LUMA_BTM_FLG_0_BMSK 0x00000080 +#define VIDC_SM_H264_REF_L1_LUMA_BTM_FLG_0_SHFT 7 +#define VIDC_SM_H264_REF_L1_LUMA_REF_0_BMSK 0x0000007f +#define VIDC_SM_H264_REF_L1_LUMA_REF_0_SHFT 0 + +#define VIDC_SM_P_B_FRAME_QP_ADDR 0x0070 +#define VIDC_SM_P_B_FRAME_QP_B_FRAME_QP_BMASK 0x00000fc0 +#define VIDC_SM_P_B_FRAME_QP_B_FRAME_QP_SHFT 6 +#define VIDC_SM_P_B_FRAME_QP_P_FRAME_QP_BMASK 0x0000003f +#define VIDC_SM_P_B_FRAME_QP_P_FRAME_QP_SHFT 0 + +#define VIDC_SM_NEW_RC_BIT_RATE_ADDR 0x0090 +#define VIDC_SM_NEW_RC_BIT_RATE_VALUE_BMASK 0xffffffff +#define VIDC_SM_NEW_RC_BIT_RATE_VALUE_SHFT 0 +#define VIDC_SM_NEW_RC_FRAME_RATE_ADDR 0x0094 +#define VIDC_SM_NEW_RC_FRAME_RATE_VALUE_BMASK 0xffffffff +#define VIDC_SM_NEW_RC_FRAME_RATE_VALUE_SHFT 0 +#define VIDC_SM_NEW_I_PERIOD_ADDR 0x0098 +#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 +#define VIDC_SM_ALLOCATED_MV_SIZE_ADDR 0x006c +#define VIDC_SM_FLUSH_CMD_TYPE_ADDR 0x0080 +#define VIDC_SM_FLUSH_CMD_INBUF1_ADDR 0x0084 +#define VIDC_SM_FLUSH_CMD_INBUF2_ADDR 0x0088 +#define VIDC_SM_FLUSH_CMD_OUTBUF_ADDR 0x008c +#define VIDC_SM_MIN_LUMA_DPB_SIZE_ADDR 0x00b0 +#define VIDC_SM_MIN_CHROMA_DPB_SIZE_ADDR 0x00bc + + +#define VIDC_SM_METADATA_ENABLE_ADDR 0x0038 +#define VIDC_SM_METADATA_ENABLE_EXTRADATA_BMSK 0x40 +#define VIDC_SM_METADATA_ENABLE_EXTRADATA_SHFT 6 +#define VIDC_SM_METADATA_ENABLE_ENC_SLICE_SIZE_BMSK 0x20 +#define VIDC_SM_METADATA_ENABLE_ENC_SLICE_SIZE_SHFT 5 +#define VIDC_SM_METADATA_ENABLE_VUI_BMSK 0x10 +#define VIDC_SM_METADATA_ENABLE_VUI_SHFT 4 +#define VIDC_SM_METADATA_ENABLE_SEI_VIDC_BMSK 0x8 +#define VIDC_SM_METADATA_ENABLE_SEI_VIDC_SHFT 3 +#define VIDC_SM_METADATA_ENABLE_VC1_PARAM_BMSK 0x4 +#define VIDC_SM_METADATA_ENABLE_VC1_PARAM_SHFT 2 +#define VIDC_SM_METADATA_ENABLE_CONCEALED_MB_BMSK 0x2 +#define VIDC_SM_METADATA_ENABLE_CONCEALED_MB_SHFT 1 +#define VIDC_SM_METADATA_ENABLE_QP_BMSK 0x1 +#define VIDC_SM_METADATA_ENABLE_QP_SHFT 0 + +#define VIDC_SM_ASPECT_RATIO_INFO_ADDR 0x00c8 +#define VIDC_SM_MPEG4_ASPECT_RATIO_INFO_BMSK 0xf +#define VIDC_SM_MPEG4_ASPECT_RATIO_INFO_SHFT 0x0 +#define VIDC_SM_EXTENDED_PAR_ADDR 0x00cc +#define VIDC_SM_EXTENDED_PAR_WIDTH_BMSK 0xffff0000 +#define VIDC_SM_EXTENDED_PAR_WIDTH_SHFT 16 +#define VIDC_SM_EXTENDED_PAR_HEIGHT_BMSK 0x0000ffff +#define VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT 0x0 + +#define VIDC_SM_METADATA_STATUS_ADDR 0x003c +#define VIDC_SM_METADATA_STATUS_STATUS_BMSK 0x1 +#define VIDC_SM_METADATA_STATUS_STATUS_SHFT 0 + +#define VIDC_SM_METADATA_DISPLAY_INDEX_ADDR 0x0040 +#define VIDC_SM_EXT_METADATA_START_ADDR_ADDR 0x0044 + +#define VIDC_SM_PUT_EXTRADATA_ADDR 0x0048 +#define VIDC_SM_PUT_EXTRADATA_PUT_BMSK 0x1 +#define VIDC_SM_PUT_EXTRADATA_PUT_SHFT 0 + +#define VIDC_SM_EXTRADATA_ADDR_ADDR 0x004c + +#define VIDC_SM_CHROMA_ADDR_CHANGE_ADDR 0x0148 +#define VIDC_SM_CHROMA_ADDR_CHANGE_BMASK 0x00000001 +#define VIDC_SM_CHROMA_ADDR_CHANGE_SHFT 0 + +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_ADDR 0x0154 + +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTER_SLICE_BMSK 0x0c +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTER_SLICE_SHFT 2 +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTRA_SLICE_BMSK 0X02 +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTRA_SLICE_SHFT 1 +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_CONCEAL_ENABLE_BMSK 0x01 +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_CONCEAL_ENABLE_SHFT 0 + +#define VIDC_SM_SEI_ENABLE_ADDR 0x0180 +#define VIDC_SM_SEI_ENABLE_RECOVERY_POINT_SEI_BMSK 0x00000001 +#define VIDC_SM_SEI_ENABLE_RECOVERY_POINT_SEI_SHFT 0 + +#define VIDC_SM_NUM_STUFF_BYTES_CONSUME_ADDR 0X01ac + +#define VIDC_SM_TIMEOUT_VALUE_ADDR 0x0158 +#define VIDC_SM_TIMEOUT_VALUE_BMSK 0xffffffff +#define VIDC_SM_TIMEOUT_VALUE_SHFT 0 + +#define VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_BMSK 0x40 +#define VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_SHFT 6 + +#define DDL_MEM_WRITE_32(base, offset, val) ddl_mem_write_32(\ + (u32 *) ((u8 *) (base)->align_virtual_addr + (offset)), (val)) +#define DDL_MEM_READ_32(base, offset) ddl_mem_read_32(\ + (u32 *) ((u8 *) (base)->align_virtual_addr + (offset))) + +#define DDL_SHARED_MEM_11BIT_RIGHT_SHIFT 11 + +static void ddl_mem_write_32(u32 *addr, u32 data) +{ + *addr = data; +} + +static u32 ddl_mem_read_32(u32 *addr) +{ + return *addr; +} + +void vidc_sm_get_extended_decode_status(struct ddl_buf_addr *shared_mem, + u32 *more_field_needed, + u32 *resl_change) +{ + u32 decode_status = DDL_MEM_READ_32(shared_mem, + VIDC_SM_EXTENDED_DECODE_STATUS_ADDR); + if (more_field_needed) + *more_field_needed = + VIDC_GETFIELD(decode_status, + VIDC_SM_EXT_DEC_STATUS_MORE_FIELD_NEEDED_BMSK, + VIDC_SM_EXT_DEC_STATUS_MORE_FIELD_NEEDED_SHFT); + if (resl_change) + *resl_change = + VIDC_GETFIELD(decode_status, + VIDC_SM_EXT_DEC_STATUS_RESOLUTION_CHANGE_BMSK, + VIDC_SM_EXT_DEC_STATUS_RESOLUTION_CHANGE_SHFT); +} + +void vidc_sm_set_frame_tag(struct ddl_buf_addr *shared_mem, + u32 frame_tag) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_SET_FRAME_TAG_ADDR, frame_tag); +} + +void vidc_sm_get_frame_tags(struct ddl_buf_addr *shared_mem, + u32 *pn_frame_tag_top, u32 *pn_frame_tag_bottom) +{ + *pn_frame_tag_top = DDL_MEM_READ_32(shared_mem, + VIDC_SM_GET_FRAME_TAG_TOP_ADDR); + *pn_frame_tag_bottom = DDL_MEM_READ_32(shared_mem, + VIDC_SM_GET_FRAME_TAG_BOTTOM_ADDR); +} + +void vidc_sm_get_picture_times(struct ddl_buf_addr *shared_mem, + u32 *pn_time_top, u32 *pn_time_bottom) +{ + *pn_time_top = DDL_MEM_READ_32(shared_mem, VIDC_SM_PIC_TIME_TOP_ADDR); + *pn_time_bottom = DDL_MEM_READ_32(shared_mem, + VIDC_SM_PIC_TIME_BOTTOM_ADDR); +} + +void vidc_sm_set_start_byte_number(struct ddl_buf_addr *shared_mem, + u32 byte_num) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_START_BYTE_NUM_ADDR, byte_num); +} + +void vidc_sm_get_crop_info(struct ddl_buf_addr *shared_mem, + u32 *pn_left, u32 *pn_right, u32 *pn_top, u32 *pn_bottom) +{ + u32 info1, info2; + + info1 = DDL_MEM_READ_32(shared_mem, VIDC_SM_CROP_INFO1_ADDR); + + *pn_left = VIDC_GETFIELD(info1, VIDC_SM_CROP_INFO1_LEFT_OFFSET_BMSK, + VIDC_SM_CROP_INFO1_LEFT_OFFSET_SHFT); + *pn_right = VIDC_GETFIELD(info1, VIDC_SM_CROP_INFO1_RIGHT_OFFSET_BMSK, + VIDC_SM_CROP_INFO1_RIGHT_OFFSET_SHFT); + info2 = DDL_MEM_READ_32(shared_mem, VIDC_SM_CROP_INFO2_ADDR); + *pn_top = VIDC_GETFIELD(info2, VIDC_SM_CROP_INFO2_TOP_OFFSET_BMSK, + VIDC_SM_CROP_INFO2_TOP_OFFSET_SHFT); + *pn_bottom = VIDC_GETFIELD(info2, + VIDC_SM_CROP_INFO2_BOTTOM_OFFSET_BMSK, + VIDC_SM_CROP_INFO2_BOTTOM_OFFSET_SHFT); +} + +void vidc_sm_get_displayed_picture_frame(struct ddl_buf_addr + *shared_mem, u32 *n_disp_picture_frame) +{ + u32 disp_pict_frame; + + disp_pict_frame = DDL_MEM_READ_32(shared_mem, + VIDC_SM_DISP_PIC_FRAME_TYPE_ADDR); + *n_disp_picture_frame = VIDC_GETFIELD(disp_pict_frame, + VIDC_SM_DISP_PIC_FRAME_TYPE_BMSK, + VIDC_SM_DISP_PIC_FRAME_TYPE_SHFT); +} +void vidc_sm_get_available_luma_dpb_address(struct ddl_buf_addr + *shared_mem, u32 *pn_free_luma_dpb_address) +{ + *pn_free_luma_dpb_address = DDL_MEM_READ_32(shared_mem, + VIDC_SM_FREE_LUMA_DPB_ADDR); +} + +void vidc_sm_get_available_luma_dpb_dec_order_address( + struct ddl_buf_addr *shared_mem, + u32 *pn_free_luma_dpb_address) +{ + *pn_free_luma_dpb_address = DDL_MEM_READ_32(shared_mem, + VIDC_SM_FREE_LUMA_DPB_DEC_ORDER_ADDR); +} + +void vidc_sm_get_dec_order_resl( + struct ddl_buf_addr *shared_mem, u32 *width, u32 *height) +{ + *width = DDL_MEM_READ_32(shared_mem, + VIDC_SM_DEC_ORDER_WIDTH_ADDR); + *height = DDL_MEM_READ_32(shared_mem, + VIDC_SM_DEC_ORDER_HEIGHT_ADDR); +} + +void vidc_sm_get_dec_order_crop_info( + struct ddl_buf_addr *shared_mem, u32 *left, + u32 *right, u32 *top, u32 *bottom) +{ + u32 crop_data; + crop_data = DDL_MEM_READ_32(shared_mem, + VIDC_SM_DEC_CROP_INFO1_ADDR); + *left = VIDC_GETFIELD(crop_data, + VIDC_SM_DEC_CROP_INFO1_LEFT_OFFSET_BMSK, + VIDC_SM_DEC_CROP_INFO1_LEFT_OFFSET_SHFT); + *right = VIDC_GETFIELD(crop_data, + VIDC_SM_DEC_CROP_INFO1_RIGHT_OFFSET_BMSK, + VIDC_SM_DEC_CROP_INFO1_RIGHT_OFFSET_SHFT); + crop_data = DDL_MEM_READ_32(shared_mem, + VIDC_SM_DEC_CROP_INFO2_ADDR); + *top = VIDC_GETFIELD(crop_data, + VIDC_SM_DEC_CROP_INFO2_TOP_OFFSET_BMSK, + VIDC_SM_DEC_CROP_INFO2_TOP_OFFSET_SHFT); + *bottom = VIDC_GETFIELD(crop_data, + VIDC_SM_DEC_CROP_INFO2_BOTTOM_OFFSET_BMSK, + VIDC_SM_DEC_CROP_INFO2_BOTTOM_OFFSET_SHFT); +} + +void vidc_sm_set_extended_encoder_control(struct ddl_buf_addr + *shared_mem, u32 hec_enable, + enum VIDC_SM_frame_skip frame_skip_mode, + u32 seq_hdr_in_band, u32 vbv_buffer_size, u32 cpcfc_enable, + u32 sps_pps_control, u32 closed_gop_enable) +{ + u32 enc_ctrl; + + enc_ctrl = VIDC_SETFIELD((hec_enable) ? 1 : 0, + VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_SHFT, + VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_BMSK) | + VIDC_SETFIELD((u32) frame_skip_mode, + VIDC_SM_ENC_EXT_CTRL_FRAME_SKIP_ENABLE_SHFT, + VIDC_SM_ENC_EXT_CTRL_FRAME_SKIP_ENABLE_BMSK) | + VIDC_SETFIELD((seq_hdr_in_band) ? 1 : 0 , + VIDC_SM_ENC_EXT_CTRL_SEQ_HDR_CTRL_SHFT , + VIDC_SM_ENC_EXT_CTRL_SEQ_HDR_CTRL_BMSK) | + VIDC_SETFIELD(vbv_buffer_size, + VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_SHFT, + VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_BMSK) | + VIDC_SETFIELD((cpcfc_enable) ? 1 : 0, + VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_SHFT, + VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_BMSK) | + VIDC_SETFIELD((sps_pps_control) ? 1 : 0, + VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_SHFT, + VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_BMSK) | + VIDC_SETFIELD(closed_gop_enable, + VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_SHFT, + VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_BMSK); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_EXT_CTRL_ADDR, enc_ctrl); +} + +void vidc_sm_set_encoder_param_change(struct ddl_buf_addr *shared_mem, + u32 bit_rate_chg, u32 frame_rate_chg, u32 i_period_chg) +{ + u32 enc_param_chg; + + enc_param_chg = VIDC_SETFIELD((bit_rate_chg) ? 1 : 0, + VIDC_SM_ENC_PARAM_CHANGE_RC_BIT_RATE_SHFT, + VIDC_SM_ENC_PARAM_CHANGE_RC_BIT_RATE_BMSK) | + VIDC_SETFIELD((frame_rate_chg) ? 1 : 0, + VIDC_SM_ENC_PARAM_CHANGE_RC_FRAME_RATE_SHFT, + VIDC_SM_ENC_PARAM_CHANGE_RC_FRAME_RATE_BMSK) | + VIDC_SETFIELD((i_period_chg) ? 1 : 0, + VIDC_SM_ENC_PARAM_CHANGE_I_PERIOD_SHFT, + VIDC_SM_ENC_PARAM_CHANGE_I_PERIOD_BMSK); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_PARAM_CHANGE_ADDR, + enc_param_chg); +} + +void vidc_sm_set_encoder_vop_time(struct ddl_buf_addr *shared_mem, + u32 vop_time_enable, u32 time_resolution, u32 frame_delta) +{ + u32 vop_time; + + vop_time = VIDC_SETFIELD((vop_time_enable) ? 1 : 0, + VIDC_SM_ENC_VOP_TIMING_ENABLE_SHFT , + VIDC_SM_ENC_VOP_TIMING_ENABLE_BMSK) | + VIDC_SETFIELD(time_resolution , + VIDC_SM_ENC_VOP_TIMING_TIME_RESOLUTION_SHFT, + VIDC_SM_ENC_VOP_TIMING_TIME_RESOLUTION_BMSK) | + VIDC_SETFIELD(frame_delta, + VIDC_SM_ENC_VOP_TIMING_FRAME_DELTA_SHFT, + VIDC_SM_ENC_VOP_TIMING_FRAME_DELTA_BMSK); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_VOP_TIMING_ADDR, vop_time); +} + +void vidc_sm_set_encoder_hec_period(struct ddl_buf_addr *shared_mem, + u32 hec_period) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_HEC_PERIOD_ADDR, + hec_period); +} + +void vidc_sm_get_h264_encoder_reference_list0(struct ddl_buf_addr + *shared_mem, enum VIDC_SM_ref_picture *pe_luma_picture0, + u32 *pn_luma_picture_index0, enum VIDC_SM_ref_picture + *pe_luma_picture1, u32 *pn_luma_picture_index1, + enum VIDC_SM_ref_picture *pe_chroma_picture0, + u32 *pn_chroma_picture_index0, + enum VIDC_SM_ref_picture *pe_chroma_picture1, + u32 *pn_chroma_picture_index1) +{ + u32 ref_list; + + ref_list = DDL_MEM_READ_32(shared_mem, VIDC_SM_H264_REF_L0_ADDR); + + *pe_luma_picture0 = (enum VIDC_SM_ref_picture) + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_0_BMSK, + VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_0_SHFT); + *pn_luma_picture_index0 = + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_LUMA_REF_0_BMSK, + VIDC_SM_H264_REF_L0_LUMA_REF_0_SHFT); + *pe_luma_picture1 = (enum VIDC_SM_ref_picture) + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_1_BMSK, + VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_1_SHFT); + *pn_luma_picture_index1 = VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_LUMA_REF_1_BMSK, + VIDC_SM_H264_REF_L0_LUMA_REF_1_SHFT); + *pe_chroma_picture0 = (enum VIDC_SM_ref_picture) + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_0_BMSK, + VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_0_SHFT); + *pn_chroma_picture_index0 = VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_CHRO_REF_0_BMSK, + VIDC_SM_H264_REF_L0_CHRO_REF_0_SHFT); + *pe_chroma_picture1 = (enum VIDC_SM_ref_picture) + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_1_BMSK, + VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_1_SHFT); + *pn_chroma_picture_index1 = + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_CHRO_REF_1_BMSK, + VIDC_SM_H264_REF_L0_CHRO_REF_1_SHFT); +} + +void vidc_sm_get_h264_encoder_reference_list1(struct ddl_buf_addr + *shared_mem, enum VIDC_SM_ref_picture *pe_luma_picture, + u32 *pn_luma_picture_index, + enum VIDC_SM_ref_picture *pe_chroma_picture, + u32 *pn_chroma_picture_index) +{ + u32 ref_list; + + ref_list = DDL_MEM_READ_32(shared_mem, VIDC_SM_H264_REF_L1_ADDR); + + *pe_luma_picture = (enum VIDC_SM_ref_picture) + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L1_LUMA_BTM_FLG_0_BMSK, + VIDC_SM_H264_REF_L1_LUMA_BTM_FLG_0_SHFT); + *pn_luma_picture_index = + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L1_LUMA_REF_0_BMSK, + VIDC_SM_H264_REF_L1_LUMA_REF_0_SHFT); + *pe_chroma_picture = (enum VIDC_SM_ref_picture) + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L1_CHRO_BTM_FLG_0_BMSK, + VIDC_SM_H264_REF_L1_CHRO_BTM_FLG_0_SHFT); + *pn_chroma_picture_index = VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L1_CHRO_REF_0_BMSK, + VIDC_SM_H264_REF_L1_CHRO_REF_0_SHFT); +} + +void vidc_sm_set_allocated_dpb_size(struct ddl_buf_addr *shared_mem, + u32 y_size, u32 c_size) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ALLOCATED_LUMA_DPB_SIZE_ADDR, + y_size); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ALLOCATED_CHROMA_DPB_SIZE_ADDR, + c_size); +} + +void vidc_sm_set_allocated_h264_mv_size(struct ddl_buf_addr *shared_mem, + u32 mv_size) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ALLOCATED_MV_SIZE_ADDR, + mv_size); +} + +void vidc_sm_get_min_yc_dpb_sizes(struct ddl_buf_addr *shared_mem, + u32 *pn_min_luma_dpb_size, u32 *pn_min_chroma_dpb_size) +{ + *pn_min_luma_dpb_size = DDL_MEM_READ_32(shared_mem, + VIDC_SM_MIN_LUMA_DPB_SIZE_ADDR); + *pn_min_chroma_dpb_size = DDL_MEM_READ_32(shared_mem, + VIDC_SM_MIN_CHROMA_DPB_SIZE_ADDR); +} + +void vidc_sm_set_concealment_color(struct ddl_buf_addr *shared_mem, + u32 conceal_ycolor, u32 conceal_ccolor) +{ + u32 conceal_color; + + conceal_color = (((conceal_ycolor << 8) & 0xff00) | + (conceal_ccolor & 0xff)); + DDL_MEM_WRITE_32(shared_mem, 0x00f0, conceal_color); +} + +void vidc_sm_set_metadata_enable(struct ddl_buf_addr *shared_mem, + u32 extradata_enable, u32 qp_enable, u32 concealed_mb_enable, + u32 vc1Param_enable, u32 sei_nal_enable, u32 vui_enable, + u32 enc_slice_size_enable) +{ + u32 metadata_enable; + + metadata_enable = VIDC_SETFIELD((extradata_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_EXTRADATA_SHFT, + VIDC_SM_METADATA_ENABLE_EXTRADATA_BMSK) | + VIDC_SETFIELD((enc_slice_size_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_ENC_SLICE_SIZE_SHFT, + VIDC_SM_METADATA_ENABLE_ENC_SLICE_SIZE_BMSK) | + VIDC_SETFIELD((vui_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_VUI_SHFT, + VIDC_SM_METADATA_ENABLE_VUI_BMSK) | + VIDC_SETFIELD((sei_nal_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_SEI_VIDC_SHFT, + VIDC_SM_METADATA_ENABLE_SEI_VIDC_BMSK) | + VIDC_SETFIELD((vc1Param_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_VC1_PARAM_SHFT, + VIDC_SM_METADATA_ENABLE_VC1_PARAM_BMSK) | + VIDC_SETFIELD((concealed_mb_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_CONCEALED_MB_SHFT, + VIDC_SM_METADATA_ENABLE_CONCEALED_MB_BMSK) | + VIDC_SETFIELD((qp_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_QP_SHFT, + VIDC_SM_METADATA_ENABLE_QP_BMSK); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_METADATA_ENABLE_ADDR, + metadata_enable); +} + +void vidc_sm_get_metadata_status(struct ddl_buf_addr + *shared_mem, u32 *pb_metadata_present) +{ + u32 status; + + status = DDL_MEM_READ_32(shared_mem, VIDC_SM_METADATA_STATUS_ADDR); + *pb_metadata_present = (u32) VIDC_GETFIELD(status, + VIDC_SM_METADATA_STATUS_STATUS_BMSK, + VIDC_SM_METADATA_STATUS_STATUS_SHFT); +} + +void vidc_sm_get_metadata_display_index(struct ddl_buf_addr *shared_mem, + u32 *pn_dixplay_index) +{ + *pn_dixplay_index = DDL_MEM_READ_32(shared_mem, + VIDC_SM_METADATA_DISPLAY_INDEX_ADDR); +} + +void vidc_sm_set_metadata_start_address(struct ddl_buf_addr *shared_mem, + u32 address) +{ + u32 address_shift = address; + + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_EXT_METADATA_START_ADDR_ADDR, + address_shift); +} + +void vidc_sm_set_extradata_presence(struct ddl_buf_addr *shared_mem, + u32 extradata_present) +{ + u32 put_extradata; + + put_extradata = VIDC_SETFIELD((extradata_present) ? 1 : 0, + VIDC_SM_PUT_EXTRADATA_PUT_SHFT, + VIDC_SM_PUT_EXTRADATA_PUT_BMSK); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_PUT_EXTRADATA_ADDR, + put_extradata); +} + +void vidc_sm_set_extradata_addr(struct ddl_buf_addr *shared_mem, + u32 extradata_addr) +{ + u32 address_shift = extradata_addr; + + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_EXTRADATA_ADDR_ADDR, + address_shift); +} + +void vidc_sm_set_pand_b_frame_qp(struct ddl_buf_addr *shared_mem, + u32 b_frame_qp, u32 p_frame_qp) +{ + u32 nP_B_frame_qp; + + nP_B_frame_qp = VIDC_SETFIELD(b_frame_qp, + VIDC_SM_P_B_FRAME_QP_B_FRAME_QP_SHFT, + VIDC_SM_P_B_FRAME_QP_B_FRAME_QP_BMASK); + nP_B_frame_qp |= VIDC_SETFIELD(p_frame_qp, + VIDC_SM_P_B_FRAME_QP_P_FRAME_QP_SHFT, + VIDC_SM_P_B_FRAME_QP_P_FRAME_QP_BMASK); + DDL_MEM_WRITE_32(shared_mem , VIDC_SM_P_B_FRAME_QP_ADDR, + nP_B_frame_qp); +} + + +void vidc_sm_get_profile_info(struct ddl_buf_addr *shared_mem, + struct ddl_profile_info_type *ddl_profile_info) +{ + u32 disp_pic_profile; + + disp_pic_profile = DDL_MEM_READ_32(shared_mem, + VIDC_SM_DISP_PIC_PROFILE_ADDR); + ddl_profile_info->bit_depth_chroma_minus8 = + (disp_pic_profile & 0x00380000) >> 19; + ddl_profile_info->bit_depth_luma_minus8 = + (disp_pic_profile & 0x00070000) >> 16; + ddl_profile_info->pic_profile = VIDC_GETFIELD( + disp_pic_profile, + VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_BMASK, + VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_SHFT); + ddl_profile_info->pic_level = VIDC_GETFIELD( + disp_pic_profile, + VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_LEVEL_BMASK, + VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_LEVEL_SHFT); + ddl_profile_info->chroma_format_idc = + (disp_pic_profile & 0x60) >> 5; +} + +void vidc_sm_set_encoder_new_bit_rate(struct ddl_buf_addr *shared_mem, + u32 new_bit_rate) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NEW_RC_BIT_RATE_ADDR, + new_bit_rate); +} + +void vidc_sm_set_encoder_new_frame_rate(struct ddl_buf_addr *shared_mem, + u32 new_frame_rate) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NEW_RC_FRAME_RATE_ADDR, + new_frame_rate); +} + +void vidc_sm_set_encoder_new_i_period(struct ddl_buf_addr *shared_mem, + u32 new_i_period) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NEW_I_PERIOD_ADDR, + new_i_period); +} +void vidc_sm_set_encoder_init_rc_value(struct ddl_buf_addr *shared_mem, + u32 new_rc_value) +{ + DDL_MEM_WRITE_32(shared_mem, 0x011C, new_rc_value); + +} +void vidc_sm_set_idr_decode_only(struct ddl_buf_addr *shared_mem, + u32 enable) +{ + u32 idr_decode_only = VIDC_SETFIELD((enable) ? 1 : 0, + VIDC_SM_IDR_DECODING_ONLY_SHIFT, + VIDC_SM_IDR_DECODING_ONLY_BMSK + ); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_IDR_DECODING_ONLY_ADDR, + idr_decode_only); +} + +void vidc_sm_set_chroma_addr_change(struct ddl_buf_addr *shared_mem, + u32 addr_change) +{ + u32 chroma_addr_change = VIDC_SETFIELD((addr_change) ? 1 : 0, + VIDC_SM_CHROMA_ADDR_CHANGE_SHFT, + VIDC_SM_CHROMA_ADDR_CHANGE_BMASK); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_CHROMA_ADDR_CHANGE_ADDR, + chroma_addr_change); + +} + +void vidc_sm_set_mpeg4_profile_override(struct ddl_buf_addr *shared_mem, + enum vidc_sm_mpeg4_profileinfo profile_info) +{ + u32 profile_enforce = 0; + if (shared_mem != NULL) { + profile_enforce = 1; + switch (profile_info) { + case VIDC_SM_PROFILE_INFO_ASP: + profile_enforce |= 4; + break; + case VIDC_SM_PROFILE_INFO_SP: + profile_enforce |= 2; + break; + case VIDC_SM_PROFILE_INFO_DISABLE: + default: + profile_enforce = 0; + break; + } + DDL_MEM_WRITE_32(shared_mem, 0x15c, profile_enforce); + } +} +void vidc_sm_set_decoder_sei_enable(struct ddl_buf_addr *shared_mem, + u32 sei_enable) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_SEI_ENABLE_ADDR, sei_enable); +} + +void vidc_sm_get_decoder_sei_enable(struct ddl_buf_addr *shared_mem, + u32 *sei_enable) +{ + *sei_enable = DDL_MEM_READ_32(shared_mem, VIDC_SM_SEI_ENABLE_ADDR); +} + +void vidc_sm_set_error_concealment_config(struct ddl_buf_addr *shared_mem, + u32 inter_slice, u32 intra_slice, u32 conceal_config_enable) +{ + u32 error_conceal_config = 0; + + error_conceal_config = VIDC_SETFIELD(inter_slice, + VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTER_SLICE_SHFT, + VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTER_SLICE_BMSK); + + error_conceal_config |= VIDC_SETFIELD(intra_slice, + VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTRA_SLICE_SHFT, + VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTRA_SLICE_BMSK); + + error_conceal_config |= VIDC_SETFIELD(conceal_config_enable, + VIDC_SM_ERROR_CONCEALMENT_CONFIG_CONCEAL_ENABLE_SHFT, + VIDC_SM_ERROR_CONCEALMENT_CONFIG_CONCEAL_ENABLE_BMSK); + + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ERROR_CONCEALMENT_CONFIG_ADDR, + error_conceal_config); +} + +void vidc_sm_set_decoder_stuff_bytes_consumption( + struct ddl_buf_addr *shared_mem, + enum vidc_sm_num_stuff_bytes_consume_info consume_info) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NUM_STUFF_BYTES_CONSUME_ADDR, + consume_info); +} + +void vidc_sm_get_aspect_ratio_info(struct ddl_buf_addr *shared_mem, + struct vcd_aspect_ratio *aspect_ratio_info) +{ + u32 extended_par_info = 0; + aspect_ratio_info->aspect_ratio = DDL_MEM_READ_32(shared_mem, + VIDC_SM_ASPECT_RATIO_INFO_ADDR); + + if (aspect_ratio_info->aspect_ratio == 0x0f) { + extended_par_info = DDL_MEM_READ_32(shared_mem, + VIDC_SM_EXTENDED_PAR_ADDR); + aspect_ratio_info->extended_par_width = + VIDC_GETFIELD(extended_par_info, + VIDC_SM_EXTENDED_PAR_WIDTH_BMSK, + VIDC_SM_EXTENDED_PAR_WIDTH_SHFT); + aspect_ratio_info->extended_par_height = + VIDC_GETFIELD(extended_par_info, + VIDC_SM_EXTENDED_PAR_HEIGHT_BMSK, + 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); +} + +void vidc_sm_set_video_core_timeout_value(struct ddl_buf_addr *shared_mem, + u32 timeout) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_TIMEOUT_VALUE_ADDR, + timeout); +} + 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 new file mode 100644 index 0000000000000000000000000000000000000000..fd7745414281700102fe87e593f2fe0ea50e5934 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h @@ -0,0 +1,196 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VCD_DDL_SHARED_MEM_H_ +#define _VCD_DDL_SHARED_MEM_H_ + +#include "vcd_ddl.h" + +#define VIDC_SM_PROFILE_MPEG4_SIMPLE (0) +#define VIDC_SM_PROFILE_MPEG4_ADV_SIMPLE (1) + +#define VIDC_SM_PROFILE_H264_BASELINE (0) +#define VIDC_SM_PROFILE_H264_MAIN (1) +#define VIDC_SM_PROFILE_H264_HIGH (2) + +#define VIDC_SM_PROFILE_H263_BASELINE (0) + +#define VIDC_SM_PROFILE_VC1_SIMPLE (0) +#define VIDC_SM_PROFILE_VC1_MAIN (1) +#define VIDC_SM_PROFILE_VC1_ADVANCED (2) + +#define VIDC_SM_PROFILE_MPEG2_MAIN (4) +#define VIDC_SM_PROFILE_MPEG2_SIMPLE (5) + +#define VIDC_SM_LEVEL_MPEG2_LOW (10) +#define VIDC_SM_LEVEL_MPEG2_MAIN (8) +#define VIDC_SM_LEVEL_MPEG2_HIGH_1440 (6) +#define VIDC_SM_LEVEL_MPEG2_HIGH (4) + +#define VIDC_SM_LEVEL_VC1_LOW (0) +#define VIDC_SM_LEVEL_VC1_MEDIUM (2) +#define VIDC_SM_LEVEL_VC1_HIGH (4) + +#define VIDC_SM_LEVEL_VC1_ADV_0 (0) +#define VIDC_SM_LEVEL_VC1_ADV_1 (1) +#define VIDC_SM_LEVEL_VC1_ADV_2 (2) +#define VIDC_SM_LEVEL_VC1_ADV_3 (3) +#define VIDC_SM_LEVEL_VC1_ADV_4 (4) + +#define VIDC_SM_RECOVERY_POINT_SEI (1) +enum VIDC_SM_frame_skip { + VIDC_SM_FRAME_SKIP_DISABLE = 0, + VIDC_SM_FRAME_SKIP_ENABLE_LEVEL = 1, + VIDC_SM_FRAME_SKIP_ENABLE_VBV = 2 +}; +enum VIDC_SM_ref_picture { + VIDC_SM_REF_PICT_FRAME_OR_TOP_FIELD = 0, + VIDC_SM_REF_PICT_BOTTOM_FIELD = 1 +}; + +struct ddl_profile_info_type { + u32 bit_depth_chroma_minus8; + u32 bit_depth_luma_minus8; + u32 pic_level; + u32 chroma_format_idc; + u32 pic_profile; +}; + +enum vidc_sm_mpeg4_profileinfo { + VIDC_SM_PROFILE_INFO_DISABLE = 0, + VIDC_SM_PROFILE_INFO_SP = 1, + VIDC_SM_PROFILE_INFO_ASP = 2, + VIDC_SM_PROFILE_INFO_MAX = 0x7fffffff +}; + +enum vidc_sm_num_stuff_bytes_consume_info { + VIDC_SM_NUM_STUFF_BYTES_CONSUME_ALL = 0x0, + VIDC_SM_NUM_STUFF_BYTES_CONSUME_NONE = 0xffffffff +}; + +void vidc_sm_get_extended_decode_status(struct ddl_buf_addr *shared_mem, + u32 *more_field_needed, + u32 *resl_change); +void vidc_sm_set_frame_tag(struct ddl_buf_addr *shared_mem, + u32 frame_tag); +void vidc_sm_get_frame_tags(struct ddl_buf_addr *shared_mem, + u32 *pn_frame_tag_top, u32 *pn_frame_tag_bottom); +void vidc_sm_get_picture_times(struct ddl_buf_addr *shared_mem, + u32 *pn_time_top, u32 *pn_time_bottom); +void vidc_sm_set_start_byte_number(struct ddl_buf_addr *shared_mem, + u32 byte_num); +void vidc_sm_get_crop_info(struct ddl_buf_addr *shared_mem, u32 *pn_left, + u32 *pn_right, u32 *pn_top, u32 *pn_bottom); +void vidc_sm_get_displayed_picture_frame(struct ddl_buf_addr + *shared_mem, u32 *n_disp_picture_frame); +void vidc_sm_get_available_luma_dpb_address( + struct ddl_buf_addr *shared_mem, u32 *pn_free_luma_dpb_address); +void vidc_sm_get_available_luma_dpb_dec_order_address( + struct ddl_buf_addr *shared_mem, u32 *pn_free_luma_dpb_address); +void vidc_sm_get_dec_order_resl( + struct ddl_buf_addr *shared_mem, u32 *width, u32 *height); +void vidc_sm_get_dec_order_crop_info( + struct ddl_buf_addr *shared_mem, u32 *left, + u32 *right, u32 *top, u32 *bottom); +void vidc_sm_set_extended_encoder_control( + struct ddl_buf_addr *shared_mem, u32 hec_enable, + enum VIDC_SM_frame_skip frame_skip_mode, u32 seq_hdr_in_band, + u32 vbv_buffer_size, u32 cpcfc_enable, u32 sps_pps_control, + u32 closed_gop_enable); +void vidc_sm_set_encoder_param_change(struct ddl_buf_addr *shared_mem, + u32 bit_rate_chg, u32 frame_rate_chg, u32 i_period_chg); +void vidc_sm_set_encoder_vop_time(struct ddl_buf_addr *shared_mem, + u32 vop_time_enable, u32 time_resolution, u32 frame_delta); +void vidc_sm_set_encoder_hec_period(struct ddl_buf_addr *shared_mem, + u32 hec_period); +void vidc_sm_get_h264_encoder_reference_list0( + struct ddl_buf_addr *shared_mem, + enum VIDC_SM_ref_picture *pe_luma_picture0, + u32 *pn_luma_picture_index0, + enum VIDC_SM_ref_picture *pe_luma_picture1, + u32 *pn_luma_picture_index1, + enum VIDC_SM_ref_picture *pe_chroma_picture0, + u32 *pn_chroma_picture_index0, + enum VIDC_SM_ref_picture *pe_chroma_picture1, + u32 *pn_chroma_picture_index1); + +void vidc_sm_get_h264_encoder_reference_list1( + struct ddl_buf_addr *shared_mem, + enum VIDC_SM_ref_picture *pe_luma_picture, + u32 *pn_luma_picture_index, + enum VIDC_SM_ref_picture *pe_chroma_picture, + u32 *pn_chroma_picture_index); +void vidc_sm_set_allocated_dpb_size(struct ddl_buf_addr *shared_mem, + u32 y_size, u32 c_size); +void vidc_sm_set_allocated_h264_mv_size(struct ddl_buf_addr *shared_mem, + u32 mv_size); +void vidc_sm_get_min_yc_dpb_sizes(struct ddl_buf_addr *shared_mem, + u32 *pn_min_luma_dpb_size, u32 *pn_min_chroma_dpb_size); +void vidc_sm_set_metadata_enable(struct ddl_buf_addr *shared_mem, + u32 extradata_enable, u32 qp_enable, u32 concealed_mb_enable, + u32 vc1Param_enable, u32 sei_nal_enable, u32 vui_enable, + u32 enc_slice_size_enable); +void vidc_sm_get_metadata_status(struct ddl_buf_addr *shared_mem, + u32 *pb_metadata_present); +void vidc_sm_get_metadata_display_index(struct ddl_buf_addr *shared_mem, + u32 *pn_dixplay_index); +void vidc_sm_set_metadata_start_address(struct ddl_buf_addr *shared_mem, + u32 address); +void vidc_sm_set_extradata_presence(struct ddl_buf_addr *shared_mem, + u32 extradata_present); +void vidc_sm_set_extradata_addr(struct ddl_buf_addr *shared_mem, + u32 extradata_addr); +void vidc_sm_set_pand_b_frame_qp(struct ddl_buf_addr *shared_mem, + u32 b_frame_qp, u32 p_frame_qp); +void vidc_sm_get_profile_info(struct ddl_buf_addr *shared_mem, + struct ddl_profile_info_type *ddl_profile_info); +void vidc_sm_set_encoder_new_bit_rate(struct ddl_buf_addr *shared_mem, + u32 new_bit_rate); +void vidc_sm_set_encoder_new_frame_rate(struct ddl_buf_addr *shared_mem, + u32 new_frame_rate); +void vidc_sm_set_encoder_new_i_period(struct ddl_buf_addr *shared_mem, + u32 new_i_period); +void vidc_sm_set_encoder_init_rc_value(struct ddl_buf_addr *shared_mem, + u32 new_rc_value); +void vidc_sm_set_idr_decode_only(struct ddl_buf_addr *shared_mem, + u32 enable); +void vidc_sm_set_concealment_color(struct ddl_buf_addr *shared_mem, + u32 conceal_ycolor, u32 conceal_ccolor); +void vidc_sm_set_chroma_addr_change(struct ddl_buf_addr *shared_mem, + u32 addr_change); +void vidc_sm_set_mpeg4_profile_override(struct ddl_buf_addr *shared_mem, + enum vidc_sm_mpeg4_profileinfo profile_info); +void vidc_sm_set_decoder_sei_enable(struct ddl_buf_addr *shared_mem, + u32 sei_enable); +void vidc_sm_get_decoder_sei_enable(struct ddl_buf_addr *shared_mem, + u32 *sei_enable); +void vidc_sm_set_error_concealment_config(struct ddl_buf_addr *shared_mem, + u32 inter_slice, u32 intra_slice, u32 conceal_config_enable); +void vidc_sm_set_decoder_stuff_bytes_consumption( + struct ddl_buf_addr *shared_mem, + 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); +void vidc_sm_set_video_core_timeout_value(struct ddl_buf_addr *shared_mem, + u32 timeout); +#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 new file mode 100644 index 0000000000000000000000000000000000000000..c74234c8325f2f880be3fe18ed614790f6f076fc --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c @@ -0,0 +1,518 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include "vcd_ddl_utils.h" +#include "vcd_ddl.h" +#include "vcd_res_tracker_api.h" + +struct time_data { + unsigned int ddl_t1; + unsigned int ddl_ttotal; + unsigned int ddl_count; +}; +static struct time_data proc_time[MAX_TIME_DATA]; +#define DDL_MSG_TIME(x...) printk(KERN_DEBUG x) +static unsigned int vidc_mmu_subsystem[] = { + MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE}; + +#ifdef DDL_BUF_LOG +static void ddl_print_buffer(struct ddl_context *ddl_context, + struct ddl_buf_addr *buf, u32 idx, u8 *str); +static void ddl_print_port(struct ddl_context *ddl_context, + struct ddl_buf_addr *buf); +static void ddl_print_buffer_port(struct ddl_context *ddl_context, + struct ddl_buf_addr *buf, u32 idx, u8 *str); +#endif +void *ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment) +{ + u32 alloc_size, offset = 0 ; + u32 index = 0; + struct ddl_context *ddl_context; + struct msm_mapped_buffer *mapped_buffer = NULL; + unsigned long iova = 0; + unsigned long buffer_size = 0; + unsigned long *kernel_vaddr = NULL; + unsigned long ionflag = 0; + unsigned long flags = 0; + int ret = 0; + ion_phys_addr_t phyaddr = 0; + size_t len = 0; + int rc = 0; + DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz); + if (!addr) { + DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__); + goto bail_out; + } + ddl_context = ddl_get_context(); + res_trk_set_mem_type(addr->mem_type); + alloc_size = (sz + alignment); + if (res_trk_get_enable_ion()) { + if (!ddl_context->video_ion_client) + ddl_context->video_ion_client = + res_trk_get_ion_client(); + if (!ddl_context->video_ion_client) { + DDL_MSG_ERROR("%s() :DDL ION Client Invalid handle\n", + __func__); + goto bail_out; + } + alloc_size = (alloc_size+4095) & ~4095; + addr->alloc_handle = ion_alloc( + ddl_context->video_ion_client, alloc_size, SZ_4K, + res_trk_get_mem_type()); + if (IS_ERR_OR_NULL(addr->alloc_handle)) { + DDL_MSG_ERROR("%s() :DDL ION alloc failed\n", + __func__); + goto bail_out; + } + if (res_trk_check_for_sec_session() || + addr->mem_type == DDL_FW_MEM) + ionflag = UNCACHED; + else + ionflag = CACHED; + kernel_vaddr = (unsigned long *) ion_map_kernel( + ddl_context->video_ion_client, + addr->alloc_handle, ionflag); + if (IS_ERR_OR_NULL(kernel_vaddr)) { + DDL_MSG_ERROR("%s() :DDL ION map failed\n", + __func__); + goto free_ion_alloc; + } + addr->virtual_base_addr = (u8 *) kernel_vaddr; + if (res_trk_check_for_sec_session()) { + rc = ion_phys(ddl_context->video_ion_client, + addr->alloc_handle, &phyaddr, + &len); + if (rc || !phyaddr) { + DDL_MSG_ERROR( + "%s():DDL ION client physical failed\n", + __func__); + goto unmap_ion_alloc; + } + addr->alloced_phys_addr = phyaddr; + } else { + ret = ion_map_iommu(ddl_context->video_ion_client, + addr->alloc_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL, + SZ_4K, + 0, + &iova, + &buffer_size, + UNCACHED, 0); + if (ret) { + DDL_MSG_ERROR( + "%s():DDL ION ion map iommu failed\n", + __func__); + goto unmap_ion_alloc; + } + addr->alloced_phys_addr = (phys_addr_t) iova; + } + if (!addr->alloced_phys_addr) { + DDL_MSG_ERROR("%s():DDL ION client physical failed\n", + __func__); + goto unmap_ion_alloc; + } + addr->mapped_buffer = NULL; + addr->physical_base_addr = (u8 *) addr->alloced_phys_addr; + addr->align_physical_addr = (u8 *) DDL_ALIGN((u32) + addr->physical_base_addr, alignment); + offset = (u32)(addr->align_physical_addr - + addr->physical_base_addr); + addr->align_virtual_addr = addr->virtual_base_addr + offset; + addr->buffer_size = alloc_size; + } else { + addr->alloced_phys_addr = (phys_addr_t) + allocate_contiguous_memory_nomap(alloc_size, + res_trk_get_mem_type(), SZ_4K); + if (!addr->alloced_phys_addr) { + DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n", + __func__, alloc_size); + goto bail_out; + } + flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR; + if (alignment == DDL_KILO_BYTE(128)) + index = 1; + else if (alignment > SZ_4K) + flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K; + + addr->mapped_buffer = + msm_subsystem_map_buffer((unsigned long)addr->alloced_phys_addr, + alloc_size, flags, &vidc_mmu_subsystem[index], + sizeof(vidc_mmu_subsystem[index])/sizeof(unsigned int)); + if (IS_ERR(addr->mapped_buffer)) { + pr_err(" %s() buffer map failed", __func__); + goto free_acm_alloc; + } + mapped_buffer = addr->mapped_buffer; + if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) { + pr_err("%s() map buffers failed\n", __func__); + goto free_map_buffers; + } + addr->physical_base_addr = (u8 *)mapped_buffer->iova[0]; + addr->virtual_base_addr = mapped_buffer->vaddr; + addr->align_physical_addr = (u8 *) DDL_ALIGN((u32) + addr->physical_base_addr, alignment); + offset = (u32)(addr->align_physical_addr - + addr->physical_base_addr); + addr->align_virtual_addr = addr->virtual_base_addr + offset; + addr->buffer_size = sz; + } + return addr->virtual_base_addr; +free_map_buffers: + msm_subsystem_unmap_buffer(addr->mapped_buffer); + addr->mapped_buffer = NULL; +free_acm_alloc: + free_contiguous_memory_by_paddr( + (unsigned long)addr->alloced_phys_addr); + addr->alloced_phys_addr = (phys_addr_t)NULL; + return NULL; +unmap_ion_alloc: + ion_unmap_kernel(ddl_context->video_ion_client, + addr->alloc_handle); + addr->virtual_base_addr = NULL; + addr->alloced_phys_addr = (phys_addr_t)NULL; +free_ion_alloc: + ion_free(ddl_context->video_ion_client, + addr->alloc_handle); + addr->alloc_handle = NULL; +bail_out: + return NULL; +} + +void ddl_pmem_free(struct ddl_buf_addr *addr) +{ + struct ddl_context *ddl_context; + ddl_context = ddl_get_context(); + if (!addr) { + pr_err("%s() invalid args\n", __func__); + return; + } + if (ddl_context->video_ion_client) { + if (!IS_ERR_OR_NULL(addr->alloc_handle)) { + ion_unmap_kernel(ddl_context->video_ion_client, + addr->alloc_handle); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu(ddl_context->video_ion_client, + addr->alloc_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + } + ion_free(ddl_context->video_ion_client, + addr->alloc_handle); + } + } else { + if (addr->mapped_buffer) + msm_subsystem_unmap_buffer(addr->mapped_buffer); + if (addr->alloced_phys_addr) + free_contiguous_memory_by_paddr( + (unsigned long)addr->alloced_phys_addr); + } + memset(addr, 0, sizeof(struct ddl_buf_addr)); +} + +#ifdef DDL_BUF_LOG + +static void ddl_print_buffer(struct ddl_context *ddl_context, + struct ddl_buf_addr *buf, u32 idx, u8 *str) +{ + struct ddl_buf_addr *base_ram; + s32 offset; + size_t sz, KB = 0; + + base_ram = &ddl_context->dram_base_a; + offset = (s32) DDL_ADDR_OFFSET(*base_ram, *buf); + sz = buf->buffer_size; + if (sz > 0) { + if (!(sz % 1024)) { + sz /= 1024; + KB++; + if (!(sz % 1024)) { + sz /= 1024; + KB++; + } + } + } + DDL_MSG_LOW("\n%12s [%2d]: 0x%08x [0x%04x], 0x%08x(%d%s), %s", + str, idx, (u32) buf->align_physical_addr, + (offset > 0) ? offset : 0, buf->buffer_size, sz, + ((2 == KB) ? "MB" : (1 == KB) ? "KB" : ""), + (((u32) buf->virtual_base_addr) ? "Alloc" : "")); +} + +static void ddl_print_port(struct ddl_context *ddl_context, + struct ddl_buf_addr *buf) +{ + struct ddl_buf_addr *a = &ddl_context->dram_base_a; + struct ddl_buf_addr *b = &ddl_context->dram_base_b; + + if (!buf->align_physical_addr || !buf->buffer_size) + return; + if (buf->align_physical_addr >= a->align_physical_addr && + buf->align_physical_addr + buf->buffer_size <= + a->align_physical_addr + a->buffer_size) + DDL_MSG_LOW(" -A [0x%x]-", DDL_ADDR_OFFSET(*a, *buf)); + else if (buf->align_physical_addr >= b->align_physical_addr && + buf->align_physical_addr + buf->buffer_size <= + b->align_physical_addr + b->buffer_size) + DDL_MSG_LOW(" -B [0x%x]-", DDL_ADDR_OFFSET(*b, *buf)); + else + DDL_MSG_LOW(" -?-"); +} + +static void ddl_print_buffer_port(struct ddl_context *ddl_context, + struct ddl_buf_addr *buf, u32 idx, u8 *str) +{ + DDL_MSG_LOW("\n"); + ddl_print_buffer(ddl_context, buf, idx, str); + ddl_print_port(ddl_context, buf); +} + +void ddl_list_buffers(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context; + u32 i; + + ddl_context = ddl->ddl_context; + DDL_MSG_LOW("\n\n"); + DDL_MSG_LOW("\n Buffer : Start [offs], Size \ + (Size), Alloc/Port"); + DDL_MSG_LOW("\n-------------------------------------------------------\ + -------------------------"); + ddl_print_buffer(ddl_context, &ddl_context->dram_base_a, 0, + "dram_base_a"); + ddl_print_buffer(ddl_context, &ddl_context->dram_base_b, 0, + "dram_base_b"); + if (ddl->codec_data.hdr.decoding) { + struct ddl_dec_buffers *dec_bufs = + &ddl->codec_data.decoder.hw_bufs; + for (i = 0; i < 32; i++) + ddl_print_buffer_port(ddl_context, + &dec_bufs->h264Mv[i], i, "h264Mv"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->h264Vert_nb_mv, 0, "h264Vert_nb_mv"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->h264Nb_ip, 0, "h264Nb_ip"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->nb_dcac, 0, "nb_dcac"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->upnb_mv, 0, "upnb_mv"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->sub_anchor_mv, 0, "sub_anchor_mv"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->overlay_xform, 0, "overlay_xform"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->bit_plane3, 0, "bit_plane3"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->bit_plane2, 0, "bit_plane2"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->bit_plane1, 0, "bit_plane1"); + ddl_print_buffer_port(ddl_context, + dec_bufs->stx_parser, 0, "stx_parser"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->desc, 0, "desc"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->context, 0, "context"); + } else { + struct ddl_enc_buffers *enc_bufs = + &ddl->codec_data.encoder.hw_bufs; + + for (i = 0; i < 4; i++) + ddl_print_buffer_port(ddl_context, + &enc_bufs->dpb_y[i], i, "dpb_y"); + for (i = 0; i < 4; i++) + ddl_print_buffer_port(ddl_context, + &enc_bufs->dpb_c[i], i, "dpb_c"); + ddl_print_buffer_port(ddl_context, &enc_bufs->mv, 0, "mv"); + ddl_print_buffer_port(ddl_context, + &enc_bufs->col_zero, 0, "col_zero"); + ddl_print_buffer_port(ddl_context, &enc_bufs->md, 0, "md"); + ddl_print_buffer_port(ddl_context, + &enc_bufs->pred, 0, "pred"); + ddl_print_buffer_port(ddl_context, + &enc_bufs->nbor_info, 0, "nbor_info"); + ddl_print_buffer_port(ddl_context, + &enc_bufs->acdc_coef, 0, "acdc_coef"); + ddl_print_buffer_port(ddl_context, + &enc_bufs->context, 0, "context"); + } +} +#endif + +u32 ddl_fw_init(struct ddl_buf_addr *dram_base) +{ + u8 *dest_addr; + dest_addr = DDL_GET_ALIGNED_VITUAL(*dram_base); + DDL_MSG_LOW("FW Addr / FW Size : %x/%d", (u32)vidc_video_codec_fw, + vidc_video_codec_fw_size); + if (res_trk_check_for_sec_session() && res_trk_is_cp_enabled()) { + if (res_trk_enable_footswitch()) { + pr_err("Failed to enable footswitch"); + return false; + } + if (res_trk_enable_iommu_clocks()) { + res_trk_disable_footswitch(); + pr_err("Failed to enable iommu clocks\n"); + return false; + } + dram_base->pil_cookie = pil_get("vidc"); + if (res_trk_disable_iommu_clocks()) + pr_err("Failed to disable iommu clocks\n"); + if (IS_ERR_OR_NULL(dram_base->pil_cookie)) { + res_trk_disable_footswitch(); + pr_err("pil_get failed\n"); + return false; + } + } else { + if (vidc_video_codec_fw_size > dram_base->buffer_size || + !vidc_video_codec_fw) + return false; + memcpy(dest_addr, vidc_video_codec_fw, + vidc_video_codec_fw_size); + } + return true; +} + +void ddl_fw_release(struct ddl_buf_addr *dram_base) +{ + void *cookie = dram_base->pil_cookie; + if (res_trk_is_cp_enabled() && + res_trk_check_for_sec_session()) { + res_trk_close_secure_session(); + if (IS_ERR_OR_NULL(cookie)) { + pr_err("Invalid params"); + return; + } + if (res_trk_enable_footswitch()) { + pr_err("Failed to enable footswitch"); + return; + } + if (res_trk_enable_iommu_clocks()) { + res_trk_disable_footswitch(); + pr_err("Failed to enable iommu clocks\n"); + return; + } + pil_put(cookie); + if (res_trk_disable_iommu_clocks()) + pr_err("Failed to disable iommu clocks\n"); + if (res_trk_disable_footswitch()) + pr_err("Failed to disable footswitch\n"); + } else { + if (res_trk_check_for_sec_session()) + res_trk_close_secure_session(); + res_trk_release_fw_addr(); + } +} + +void ddl_set_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); + if (!time_data->ddl_t1) { + time_data->ddl_t1 = act_time; + DDL_MSG_LOW("\n%s(): Start Time (%u)", func_name, act_time); + } else if (vidc_msg_timing) { + DDL_MSG_TIME("\n%s(): Timer already started! St(%u) Act(%u)", + func_name, time_data->ddl_t1, act_time); + } +} + +void ddl_calc_core_proc_time(const char *func_name, u32 index, + struct ddl_client_context *ddl) +{ + struct time_data *time_data = &proc_time[index]; + struct ddl_decoder_data *decoder = NULL; + 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++; + if (vidc_msg_timing) { + 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); + } + if ((index == DEC_OP_TIME) && (time_data->ddl_count > 2) && + (time_data->ddl_count < 6)) { + decoder = &(ddl->codec_data.decoder); + decoder->dec_time_sum = decoder->dec_time_sum + + ddl_t2 - time_data->ddl_t1; + if (time_data->ddl_count == 5) + decoder->avg_dec_time = + decoder->dec_time_sum / 3; + } + time_data->ddl_t1 = 0; + } +} + +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; + proc_time[index].ddl_ttotal = 0; + proc_time[index].ddl_count = 0; +} + +int ddl_get_core_decode_proc_time(u32 *ddl_handle) +{ + int avg_time = 0; + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + avg_time = ddl_vidc_decode_get_avg_time(ddl); + return avg_time; +} + +void ddl_reset_avg_dec_time(u32 *ddl_handle) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + ddl_vidc_decode_reset_avg_time(ddl); +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..565fa93c937bd54061b1f8d3041e46cf053a50e6 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h @@ -0,0 +1,78 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VCD_DDL_UTILS_H_ +#define _VCD_DDL_UTILS_H_ + +#include +#include + +extern u32 vidc_msg_pmem; +extern u32 vidc_msg_timing; + +enum timing_data { + DEC_OP_TIME, + DEC_IP_TIME, + ENC_OP_TIME, + ENC_SLICE_OP_TIME, + MAX_TIME_DATA +}; + +#define DBG_PMEM(x...) \ +do { \ + if (vidc_msg_pmem) \ + printk(KERN_DEBUG x); \ +} while (0) + +#ifdef DDL_MSG_LOG +#define DDL_MSG_LOW(x...) printk(KERN_INFO x) +#define DDL_MSG_MED(x...) printk(KERN_INFO x) +#define DDL_MSG_HIGH(x...) printk(KERN_INFO x) +#else +#define DDL_MSG_LOW(x...) +#define DDL_MSG_MED(x...) +#define DDL_MSG_HIGH(x...) +#endif + +#define DDL_MSG_ERROR(x...) printk(KERN_INFO x) +#define DDL_MSG_FATAL(x...) printk(KERN_INFO x) + +#define DDL_ALIGN_SIZE(sz, guard_bytes, align_mask) \ + (((u32)(sz) + guard_bytes) & align_mask) +#define DDL_ADDR_IS_ALIGNED(addr, align_bytes) \ + (!((u32)(addr) & ((align_bytes) - 1))) +#define DDL_ALIGN(val, grid) ((!(grid)) ? (val) : \ + ((((val) + (grid) - 1) / (grid)) * (grid))) +#define DDL_ALIGN_FLOOR(val, grid) ((!(grid)) ? (val) : \ + (((val) / (grid)) * (grid))) +#define DDL_OFFSET(base, addr) ((!(addr)) ? 0 : (u32)((u8 *) \ + (addr) - (u8 *) (base))) +#define DDL_ADDR_OFFSET(base, addr) DDL_OFFSET((base).align_physical_addr, \ + (addr).align_physical_addr) +#define DDL_GET_ALIGNED_VITUAL(x) ((x).align_virtual_addr) +#define DDL_KILO_BYTE(x) ((x)*1024) +#define DDL_MEGA_BYTE(x) ((x)*1024*1024) +#define DDL_FRAMERATE_SCALE(x) ((x) * 1000) + +#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_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); +int ddl_get_core_decode_proc_time(u32 *ddl_handle); +void ddl_reset_avg_dec_time(u32 *ddl_handle); +#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 new file mode 100644 index 0000000000000000000000000000000000000000..6c2fa5e0fdddfcbd2e3c57cb29d32e4fdcc947ab --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c @@ -0,0 +1,1182 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "vcd_ddl.h" +#include "vcd_ddl_metadata.h" +#include "vcd_ddl_shared_mem.h" +#include "vcd_core.h" + +#if defined(PIX_CACHE_DISABLE) +#define DDL_PIX_CACHE_ENABLE false +#else +#define DDL_PIX_CACHE_ENABLE true +#endif +static unsigned int run_cnt; + +void ddl_vidc_core_init(struct ddl_context *ddl_context) +{ + struct vidc_1080P_pix_cache_config pixel_cache_config; + + vidc_1080p_do_sw_reset(VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE); + msleep(DDL_SW_RESET_SLEEP); + vidc_1080p_do_sw_reset(VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE); + vidc_1080p_init_memory_controller( + (u32) ddl_context->dram_base_a.align_physical_addr, + (u32) ddl_context->dram_base_b.align_physical_addr); + vidc_1080p_clear_returned_channel_inst_id(); + ddl_context->vidc_decode_seq_start[0] = + vidc_1080p_decode_seq_start_ch0; + ddl_context->vidc_decode_seq_start[1] = + vidc_1080p_decode_seq_start_ch1; + ddl_context->vidc_decode_init_buffers[0] = + vidc_1080p_decode_init_buffers_ch0; + ddl_context->vidc_decode_init_buffers[1] = + vidc_1080p_decode_init_buffers_ch1; + ddl_context->vidc_decode_frame_start[0] = + vidc_1080p_decode_frame_start_ch0; + ddl_context->vidc_decode_frame_start[1] = + vidc_1080p_decode_frame_start_ch1; + ddl_context->vidc_set_dec_resolution[0] = + vidc_1080p_set_dec_resolution_ch0; + ddl_context->vidc_set_dec_resolution[1] = + vidc_1080p_set_dec_resolution_ch1; + ddl_context->vidc_encode_seq_start[0] = + vidc_1080p_encode_seq_start_ch0; + ddl_context->vidc_encode_seq_start[1] = + vidc_1080p_encode_seq_start_ch1; + ddl_context->vidc_encode_frame_start[0] = + 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) { + vidc_pix_cache_sw_reset(); + pixel_cache_config.cache_enable = true; + pixel_cache_config.prefetch_en = true; + pixel_cache_config.port_select = VIDC_1080P_PIX_CACHE_PORT_B; + pixel_cache_config.statistics_off = true; + pixel_cache_config.page_size = + VIDC_1080P_PIX_CACHE_PAGE_SIZE_1K; + vidc_pix_cache_init_config(&pixel_cache_config); + } +} + +void ddl_vidc_core_term(struct ddl_context *ddl_context) +{ + if (ddl_context->pix_cache_enable) { + u32 pix_cache_idle = false; + u32 counter = 0; + + vidc_pix_cache_set_halt(true); + + do { + msleep(DDL_SW_RESET_SLEEP); + vidc_pix_cache_get_status_idle(&pix_cache_idle); + counter++; + } while (!pix_cache_idle && + counter < DDL_PIXEL_CACHE_STATUS_READ_RETRY); + + if (!pix_cache_idle) { + ddl_context->cmd_err_status = + DDL_PIXEL_CACHE_NOT_IDLE; + ddl_handle_core_errors(ddl_context); + } + } +} + +void ddl_vidc_channel_set(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + enum vcd_codec *vcd_codec; + enum vidc_1080p_codec codec = VIDC_1080P_H264_DECODE; + const enum vidc_1080p_decode_p_cache_enable + dec_pix_cache = VIDC_1080P_DECODE_PCACHE_DISABLE; + const enum vidc_1080p_encode_p_cache_enable + enc_pix_cache = VIDC_1080P_ENCODE_PCACHE_ENABLE; + u32 pix_cache_ctrl, ctxt_mem_offset, ctxt_mem_size; + + if (ddl->decoding) { + ddl_set_core_start_time(__func__, DEC_OP_TIME); + vcd_codec = &(ddl->codec_data.decoder.codec.codec); + pix_cache_ctrl = (u32)dec_pix_cache; + ctxt_mem_offset = DDL_ADDR_OFFSET(ddl_context->dram_base_a, + ddl->codec_data.decoder.hw_bufs.context) >> 11; + ctxt_mem_size = + ddl->codec_data.decoder.hw_bufs.context.buffer_size; + } else { + vcd_codec = &(ddl->codec_data.encoder.codec.codec); + pix_cache_ctrl = (u32)enc_pix_cache; + ctxt_mem_offset = DDL_ADDR_OFFSET(ddl_context->dram_base_a, + ddl->codec_data.encoder.hw_bufs.context) >> 11; + ctxt_mem_size = + ddl->codec_data.encoder.hw_bufs.context.buffer_size; + } + switch (*vcd_codec) { + default: + case VCD_CODEC_MPEG4: + if (ddl->decoding) + codec = VIDC_1080P_MPEG4_DECODE; + else + codec = VIDC_1080P_MPEG4_ENCODE; + break; + case VCD_CODEC_H264: + if (ddl->decoding) + codec = VIDC_1080P_H264_DECODE; + else + codec = VIDC_1080P_H264_ENCODE; + break; + case VCD_CODEC_DIVX_3: + if (ddl->decoding) + codec = VIDC_1080P_DIVX311_DECODE; + break; + case VCD_CODEC_DIVX_4: + if (ddl->decoding) + codec = VIDC_1080P_DIVX412_DECODE; + break; + case VCD_CODEC_DIVX_5: + if (ddl->decoding) + codec = VIDC_1080P_DIVX502_DECODE; + break; + case VCD_CODEC_DIVX_6: + if (ddl->decoding) + codec = VIDC_1080P_DIVX503_DECODE; + break; + case VCD_CODEC_XVID: + if (ddl->decoding) + codec = VIDC_1080P_MPEG4_DECODE; + break; + case VCD_CODEC_H263: + if (ddl->decoding) + codec = VIDC_1080P_H263_DECODE; + else + codec = VIDC_1080P_H263_ENCODE; + break; + case VCD_CODEC_MPEG1: + case VCD_CODEC_MPEG2: + if (ddl->decoding) + codec = VIDC_1080P_MPEG2_DECODE; + break; + case VCD_CODEC_VC1: + if (ddl->decoding) + codec = VIDC_1080P_VC1_DECODE; + break; + case VCD_CODEC_VC1_RCV: + if (ddl->decoding) + codec = VIDC_1080P_VC1_RCV_DECODE; + break; + } + ddl->cmd_state = DDL_CMD_CHANNEL_SET; + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_CHDONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_CHDONE; + vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_OPEN_CH, + (u32)codec, pix_cache_ctrl, ctxt_mem_offset, + ctxt_mem_size); +} + +void ddl_vidc_decode_init_codec(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vidc_1080p_dec_seq_start_param seq_start_param; + u32 seq_size; + + ddl_set_core_start_time(__func__, DEC_OP_TIME); + vidc_1080p_set_decode_mpeg4_pp_filter(decoder->post_filter.post_filter); + vidc_sm_set_concealment_color(&ddl->shared_mem[ddl->command_channel], + DDL_CONCEALMENT_Y_COLOR, DDL_CONCEALMENT_C_COLOR); + + vidc_sm_set_error_concealment_config( + &ddl->shared_mem[ddl->command_channel], + VIDC_SM_ERR_CONCEALMENT_INTER_SLICE_MB_COPY, + VIDC_SM_ERR_CONCEALMENT_INTRA_SLICE_COLOR_CONCEALMENT, + VIDC_SM_ERR_CONCEALMENT_ENABLE); + + ddl_vidc_metadata_enable(ddl); + vidc_sm_set_metadata_start_address(&ddl->shared_mem + [ddl->command_channel], + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + ddl->codec_data.decoder.meta_data_input)); + + vidc_sm_set_idr_decode_only(&ddl->shared_mem[ddl->command_channel], + decoder->idr_only_decoding); + + if ((decoder->codec.codec == VCD_CODEC_DIVX_3) || + (decoder->codec.codec == VCD_CODEC_VC1_RCV || + decoder->codec.codec == VCD_CODEC_VC1)) + ddl_context->vidc_set_dec_resolution + [ddl->command_channel](decoder->client_frame_size.width, + decoder->client_frame_size.height); + else + ddl_context->vidc_set_dec_resolution + [ddl->command_channel](0x0, 0x0); + DDL_MSG_LOW("HEADER-PARSE-START"); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_INITCODECDONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODECDONE; + ddl->cmd_state = DDL_CMD_HEADER_PARSE; + seq_start_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + seq_start_param.inst_id = ddl->instance_id; + seq_start_param.shared_mem_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, ddl->shared_mem + [ddl->command_channel]); + seq_start_param.stream_buffer_addr_offset = + DDL_OFFSET(ddl_context->dram_base_a.align_physical_addr, + decoder->decode_config.sequence_header); + seq_start_param.stream_buffersize = + decoder->client_input_buf_req.sz; + seq_size = decoder->decode_config.sequence_header_len + + DDL_LINEAR_BUFFER_ALIGN_BYTES + VCD_SEQ_HDR_PADDING_BYTES; + if (seq_start_param.stream_buffersize < seq_size) + seq_start_param.stream_buffersize = seq_size; + seq_start_param.stream_frame_size = + decoder->decode_config.sequence_header_len; + seq_start_param.descriptor_buffer_addr_offset = + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + decoder->hw_bufs.desc), + seq_start_param.descriptor_buffer_size = + decoder->hw_bufs.desc.buffer_size; + if ((decoder->codec.codec == VCD_CODEC_MPEG4) || + (decoder->codec.codec == VCD_CODEC_DIVX_4) || + (decoder->codec.codec == VCD_CODEC_DIVX_5) || + (decoder->codec.codec == VCD_CODEC_DIVX_6) || + (decoder->codec.codec == VCD_CODEC_XVID)) + vidc_sm_set_mpeg4_profile_override( + &ddl->shared_mem[ddl->command_channel], + VIDC_SM_PROFILE_INFO_ASP); + if (VCD_CODEC_H264 == decoder->codec.codec) + vidc_sm_set_decoder_sei_enable( + &ddl->shared_mem[ddl->command_channel], + VIDC_SM_RECOVERY_POINT_SEI); + ddl_context->vidc_decode_seq_start[ddl->command_channel]( + &seq_start_param); + + vidc_sm_set_decoder_stuff_bytes_consumption( + &ddl->shared_mem[ddl->command_channel], + VIDC_SM_NUM_STUFF_BYTES_CONSUME_NONE); +} + +void ddl_vidc_decode_dynamic_property(struct ddl_client_context *ddl, + u32 enable) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vcd_frame_data *bit_stream = + &(ddl->input_frame.vcd_frm); + struct ddl_context *ddl_context = ddl->ddl_context; + + if (!enable) { + if (decoder->dynmic_prop_change_req) + decoder->dynmic_prop_change_req = false; + return; + } + if ((decoder->dynamic_prop_change & DDL_DEC_REQ_OUTPUT_FLUSH)) { + decoder->dynmic_prop_change_req = true; + decoder->dynamic_prop_change &= ~(DDL_DEC_REQ_OUTPUT_FLUSH); + decoder->dpb_mask.hw_mask = 0; + decoder->flush_pending = true; + } + if (((decoder->meta_data_enable_flag & VCD_METADATA_PASSTHROUGH)) && + ((VCD_FRAME_FLAG_EXTRADATA & bit_stream->flags))) { + u32 extradata_presence = true; + u8* tmp = ((u8 *) bit_stream->physical + + bit_stream->offset + + bit_stream->data_len + 3); + u32 extra_data_start = (u32) ((u32)tmp & ~3); + + extra_data_start = extra_data_start - + (u32)ddl_context->dram_base_a.align_physical_addr; + decoder->dynmic_prop_change_req = true; + vidc_sm_set_extradata_addr(&ddl->shared_mem + [ddl->command_channel], extra_data_start); + vidc_sm_set_extradata_presence(&ddl->shared_mem + [ddl->command_channel], extradata_presence); + } +} + +void ddl_vidc_encode_dynamic_property(struct ddl_client_context *ddl, + u32 enable) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + u32 frame_rate_change = false, bit_rate_change = false; + u32 i_period_change = false, reset_req = false; + + if (!enable) { + if (encoder->dynmic_prop_change_req) { + reset_req = true; + encoder->dynmic_prop_change_req = false; + } + } else { + if ((encoder->dynamic_prop_change & DDL_ENC_REQ_IFRAME)) { + encoder->intra_frame_insertion = true; + encoder->dynamic_prop_change &= + ~(DDL_ENC_REQ_IFRAME); + } + if ((encoder->dynamic_prop_change & + DDL_ENC_CHANGE_BITRATE)) { + bit_rate_change = true; + vidc_sm_set_encoder_new_bit_rate( + &ddl->shared_mem[ddl->command_channel], + encoder->target_bit_rate.target_bitrate); + encoder->dynamic_prop_change &= + ~(DDL_ENC_CHANGE_BITRATE); + } + if ((encoder->dynamic_prop_change + & DDL_ENC_CHANGE_IPERIOD)) { + i_period_change = true; + vidc_sm_set_encoder_new_i_period( + &ddl->shared_mem[ddl->command_channel], + encoder->i_period.p_frames); + encoder->dynamic_prop_change &= + ~(DDL_ENC_CHANGE_IPERIOD); + } + if ((encoder->dynamic_prop_change + & DDL_ENC_CHANGE_FRAMERATE)) { + frame_rate_change = true; + vidc_sm_set_encoder_new_frame_rate( + &ddl->shared_mem[ddl->command_channel], + (u32)(DDL_FRAMERATE_SCALE(encoder->\ + frame_rate.fps_numerator) / + encoder->frame_rate.fps_denominator)); + encoder->dynamic_prop_change &= + ~(DDL_ENC_CHANGE_FRAMERATE); + } + } + if ((enable) || (reset_req)) { + vidc_sm_set_encoder_param_change( + &ddl->shared_mem[ddl->command_channel], + bit_rate_change, frame_rate_change, + i_period_change); + } +} + +static void ddl_vidc_encode_set_profile_level( + struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + u32 encode_profile, level = 0; + + switch (encoder->profile.profile) { + default: + case VCD_PROFILE_MPEG4_SP: + encode_profile = VIDC_1080P_PROFILE_MPEG4_SIMPLE; + break; + case VCD_PROFILE_MPEG4_ASP: + encode_profile = VIDC_1080P_PROFILE_MPEG4_ADV_SIMPLE; + break; + case VCD_PROFILE_H264_BASELINE: + encode_profile = VIDC_1080P_PROFILE_H264_BASELINE; + break; + case VCD_PROFILE_H264_MAIN: + encode_profile = VIDC_1080P_PROFILE_H264_MAIN; + break; + case VCD_PROFILE_H264_HIGH: + encode_profile = VIDC_1080P_PROFILE_H264_HIGH; + break; + } + switch (encoder->level.level) { + default: + case VCD_LEVEL_MPEG4_0: + level = VIDC_1080P_MPEG4_LEVEL0; + break; + case VCD_LEVEL_MPEG4_0b: + level = VIDC_1080P_MPEG4_LEVEL0b; + break; + case VCD_LEVEL_MPEG4_1: + level = VIDC_1080P_MPEG4_LEVEL1; + break; + case VCD_LEVEL_MPEG4_2: + level = VIDC_1080P_MPEG4_LEVEL2; + break; + case VCD_LEVEL_MPEG4_3: + level = VIDC_1080P_MPEG4_LEVEL3; + break; + case VCD_LEVEL_MPEG4_3b: + level = VIDC_1080P_MPEG4_LEVEL3b; + break; + case VCD_LEVEL_MPEG4_4: + level = VIDC_1080P_MPEG4_LEVEL4; + break; + case VCD_LEVEL_MPEG4_4a: + level = VIDC_1080P_MPEG4_LEVEL4a; + break; + case VCD_LEVEL_MPEG4_5: + level = VIDC_1080P_MPEG4_LEVEL5; + break; + case VCD_LEVEL_MPEG4_6: + level = VIDC_1080P_MPEG4_LEVEL6; + break; + case VCD_LEVEL_MPEG4_7: + level = VIDC_1080P_MPEG4_LEVEL7; + break; + case VCD_LEVEL_H264_1: + level = VIDC_1080P_H264_LEVEL1; + break; + case VCD_LEVEL_H264_1b: + level = VIDC_1080P_H264_LEVEL1b; + break; + case VCD_LEVEL_H264_1p1: + level = VIDC_1080P_H264_LEVEL1p1; + break; + case VCD_LEVEL_H264_1p2: + level = VIDC_1080P_H264_LEVEL1p2; + break; + case VCD_LEVEL_H264_1p3: + level = VIDC_1080P_H264_LEVEL1p3; + break; + case VCD_LEVEL_H264_2: + level = VIDC_1080P_H264_LEVEL2; + break; + case VCD_LEVEL_H264_2p1: + level = VIDC_1080P_H264_LEVEL2p1; + break; + case VCD_LEVEL_H264_2p2: + level = VIDC_1080P_H264_LEVEL2p2; + break; + case VCD_LEVEL_H264_3: + level = VIDC_1080P_H264_LEVEL3; + break; + case VCD_LEVEL_H264_3p1: + level = VIDC_1080P_H264_LEVEL3p1; + break; + case VCD_LEVEL_H264_3p2: + level = VIDC_1080P_H264_LEVEL3p2; + break; + case VCD_LEVEL_H264_4: + level = VIDC_1080P_H264_LEVEL4; + break; + case VCD_LEVEL_H263_10: + level = VIDC_1080P_H263_LEVEL10; + break; + case VCD_LEVEL_H263_20: + level = VIDC_1080P_H263_LEVEL20; + break; + case VCD_LEVEL_H263_30: + level = VIDC_1080P_H263_LEVEL30; + break; + case VCD_LEVEL_H263_40: + level = VIDC_1080P_H263_LEVEL40; + break; + case VCD_LEVEL_H263_45: + level = VIDC_1080P_H263_LEVEL45; + break; + case VCD_LEVEL_H263_50: + level = VIDC_1080P_H263_LEVEL50; + break; + case VCD_LEVEL_H263_60: + level = VIDC_1080P_H263_LEVEL60; + break; + case VCD_LEVEL_H263_70: + level = VIDC_1080P_H263_LEVEL70; + break; + } + vidc_1080p_set_encode_profile_level(encode_profile, level); +} + +static void ddl_vidc_encode_set_multi_slice_info( + struct ddl_encoder_data *encoder) +{ + enum vidc_1080p_MSlice_selection m_slice_sel; + u32 i_multi_slice_size = 0, i_multi_slice_byte = 0; + + if (!encoder) { + DDL_MSG_ERROR("Invalid Parameter"); + return; + } + + switch (encoder->multi_slice.m_slice_sel) { + default: + case VCD_MSLICE_OFF: + m_slice_sel = VIDC_1080P_MSLICE_DISABLE; + break; + case VCD_MSLICE_BY_GOB: + case VCD_MSLICE_BY_MB_COUNT: + m_slice_sel = VIDC_1080P_MSLICE_BY_MB_COUNT; + i_multi_slice_size = encoder->multi_slice.m_slice_size; + break; + case VCD_MSLICE_BY_BYTE_COUNT: + m_slice_sel = VIDC_1080P_MSLICE_BY_BYTE_COUNT; + i_multi_slice_byte = encoder->multi_slice.m_slice_size; + break; + } + vidc_1080p_set_encode_multi_slice_control(m_slice_sel, + 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; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + struct ddl_enc_buffers *enc_buffers = &encoder->hw_bufs; + struct vidc_1080p_enc_seq_start_param seq_start_param; + enum vidc_1080p_memory_access_method mem_access_method; + enum vidc_1080p_DBConfig db_config; + enum VIDC_SM_frame_skip r_cframe_skip = + VIDC_SM_FRAME_SKIP_DISABLE; + u32 index, luma[4], chroma[4], hdr_ext_control = false; + const u32 recon_bufs = 4; + u32 h263_cpfc_enable = false; + u32 scaled_frame_rate; + + ddl_vidc_encode_set_profile_level(ddl); + vidc_1080p_set_encode_frame_size(encoder->frame_size.width, + encoder->frame_size.height); + vidc_1080p_encode_set_qp_params(encoder->qp_range.max_qp, + encoder->qp_range.min_qp); + vidc_1080p_encode_set_rc_config(encoder->rc_level.frame_level_rc, + encoder->rc_level.mb_level_rc, + encoder->session_qp.i_frame_qp); + if (encoder->hdr_ext_control > 0) + hdr_ext_control = true; + if (encoder->r_cframe_skip > 0) + r_cframe_skip = VIDC_SM_FRAME_SKIP_ENABLE_LEVEL; + scaled_frame_rate = DDL_FRAMERATE_SCALE(encoder->\ + frame_rate.fps_numerator) / + encoder->frame_rate.fps_denominator; + if ((encoder->codec.codec == VCD_CODEC_H263) && + (DDL_FRAMERATE_SCALE(DDL_INITIAL_FRAME_RATE) + != scaled_frame_rate)) + h263_cpfc_enable = true; + vidc_sm_set_extended_encoder_control(&ddl->shared_mem + [ddl->command_channel], hdr_ext_control, + r_cframe_skip, false, 0, + h263_cpfc_enable, encoder->sps_pps.sps_pps_for_idr_enable_flag, + encoder->closed_gop); + vidc_sm_set_encoder_init_rc_value(&ddl->shared_mem + [ddl->command_channel], + encoder->target_bit_rate.target_bitrate); + vidc_sm_set_encoder_hec_period(&ddl->shared_mem + [ddl->command_channel], encoder->hdr_ext_control); + vidc_sm_set_encoder_vop_time(&ddl->shared_mem + [ddl->command_channel], true, + encoder->vop_timing.vop_time_resolution, 0); + if (encoder->rc_level.frame_level_rc) + vidc_1080p_encode_set_frame_level_rc_params( + scaled_frame_rate, + encoder->target_bit_rate.target_bitrate, + encoder->frame_level_rc.reaction_coeff); + if (encoder->rc_level.mb_level_rc) + vidc_1080p_encode_set_mb_level_rc_params( + encoder->adaptive_rc.disable_dark_region_as_flag, + encoder->adaptive_rc.disable_smooth_region_as_flag, + encoder->adaptive_rc.disable_static_region_as_flag, + encoder->adaptive_rc.disable_activity_region_flag); + if ((!encoder->rc_level.frame_level_rc) && + (!encoder->rc_level.mb_level_rc)) + 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 (encoder->codec.codec == VCD_CODEC_MPEG4) { + vidc_1080p_set_mpeg4_encode_quarter_pel_control(false); + vidc_1080p_set_encode_field_picture_structure(false); + } + if (encoder->codec.codec == VCD_CODEC_H264) { + enum vidc_1080p_entropy_sel entropy_sel; + switch (encoder->entropy_control.entropy_sel) { + default: + case VCD_ENTROPY_SEL_CAVLC: + entropy_sel = VIDC_1080P_ENTROPY_SEL_CAVLC; + break; + case VCD_ENTROPY_SEL_CABAC: + entropy_sel = VIDC_1080P_ENTROPY_SEL_CABAC; + break; + } + vidc_1080p_set_h264_encode_entropy(entropy_sel); + switch (encoder->db_control.db_config) { + default: + case VCD_DB_ALL_BLOCKING_BOUNDARY: + db_config = VIDC_1080P_DB_ALL_BLOCKING_BOUNDARY; + break; + case VCD_DB_DISABLE: + db_config = VIDC_1080P_DB_DISABLE; + break; + case VCD_DB_SKIP_SLICE_BOUNDARY: + db_config = VIDC_1080P_DB_SKIP_SLICE_BOUNDARY; + break; + } + vidc_1080p_set_h264_encode_loop_filter(db_config, + encoder->db_control.slice_alpha_offset, + encoder->db_control.slice_beta_offset); + vidc_1080p_set_h264_encoder_p_frame_ref_count(encoder->\ + num_references_for_p_frame); + if (encoder->profile.profile == VCD_PROFILE_H264_HIGH) + vidc_1080p_set_h264_encode_8x8transform_control(true); + } + vidc_1080p_set_encode_picture(encoder->i_period.p_frames, + encoder->i_period.b_frames); + vidc_1080p_set_encode_circular_intra_refresh( + encoder->intra_refresh.cir_mb_number); + ddl_vidc_encode_set_multi_slice_info(encoder); + ddl_vidc_metadata_enable(ddl); + if (encoder->meta_data_enable_flag) + vidc_sm_set_metadata_start_address(&ddl->shared_mem + [ddl->command_channel], DDL_ADDR_OFFSET( + ddl_context->dram_base_a, + ddl->codec_data.encoder.meta_data_input)); + luma[0] = DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->dpb_y[0]); + luma[1] = DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->dpb_y[1]); + if (encoder->hw_bufs.dpb_count == DDL_ENC_MAX_DPB_BUFFERS) { + luma[2] = DDL_ADDR_OFFSET(ddl_context->dram_base_b, + enc_buffers->dpb_y[2]); + luma[3] = DDL_ADDR_OFFSET(ddl_context->dram_base_b, + enc_buffers->dpb_y[3]); + } + for (index = 0; index < recon_bufs; index++) + chroma[index] = DDL_ADDR_OFFSET(ddl_context->dram_base_b, + enc_buffers->dpb_c[index]); + vidc_1080p_set_encode_recon_buffers(recon_bufs, luma, chroma); + switch (encoder->codec.codec) { + case VCD_CODEC_MPEG4: + vidc_1080p_set_mpeg4_encode_work_buffers( + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->col_zero), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->acdc_coef), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->mv)); + break; + case VCD_CODEC_H263: + vidc_1080p_set_h263_encode_work_buffers( + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->acdc_coef)); + break; + case VCD_CODEC_H264: + vidc_1080p_set_h264_encode_work_buffers( + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->col_zero), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->md), + DDL_ADDR_OFFSET(ddl_context->dram_base_b, + enc_buffers->pred), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->nbor_info), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->mb_info)); + break; + default: + break; + } + if (encoder->buf_format.buffer_format == + VCD_BUFFER_FORMAT_NV12_16M2KA) + mem_access_method = VIDC_1080P_TILE_LINEAR; + else + mem_access_method = VIDC_1080P_TILE_64x32; + vidc_1080p_set_encode_input_frame_format(mem_access_method); + vidc_1080p_set_encode_padding_control(0, 0, 0, 0); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_INITCODECDONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODECDONE; + ddl->cmd_state = DDL_CMD_INIT_CODEC; + vidc_1080p_set_encode_field_picture_structure(false); + seq_start_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + seq_start_param.inst_id = ddl->instance_id; + seq_start_param.shared_mem_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, ddl->shared_mem + [ddl->command_channel]); + seq_start_param.stream_buffer_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, encoder->seq_header); + seq_start_param.stream_buffer_size = + encoder->seq_header.buffer_size; + encoder->seq_header_length = 0; + ddl_context->vidc_encode_seq_start[ddl->command_channel]( + &seq_start_param); +} + +void ddl_vidc_channel_end(struct ddl_client_context *ddl) +{ + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_CHEND", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_CHEND; + ddl->cmd_state = DDL_CMD_CHANNEL_END; + vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_CLOSE_CH, + ddl->instance_id, 0, 0, 0); +} + +void ddl_vidc_encode_frame_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 *stream = &(ddl->output_frame.vcd_frm); + 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; + + DDL_MSG_LOW("%s\n", __func__); + ddl_vidc_encode_set_metadata_output_buf(ddl); + + encoder->enc_frame_info.meta_data_exists = false; + + 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); + if (input_vcd_frm->flags & VCD_FRAME_FLAG_EOS) { + enc_param.encode = VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA; + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_EOS_DONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE; + } else { + enc_param.encode = VIDC_1080P_ENC_TYPE_FRAME_DATA; + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_FRAME_DONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE; + } + ddl->cmd_state = DDL_CMD_ENCODE_FRAME; + if (encoder->dynamic_prop_change) { + encoder->dynmic_prop_change_req = true; + ddl_vidc_encode_dynamic_property(ddl, true); + } + + 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_addr_offset = DDL_OFFSET( + ddl_context->dram_base_a.align_physical_addr, stream->physical); + enc_param.stream_buffer_size = + encoder->client_output_buf_req.sz; + + 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 = false; + 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); + 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(); + } + ddl_context->vidc_encode_frame_start[ddl->command_channel] ( + &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; + encoder->batch_frame.first_output_frame_tag = 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; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + u32 vcd_status = VCD_S_SUCCESS; + struct vidc_1080p_dec_init_buffers_param init_buf_param; + u32 size_y = 0; + u32 size_c = 0; + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) { + DDL_MSG_ERROR("STATE-CRITICAL"); + return VCD_ERR_FAIL; + } + ddl_set_vidc_timeout(ddl); + ddl_vidc_decode_set_metadata_output(decoder); + if (decoder->dp_buf.no_of_dec_pic_buf < + decoder->client_output_buf_req.actual_count) + return VCD_ERR_BAD_STATE; + if (decoder->codec.codec == VCD_CODEC_H264) { + vidc_sm_set_allocated_h264_mv_size( + &ddl->shared_mem[ddl->command_channel], + decoder->hw_bufs.h264_mv[0].buffer_size); + } + if (vcd_status) + return vcd_status; +#ifdef DDL_BUF_LOG + ddl_list_buffers(ddl); +#endif + ddl_set_core_start_time(__func__, DEC_OP_TIME); + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_INIT); + if (ddl_decoder_dpb_init(ddl) == VCD_ERR_FAIL) + return VCD_ERR_FAIL; + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_DPBDONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_DPBDONE; + ddl->cmd_state = DDL_CMD_DECODE_SET_DPB; + if (decoder->cont_mode) { + size_y = ddl_get_yuv_buf_size(decoder->client_frame_size.width, + decoder->client_frame_size.height, + DDL_YUV_BUF_TYPE_TILE); + size_c = ddl_get_yuv_buf_size(decoder->client_frame_size.width, + (decoder->client_frame_size.height >> 1), + DDL_YUV_BUF_TYPE_TILE); + vidc_sm_set_allocated_dpb_size( + &ddl->shared_mem[ddl->command_channel], + size_y, + size_c); + } else { + vidc_sm_set_allocated_dpb_size( + &ddl->shared_mem[ddl->command_channel], + decoder->dpb_buf_size.size_y, + decoder->dpb_buf_size.size_c); + } + init_buf_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + init_buf_param.inst_id = ddl->instance_id; + init_buf_param.shared_mem_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, ddl->shared_mem + [ddl->command_channel]); + init_buf_param.dpb_count = decoder->dp_buf.no_of_dec_pic_buf; + init_buf_param.dmx_disable = decoder->dmx_disable; + ddl_context->vidc_decode_init_buffers[ddl->command_channel] ( + &init_buf_param); + return VCD_S_SUCCESS; +} + +void ddl_vidc_decode_frame_run(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vcd_frame_data *bit_stream = + &(ddl->input_frame.vcd_frm); + struct ddl_dec_buffers *dec_buffers = &decoder->hw_bufs; + struct ddl_mask *dpb_mask = &ddl->codec_data.decoder.dpb_mask; + struct vidc_1080p_dec_frame_start_param dec_param; + u32 dpb_addr_y[32], index; + ddl_set_core_start_time(__func__, DEC_OP_TIME); + ddl_set_core_start_time(__func__, DEC_IP_TIME); + if ((!bit_stream->data_len) || (!bit_stream->physical)) { + ddl_vidc_decode_eos_run(ddl); + return; + } + DDL_MSG_LOW("ddl_state_transition: %s ~~" + "DDL_CLIENT_WAIT_FOR_FRAME_DONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE; + ddl_vidc_decode_dynamic_property(ddl, true); + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK); + ddl->cmd_state = DDL_CMD_DECODE_FRAME; + dec_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + dec_param.inst_id = ddl->instance_id; + dec_param.shared_mem_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, ddl->shared_mem + [ddl->command_channel]); + dec_param.stream_buffer_addr_offset = DDL_OFFSET( + ddl_context->dram_base_a.align_physical_addr, + bit_stream->physical); + dec_param.stream_frame_size = bit_stream->data_len; + dec_param.stream_buffersize = decoder->client_input_buf_req.sz; + dec_param.descriptor_buffer_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, dec_buffers->desc); + dec_param.descriptor_buffer_size = dec_buffers->desc.buffer_size; + dec_param.release_dpb_bit_mask = dpb_mask->hw_mask; + dec_param.decode = VIDC_1080P_DEC_TYPE_FRAME_DATA; + dec_param.dpb_count = decoder->dp_buf.no_of_dec_pic_buf; + dec_param.dmx_disable = decoder->dmx_disable; + if (decoder->dmx_disable) + ddl_fill_dec_desc_buffer(ddl); + if (decoder->flush_pending) { + dec_param.dpb_flush = true; + decoder->flush_pending = false; + } else + dec_param.dpb_flush = false; + vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel], + bit_stream->ip_frm_tag); + if (ddl_context->pix_cache_enable) { + for (index = 0; index < + decoder->dp_buf.no_of_dec_pic_buf; index++) { + dpb_addr_y[index] = (u32) + decoder->dp_buf.dec_pic_buffers + [index].vcd_frm.physical; + } + vidc_pix_cache_init_luma_chroma_base_addr( + decoder->dp_buf.no_of_dec_pic_buf, + dpb_addr_y, NULL); + vidc_pix_cache_set_frame_range(decoder->dpb_buf_size.size_y, + decoder->dpb_buf_size.size_c); + vidc_pix_cache_clear_cache_tags(); + } + ddl_context->vidc_decode_frame_start[ddl->command_channel] ( + &dec_param); +} + +void ddl_vidc_decode_eos_run(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vcd_frame_data *bit_stream = + &(ddl->input_frame.vcd_frm); + struct ddl_dec_buffers *dec_buffers = &(decoder->hw_bufs); + struct ddl_mask *dpb_mask = + &(ddl->codec_data.decoder.dpb_mask); + struct vidc_1080p_dec_frame_start_param dec_param; + + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_EOS_DONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE; + if (decoder->output_order == VCD_DEC_ORDER_DECODE) + decoder->dynamic_prop_change |= DDL_DEC_REQ_OUTPUT_FLUSH; + ddl_vidc_decode_dynamic_property(ddl, true); + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK); + decoder->dynmic_prop_change_req = true; + ddl->cmd_state = DDL_CMD_EOS; + memset(&dec_param, 0, sizeof(dec_param)); + dec_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + dec_param.inst_id = ddl->instance_id; + dec_param.shared_mem_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, + ddl->shared_mem[ddl->command_channel]); + dec_param.descriptor_buffer_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, dec_buffers->desc); + dec_param.descriptor_buffer_size = dec_buffers->desc.buffer_size; + dec_param.release_dpb_bit_mask = dpb_mask->hw_mask; + dec_param.decode = VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA; + dec_param.dpb_count = decoder->dp_buf.no_of_dec_pic_buf; + if (decoder->flush_pending) { + dec_param.dpb_flush = true; + decoder->flush_pending = false; + } else + dec_param.dpb_flush = false; + vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel], + bit_stream->ip_frm_tag); + 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); +} + +int ddl_vidc_decode_get_avg_time(struct ddl_client_context *ddl) +{ + int avg_time = 0; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + avg_time = decoder->avg_dec_time; + return avg_time; +} + +void ddl_vidc_decode_reset_avg_time(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + decoder->avg_dec_time = 0; + decoder->dec_time_sum = 0; +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.c b/drivers/video/msm/vidc/1080p/ddl/vidc.c new file mode 100644 index 0000000000000000000000000000000000000000..00f75a9b057997959bcccc8f746794e02c6ab882 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vidc.c @@ -0,0 +1,1108 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "vidc.h" +#include "vidc_hwio.h" + + +#define VIDC_1080P_INIT_CH_INST_ID 0x0000ffff +#define VIDC_1080P_RESET_VI 0x3f7 +#define VIDC_1080P_RESET_VI_RISC 0x3f6 +#define VIDC_1080P_RESET_VI_VIDC_RISC 0x3f2 +#define VIDC_1080P_RESET_ALL 0 +#define VIDC_1080P_RESET_RISC 0x3fe +#define VIDC_1080P_RESET_NONE 0x3ff +#define VIDC_1080P_INTERRUPT_CLEAR 0 +#define VIDC_1080P_MAX_H264DECODER_DPB 32 +#define VIDC_1080P_MAX_DEC_RECON_BUF 32 + +#define VIDC_1080P_SI_RG7_DISPLAY_STATUS_MASK 0x00000007 +#define VIDC_1080P_SI_RG7_DISPLAY_STATUS_SHIFT 0 +#define VIDC_1080P_SI_RG7_DISPLAY_CODING_MASK 0x00000008 +#define VIDC_1080P_SI_RG7_DISPLAY_CODING_SHIFT 3 +#define VIDC_1080P_SI_RG7_DISPLAY_RES_MASK 0x00000030 +#define VIDC_1080P_SI_RG7_DISPLAY_RES_SHIFT 4 + +#define VIDC_1080P_SI_RG7_DISPLAY_CROP_MASK 0x00000040 +#define VIDC_1080P_SI_RG7_DISPLAY_CROP_SHIFT 6 + +#define VIDC_1080P_SI_RG7_DISPLAY_CORRECT_MASK 0x00000180 +#define VIDC_1080P_SI_RG7_DISPLAY_CORRECT_SHIFT 7 +#define VIDC_1080P_SI_RG8_DECODE_FRAMETYPE_MASK 0x00000007 + +#define VIDC_1080P_SI_RG10_NUM_DPB_BMSK 0x00003fff +#define VIDC_1080P_SI_RG10_NUM_DPB_SHFT 0 +#define VIDC_1080P_SI_RG10_DPB_FLUSH_BMSK 0x00004000 +#define VIDC_1080P_SI_RG10_DPB_FLUSH_SHFT 14 +#define VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK 0x00008000 +#define VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT 15 + +#define VIDC_1080P_SI_RG11_DECODE_STATUS_MASK 0x00000007 +#define VIDC_1080P_SI_RG11_DECODE_STATUS_SHIFT 0 +#define VIDC_1080P_SI_RG11_DECODE_CODING_MASK 0x00000008 +#define VIDC_1080P_SI_RG11_DECODE_CODING_SHIFT 3 +#define VIDC_1080P_SI_RG11_DECODE_RES_MASK 0x000000C0 +#define VIDC_1080P_SI_RG11_DECODE_RES_SHIFT 6 +#define VIDC_1080P_SI_RG11_DECODE_CROPP_MASK 0x00000100 +#define VIDC_1080P_SI_RG11_DECODE_CROPP_SHIFT 8 + +#define VIDC_1080P_SI_RG11_DECODE_CORRECT_MASK 0x00000600 +#define VIDC_1080P_SI_RG11_DECODE_CORRECT_SHIFT 9 +#define VIDC_1080P_BASE_OFFSET_SHIFT 11 + + +#define VIDC_1080P_H264DEC_LUMA_ADDR HWIO_REG_759068_ADDR +#define VIDC_1080P_H264DEC_CHROMA_ADDR HWIO_REG_515200_ADDR +#define VIDC_1080P_H264DEC_MV_PLANE_ADDR HWIO_REG_466192_ADDR + +#define VIDC_1080P_DEC_LUMA_ADDR HWIO_REG_759068_ADDR +#define VIDC_1080P_DEC_CHROMA_ADDR HWIO_REG_515200_ADDR + +#define VIDC_1080P_DEC_TYPE_SEQ_HEADER 0x00010000 +#define VIDC_1080P_DEC_TYPE_FRAME_DATA 0x00020000 +#define VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA 0x00030000 +#define VIDC_1080P_DEC_TYPE_INIT_BUFFERS 0x00040000 + +#define VIDC_1080P_ENC_TYPE_SEQ_HEADER 0x00010000 +#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; + +void vidc_1080p_do_sw_reset(enum vidc_1080p_reset init_flag) +{ + if (init_flag == VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE) { + u32 sw_reset_value = 0; + + VIDC_HWIO_IN(REG_557899, &sw_reset_value); + sw_reset_value &= (~HWIO_REG_557899_RSTN_VI_BMSK); + VIDC_HWIO_OUT(REG_557899, sw_reset_value); + sw_reset_value &= (~HWIO_REG_557899_RSTN_RISC_BMSK); + VIDC_HWIO_OUT(REG_557899, sw_reset_value); + sw_reset_value &= (~(HWIO_REG_557899_RSTN_VIDCCORE_BMSK | + HWIO_REG_557899_RSTN_DMX_BMSK)); + + VIDC_HWIO_OUT(REG_557899, sw_reset_value); + } else if (init_flag == VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE) { + VIDC_HWIO_OUT(REG_557899, VIDC_1080P_RESET_ALL); + VIDC_HWIO_OUT(REG_557899, VIDC_1080P_RESET_RISC); + } +} + +void vidc_1080p_release_sw_reset(void) +{ + u32 nAxiCtl; + u32 nAxiStatus; + u32 nRdWrBurst; + u32 nOut_Order; + + nOut_Order = VIDC_SETFIELD(1, HWIO_REG_5519_AXI_AOOORD_SHFT, + HWIO_REG_5519_AXI_AOOORD_BMSK); + VIDC_HWIO_OUT(REG_5519, nOut_Order); + + nOut_Order = VIDC_SETFIELD(1, HWIO_REG_606364_AXI_AOOOWR_SHFT, + HWIO_REG_606364_AXI_AOOOWR_BMSK); + VIDC_HWIO_OUT(REG_606364, nOut_Order); + + nAxiCtl = VIDC_SETFIELD(1, HWIO_REG_471159_AXI_HALT_REQ_SHFT, + HWIO_REG_471159_AXI_HALT_REQ_BMSK); + + VIDC_HWIO_OUT(REG_471159, nAxiCtl); + + do { + VIDC_HWIO_IN(REG_437878, &nAxiStatus); + nAxiStatus = VIDC_GETFIELD(nAxiStatus, + HWIO_REG_437878_AXI_HALT_ACK_BMSK, + HWIO_REG_437878_AXI_HALT_ACK_SHFT); + } while (0x3 != nAxiStatus); + + nAxiCtl = VIDC_SETFIELD(1, + HWIO_REG_471159_AXI_RESET_SHFT, + HWIO_REG_471159_AXI_RESET_BMSK); + + VIDC_HWIO_OUT(REG_471159, nAxiCtl); + VIDC_HWIO_OUT(REG_471159, 0); + + nRdWrBurst = VIDC_SETFIELD(8, + HWIO_REG_922106_XBAR_OUT_MAX_RD_BURST_SHFT, + HWIO_REG_922106_XBAR_OUT_MAX_RD_BURST_BMSK) | + VIDC_SETFIELD(8, HWIO_REG_922106_XBAR_OUT_MAX_WR_BURST_SHFT, + HWIO_REG_922106_XBAR_OUT_MAX_WR_BURST_BMSK); + + VIDC_HWIO_OUT(REG_922106, nRdWrBurst); + + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_611794, VIDC_1080P_HOST2RISC_CMD_EMPTY); + VIDC_HWIO_OUT(REG_557899, VIDC_1080P_RESET_NONE); +} + +void vidc_1080p_clear_interrupt(void) +{ + VIDC_HWIO_OUT(REG_575377, VIDC_1080P_INTERRUPT_CLEAR); +} + +void vidc_1080p_set_host2risc_cmd(enum vidc_1080p_host2risc_cmd + host2risc_command, u32 host2risc_arg1, u32 host2risc_arg2, + u32 host2risc_arg3, u32 host2risc_arg4) +{ + VIDC_HWIO_OUT(REG_611794, VIDC_1080P_HOST2RISC_CMD_EMPTY); + VIDC_HWIO_OUT(REG_356340, host2risc_arg1); + VIDC_HWIO_OUT(REG_899023, host2risc_arg2); + VIDC_HWIO_OUT(REG_987762, host2risc_arg3); + VIDC_HWIO_OUT(REG_544000, host2risc_arg4); + VIDC_HWIO_OUT(REG_611794, host2risc_command); +} + +void vidc_1080p_get_risc2host_cmd(u32 *pn_risc2host_command, + u32 *pn_risc2host_arg1, u32 *pn_risc2host_arg2, + u32 *pn_risc2host_arg3, u32 *pn_risc2host_arg4) +{ + VIDC_HWIO_IN(REG_695082, pn_risc2host_command); + VIDC_HWIO_IN(REG_156596, pn_risc2host_arg1); + VIDC_HWIO_IN(REG_222292, pn_risc2host_arg2); + VIDC_HWIO_IN(REG_790962, pn_risc2host_arg3); + VIDC_HWIO_IN(REG_679882, pn_risc2host_arg4); +} + +void vidc_1080p_get_risc2host_cmd_status(u32 err_status, + u32 *dec_err_status, u32 *disp_err_status) +{ + *dec_err_status = VIDC_GETFIELD(err_status, + VIDC_RISC2HOST_ARG2_VIDC_DEC_ERROR_STATUS_BMSK, + VIDC_RISC2HOST_ARG2_VIDC_DEC_ERROR_STATUS_SHFT); + *disp_err_status = VIDC_GETFIELD(err_status, + VIDC_RISC2HOST_ARG2_VIDC_DISP_ERROR_STATUS_BMSK, + VIDC_RISC2HOST_ARG2_VIDC_DISP_ERROR_STATUS_SHFT); + +} + +void vidc_1080p_clear_risc2host_cmd(void) +{ + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); +} + +void vidc_1080p_get_fw_version(u32 *pn_fw_version) +{ + VIDC_HWIO_IN(REG_653206, pn_fw_version); +} + +void vidc_1080p_get_fw_status(u32 *pn_fw_status) +{ + VIDC_HWIO_IN(REG_350619, pn_fw_status); +} + +void vidc_1080p_init_memory_controller(u32 dram_base_addr_a, + u32 dram_base_addr_b) +{ + VIDC_HWIO_OUT(REG_64440, dram_base_addr_a); + VIDC_HWIO_OUT(REG_675915, dram_base_addr_b); +} + +void vidc_1080p_get_memory_controller_status(u32 *pb_mc_abusy, + u32 *pb_mc_bbusy) +{ + u32 mc_status = 0; + + VIDC_HWIO_IN(REG_399911, &mc_status); + *pb_mc_abusy = (u32) ((mc_status & + HWIO_REG_399911_MC_BUSY_A_BMSK) >> + HWIO_REG_399911_MC_BUSY_A_SHFT); + *pb_mc_bbusy = (u32) ((mc_status & + HWIO_REG_399911_MC_BUSY_B_BMSK) >> + HWIO_REG_399911_MC_BUSY_B_SHFT); +} + +void vidc_1080p_set_h264_decode_buffers(u32 dpb, u32 dec_vert_nb_mv_offset, + u32 dec_nb_ip_offset, u32 *pn_dpb_luma_offset, + u32 *pn_dpb_chroma_offset, u32 *pn_mv_buffer_offset) +{ + u32 count = 0, num_dpb_used = dpb; + u8 *vidc_dpb_luma_reg = (u8 *) VIDC_1080P_H264DEC_LUMA_ADDR; + u8 *vidc_dpb_chroma_reg = (u8 *) VIDC_1080P_H264DEC_CHROMA_ADDR; + u8 *vidc_mv_buffer_reg = (u8 *) VIDC_1080P_H264DEC_MV_PLANE_ADDR; + + VIDC_HWIO_OUT(REG_931311, (dec_vert_nb_mv_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_16277, (dec_nb_ip_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + if (num_dpb_used > VIDC_1080P_MAX_H264DECODER_DPB) + num_dpb_used = VIDC_1080P_MAX_H264DECODER_DPB; + for (count = 0; count < num_dpb_used; count++) { + VIDC_OUT_DWORD(vidc_dpb_luma_reg, + (pn_dpb_luma_offset[count] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_OUT_DWORD(vidc_dpb_chroma_reg, + (pn_dpb_chroma_offset[count] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_OUT_DWORD(vidc_mv_buffer_reg, + (pn_mv_buffer_offset[count] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + vidc_dpb_luma_reg += 4; + vidc_dpb_chroma_reg += 4; + vidc_mv_buffer_reg += 4; + } +} + +void vidc_1080p_set_decode_recon_buffers(u32 recon_buffer, + u32 *pn_dec_luma, u32 *pn_dec_chroma) +{ + u32 count = 0, recon_buf_to_program = recon_buffer; + u8 *dec_recon_luma_reg = (u8 *) VIDC_1080P_DEC_LUMA_ADDR; + u8 *dec_recon_chroma_reg = (u8 *) VIDC_1080P_DEC_CHROMA_ADDR; + + if (recon_buf_to_program > VIDC_1080P_MAX_DEC_RECON_BUF) + recon_buf_to_program = VIDC_1080P_MAX_DEC_RECON_BUF; + for (count = 0; count < recon_buf_to_program; count++) { + VIDC_OUT_DWORD(dec_recon_luma_reg, (pn_dec_luma[count] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_OUT_DWORD(dec_recon_chroma_reg, + (pn_dec_chroma[count] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + dec_recon_luma_reg += 4; + dec_recon_chroma_reg += 4; + } +} + +void vidc_1080p_set_mpeg4_divx_decode_work_buffers(u32 nb_dcac_buffer_offset, + u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset, + u32 overlay_transform_buffer_offset, u32 stx_parser_buffer_offset) +{ + VIDC_HWIO_OUT(REG_931311, (nb_dcac_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_16277, (upnb_mv_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_654169, (sub_anchor_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_802794, + (overlay_transform_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_252167, (stx_parser_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); +} + +void vidc_1080p_set_h263_decode_work_buffers(u32 nb_dcac_buffer_offset, + u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset, + u32 overlay_transform_buffer_offset) +{ + VIDC_HWIO_OUT(REG_931311, (nb_dcac_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_16277, (upnb_mv_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_654169, (sub_anchor_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_802794, + (overlay_transform_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); +} + +void vidc_1080p_set_vc1_decode_work_buffers(u32 nb_dcac_buffer_offset, + u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset, + u32 overlay_transform_buffer_offset, u32 bitplain1Buffer_offset, + u32 bitplain2Buffer_offset, u32 bitplain3Buffer_offset) +{ + VIDC_HWIO_OUT(REG_931311, (nb_dcac_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_16277, (upnb_mv_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_654169, (sub_anchor_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_802794, + (overlay_transform_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_724376, (bitplain3Buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_551674, (bitplain2Buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_115991, (bitplain1Buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); +} + +void vidc_1080p_set_encode_recon_buffers(u32 recon_buffer, + u32 *pn_enc_luma, u32 *pn_enc_chroma) +{ + if (recon_buffer > 0) { + VIDC_HWIO_OUT(REG_294579, (pn_enc_luma[0] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_759068, (pn_enc_chroma[0] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + } + if (recon_buffer > 1) { + VIDC_HWIO_OUT(REG_616802, (pn_enc_luma[1] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_833502, (pn_enc_chroma[1] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + } + if (recon_buffer > 2) { + VIDC_HWIO_OUT(REG_61427, (pn_enc_luma[2] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_68356, (pn_enc_chroma[2] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + } + if (recon_buffer > 3) { + VIDC_HWIO_OUT(REG_23318, (pn_enc_luma[3] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_127855, (pn_enc_chroma[3] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + } +} + +void vidc_1080p_set_h264_encode_work_buffers(u32 up_row_mv_buffer_offset, + u32 direct_colzero_flag_buffer_offset, + u32 upper_intra_md_buffer_offset, + u32 upper_intra_pred_buffer_offset, u32 nbor_infor_buffer_offset, + u32 mb_info_offset) +{ + VIDC_HWIO_OUT(REG_515200, (up_row_mv_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_69832, + (direct_colzero_flag_buffer_offset>> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_256132, + (upper_intra_md_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_475648, + (upper_intra_pred_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_29510, (nbor_infor_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_175929, (mb_info_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); +} + +void vidc_1080p_set_h263_encode_work_buffers(u32 up_row_mv_buffer_offset, + u32 up_row_inv_quanti_coeff_buffer_offset) +{ + VIDC_HWIO_OUT(REG_515200, (up_row_mv_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_29510, ( + up_row_inv_quanti_coeff_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); +} + +void vidc_1080p_set_mpeg4_encode_work_buffers(u32 skip_flag_buffer_offset, + u32 up_row_inv_quanti_coeff_buffer_offset, u32 upper_mv_offset) +{ + VIDC_HWIO_OUT(REG_69832, (skip_flag_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_29510, ( + up_row_inv_quanti_coeff_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_515200, (upper_mv_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); +} + +void vidc_1080p_set_encode_frame_size(u32 hori_size, u32 vert_size) +{ + VIDC_HWIO_OUT(REG_934655, hori_size); + VIDC_HWIO_OUT(REG_179070, vert_size); +} + +void vidc_1080p_set_encode_profile_level(u32 encode_profile, u32 enc_level) +{ + u32 profile_level = 0; + + profile_level = VIDC_SETFIELD(enc_level, + HWIO_REG_63643_LEVEL_SHFT, + HWIO_REG_63643_LEVEL_BMSK) | + VIDC_SETFIELD(encode_profile, + HWIO_REG_63643_PROFILE_SHFT, + HWIO_REG_63643_PROFILE_BMSK); + VIDC_HWIO_OUT(REG_63643, profile_level); +} + +void vidc_1080p_set_encode_field_picture_structure(u32 enc_field_picture) +{ + VIDC_HWIO_OUT(REG_786024, enc_field_picture); +} + +void vidc_1080p_set_decode_mpeg4_pp_filter(u32 lf_enables) +{ + VIDC_HWIO_OUT(REG_152500, lf_enables); +} + +void vidc_1080p_set_decode_qp_save_control(u32 enable_q_pout) +{ + VIDC_HWIO_OUT(REG_143629, enable_q_pout); +} + +void vidc_1080p_get_returned_channel_inst_id(u32 *pn_rtn_chid) +{ + VIDC_HWIO_IN(REG_607589, pn_rtn_chid); +} + +void vidc_1080p_clear_returned_channel_inst_id(void) +{ + VIDC_HWIO_OUT(REG_607589, VIDC_1080P_INIT_CH_INST_ID); +} + +void vidc_1080p_get_decode_seq_start_result( + struct vidc_1080p_seq_hdr_info *seq_hdr_info) +{ + u32 dec_disp_result; + u32 frame = 0; + VIDC_HWIO_IN(REG_845544, &seq_hdr_info->img_size_y); + VIDC_HWIO_IN(REG_859906, &seq_hdr_info->img_size_x); + VIDC_HWIO_IN(REG_490078, &seq_hdr_info->min_num_dpb); + VIDC_HWIO_IN(REG_489688, &seq_hdr_info->dec_frm_size); + VIDC_HWIO_IN(REG_853667, &dec_disp_result); + seq_hdr_info->disp_progressive = VIDC_GETFIELD(dec_disp_result, + VIDC_1080P_SI_RG7_DISPLAY_CODING_MASK, + VIDC_1080P_SI_RG7_DISPLAY_CODING_SHIFT); + seq_hdr_info->disp_crop_exists = VIDC_GETFIELD(dec_disp_result, + VIDC_1080P_SI_RG7_DISPLAY_CROP_MASK, + VIDC_1080P_SI_RG7_DISPLAY_CROP_SHIFT); + VIDC_HWIO_IN(REG_692991, &dec_disp_result); + seq_hdr_info->dec_progressive = VIDC_GETFIELD(dec_disp_result, + VIDC_1080P_SI_RG11_DECODE_CODING_MASK, + VIDC_1080P_SI_RG11_DECODE_CODING_SHIFT); + seq_hdr_info->dec_crop_exists = VIDC_GETFIELD(dec_disp_result, + VIDC_1080P_SI_RG11_DECODE_CROPP_MASK, + VIDC_1080P_SI_RG11_DECODE_CROPP_SHIFT); + VIDC_HWIO_IN(REG_760102, &frame); + seq_hdr_info->data_partition = ((frame & 0x8) >> 3); +} + +void vidc_1080p_get_decoded_frame_size(u32 *pn_decoded_size) +{ + VIDC_HWIO_IN(REG_489688, pn_decoded_size); +} + +void vidc_1080p_get_display_frame_result( + struct vidc_1080p_dec_disp_info *dec_disp_info) +{ + u32 display_result; + VIDC_HWIO_IN(REG_640904, &dec_disp_info->display_y_addr); + VIDC_HWIO_IN(REG_60114, &dec_disp_info->display_c_addr); + VIDC_HWIO_IN(REG_853667, &display_result); + VIDC_HWIO_IN(REG_845544, &dec_disp_info->img_size_y); + VIDC_HWIO_IN(REG_859906, &dec_disp_info->img_size_x); + dec_disp_info->display_status = + (enum vidc_1080p_display_status) + VIDC_GETFIELD(display_result, + VIDC_1080P_SI_RG7_DISPLAY_STATUS_MASK, + VIDC_1080P_SI_RG7_DISPLAY_STATUS_SHIFT); + dec_disp_info->display_coding = + (enum vidc_1080p_display_coding) + VIDC_GETFIELD(display_result, VIDC_1080P_SI_RG7_DISPLAY_CODING_MASK, + VIDC_1080P_SI_RG7_DISPLAY_CODING_SHIFT); + dec_disp_info->disp_resl_change = VIDC_GETFIELD(display_result, + VIDC_1080P_SI_RG7_DISPLAY_RES_MASK, + VIDC_1080P_SI_RG7_DISPLAY_RES_SHIFT); + dec_disp_info->disp_crop_exists = VIDC_GETFIELD(display_result, + VIDC_1080P_SI_RG7_DISPLAY_CROP_MASK, + VIDC_1080P_SI_RG7_DISPLAY_CROP_SHIFT); + dec_disp_info->display_correct = VIDC_GETFIELD(display_result, + VIDC_1080P_SI_RG7_DISPLAY_CORRECT_MASK, + VIDC_1080P_SI_RG7_DISPLAY_CORRECT_SHIFT); +} + +void vidc_1080p_get_decode_frame( + enum vidc_1080p_decode_frame *pe_frame) +{ + u32 frame = 0; + + VIDC_HWIO_IN(REG_760102, &frame); + *pe_frame = (enum vidc_1080p_decode_frame) + (frame & VIDC_1080P_SI_RG8_DECODE_FRAMETYPE_MASK); +} + +void vidc_1080p_get_decode_frame_result( + struct vidc_1080p_dec_disp_info *dec_disp_info) +{ + u32 decode_result; + + VIDC_HWIO_IN(REG_378318, &dec_disp_info->decode_y_addr); + VIDC_HWIO_IN(REG_203487, &dec_disp_info->decode_c_addr); + VIDC_HWIO_IN(REG_692991, &decode_result); + dec_disp_info->decode_status = (enum vidc_1080p_display_status) + VIDC_GETFIELD(decode_result, + VIDC_1080P_SI_RG11_DECODE_STATUS_MASK, + VIDC_1080P_SI_RG11_DECODE_STATUS_SHIFT); + dec_disp_info->decode_coding = (enum vidc_1080p_display_coding) + VIDC_GETFIELD(decode_result, + VIDC_1080P_SI_RG11_DECODE_CODING_MASK, + VIDC_1080P_SI_RG11_DECODE_CODING_SHIFT); + dec_disp_info->dec_resl_change = VIDC_GETFIELD(decode_result, + VIDC_1080P_SI_RG11_DECODE_RES_MASK, + VIDC_1080P_SI_RG11_DECODE_RES_SHIFT); + dec_disp_info->dec_crop_exists = VIDC_GETFIELD(decode_result, + VIDC_1080P_SI_RG11_DECODE_CROPP_MASK, + VIDC_1080P_SI_RG11_DECODE_CROPP_SHIFT); + dec_disp_info->decode_correct = VIDC_GETFIELD(decode_result, + VIDC_1080P_SI_RG11_DECODE_CORRECT_MASK, + VIDC_1080P_SI_RG11_DECODE_CORRECT_SHIFT); +} + +void vidc_1080p_decode_seq_start_ch0( + struct vidc_1080p_dec_seq_start_param *param) +{ + 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, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_145068, param->stream_frame_size); + VIDC_HWIO_OUT(REG_921356, + param->descriptor_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_190381, param->stream_buffersize); + VIDC_HWIO_OUT(REG_85655, param->descriptor_buffer_size); + VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_404623, 0); + VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_DEC_TYPE_SEQ_HEADER | + param->inst_id); +} + +void vidc_1080p_decode_seq_start_ch1( + struct vidc_1080p_dec_seq_start_param *param) +{ + 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, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_936704, param->stream_frame_size); + VIDC_HWIO_OUT(REG_821977, + param->descriptor_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_887095, param->stream_buffersize); + VIDC_HWIO_OUT(REG_576987, param->descriptor_buffer_size); + VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_404623, 0); + VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_DEC_TYPE_SEQ_HEADER | + param->inst_id); +} + +void vidc_1080p_decode_frame_start_ch0( + struct vidc_1080p_dec_frame_start_param *param) +{ + u32 dpb_config; + + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID); + if ((param->decode == VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA) && + ((!param->stream_buffer_addr_offset) || + (!param->stream_frame_size))) { + VIDC_HWIO_OUT(REG_117192, 0); + VIDC_HWIO_OUT(REG_145068, 0); + VIDC_HWIO_OUT(REG_190381, 0); + } else { + VIDC_HWIO_OUT(REG_117192, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_145068, + param->stream_frame_size); + VIDC_HWIO_OUT(REG_190381, + param->stream_buffersize); + } + dpb_config = VIDC_SETFIELD(param->dmx_disable, + VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT, + VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK) | + VIDC_SETFIELD(param->dpb_flush, + VIDC_1080P_SI_RG10_DPB_FLUSH_SHFT, + VIDC_1080P_SI_RG10_DPB_FLUSH_BMSK) | + VIDC_SETFIELD(param->dpb_count, + VIDC_1080P_SI_RG10_NUM_DPB_SHFT, + VIDC_1080P_SI_RG10_NUM_DPB_BMSK); + VIDC_HWIO_OUT(REG_921356, + param->descriptor_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_85655, param->descriptor_buffer_size); + VIDC_HWIO_OUT(REG_86830, param->release_dpb_bit_mask); + VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_404623, dpb_config); + VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_666957, (u32)param->decode | + param->inst_id); +} + + +void vidc_1080p_decode_frame_start_ch1( + struct vidc_1080p_dec_frame_start_param *param) +{ + u32 dpb_config; + + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID); + if ((param->decode == VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA) && + ((!param->stream_buffer_addr_offset) || + (!param->stream_frame_size))) { + VIDC_HWIO_OUT(REG_980194, 0); + VIDC_HWIO_OUT(REG_936704, 0); + VIDC_HWIO_OUT(REG_887095, 0); + } else { + VIDC_HWIO_OUT(REG_980194, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_936704, + param->stream_frame_size); + VIDC_HWIO_OUT(REG_887095, + param->stream_buffersize); + } + dpb_config = VIDC_SETFIELD(param->dmx_disable, + VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT, + VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK) | + VIDC_SETFIELD(param->dpb_flush, + VIDC_1080P_SI_RG10_DPB_FLUSH_SHFT, + VIDC_1080P_SI_RG10_DPB_FLUSH_BMSK) | + VIDC_SETFIELD(param->dpb_count, + VIDC_1080P_SI_RG10_NUM_DPB_SHFT, + VIDC_1080P_SI_RG10_NUM_DPB_BMSK); + VIDC_HWIO_OUT(REG_821977, + param->descriptor_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_576987, param->descriptor_buffer_size); + VIDC_HWIO_OUT(REG_70448, param->release_dpb_bit_mask); + VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_220637, dpb_config); + VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_313350, (u32)param->decode | + param->inst_id); +} + +void vidc_1080p_decode_init_buffers_ch0( + struct vidc_1080p_dec_init_buffers_param *param) +{ + u32 dpb_config; + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID); + dpb_config = VIDC_SETFIELD(param->dmx_disable, + VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT, + VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK) | + VIDC_SETFIELD(param->dpb_count, + VIDC_1080P_SI_RG10_NUM_DPB_SHFT, + VIDC_1080P_SI_RG10_NUM_DPB_BMSK); + VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_404623, dpb_config); + VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_DEC_TYPE_INIT_BUFFERS | + param->inst_id); +} + +void vidc_1080p_decode_init_buffers_ch1( + struct vidc_1080p_dec_init_buffers_param *param) +{ + u32 dpb_config; + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID); + dpb_config = VIDC_SETFIELD(param->dmx_disable, + VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT, + VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK) | + VIDC_SETFIELD(param->dpb_count, + VIDC_1080P_SI_RG10_NUM_DPB_SHFT, + VIDC_1080P_SI_RG10_NUM_DPB_BMSK); + VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_220637, dpb_config); + VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_DEC_TYPE_INIT_BUFFERS | + param->inst_id); +} + +void vidc_1080p_set_dec_resolution_ch0(u32 width, u32 height) +{ + VIDC_HWIO_OUT(REG_612810, height); + VIDC_HWIO_OUT(REG_175608, width); +} + +void vidc_1080p_set_dec_resolution_ch1(u32 width, u32 height) +{ + VIDC_HWIO_OUT(REG_655721, height); + VIDC_HWIO_OUT(REG_548308, width); +} + +void vidc_1080p_get_encode_frame_info( + struct vidc_1080p_enc_frame_info *frame_info) +{ + VIDC_HWIO_IN(REG_845544, &(frame_info->enc_frame_size)); + VIDC_HWIO_IN(REG_859906, + &(frame_info->enc_picture_count)); + VIDC_HWIO_IN(REG_490078, + &(frame_info->enc_write_pointer)); + VIDC_HWIO_IN(REG_640904, + (u32 *)(&(frame_info->enc_frame))); + VIDC_HWIO_IN(REG_60114, + &(frame_info->enc_luma_address)); + frame_info->enc_luma_address = frame_info->enc_luma_address << + VIDC_1080P_BASE_OFFSET_SHIFT; + VIDC_HWIO_IN(REG_489688, + &(frame_info->enc_chroma_address)); + frame_info->enc_chroma_address = frame_info->\ + enc_chroma_address << VIDC_1080P_BASE_OFFSET_SHIFT; +} + +void vidc_1080p_encode_seq_start_ch0( + struct vidc_1080p_enc_seq_start_param *param) +{ + 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, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_921356, param->stream_buffer_size); + VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_ENC_TYPE_SEQ_HEADER | + param->inst_id); +} + +void vidc_1080p_encode_seq_start_ch1( + struct vidc_1080p_enc_seq_start_param *param) +{ + 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, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_821977, param->stream_buffer_size); + VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_ENC_TYPE_SEQ_HEADER | + param->inst_id); +} + +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, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_921356, param->stream_buffer_size); + 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_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, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_821977, param->stream_buffer_size); + 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_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; + if (number_p >= VIDC_1080P_MAX_INTRA_PERIOD) + ifrm_ctrl = 0; + else + ifrm_ctrl = number_p + 1; + picture = VIDC_SETFIELD(1 , + HWIO_REG_783891_ENC_PIC_TYPE_USE_SHFT, + HWIO_REG_783891_ENC_PIC_TYPE_USE_BMSK) | + VIDC_SETFIELD(ifrm_ctrl, + HWIO_REG_783891_I_FRM_CTRL_SHFT, + HWIO_REG_783891_I_FRM_CTRL_BMSK) + | VIDC_SETFIELD(number_b , + HWIO_REG_783891_B_FRM_CTRL_SHFT , + HWIO_REG_783891_B_FRM_CTRL_BMSK); + VIDC_HWIO_OUT(REG_783891, picture); +} + +void vidc_1080p_set_encode_multi_slice_control( + enum vidc_1080p_MSlice_selection multiple_slice_selection, + u32 mslice_mb, u32 mslice_byte) +{ + VIDC_HWIO_OUT(REG_226332, multiple_slice_selection); + VIDC_HWIO_OUT(REG_696136, mslice_mb); + VIDC_HWIO_OUT(REG_515564, mslice_byte); +} + +void vidc_1080p_set_encode_circular_intra_refresh(u32 cir_num) +{ + VIDC_HWIO_OUT(REG_886210, cir_num); +} + +void vidc_1080p_set_encode_input_frame_format( + enum vidc_1080p_memory_access_method memory_format) +{ + VIDC_HWIO_OUT(REG_645603, memory_format); +} + +void vidc_1080p_set_encode_padding_control(u32 pad_ctrl_on, + u32 cr_pad_val, u32 cb_pad_val, u32 luma_pad_val) +{ + u32 padding = VIDC_SETFIELD(pad_ctrl_on , + HWIO_REG_811733_PAD_CTRL_ON_SHFT, + HWIO_REG_811733_PAD_CTRL_ON_BMSK) | + VIDC_SETFIELD(cr_pad_val , + HWIO_REG_811733_CR_PAD_VIDC_SHFT , + HWIO_REG_811733_CR_PAD_VIDC_BMSK) | + VIDC_SETFIELD(cb_pad_val , + HWIO_REG_811733_CB_PAD_VIDC_SHFT , + HWIO_REG_811733_CB_PAD_VIDC_BMSK) | + VIDC_SETFIELD(luma_pad_val , + HWIO_REG_811733_LUMA_PAD_VIDC_SHFT , + HWIO_REG_811733_LUMA_PAD_VIDC_BMSK) ; + VIDC_HWIO_OUT(REG_811733, padding); +} + +void vidc_1080p_encode_set_rc_config(u32 enable_frame_level_rc, + u32 enable_mb_level_rc_flag, u32 frame_qp) +{ + u32 rc_config = VIDC_SETFIELD(enable_frame_level_rc , + HWIO_REG_559908_FR_RC_EN_SHFT , + HWIO_REG_559908_FR_RC_EN_BMSK) | + VIDC_SETFIELD(enable_mb_level_rc_flag , + HWIO_REG_559908_MB_RC_EN_SHFT, + HWIO_REG_559908_MB_RC_EN_BMSK) | + VIDC_SETFIELD(frame_qp , + HWIO_REG_559908_FRAME_QP_SHFT , + HWIO_REG_559908_FRAME_QP_BMSK); + VIDC_HWIO_OUT(REG_559908, rc_config); +} + +void vidc_1080p_encode_set_frame_level_rc_params(u32 rc_frame_rate, + u32 target_bitrate, u32 reaction_coeff) +{ + VIDC_HWIO_OUT(REG_977937, rc_frame_rate); + VIDC_HWIO_OUT(REG_166135, target_bitrate); + VIDC_HWIO_OUT(REG_550322, reaction_coeff); +} + +void vidc_1080p_encode_set_qp_params(u32 max_qp, u32 min_qp) +{ + u32 qbound = VIDC_SETFIELD(max_qp , HWIO_REG_109072_MAX_QP_SHFT, + HWIO_REG_109072_MAX_QP_BMSK) | + VIDC_SETFIELD(min_qp, + HWIO_REG_109072_MIN_QP_SHFT , + HWIO_REG_109072_MIN_QP_BMSK); + VIDC_HWIO_OUT(REG_109072, qbound); +} + +void vidc_1080p_encode_set_mb_level_rc_params(u32 disable_dark_region_as_flag, + u32 disable_smooth_region_as_flag , u32 disable_static_region_as_flag, + u32 disable_activity_region_flag) +{ + u32 rc_active_feature = VIDC_SETFIELD( + disable_dark_region_as_flag, + HWIO_REG_949086_DARK_DISABLE_SHFT, + HWIO_REG_949086_DARK_DISABLE_BMSK) | + VIDC_SETFIELD( + disable_smooth_region_as_flag, + HWIO_REG_949086_SMOOTH_DISABLE_SHFT, + HWIO_REG_949086_SMOOTH_DISABLE_BMSK) | + VIDC_SETFIELD( + disable_static_region_as_flag, + HWIO_REG_949086_STATIC_DISABLE_SHFT, + HWIO_REG_949086_STATIC_DISABLE_BMSK) | + VIDC_SETFIELD( + disable_activity_region_flag, + HWIO_REG_949086_ACT_DISABLE_SHFT, + HWIO_REG_949086_ACT_DISABLE_BMSK); + VIDC_HWIO_OUT(REG_949086, rc_active_feature); +} + +void vidc_1080p_set_h264_encode_entropy( + enum vidc_1080p_entropy_sel entropy_sel) +{ + VIDC_HWIO_OUT(REG_447796, entropy_sel); +} + +void vidc_1080p_set_h264_encode_loop_filter( + enum vidc_1080p_DBConfig db_config, u32 slice_alpha_offset, + u32 slice_beta_offset) +{ + VIDC_HWIO_OUT(REG_152500, db_config); + VIDC_HWIO_OUT(REG_266285, slice_alpha_offset); + VIDC_HWIO_OUT(REG_964731, slice_beta_offset); +} + +void vidc_1080p_set_h264_encoder_p_frame_ref_count(u32 max_reference) +{ + u32 ref_frames; + ref_frames = VIDC_SETFIELD(max_reference, + HWIO_REG_744348_P_SHFT, + HWIO_REG_744348_P_BMSK); + VIDC_HWIO_OUT(REG_744348, ref_frames); +} + +void vidc_1080p_set_h264_encode_8x8transform_control(u32 enable_8x8transform) +{ + VIDC_HWIO_OUT(REG_672163, enable_8x8transform); +} + +void vidc_1080p_set_mpeg4_encode_quarter_pel_control( + u32 enable_mpeg4_quarter_pel) +{ + VIDC_HWIO_OUT(REG_330132, enable_mpeg4_quarter_pel); +} + +void vidc_1080p_set_device_base_addr(u8 *mapped_va) +{ + VIDC_BASE_PTR = mapped_va; +} + +void vidc_1080p_get_intra_bias(u32 *bias) +{ + u32 intra_bias; + + VIDC_HWIO_IN(REG_676866, &intra_bias); + *bias = VIDC_GETFIELD(intra_bias, + HWIO_REG_676866_RMSK, + HWIO_REG_676866_SHFT); +} + +void vidc_1080p_set_intra_bias(u32 bias) +{ + u32 intra_bias; + + intra_bias = VIDC_SETFIELD(bias, + HWIO_REG_676866_SHFT, + HWIO_REG_676866_RMSK); + VIDC_HWIO_OUT(REG_676866, intra_bias); +} + +void vidc_1080p_get_bi_directional_bias(u32 *bi_directional_bias) +{ + u32 nbi_direct_bias; + + VIDC_HWIO_IN(REG_54267, &nbi_direct_bias); + *bi_directional_bias = VIDC_GETFIELD(nbi_direct_bias, + HWIO_REG_54267_RMSK, + HWIO_REG_54267_SHFT); +} + +void vidc_1080p_set_bi_directional_bias(u32 bi_directional_bias) +{ + u32 nbi_direct_bias; + + nbi_direct_bias = VIDC_SETFIELD(bi_directional_bias, + HWIO_REG_54267_SHFT, + HWIO_REG_54267_RMSK); + VIDC_HWIO_OUT(REG_54267, nbi_direct_bias); +} + +void vidc_1080p_get_encoder_sequence_header_size(u32 *seq_header_size) +{ + VIDC_HWIO_IN(REG_845544, seq_header_size); +} + +void vidc_1080p_get_intermedia_stage_debug_counter( + u32 *intermediate_stage_counter) +{ + VIDC_HWIO_IN(REG_805993, intermediate_stage_counter); +} + +void vidc_1080p_get_exception_status(u32 *exception_status) +{ + VIDC_HWIO_IN(REG_493355, exception_status); +} + +void vidc_1080p_frame_start_realloc(u32 instance_id) +{ + 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_666957, + VIDC_1080P_DEC_TYPE_FRAME_START_REALLOC | instance_id); +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.h b/drivers/video/msm/vidc/1080p/ddl/vidc.h new file mode 100644 index 0000000000000000000000000000000000000000..39d3e8fd887a9af8f3de3ada57eba57998557400 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vidc.h @@ -0,0 +1,586 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VIDC_H_ +#define _VIDC_H_ + +#include "vidc_hwio_reg.h" + +#define VIDC_1080P_RISC2HOST_CMD_EMPTY 0 +#define VIDC_1080P_RISC2HOST_CMD_OPEN_CH_RET 1 +#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 + +#define VIDC_RISC2HOST_ARG2_VIDC_DISP_ERROR_STATUS_BMSK 0xffff0000 +#define VIDC_RISC2HOST_ARG2_VIDC_DISP_ERROR_STATUS_SHFT 16 +#define VIDC_RISC2HOST_ARG2_VIDC_DEC_ERROR_STATUS_BMSK 0x0000ffff +#define VIDC_RISC2HOST_ARG2_VIDC_DEC_ERROR_STATUS_SHFT 0 + +#define VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER 1 +#define VIDC_1080P_ERROR_INVALID_COMMAND_ID 2 +#define VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE 3 +#define VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE 4 +#define VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START 5 +#define VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED 6 +#define VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS 7 +#define VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS 8 +#define VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED 9 +#define VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START 10 +#define VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START 11 +#define VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START 12 +#define VIDC_1080P_ERROR_RESOLUTION_CHANGED 13 +#define VIDC_1080P_ERROR_INVALID_COMMAND_LAST_FRAME 14 +#define VIDC_1080P_ERROR_INVALID_COMMAND 15 +#define VIDC_1080P_ERROR_INVALID_CODEC_TYPE 16 + +#define VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED 20 +#define VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE 25 +#define VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE 27 +#define VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED 28 + +#define VIDC_1080P_ERROR_HEADER_NOT_FOUND 52 +#define VIDC_1080P_ERROR_VOS_END_CODE_RECEIVED 53 +#define VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED 62 +#define VIDC_1080P_ERROR_INVALID_QP_VALUE 63 +#define VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT 64 +#define VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL 65 +#define VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED 66 +#define VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT 71 +#define VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE 74 +#define VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER 77 +#define VIDC_1080P_ERROR_NULL_DPB_POINTER 78 +#define VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR 79 +#define VIDC_1080P_ERROR_NULL_MV_POINTER 80 +#define VIDC_1080P_ERROR_DIVIDE_BY_ZERO 81 +#define VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST 82 +#define VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY 83 +#define VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE 84 +#define VIDC_1080P_ERROR_DESCRIPTOR_TABLE_ENTRY_INVALID 85 +#define VIDC_1080P_ERROR_MB_COEFF_NOT_DONE 86 +#define VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE 87 +#define VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT 88 +#define VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR 89 +#define VIDC_1080P_ERROR_VSP_NOT_READY 90 +#define VIDC_1080P_ERROR_BUFFER_FULL_STATE 91 + +#define VIDC_1080P_ERROR_RESOLUTION_MISMATCH 112 +#define VIDC_1080P_ERROR_NV_QUANT_ERR 113 +#define VIDC_1080P_ERROR_SYNC_MARKER_ERR 114 +#define VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED 115 +#define VIDC_1080P_ERROR_MEM_CORRUPTION 116 +#define VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME 117 +#define VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR 118 +#define VIDC_1080P_ERROR_MV_RANGE_ERR 119 +#define VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR 120 +#define VIDC_1080P_ERROR_SLICE_ADDR_INVALID 121 +#define VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED 122 +#define VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED 123 +#define VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST 125 +#define VIDC_1080P_ERROR_NULL_FW_DEBUG_INFO_POINTER 126 +#define VIDC_1080P_ERROR_ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT 127 +#define VIDC_1080P_ERROR_NALU_HEADER_ERROR 128 +#define VIDC_1080P_ERROR_SPS_PARSE_ERROR 129 +#define VIDC_1080P_ERROR_PPS_PARSE_ERROR 130 +#define VIDC_1080P_ERROR_SLICE_PARSE_ERROR 131 +#define VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED 171 + +#define VIDC_1080P_WARN_COMMAND_FLUSHED 145 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_NUM_CONCEAL_MB 150 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_QP 151 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_CONCEAL_MB 152 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_VC1_PARAM 153 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_SEI 154 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_VUI 155 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_EXTRA 156 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_DATA_NONE 157 +#define VIDC_1080P_WARN_FRAME_RATE_UNKNOWN 158 +#define VIDC_1080P_WARN_ASPECT_RATIO_UNKNOWN 159 +#define VIDC_1080P_WARN_COLOR_PRIMARIES_UNKNOWN 160 +#define VIDC_1080P_WARN_TRANSFER_CHAR_UNKNOWN 161 +#define VIDC_1080P_WARN_MATRIX_COEFF_UNKNOWN 162 +#define VIDC_1080P_WARN_NON_SEQ_SLICE_ADDR 163 +#define VIDC_1080P_WARN_BROKEN_LINK 164 +#define VIDC_1080P_WARN_FRAME_CONCEALED 165 +#define VIDC_1080P_WARN_PROFILE_UNKNOWN 166 +#define VIDC_1080P_WARN_LEVEL_UNKNOWN 167 +#define VIDC_1080P_WARN_BIT_RATE_NOT_SUPPORTED 168 +#define VIDC_1080P_WARN_COLOR_DIFF_FORMAT_NOT_SUPPORTED 169 +#define VIDC_1080P_WARN_NULL_EXTRA_METADATA_POINTER 170 +#define VIDC_1080P_WARN_DEBLOCKING_NOT_DONE 178 +#define VIDC_1080P_WARN_INCOMPLETE_FRAME 179 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_MB_INFO 180 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_SLICE_SIZE 181 +#define VIDC_1080P_WARN_RESOLUTION_WARNING 182 + +#define VIDC_1080P_WARN_NO_LONG_TERM_REFERENCE 183 +#define VIDC_1080P_WARN_NO_SPACE_MPEG2_DATA_DUMP 190 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_MISSING_MB 191 + +#define VIDC_1080P_H264_ENC_TYPE_P 0 +#define VIDC_1080P_H264_ENC_TYPE_B 1 +#define VIDC_1080P_H264_ENC_TYPE_IDR 2 +#define VIDC_1080P_MP4_H263_ENC_TYPE_I 0 +#define VIDC_1080P_MP4_H263_ENC_TYPE_P 1 +#define VIDC_1080P_MP4_H263_ENC_TYPE_B 2 + +#define VIDC_1080P_MPEG4_LEVEL0 0 +#define VIDC_1080P_MPEG4_LEVEL0b 9 +#define VIDC_1080P_MPEG4_LEVEL1 1 +#define VIDC_1080P_MPEG4_LEVEL2 2 +#define VIDC_1080P_MPEG4_LEVEL3 3 +#define VIDC_1080P_MPEG4_LEVEL3b 7 +#define VIDC_1080P_MPEG4_LEVEL4 4 +#define VIDC_1080P_MPEG4_LEVEL4a 4 +#define VIDC_1080P_MPEG4_LEVEL5 5 +#define VIDC_1080P_MPEG4_LEVEL6 6 +#define VIDC_1080P_MPEG4_LEVEL7 7 + +#define VIDC_1080P_H264_LEVEL1 10 +#define VIDC_1080P_H264_LEVEL1b 9 +#define VIDC_1080P_H264_LEVEL1p1 11 +#define VIDC_1080P_H264_LEVEL1p2 12 +#define VIDC_1080P_H264_LEVEL1p3 13 +#define VIDC_1080P_H264_LEVEL2 20 +#define VIDC_1080P_H264_LEVEL2p1 21 +#define VIDC_1080P_H264_LEVEL2p2 22 +#define VIDC_1080P_H264_LEVEL3 30 +#define VIDC_1080P_H264_LEVEL3p1 31 +#define VIDC_1080P_H264_LEVEL3p2 32 +#define VIDC_1080P_H264_LEVEL4 40 +#define VIDC_1080P_H264_LEVEL5p1 51 +#define VIDC_1080P_H264_LEVEL_MAX VIDC_1080P_H264_LEVEL5p1 + +#define VIDC_1080P_H263_LEVEL10 10 +#define VIDC_1080P_H263_LEVEL20 20 +#define VIDC_1080P_H263_LEVEL30 30 +#define VIDC_1080P_H263_LEVEL40 40 +#define VIDC_1080P_H263_LEVEL45 45 +#define VIDC_1080P_H263_LEVEL50 50 +#define VIDC_1080P_H263_LEVEL60 60 +#define VIDC_1080P_H263_LEVEL70 70 + +#define VIDC_1080P_BUS_ERROR_HANDLER 0x01 +#define VIDC_1080P_ILLEVIDC_INSTRUCTION_HANDLER 0x02 +#define VIDC_1080P_TICK_HANDLER 0x04 +#define VIDC_1080P_TRAP_HANDLER 0x10 +#define VIDC_1080P_ALIGN_HANDLER 0x20 +#define VIDC_1080P_RANGE_HANDLER 0x40 +#define VIDC_1080P_DTLB_MISS_EXCEPTION_HANDLER 0x80 +#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, +}; +enum vidc_1080p_memory_access_method{ + VIDC_1080P_TILE_LINEAR = 0, + VIDC_1080P_TILE_16x16 = 2, + VIDC_1080P_TILE_64x32 = 3, + VIDC_1080P_TILE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_host2risc_cmd{ + VIDC_1080P_HOST2RISC_CMD_EMPTY = 0, + VIDC_1080P_HOST2RISC_CMD_OPEN_CH = 1, + VIDC_1080P_HOST2RISC_CMD_CLOSE_CH = 2, + VIDC_1080P_HOST2RISC_CMD_SYS_INIT = 3, + VIDC_1080P_HOST2RISC_CMD_FLUSH_COMMMAND = 4, + VIDC_1080P_HOST2RISC_CMD_CONTINUE_ENC = 7, + VIDC_1080P_HOST2RISC_CMD_ABORT_ENC = 8, + VIDC_1080P_HOST2RISC_CMD_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_decode_p_cache_enable{ + VIDC_1080P_DECODE_PCACHE_ENABLE_P = 0, + VIDC_1080P_DECODE_PCACHE_ENABLE_B = 1, + VIDC_1080P_DECODE_PCACHE_ENABLE_PB = 2, + VIDC_1080P_DECODE_PCACHE_DISABLE = 3, + VIDC_1080P_DECODE_PCACHE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_encode_p_cache_enable{ + VIDC_1080P_ENCODE_PCACHE_ENABLE = 0, + VIDC_1080P_ENCODE_PCACHE_DISABLE = 3, + VIDC_1080P_ENCODE_PCACHE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_codec{ + VIDC_1080P_H264_DECODE = 0, + VIDC_1080P_VC1_DECODE = 1, + VIDC_1080P_MPEG4_DECODE = 2, + VIDC_1080P_MPEG2_DECODE = 3, + VIDC_1080P_H263_DECODE = 4, + VIDC_1080P_VC1_RCV_DECODE = 5, + VIDC_1080P_DIVX311_DECODE = 6, + VIDC_1080P_DIVX412_DECODE = 7, + VIDC_1080P_DIVX502_DECODE = 8, + VIDC_1080P_DIVX503_DECODE = 9, + VIDC_1080P_H264_ENCODE = 16, + VIDC_1080P_MPEG4_ENCODE = 17, + VIDC_1080P_H263_ENCODE = 18, + VIDC_1080P_CODEC_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_entropy_sel{ + VIDC_1080P_ENTROPY_SEL_CAVLC = 0, + VIDC_1080P_ENTROPY_SEL_CABAC = 1, + VIDC_1080P_ENTROPY_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_DBConfig{ + VIDC_1080P_DB_ALL_BLOCKING_BOUNDARY = 0, + VIDC_1080P_DB_DISABLE = 1, + VIDC_1080P_DB_SKIP_SLICE_BOUNDARY = 2, + VIDC_1080P_DB_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_MSlice_selection{ + VIDC_1080P_MSLICE_DISABLE = 0, + VIDC_1080P_MSLICE_BY_MB_COUNT = 1, + VIDC_1080P_MSLICE_BY_BYTE_COUNT = 3, + VIDC_1080P_MSLICE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_display_status{ + VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY = 0, + VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY = 1, + VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY = 2, + VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY = 3, + VIDC_1080P_DISPLAY_STATUS_NOOP = 4, + VIDC_1080P_DISPLAY_STATUS_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_display_coding{ + VIDC_1080P_DISPLAY_CODING_PROGRESSIVE_SCAN = 0, + VIDC_1080P_DISPLAY_CODING_INTERLACED = 1, + VIDC_1080P_DISPLAY_CODING_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_decode_frame{ + VIDC_1080P_DECODE_FRAMETYPE_NOT_CODED = 0, + VIDC_1080P_DECODE_FRAMETYPE_I = 1, + VIDC_1080P_DECODE_FRAMETYPE_P = 2, + VIDC_1080P_DECODE_FRAMETYPE_B = 3, + VIDC_1080P_DECODE_FRAMETYPE_OTHERS = 4, + VIDC_1080P_DECODE_FRAMETYPE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080P_decode_frame_correct_type { + VIDC_1080P_DECODE_NOT_CORRECT = 0, + VIDC_1080P_DECODE_CORRECT = 1, + VIDC_1080P_DECODE_APPROX_CORRECT = 2, + VIDC_1080P_DECODE_CORRECTTYPE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_encode_frame{ + VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED = 0, + VIDC_1080P_ENCODE_FRAMETYPE_I = 1, + VIDC_1080P_ENCODE_FRAMETYPE_P = 2, + VIDC_1080P_ENCODE_FRAMETYPE_B = 3, + VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED = 4, + VIDC_1080P_ENCODE_FRAMETYPE_OTHERS = 5, + VIDC_1080P_ENCODE_FRAMETYPE_32BIT = 0x7FFFFFFF + +}; + +enum vidc_1080p_decode_idc_format { + VIDC_1080P_IDCFORMAT_MONOCHROME = 0, + VIDC_1080P_IDCFORMAT_420 = 1, + VIDC_1080P_IDCFORMAT_422 = 2, + VIDC_1080P_IDCFORMAT_444 = 3, + VIDC_1080P_IDCFORMAT_OTHERS = 4, + VIDC_1080P_IDCFORMAT_32BIT = 0x7FFFFFFF +}; + +#define VIDC_1080P_PROFILE_MPEG4_SIMPLE 0x00000000 +#define VIDC_1080P_PROFILE_MPEG4_ADV_SIMPLE 0x00000001 + +#define VIDC_1080P_PROFILE_H264_MAIN 0x00000000 +#define VIDC_1080P_PROFILE_H264_HIGH 0x00000001 +#define VIDC_1080P_PROFILE_H264_BASELINE 0x00000002 + + +enum vidc_1080p_decode{ + VIDC_1080P_DEC_TYPE_SEQ_HEADER = 0x00010000, + VIDC_1080P_DEC_TYPE_FRAME_DATA = 0x00020000, + VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA = 0x00030000, + VIDC_1080P_DEC_TYPE_INIT_BUFFERS = 0x00040000, + VIDC_1080P_DEC_TYPE_FRAME_START_REALLOC = 0x00050000, + 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_SLICE_BATCH_START = 0x00070000, + VIDC_1080P_ENC_TYPE_32BIT = 0x7FFFFFFF +}; +struct vidc_1080p_dec_seq_start_param{ + u32 cmd_seq_num; + u32 inst_id; + u32 shared_mem_addr_offset; + u32 stream_buffer_addr_offset; + u32 stream_buffersize; + u32 stream_frame_size; + u32 descriptor_buffer_addr_offset; + u32 descriptor_buffer_size; +}; +struct vidc_1080p_dec_frame_start_param{ + u32 cmd_seq_num; + u32 inst_id; + u32 shared_mem_addr_offset; + u32 stream_buffer_addr_offset; + u32 stream_buffersize; + u32 stream_frame_size; + u32 descriptor_buffer_addr_offset; + u32 descriptor_buffer_size; + u32 release_dpb_bit_mask; + u32 dpb_count; + u32 dpb_flush; + u32 dmx_disable; + enum vidc_1080p_decode decode; +}; +struct vidc_1080p_dec_init_buffers_param{ + u32 cmd_seq_num; + u32 inst_id; + u32 shared_mem_addr_offset; + u32 dpb_count; + u32 dmx_disable; +}; +struct vidc_1080p_seq_hdr_info{ + u32 img_size_x; + u32 img_size_y; + u32 dec_frm_size; + u32 min_num_dpb; + u32 min_luma_dpb_size; + u32 min_chroma_dpb_size; + u32 profile; + u32 level; + u32 disp_progressive; + u32 disp_crop_exists; + u32 dec_progressive; + u32 dec_crop_exists; + u32 crop_right_offset; + u32 crop_left_offset; + u32 crop_bottom_offset; + u32 crop_top_offset; + u32 data_partition; +}; +struct vidc_1080p_enc_seq_start_param{ + u32 cmd_seq_num; + u32 inst_id; + u32 shared_mem_addr_offset; + u32 stream_buffer_addr_offset; + u32 stream_buffer_size; +}; +struct vidc_1080p_enc_frame_start_param{ + u32 cmd_seq_num; + u32 inst_id; + u32 shared_mem_addr_offset; + u32 current_y_addr_offset; + u32 current_c_addr_offset; + u32 stream_buffer_addr_offset; + u32 stream_buffer_size; + u32 intra_frame; + u32 input_flush; + u32 slice_enable; + enum vidc_1080p_encode encode; +}; +struct vidc_1080p_enc_frame_info{ + u32 enc_frame_size; + u32 enc_picture_count; + u32 enc_write_pointer; + u32 enc_luma_address; + u32 enc_chroma_address; + 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; + u32 reconfig_flush_done; + u32 img_size_x; + u32 img_size_y; + u32 display_y_addr; + u32 display_c_addr; + u32 decode_y_addr; + u32 decode_c_addr; + u32 tag_top; + u32 pic_time_top; + u32 tag_bottom; + u32 pic_time_bottom; + u32 metadata_exists; + u32 disp_crop_exists; + u32 dec_crop_exists; + u32 crop_right_offset; + u32 crop_left_offset; + u32 crop_bottom_offset; + u32 crop_top_offset; + u32 input_bytes_consumed; + u32 input_is_interlace; + u32 input_frame_num; + enum vidc_1080p_display_status display_status; + enum vidc_1080p_display_status decode_status; + enum vidc_1080p_display_coding display_coding; + enum vidc_1080p_display_coding decode_coding; + enum vidc_1080P_decode_frame_correct_type display_correct; + enum vidc_1080P_decode_frame_correct_type decode_correct; + enum vidc_1080p_decode_frame input_frame; +}; +void vidc_1080p_do_sw_reset(enum vidc_1080p_reset init_flag); +void vidc_1080p_release_sw_reset(void); +void vidc_1080p_clear_interrupt(void); +void vidc_1080p_set_host2risc_cmd( + enum vidc_1080p_host2risc_cmd host2risc_command, + u32 host2risc_arg1, u32 host2risc_arg2, + u32 host2risc_arg3, u32 host2risc_arg4); +void vidc_1080p_get_risc2host_cmd(u32 *pn_risc2host_command, + u32 *pn_risc2host_arg1, u32 *pn_risc2host_arg2, + u32 *pn_risc2host_arg3, u32 *pn_risc2host_arg4); +void vidc_1080p_get_risc2host_cmd_status(u32 err_status, + u32 *dec_err_status, u32 *disp_err_status); +void vidc_1080p_clear_risc2host_cmd(void); +void vidc_1080p_get_fw_version(u32 *pn_fw_version); +void vidc_1080p_get_fw_status(u32 *pn_fw_status); +void vidc_1080p_init_memory_controller(u32 dram_base_addr_a, + u32 dram_base_addr_b); +void vidc_1080p_get_memory_controller_status(u32 *pb_mc_abusy, + u32 *pb_mc_bbusy); +void vidc_1080p_set_h264_decode_buffers(u32 dpb, u32 dec_vert_nb_mv_offset, + u32 dec_nb_ip_offset, u32 *pn_dpb_luma_offset, + u32 *pn_dpb_chroma_offset, u32 *pn_mv_buffer_offset); +void vidc_1080p_set_decode_recon_buffers(u32 recon_buffer, u32 *pn_dec_luma, + u32 *pn_dec_chroma); +void vidc_1080p_set_mpeg4_divx_decode_work_buffers(u32 nb_dcac_buffer_offset, + u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset, + u32 overlay_transform_buffer_offset, u32 stx_parser_buffer_offset); +void vidc_1080p_set_h263_decode_work_buffers(u32 nb_dcac_buffer_offset, + u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset, + u32 overlay_transform_buffer_offset); +void vidc_1080p_set_vc1_decode_work_buffers(u32 nb_dcac_buffer_offset, + u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset, + u32 overlay_transform_buffer_offset, u32 bitplain1Buffer_offset, + u32 bitplain2Buffer_offset, u32 bitplain3Buffer_offset); +void vidc_1080p_set_encode_recon_buffers(u32 recon_buffer, u32 *pn_enc_luma, + u32 *pn_enc_chroma); +void vidc_1080p_set_h264_encode_work_buffers(u32 up_row_mv_buffer_offset, + u32 direct_colzero_flag_buffer_offset, + u32 upper_intra_md_buffer_offset, + u32 upper_intra_pred_buffer_offset, u32 nbor_infor_buffer_offset, + u32 mb_info_offset); +void vidc_1080p_set_h263_encode_work_buffers(u32 up_row_mv_buffer_offset, + u32 up_row_inv_quanti_coeff_buffer_offset); +void vidc_1080p_set_mpeg4_encode_work_buffers(u32 skip_flag_buffer_offset, + u32 up_row_inv_quanti_coeff_buffer_offset, u32 upper_mv_offset); +void vidc_1080p_set_encode_frame_size(u32 hori_size, u32 vert_size); +void vidc_1080p_set_encode_profile_level(u32 encode_profile, u32 enc_level); +void vidc_1080p_set_encode_field_picture_structure(u32 enc_field_picture); +void vidc_1080p_set_decode_mpeg4_pp_filter(u32 lf_enables); +void vidc_1080p_set_decode_qp_save_control(u32 enable_q_pout); +void vidc_1080p_get_returned_channel_inst_id(u32 *pn_rtn_chid); +void vidc_1080p_clear_returned_channel_inst_id(void); +void vidc_1080p_get_decode_seq_start_result( + struct vidc_1080p_seq_hdr_info *seq_hdr_info); +void vidc_1080p_get_decoded_frame_size(u32 *pn_decoded_size); +void vidc_1080p_get_display_frame_result( + struct vidc_1080p_dec_disp_info *dec_disp_info); +void vidc_1080p_get_decode_frame( + enum vidc_1080p_decode_frame *pe_frame); +void vidc_1080p_get_decode_frame_result( + struct vidc_1080p_dec_disp_info *dec_disp_info); +void vidc_1080p_decode_seq_start_ch0( + struct vidc_1080p_dec_seq_start_param *param); +void vidc_1080p_decode_seq_start_ch1( + struct vidc_1080p_dec_seq_start_param *param); +void vidc_1080p_decode_init_buffers_ch0 + (struct vidc_1080p_dec_init_buffers_param *param); +void vidc_1080p_decode_init_buffers_ch1( + struct vidc_1080p_dec_init_buffers_param *param); +void vidc_1080p_decode_frame_start_ch0( + struct vidc_1080p_dec_frame_start_param *param); +void vidc_1080p_decode_frame_start_ch1( + struct vidc_1080p_dec_frame_start_param *param); +void vidc_1080p_set_dec_resolution_ch0(u32 width, u32 height); +void vidc_1080p_set_dec_resolution_ch1(u32 width, u32 height); +void vidc_1080p_get_encode_frame_info( + struct vidc_1080p_enc_frame_info *frame_info); +void vidc_1080p_encode_seq_start_ch0( + struct vidc_1080p_enc_seq_start_param *param); +void vidc_1080p_encode_seq_start_ch1( + struct vidc_1080p_enc_seq_start_param *param); +void vidc_1080p_encode_frame_start_ch0( + 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, + u32 mslice_mb, u32 mslice_byte); +void vidc_1080p_set_encode_circular_intra_refresh(u32 cir_num); +void vidc_1080p_set_encode_input_frame_format( + enum vidc_1080p_memory_access_method memory_format); +void vidc_1080p_set_encode_padding_control(u32 pad_ctrl_on, + u32 cr_pad_val, u32 cb_pad_val, u32 luma_pad_val); +void vidc_1080p_encode_set_rc_config(u32 enable_frame_level_rc, + u32 enable_mb_level_rc_flag, u32 frame_qp); +void vidc_1080p_encode_set_frame_level_rc_params(u32 rc_frame_rate, + u32 target_bitrate, u32 reaction_coeff); +void vidc_1080p_encode_set_qp_params(u32 max_qp, u32 min_qp); +void vidc_1080p_encode_set_mb_level_rc_params(u32 disable_dark_region_as_flag, + u32 disable_smooth_region_as_flag , u32 disable_static_region_as_flag, + u32 disable_activity_region_flag); +void vidc_1080p_get_qp(u32 *pn_frame_qp); +void vidc_1080p_set_h264_encode_entropy( + enum vidc_1080p_entropy_sel entropy_sel); +void vidc_1080p_set_h264_encode_loop_filter( + enum vidc_1080p_DBConfig db_config, u32 slice_alpha_offset, + u32 slice_beta_offset); +void vidc_1080p_set_h264_encoder_p_frame_ref_count(u32 max_reference); +void vidc_1080p_set_h264_encode_8x8transform_control(u32 enable_8x8transform); +void vidc_1080p_set_mpeg4_encode_quarter_pel_control( + u32 enable_mpeg4_quarter_pel); +void vidc_1080p_set_device_base_addr(u8 *mapped_va); +void vidc_1080p_get_intra_bias(u32 *intra_bias); +void vidc_1080p_set_intra_bias(u32 intra_bias); +void vidc_1080p_get_bi_directional_bias(u32 *bi_directional_bias); +void vidc_1080p_set_bi_directional_bias(u32 bi_directional_bias); +void vidc_1080p_get_encoder_sequence_header_size(u32 *seq_header_size); +void vidc_1080p_get_intermedia_stage_debug_counter( + u32 *intermediate_stage_counter); +void vidc_1080p_get_exception_status(u32 *exception_status); +void vidc_1080p_frame_start_realloc(u32 instance_id); +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h new file mode 100644 index 0000000000000000000000000000000000000000..d63a45bb420424630d80f9bc66cbe110d9ec97aa --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h @@ -0,0 +1,115 @@ +/* Copyright (c) 2010, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VIDC_HWIO_H_ +#define _VIDC_HWIO_H_ + +#include "vidc_hwio_reg.h" + +#ifdef VIDC_REGISTER_LOG +#define VIDC_REG_OUT(x...) printk(KERN_DEBUG x) +#define VIDC_REG_IN(x...) printk(KERN_DEBUG x) +#else +#define VIDC_REG_OUT(x...) +#define VIDC_REG_IN(x...) +#endif + +#define __inpdw(port) __raw_readl(port) +#define __outpdw(port, val) __raw_writel(val, port) + +#define in_dword(addr) (__inpdw(addr)) +#define in_dword_masked(addr, mask) (__inpdw(addr) & (mask)) +#define out_dword(addr, val) __outpdw(addr, val) + +#define out_dword_masked(io, mask, val, shadow) \ +do { \ + shadow = (shadow & (u32)(~(mask))) | ((u32)((val) & (mask))); \ + out_dword(io, shadow); \ +} while (0) +#define out_dword_masked_ns(io, mask, val, current_reg_content) \ + out_dword(io, ((current_reg_content & (u32)(~(mask))) | \ + ((u32)((val) & (mask))))) + +#define HWIO_IN(hwiosym) HWIO_##hwiosym##_IN +#define HWIO_INI(hwiosym, index) HWIO_##hwiosym##_INI(index) +#define HWIO_INM(hwiosym, mask) HWIO_##hwiosym##_INM(mask) +#define HWIO_INF(hwiosym, field) (HWIO_INM(hwiosym, \ + HWIO_FMSK(hwiosym, field)) >> HWIO_SHFT(hwiosym, field)) + +#define HWIO_OUT(hwiosym, val) HWIO_##hwiosym##_OUT(val) +#define HWIO_OUTI(hwiosym, index, val) HWIO_##hwiosym##_OUTI(index, val) +#define HWIO_OUTM(hwiosym, mask, val) HWIO_##hwiosym##_OUTM(mask, val) +#define HWIO_OUTF(hwiosym, field, val) HWIO_OUTM(hwiosym, \ + HWIO_FMSK(hwiosym, field), (u32)(val) << HWIO_SHFT(hwiosym, field)) + +#define HWIO_SHFT(hwio_regsym, hwio_fldsym) \ + HWIO_##hwiosym##_##hwiofldsym##_SHFT +#define HWIO_FMSK(hwio_regsym, hwio_fldsym) \ + HWIO_##hwiosym##_##hwiofldsym##_BMSK + +#define VIDC_SETFIELD(val, shift, mask) \ + (((val) << (shift)) & (mask)) +#define VIDC_GETFIELD(val, mask, shift) \ + (((val) & (mask)) >> (shift)) + +#define VIDC_HWIO_OUT(hwiosym, val) \ +do { \ + VIDC_REG_OUT("\n(0x%x:"#hwiosym"=0x%x)", \ + HWIO_##hwiosym##_ADDR - VIDC_BASE_PTR, val); \ + mb(); \ + HWIO_OUT(hwiosym, val); \ +} while (0) +#define VIDC_HWIO_OUTI(hwiosym, index, val) \ +do { \ + VIDC_REG_OUT("\n(0x%x:"#hwiosym"(%d)=0x%x)", \ + HWIO_##hwiosym##_ADDR(index) - VIDC_BASE_PTR, index, val); \ + mb(); \ + HWIO_OUTI(hwiosym, index, val); \ +} while (0) +#define VIDC_HWIO_OUTF(hwiosym, field, val) \ +do { \ + VIDC_REG_OUT("\n(0x%x:"#hwiosym":0x%x:=0x%x)" , \ + HWIO_##hwiosym##_ADDR - VIDC_BASE_PTR, \ + HWIO_##hwiosym##_##field##_BMSK, val) \ + mb(); \ + HWIO_OUTF(hwiosym, field, val); \ +} while (0) +#define VIDC_OUT_DWORD(addr, val) \ +do { \ + VIDC_REG_OUT("\n(0x%x:"#addr"=0x%x)", \ + addr - VIDC_BASE_PTR, val); \ + mb(); \ + out_dword(addr, val); \ +} while (0) +#define VIDC_HWIO_IN(hwiosym, pval) \ +do { \ + mb(); \ + *pval = (u32) HWIO_IN(hwiosym); \ + VIDC_REG_IN("\n(0x%x:"#hwiosym"=0x%x)", \ + HWIO_##hwiosym##_ADDR - VIDC_BASE_PTR, *pval);\ +} while (0) +#define VIDC_HWIO_INI(hwiosym, index, pval) \ +do { \ + mb(); \ + *pval = (u32) HWIO_INI(hwiosym, index); \ + VIDC_REG_IN("(0x%x:"#hwiosym"(%d)==0x%x)", \ + HWIO_##hwiosym##_ADDR(index) - VIDC_BASE_PTR, index, *pval); \ +} while (0) +#define VIDC_HWIO_INF(hwiosym, mask, pval) \ +do { \ + mb(); \ + *pval = HWIO_INF(hwiosym, mask); \ + VIDC_REG_IN("\n(0x%x:"#hwiosym"=0x%x)", \ + HWIO_##hwiosym##_ADDR - VIDC_BASE_PTR, *pval); \ +} while (0) +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..0de06bf62faf2ec1d4daf1fe2ed19492dd1773bd --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h @@ -0,0 +1,4544 @@ +/* Copyright (c) 2010, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VIDC_HWIO_REG_H_ +#define _VIDC_HWIO_REG_H_ + +#include +#include +#include +#include "vidc.h" + +extern u8 *VIDC_BASE_PTR; + +#define VIDC_BASE VIDC_BASE_PTR + +#define VIDC_BLACKBIRD_REG_BASE (VIDC_BASE + 0x00000000) +#define VIDC_BLACKBIRD_REG_BASE_PHYS 0x04400000 + +#define HWIO_REG_557899_ADDR (VIDC_BLACKBIRD_REG_BASE + 00000000) +#define HWIO_REG_557899_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 00000000) +#define HWIO_REG_557899_RMSK 0x3ff +#define HWIO_REG_557899_SHFT 0 +#define HWIO_REG_557899_IN in_dword_masked(HWIO_REG_557899_ADDR,\ + HWIO_REG_557899_RMSK) +#define HWIO_REG_557899_INM(m) in_dword_masked(HWIO_REG_557899_ADDR, m) +#define HWIO_REG_557899_OUT(v) out_dword(HWIO_REG_557899_ADDR, v) +#define HWIO_REG_557899_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_557899_ADDR, m, v, HWIO_REG_557899_IN); +#define HWIO_REG_557899_RSTN_RG_MPEG2_BMSK 0x200 +#define HWIO_REG_557899_RSTN_RG_MPEG2_SHFT 0x9 +#define HWIO_REG_557899_RSTN_RG_MPEG4_BMSK 0x100 +#define HWIO_REG_557899_RSTN_RG_MPEG4_SHFT 0x8 +#define HWIO_REG_557899_RSTN_RG_VC1_BMSK 0x80 +#define HWIO_REG_557899_RSTN_RG_VC1_SHFT 0x7 +#define HWIO_REG_557899_RSTN_RG_H264_BMSK 0x40 +#define HWIO_REG_557899_RSTN_RG_H264_SHFT 0x6 +#define HWIO_REG_557899_RSTN_RG_COMMON_BMSK 0x20 +#define HWIO_REG_557899_RSTN_RG_COMMON_SHFT 0x5 +#define HWIO_REG_557899_RSTN_DMX_BMSK 0x10 +#define HWIO_REG_557899_RSTN_DMX_SHFT 0x4 +#define HWIO_REG_557899_RSTN_VI_BMSK 0x8 +#define HWIO_REG_557899_RSTN_VI_SHFT 0x3 +#define HWIO_REG_557899_RSTN_VIDCCORE_BMSK 0x4 +#define HWIO_REG_557899_RSTN_VIDCCORE_SHFT 0x2 +#define HWIO_REG_557899_RSTN_MC_BMSK 0x2 +#define HWIO_REG_557899_RSTN_MC_SHFT 0x1 +#define HWIO_REG_557899_RSTN_RISC_BMSK 0x1 +#define HWIO_REG_557899_RSTN_RISC_SHFT 0 + +#define HWIO_REG_575377_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000008) +#define HWIO_REG_575377_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000008) +#define HWIO_REG_575377_RMSK 0x1 +#define HWIO_REG_575377_SHFT 0 +#define HWIO_REG_575377_IN in_dword_masked(\ + HWIO_REG_575377_ADDR, HWIO_REG_575377_RMSK) +#define HWIO_REG_575377_INM(m) \ + in_dword_masked(HWIO_REG_575377_ADDR, m) +#define HWIO_REG_575377_OUT(v) \ + out_dword(HWIO_REG_575377_ADDR, v) +#define HWIO_REG_575377_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_575377_ADDR, m, v, HWIO_REG_575377_IN); +#define HWIO_REG_575377_INTERRUPT_BMSK 0x1 +#define HWIO_REG_575377_INTERRUPT_SHFT 0 + +#define HWIO_REG_611794_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000030) +#define HWIO_REG_611794_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000030) +#define HWIO_REG_611794_RMSK 0xffffffff +#define HWIO_REG_611794_SHFT 0 +#define HWIO_REG_611794_IN in_dword_masked(\ + HWIO_REG_611794_ADDR, HWIO_REG_611794_RMSK) +#define HWIO_REG_611794_INM(m) \ + in_dword_masked(HWIO_REG_611794_ADDR, m) +#define HWIO_REG_611794_OUT(v) \ + out_dword(HWIO_REG_611794_ADDR, v) +#define HWIO_REG_611794_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_611794_ADDR, m, v,\ + HWIO_REG_611794_IN); +#define HWIO_REG_611794_HOST2RISC_COMMAND_BMSK 0xffffffff +#define HWIO_REG_611794_HOST2RISC_COMMAND_SHFT 0 + +#define HWIO_REG_356340_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000034) +#define HWIO_REG_356340_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000034) +#define HWIO_REG_356340_RMSK 0xffffffff +#define HWIO_REG_356340_SHFT 0 +#define HWIO_REG_356340_IN in_dword_masked(\ + HWIO_REG_356340_ADDR, HWIO_REG_356340_RMSK) +#define HWIO_REG_356340_INM(m) \ + in_dword_masked(HWIO_REG_356340_ADDR, m) +#define HWIO_REG_356340_OUT(v) \ + out_dword(HWIO_REG_356340_ADDR, v) +#define HWIO_REG_356340_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_356340_ADDR, m, v, HWIO_REG_356340_IN); +#define HWIO_REG_356340_HOST2RISC_ARG1_BMSK 0xffffffff +#define HWIO_REG_356340_HOST2RISC_ARG1_SHFT 0 + +#define HWIO_REG_899023_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000038) +#define HWIO_REG_899023_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000038) +#define HWIO_REG_899023_RMSK 0xffffffff +#define HWIO_REG_899023_SHFT 0 +#define HWIO_REG_899023_IN in_dword_masked(\ + HWIO_REG_899023_ADDR, HWIO_REG_899023_RMSK) +#define HWIO_REG_899023_INM(m) \ + in_dword_masked(HWIO_REG_899023_ADDR, m) +#define HWIO_REG_899023_OUT(v) \ + out_dword(HWIO_REG_899023_ADDR, v) +#define HWIO_REG_899023_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_899023_ADDR, m, v, HWIO_REG_899023_IN); +#define HWIO_REG_899023_HOST2RISC_ARG2_BMSK 0xffffffff +#define HWIO_REG_899023_HOST2RISC_ARG2_SHFT 0 + +#define HWIO_REG_987762_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000003c) +#define HWIO_REG_987762_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000003c) +#define HWIO_REG_987762_RMSK 0xffffffff +#define HWIO_REG_987762_SHFT 0 +#define HWIO_REG_987762_IN in_dword_masked(\ + HWIO_REG_987762_ADDR, HWIO_REG_987762_RMSK) +#define HWIO_REG_987762_INM(m) \ + in_dword_masked(HWIO_REG_987762_ADDR, m) +#define HWIO_REG_987762_OUT(v) \ + out_dword(HWIO_REG_987762_ADDR, v) +#define HWIO_REG_987762_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_987762_ADDR, m, v, HWIO_REG_987762_IN); +#define HWIO_REG_987762_HOST2RISC_ARG3_BMSK 0xffffffff +#define HWIO_REG_987762_HOST2RISC_ARG3_SHFT 0 + +#define HWIO_REG_544000_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000040) +#define HWIO_REG_544000_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000040) +#define HWIO_REG_544000_RMSK 0xffffffff +#define HWIO_REG_544000_SHFT 0 +#define HWIO_REG_544000_IN in_dword_masked(\ + HWIO_REG_544000_ADDR, HWIO_REG_544000_RMSK) +#define HWIO_REG_544000_INM(m) \ + in_dword_masked(HWIO_REG_544000_ADDR, m) +#define HWIO_REG_544000_OUT(v) \ + out_dword(HWIO_REG_544000_ADDR, v) +#define HWIO_REG_544000_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_544000_ADDR, m, v, HWIO_REG_544000_IN); +#define HWIO_REG_544000_HOST2RISC_ARG4_BMSK 0xffffffff +#define HWIO_REG_544000_HOST2RISC_ARG4_SHFT 0 + +#define HWIO_REG_695082_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000044) +#define HWIO_REG_695082_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000044) +#define HWIO_REG_695082_RMSK 0xffffffff +#define HWIO_REG_695082_SHFT 0 +#define HWIO_REG_695082_IN in_dword_masked(\ + HWIO_REG_695082_ADDR, HWIO_REG_695082_RMSK) +#define HWIO_REG_695082_INM(m) \ + in_dword_masked(HWIO_REG_695082_ADDR, m) +#define HWIO_REG_695082_OUT(v) \ + out_dword(HWIO_REG_695082_ADDR, v) +#define HWIO_REG_695082_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_695082_ADDR, m, v, HWIO_REG_695082_IN); +#define HWIO_REG_695082_RISC2HOST_COMMAND_BMSK 0xffffffff +#define HWIO_REG_695082_RISC2HOST_COMMAND_SHFT 0 + +#define HWIO_REG_156596_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000048) +#define HWIO_REG_156596_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000048) +#define HWIO_REG_156596_RMSK 0xffffffff +#define HWIO_REG_156596_SHFT 0 +#define HWIO_REG_156596_IN in_dword_masked(\ + HWIO_REG_156596_ADDR, HWIO_REG_156596_RMSK) +#define HWIO_REG_156596_INM(m) \ + in_dword_masked(HWIO_REG_156596_ADDR, m) +#define HWIO_REG_156596_OUT(v) \ + out_dword(HWIO_REG_156596_ADDR, v) +#define HWIO_REG_156596_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_156596_ADDR, m, v, HWIO_REG_156596_IN); +#define HWIO_REG_156596_REG_156596_BMSK 0xffffffff +#define HWIO_REG_156596_REG_156596_SHFT 0 + +#define HWIO_REG_222292_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000004c) +#define HWIO_REG_222292_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000004c) +#define HWIO_REG_222292_RMSK 0xffffffff +#define HWIO_REG_222292_SHFT 0 +#define HWIO_REG_222292_IN in_dword_masked(\ + HWIO_REG_222292_ADDR, HWIO_REG_222292_RMSK) +#define HWIO_REG_222292_INM(m) \ + in_dword_masked(HWIO_REG_222292_ADDR, m) +#define HWIO_REG_222292_OUT(v) \ + out_dword(HWIO_REG_222292_ADDR, v) +#define HWIO_REG_222292_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_222292_ADDR, m, v, HWIO_REG_222292_IN); +#define HWIO_REG_222292_REG_222292_BMSK 0xffffffff +#define HWIO_REG_222292_REG_222292_SHFT 0 + +#define HWIO_REG_790962_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000050) +#define HWIO_REG_790962_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000050) +#define HWIO_REG_790962_RMSK 0xffffffff +#define HWIO_REG_790962_SHFT 0 +#define HWIO_REG_790962_IN in_dword_masked(\ + HWIO_REG_790962_ADDR, HWIO_REG_790962_RMSK) +#define HWIO_REG_790962_INM(m) \ + in_dword_masked(HWIO_REG_790962_ADDR, m) +#define HWIO_REG_790962_OUT(v) \ + out_dword(HWIO_REG_790962_ADDR, v) +#define HWIO_REG_790962_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_790962_ADDR, m, v, HWIO_REG_790962_IN); +#define HWIO_REG_790962_REG_790962_BMSK 0xffffffff +#define HWIO_REG_790962_REG_790962_SHFT 0 + +#define HWIO_REG_679882_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000054) +#define HWIO_REG_679882_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000054) +#define HWIO_REG_679882_RMSK 0xffffffff +#define HWIO_REG_679882_SHFT 0 +#define HWIO_REG_679882_IN in_dword_masked(\ + HWIO_REG_679882_ADDR, HWIO_REG_679882_RMSK) +#define HWIO_REG_679882_INM(m) \ + in_dword_masked(HWIO_REG_679882_ADDR, m) +#define HWIO_REG_679882_OUT(v) \ + out_dword(HWIO_REG_679882_ADDR, v) +#define HWIO_REG_679882_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_679882_ADDR, m, v, HWIO_REG_679882_IN); +#define HWIO_REG_679882_REG_679882_BMSK 0xffffffff +#define HWIO_REG_679882_REG_679882_SHFT 0 + +#define HWIO_REG_653206_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000058) +#define HWIO_REG_653206_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000058) +#define HWIO_REG_653206_RMSK 0xffffff +#define HWIO_REG_653206_SHFT 0 +#define HWIO_REG_653206_IN in_dword_masked(\ + HWIO_REG_653206_ADDR, HWIO_REG_653206_RMSK) +#define HWIO_REG_653206_INM(m) \ + in_dword_masked(HWIO_REG_653206_ADDR, m) +#define HWIO_REG_653206_YEAR_BMSK 0xff0000 +#define HWIO_REG_653206_YEAR_SHFT 0x10 +#define HWIO_REG_653206_MONTH_BMSK 0xff00 +#define HWIO_REG_653206_MONTH_SHFT 0x8 +#define HWIO_REG_653206_DAY_BMSK 0xff +#define HWIO_REG_653206_DAY_SHFT 0 + +#define HWIO_REG_805993_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000064) +#define HWIO_REG_805993_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000064) +#define HWIO_REG_805993_RMSK 0xffffffff +#define HWIO_REG_805993_SHFT 0 +#define HWIO_REG_805993_IN in_dword_masked(\ + HWIO_REG_805993_ADDR, HWIO_REG_805993_RMSK) +#define HWIO_REG_805993_INM(m) \ + in_dword_masked(HWIO_REG_805993_ADDR, m) +#define HWIO_REG_805993_INTERMEDIATE_STAGE_COUNTER_BMSK 0xffffffff +#define HWIO_REG_805993_INTERMEDIATE_STAGE_COUNTER_SHFT 0 + +#define HWIO_REG_493355_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000068) +#define HWIO_REG_493355_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000068) +#define HWIO_REG_493355_RMSK 0xffffffff +#define HWIO_REG_493355_SHFT 0 +#define HWIO_REG_493355_IN in_dword_masked(\ + HWIO_REG_493355_ADDR, HWIO_REG_493355_RMSK) +#define HWIO_REG_493355_INM(m) \ + in_dword_masked(HWIO_REG_493355_ADDR, m) +#define HWIO_REG_493355_EXCEPTION_STATUS_BMSK 0xffffffff +#define HWIO_REG_493355_EXCEPTION_STATUS_SHFT 0 + +#define HWIO_REG_350619_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000080) +#define HWIO_REG_350619_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000080) +#define HWIO_REG_350619_RMSK 0x1 +#define HWIO_REG_350619_SHFT 0 +#define HWIO_REG_350619_IN in_dword_masked(\ + HWIO_REG_350619_ADDR, HWIO_REG_350619_RMSK) +#define HWIO_REG_350619_INM(m) \ + in_dword_masked(HWIO_REG_350619_ADDR, m) +#define HWIO_REG_350619_FIRMWARE_STATUS_BMSK 0x1 +#define HWIO_REG_350619_FIRMWARE_STATUS_SHFT 0 + +#define HWIO_REG_64440_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000508) +#define HWIO_REG_64440_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000508) +#define HWIO_REG_64440_RMSK 0xfffe0000 +#define HWIO_REG_64440_SHFT 0 +#define HWIO_REG_64440_IN in_dword_masked(\ + HWIO_REG_64440_ADDR, HWIO_REG_64440_RMSK) +#define HWIO_REG_64440_INM(m) \ + in_dword_masked(HWIO_REG_64440_ADDR, m) +#define HWIO_REG_64440_OUT(v) \ + out_dword(HWIO_REG_64440_ADDR, v) +#define HWIO_REG_64440_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_64440_ADDR, m, v,\ + HWIO_REG_64440_IN); +#define HWIO_REG_64440_MC_DRAMBASE_ADDR_BMSK 0xfffe0000 +#define HWIO_REG_64440_MC_DRAMBASE_ADDR_SHFT 0x11 + +#define HWIO_REG_675915_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000050c) +#define HWIO_REG_675915_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000050c) +#define HWIO_REG_675915_RMSK 0xfffe0000 +#define HWIO_REG_675915_SHFT 0 +#define HWIO_REG_675915_IN in_dword_masked(\ + HWIO_REG_675915_ADDR, HWIO_REG_675915_RMSK) +#define HWIO_REG_675915_INM(m) \ + in_dword_masked(HWIO_REG_675915_ADDR, m) +#define HWIO_REG_675915_OUT(v) \ + out_dword(HWIO_REG_675915_ADDR, v) +#define HWIO_REG_675915_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_675915_ADDR, m, v,\ + HWIO_REG_675915_IN); +#define HWIO_REG_675915_MC_DRAMBASE_ADDR_BMSK 0xfffe0000 +#define HWIO_REG_675915_MC_DRAMBASE_ADDR_SHFT 0x11 + +#define HWIO_REG_399911_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000510) +#define HWIO_REG_399911_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000510) +#define HWIO_REG_399911_RMSK 0x3 +#define HWIO_REG_399911_SHFT 0 +#define HWIO_REG_399911_IN in_dword_masked(\ + HWIO_REG_399911_ADDR, HWIO_REG_399911_RMSK) +#define HWIO_REG_399911_INM(m) in_dword_masked(HWIO_REG_399911_ADDR, m) +#define HWIO_REG_399911_MC_BUSY_B_BMSK 0x2 +#define HWIO_REG_399911_MC_BUSY_B_SHFT 0x1 +#define HWIO_REG_399911_MC_BUSY_A_BMSK 0x1 +#define HWIO_REG_399911_MC_BUSY_A_SHFT 0 + +#define HWIO_REG_515200_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000600) +#define HWIO_REG_515200_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000600) +#define HWIO_REG_515200_RMSK 0x1ffff +#define HWIO_REG_515200_SHFT 0 +#define HWIO_REG_515200_IN in_dword_masked(\ + HWIO_REG_515200_ADDR, HWIO_REG_515200_RMSK) +#define HWIO_REG_515200_INM(m) \ + in_dword_masked(HWIO_REG_515200_ADDR, m) +#define HWIO_REG_515200_OUT(v) \ + out_dword(HWIO_REG_515200_ADDR, v) +#define HWIO_REG_515200_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_515200_ADDR, m, v,\ + HWIO_REG_515200_IN); +#define HWIO_REG_515200_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_515200_BASE_ADDR_SHFT 0 + +#define HWIO_REG_29510_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000604) +#define HWIO_REG_29510_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000604) +#define HWIO_REG_29510_RMSK 0x1ffff +#define HWIO_REG_29510_SHFT 0 +#define HWIO_REG_29510_IN in_dword_masked(\ + HWIO_REG_29510_ADDR, HWIO_REG_29510_RMSK) +#define HWIO_REG_29510_INM(m) \ + in_dword_masked(HWIO_REG_29510_ADDR, m) +#define HWIO_REG_29510_OUT(v) \ + out_dword(HWIO_REG_29510_ADDR, v) +#define HWIO_REG_29510_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_29510_ADDR, m, v,\ + HWIO_REG_29510_IN); +#define HWIO_REG_29510_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_29510_BASE_ADDR_SHFT 0 + +#define HWIO_REG_256132_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000608) +#define HWIO_REG_256132_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000608) +#define HWIO_REG_256132_RMSK 0x1ffff +#define HWIO_REG_256132_SHFT 0 +#define HWIO_REG_256132_IN in_dword_masked(\ + HWIO_REG_256132_ADDR, HWIO_REG_256132_RMSK) +#define HWIO_REG_256132_INM(m) \ + in_dword_masked(HWIO_REG_256132_ADDR, m) +#define HWIO_REG_256132_OUT(v) \ + out_dword(HWIO_REG_256132_ADDR, v) +#define HWIO_REG_256132_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_256132_ADDR, m, v,\ + HWIO_REG_256132_IN); +#define HWIO_REG_256132_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_256132_BASE_ADDR_SHFT 0 + +#define HWIO_REG_885152_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000060c) +#define HWIO_REG_885152_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000060c) +#define HWIO_REG_885152_RMSK 0x1ffff +#define HWIO_REG_885152_SHFT 0 +#define HWIO_REG_885152_IN in_dword_masked(\ + HWIO_REG_885152_ADDR, HWIO_REG_885152_RMSK) +#define HWIO_REG_885152_INM(m) \ + in_dword_masked(HWIO_REG_885152_ADDR, m) +#define HWIO_REG_885152_OUT(v) \ + out_dword(HWIO_REG_885152_ADDR, v) +#define HWIO_REG_885152_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_885152_ADDR, m, v,\ + HWIO_REG_885152_IN); +#define HWIO_REG_885152_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_885152_BASE_ADDR_SHFT 0 + +#define HWIO_REG_69832_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000610) +#define HWIO_REG_69832_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000610) +#define HWIO_REG_69832_RMSK 0x1ffff +#define HWIO_REG_69832_SHFT 0 +#define HWIO_REG_69832_IN in_dword_masked(\ + HWIO_REG_69832_ADDR, HWIO_REG_69832_RMSK) +#define HWIO_REG_69832_INM(m) \ + in_dword_masked(HWIO_REG_69832_ADDR, m) +#define HWIO_REG_69832_OUT(v) \ + out_dword(HWIO_REG_69832_ADDR, v) +#define HWIO_REG_69832_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_69832_ADDR, m, v,\ + HWIO_REG_69832_IN); +#define HWIO_REG_69832_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_69832_BASE_ADDR_SHFT 0 + +#define HWIO_REG_686205_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000614) +#define HWIO_REG_686205_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000614) +#define HWIO_REG_686205_RMSK 0x1ffff +#define HWIO_REG_686205_SHFT 0 +#define HWIO_REG_686205_IN in_dword_masked(\ + HWIO_REG_686205_ADDR, HWIO_REG_686205_RMSK) +#define HWIO_REG_686205_INM(m) \ + in_dword_masked(HWIO_REG_686205_ADDR, m) +#define HWIO_REG_686205_OUT(v) \ + out_dword(HWIO_REG_686205_ADDR, v) +#define HWIO_REG_686205_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_686205_ADDR, m, v,\ + HWIO_REG_686205_IN); +#define HWIO_REG_686205_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_686205_BASE_ADDR_SHFT 0 + +#define HWIO_REG_728036_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000618) +#define HWIO_REG_728036_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000618) +#define HWIO_REG_728036_RMSK 0x1ffff +#define HWIO_REG_728036_SHFT 0 +#define HWIO_REG_728036_IN in_dword_masked(\ + HWIO_REG_728036_ADDR, HWIO_REG_728036_RMSK) +#define HWIO_REG_728036_INM(m) \ + in_dword_masked(HWIO_REG_728036_ADDR, m) +#define HWIO_REG_728036_OUT(v) \ + out_dword(HWIO_REG_728036_ADDR, v) +#define HWIO_REG_728036_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_728036_ADDR, m, v,\ + HWIO_REG_728036_IN); +#define HWIO_REG_728036_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_728036_BASE_ADDR_SHFT 0 + +#define HWIO_REG_294579_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000061c) +#define HWIO_REG_294579_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000061c) +#define HWIO_REG_294579_RMSK 0x1ffff +#define HWIO_REG_294579_SHFT 0 +#define HWIO_REG_294579_IN in_dword_masked(\ + HWIO_REG_294579_ADDR, HWIO_REG_294579_RMSK) +#define HWIO_REG_294579_INM(m) \ + in_dword_masked(HWIO_REG_294579_ADDR, m) +#define HWIO_REG_294579_OUT(v) \ + out_dword(HWIO_REG_294579_ADDR, v) +#define HWIO_REG_294579_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_294579_ADDR, m, v,\ + HWIO_REG_294579_IN); +#define HWIO_REG_294579_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_294579_BASE_ADDR_SHFT 0 + +#define HWIO_REG_61427_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000620) +#define HWIO_REG_61427_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000620) +#define HWIO_REG_61427_RMSK 0x1ffff +#define HWIO_REG_61427_SHFT 0 +#define HWIO_REG_61427_IN in_dword_masked(\ + HWIO_REG_61427_ADDR, HWIO_REG_61427_RMSK) +#define HWIO_REG_61427_INM(m) \ + in_dword_masked(HWIO_REG_61427_ADDR, m) +#define HWIO_REG_61427_OUT(v) \ + out_dword(HWIO_REG_61427_ADDR, v) +#define HWIO_REG_61427_OUTM(m , v) out_dword_masked_ns(\ + HWIO_REG_61427_ADDR, m, v,\ + HWIO_REG_61427_IN); +#define HWIO_REG_61427_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_61427_BASE_ADDR_SHFT 0 + +#define HWIO_REG_578196_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000624) +#define HWIO_REG_578196_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000624) +#define HWIO_REG_578196_RMSK 0x1ffff +#define HWIO_REG_578196_SHFT 0 +#define HWIO_REG_578196_IN in_dword_masked(\ + HWIO_REG_578196_ADDR, HWIO_REG_578196_RMSK) +#define HWIO_REG_578196_INM(m) \ + in_dword_masked(HWIO_REG_578196_ADDR, m) +#define HWIO_REG_578196_OUT(v) \ + out_dword(HWIO_REG_578196_ADDR, v) +#define HWIO_REG_578196_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_578196_ADDR, m, v,\ + HWIO_REG_578196_IN); +#define HWIO_REG_578196_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_578196_BASE_ADDR_SHFT 0 + +#define HWIO_REG_408588_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000628) +#define HWIO_REG_408588_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000628) +#define HWIO_REG_408588_RMSK 0x1ffff +#define HWIO_REG_408588_SHFT 0 +#define HWIO_REG_408588_IN in_dword_masked(\ + HWIO_REG_408588_ADDR, HWIO_REG_408588_RMSK) +#define HWIO_REG_408588_INM(m) \ + in_dword_masked(HWIO_REG_408588_ADDR, m) +#define HWIO_REG_408588_OUT(v) \ + out_dword(HWIO_REG_408588_ADDR, v) +#define HWIO_REG_408588_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_408588_ADDR, m, v,\ + HWIO_REG_408588_IN); +#define HWIO_REG_408588_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_408588_BASE_ADDR_SHFT 0 + +#define HWIO_REG_55617_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000062c) +#define HWIO_REG_55617_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000062c) +#define HWIO_REG_55617_RMSK 0x1ffff +#define HWIO_REG_55617_SHFT 0 +#define HWIO_REG_55617_IN in_dword_masked(\ + HWIO_REG_55617_ADDR, HWIO_REG_55617_RMSK) +#define HWIO_REG_55617_INM(m) \ + in_dword_masked(HWIO_REG_55617_ADDR, m) +#define HWIO_REG_55617_OUT(v) \ + out_dword(HWIO_REG_55617_ADDR, v) +#define HWIO_REG_55617_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_55617_ADDR, m, v,\ + HWIO_REG_55617_IN); +#define HWIO_REG_55617_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_55617_BASE_ADDR_SHFT 0 + +#define HWIO_REG_555239_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000630) +#define HWIO_REG_555239_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000630) +#define HWIO_REG_555239_RMSK 0x1ffff +#define HWIO_REG_555239_SHFT 0 +#define HWIO_REG_555239_IN in_dword_masked(\ + HWIO_REG_555239_ADDR, HWIO_REG_555239_RMSK) +#define HWIO_REG_555239_INM(m) \ + in_dword_masked(HWIO_REG_555239_ADDR, m) +#define HWIO_REG_555239_OUT(v) \ + out_dword(HWIO_REG_555239_ADDR, v) +#define HWIO_REG_555239_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_555239_ADDR, m, v,\ + HWIO_REG_555239_IN); +#define HWIO_REG_555239_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_555239_BASE_ADDR_SHFT 0 + +#define HWIO_REG_515333_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000634) +#define HWIO_REG_515333_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000634) +#define HWIO_REG_515333_RMSK 0x1ffff +#define HWIO_REG_515333_SHFT 0 +#define HWIO_REG_515333_IN in_dword_masked(\ + HWIO_REG_515333_ADDR, HWIO_REG_515333_RMSK) +#define HWIO_REG_515333_INM(m) \ + in_dword_masked(HWIO_REG_515333_ADDR, m) +#define HWIO_REG_515333_OUT(v) \ + out_dword(HWIO_REG_515333_ADDR, v) +#define HWIO_REG_515333_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_515333_ADDR, m, v,\ + HWIO_REG_515333_IN); +#define HWIO_REG_515333_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_515333_BASE_ADDR_SHFT 0 + +#define HWIO_REG_951675_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000638) +#define HWIO_REG_951675_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000638) +#define HWIO_REG_951675_RMSK 0x1ffff +#define HWIO_REG_951675_SHFT 0 +#define HWIO_REG_951675_IN in_dword_masked(\ + HWIO_REG_951675_ADDR, HWIO_REG_951675_RMSK) +#define HWIO_REG_951675_INM(m) \ + in_dword_masked(HWIO_REG_951675_ADDR, m) +#define HWIO_REG_951675_OUT(v) \ + out_dword(HWIO_REG_951675_ADDR, v) +#define HWIO_REG_951675_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_951675_ADDR, m, v,\ + HWIO_REG_951675_IN); +#define HWIO_REG_951675_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_951675_BASE_ADDR_SHFT 0 + +#define HWIO_REG_500775_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000063c) +#define HWIO_REG_500775_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000063c) +#define HWIO_REG_500775_RMSK 0x1ffff +#define HWIO_REG_500775_SHFT 0 +#define HWIO_REG_500775_IN in_dword_masked(\ + HWIO_REG_500775_ADDR, HWIO_REG_500775_RMSK) +#define HWIO_REG_500775_INM(m) \ + in_dword_masked(HWIO_REG_500775_ADDR, m) +#define HWIO_REG_500775_OUT(v) \ + out_dword(HWIO_REG_500775_ADDR, v) +#define HWIO_REG_500775_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_500775_ADDR, m, v,\ + HWIO_REG_500775_IN); +#define HWIO_REG_500775_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_500775_BASE_ADDR_SHFT 0 + +#define HWIO_REG_649786_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000640) +#define HWIO_REG_649786_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000640) +#define HWIO_REG_649786_RMSK 0x1ffff +#define HWIO_REG_649786_SHFT 0 +#define HWIO_REG_649786_IN in_dword_masked(\ + HWIO_REG_649786_ADDR, HWIO_REG_649786_RMSK) +#define HWIO_REG_649786_INM(m) \ + in_dword_masked(HWIO_REG_649786_ADDR, m) +#define HWIO_REG_649786_OUT(v) \ + out_dword(HWIO_REG_649786_ADDR, v) +#define HWIO_REG_649786_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_649786_ADDR, m, v,\ + HWIO_REG_649786_IN); +#define HWIO_REG_649786_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_649786_BASE_ADDR_SHFT 0 + +#define HWIO_REG_233366_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000644) +#define HWIO_REG_233366_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000644) +#define HWIO_REG_233366_RMSK 0x1ffff +#define HWIO_REG_233366_SHFT 0 +#define HWIO_REG_233366_IN in_dword_masked(\ + HWIO_REG_233366_ADDR, HWIO_REG_233366_RMSK) +#define HWIO_REG_233366_INM(m) \ + in_dword_masked(HWIO_REG_233366_ADDR, m) +#define HWIO_REG_233366_OUT(v) \ + out_dword(HWIO_REG_233366_ADDR, v) +#define HWIO_REG_233366_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_233366_ADDR, m, v,\ + HWIO_REG_233366_IN); +#define HWIO_REG_233366_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_233366_BASE_ADDR_SHFT 0 + +#define HWIO_REG_366750_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000648) +#define HWIO_REG_366750_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000648) +#define HWIO_REG_366750_RMSK 0x1ffff +#define HWIO_REG_366750_SHFT 0 +#define HWIO_REG_366750_IN in_dword_masked(\ + HWIO_REG_366750_ADDR, HWIO_REG_366750_RMSK) +#define HWIO_REG_366750_INM(m) \ + in_dword_masked(HWIO_REG_366750_ADDR, m) +#define HWIO_REG_366750_OUT(v) \ + out_dword(HWIO_REG_366750_ADDR, v) +#define HWIO_REG_366750_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_366750_ADDR, m, v,\ + HWIO_REG_366750_IN); +#define HWIO_REG_366750_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_366750_BASE_ADDR_SHFT 0 + +#define HWIO_REG_616292_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000064c) +#define HWIO_REG_616292_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000064c) +#define HWIO_REG_616292_RMSK 0x1ffff +#define HWIO_REG_616292_SHFT 0 +#define HWIO_REG_616292_IN in_dword_masked(\ + HWIO_REG_616292_ADDR, HWIO_REG_616292_RMSK) +#define HWIO_REG_616292_INM(m) \ + in_dword_masked(HWIO_REG_616292_ADDR, m) +#define HWIO_REG_616292_OUT(v) \ + out_dword(HWIO_REG_616292_ADDR, v) +#define HWIO_REG_616292_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_616292_ADDR, m, v,\ + HWIO_REG_616292_IN); +#define HWIO_REG_616292_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_616292_BASE_ADDR_SHFT 0 + +#define HWIO_REG_666754_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000650) +#define HWIO_REG_666754_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000650) +#define HWIO_REG_666754_RMSK 0x1ffff +#define HWIO_REG_666754_SHFT 0 +#define HWIO_REG_666754_IN in_dword_masked(\ + HWIO_REG_666754_ADDR, HWIO_REG_666754_RMSK) +#define HWIO_REG_666754_INM(m) \ + in_dword_masked(HWIO_REG_666754_ADDR, m) +#define HWIO_REG_666754_OUT(v) \ + out_dword(HWIO_REG_666754_ADDR, v) +#define HWIO_REG_666754_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_666754_ADDR, m, v,\ + HWIO_REG_666754_IN); +#define HWIO_REG_666754_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_666754_BASE_ADDR_SHFT 0 + +#define HWIO_REG_650155_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000654) +#define HWIO_REG_650155_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000654) +#define HWIO_REG_650155_RMSK 0x1ffff +#define HWIO_REG_650155_SHFT 0 +#define HWIO_REG_650155_IN in_dword_masked(\ + HWIO_REG_650155_ADDR, HWIO_REG_650155_RMSK) +#define HWIO_REG_650155_INM(m) \ + in_dword_masked(HWIO_REG_650155_ADDR, m) +#define HWIO_REG_650155_OUT(v) \ + out_dword(HWIO_REG_650155_ADDR, v) +#define HWIO_REG_650155_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_650155_ADDR, m, v,\ + HWIO_REG_650155_IN); +#define HWIO_REG_650155_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_650155_BASE_ADDR_SHFT 0 + +#define HWIO_REG_248198_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000658) +#define HWIO_REG_248198_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000658) +#define HWIO_REG_248198_RMSK 0x1ffff +#define HWIO_REG_248198_SHFT 0 +#define HWIO_REG_248198_IN in_dword_masked(\ + HWIO_REG_248198_ADDR, HWIO_REG_248198_RMSK) +#define HWIO_REG_248198_INM(m) \ + in_dword_masked(HWIO_REG_248198_ADDR, m) +#define HWIO_REG_248198_OUT(v) \ + out_dword(HWIO_REG_248198_ADDR, v) +#define HWIO_REG_248198_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_248198_ADDR, m, v,\ + HWIO_REG_248198_IN); +#define HWIO_REG_248198_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_248198_BASE_ADDR_SHFT 0 + +#define HWIO_REG_389428_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000065c) +#define HWIO_REG_389428_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000065c) +#define HWIO_REG_389428_RMSK 0x1ffff +#define HWIO_REG_389428_SHFT 0 +#define HWIO_REG_389428_IN in_dword_masked(\ + HWIO_REG_389428_ADDR, HWIO_REG_389428_RMSK) +#define HWIO_REG_389428_INM(m) \ + in_dword_masked(HWIO_REG_389428_ADDR, m) +#define HWIO_REG_389428_OUT(v) \ + out_dword(HWIO_REG_389428_ADDR, v) +#define HWIO_REG_389428_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_389428_ADDR, m, v,\ + HWIO_REG_389428_IN); +#define HWIO_REG_389428_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_389428_BASE_ADDR_SHFT 0 + +#define HWIO_REG_504308_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000660) +#define HWIO_REG_504308_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000660) +#define HWIO_REG_504308_RMSK 0x1ffff +#define HWIO_REG_504308_SHFT 0 +#define HWIO_REG_504308_IN in_dword_masked(\ + HWIO_REG_504308_ADDR, HWIO_REG_504308_RMSK) +#define HWIO_REG_504308_INM(m) \ + in_dword_masked(HWIO_REG_504308_ADDR, m) +#define HWIO_REG_504308_OUT(v) \ + out_dword(HWIO_REG_504308_ADDR, v) +#define HWIO_REG_504308_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_504308_ADDR, m, v,\ + HWIO_REG_504308_IN); +#define HWIO_REG_504308_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_504308_BASE_ADDR_SHFT 0 + +#define HWIO_REG_280814_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000664) +#define HWIO_REG_280814_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000664) +#define HWIO_REG_280814_RMSK 0x1ffff +#define HWIO_REG_280814_SHFT 0 +#define HWIO_REG_280814_IN in_dword_masked(\ + HWIO_REG_280814_ADDR, HWIO_REG_280814_RMSK) +#define HWIO_REG_280814_INM(m) \ + in_dword_masked(HWIO_REG_280814_ADDR, m) +#define HWIO_REG_280814_OUT(v) \ + out_dword(HWIO_REG_280814_ADDR, v) +#define HWIO_REG_280814_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_280814_ADDR, m, v,\ + HWIO_REG_280814_IN); +#define HWIO_REG_280814_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_280814_BASE_ADDR_SHFT 0 + +#define HWIO_REG_785484_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000668) +#define HWIO_REG_785484_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000668) +#define HWIO_REG_785484_RMSK 0x1ffff +#define HWIO_REG_785484_SHFT 0 +#define HWIO_REG_785484_IN in_dword_masked(\ + HWIO_REG_785484_ADDR, HWIO_REG_785484_RMSK) +#define HWIO_REG_785484_INM(m) \ + in_dword_masked(HWIO_REG_785484_ADDR, m) +#define HWIO_REG_785484_OUT(v) \ + out_dword(HWIO_REG_785484_ADDR, v) +#define HWIO_REG_785484_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_785484_ADDR, m, v,\ + HWIO_REG_785484_IN); +#define HWIO_REG_785484_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_785484_BASE_ADDR_SHFT 0 + +#define HWIO_REG_218455_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000066c) +#define HWIO_REG_218455_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000066c) +#define HWIO_REG_218455_RMSK 0x1ffff +#define HWIO_REG_218455_SHFT 0 +#define HWIO_REG_218455_IN in_dword_masked(\ + HWIO_REG_218455_ADDR, HWIO_REG_218455_RMSK) +#define HWIO_REG_218455_INM(m) \ + in_dword_masked(HWIO_REG_218455_ADDR, m) +#define HWIO_REG_218455_OUT(v) \ + out_dword(HWIO_REG_218455_ADDR, v) +#define HWIO_REG_218455_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_218455_ADDR, m, v,\ + HWIO_REG_218455_IN); +#define HWIO_REG_218455_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_218455_BASE_ADDR_SHFT 0 + +#define HWIO_REG_886591_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000670) +#define HWIO_REG_886591_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000670) +#define HWIO_REG_886591_RMSK 0x1ffff +#define HWIO_REG_886591_SHFT 0 +#define HWIO_REG_886591_IN in_dword_masked(\ + HWIO_REG_886591_ADDR, HWIO_REG_886591_RMSK) +#define HWIO_REG_886591_INM(m) \ + in_dword_masked(HWIO_REG_886591_ADDR, m) +#define HWIO_REG_886591_OUT(v) \ + out_dword(HWIO_REG_886591_ADDR, v) +#define HWIO_REG_886591_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_886591_ADDR, m, v,\ + HWIO_REG_886591_IN); +#define HWIO_REG_886591_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_886591_BASE_ADDR_SHFT 0 + +#define HWIO_REG_912449_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000674) +#define HWIO_REG_912449_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000674) +#define HWIO_REG_912449_RMSK 0x1ffff +#define HWIO_REG_912449_SHFT 0 +#define HWIO_REG_912449_IN in_dword_masked(\ + HWIO_REG_912449_ADDR, HWIO_REG_912449_RMSK) +#define HWIO_REG_912449_INM(m) \ + in_dword_masked(HWIO_REG_912449_ADDR, m) +#define HWIO_REG_912449_OUT(v) \ + out_dword(HWIO_REG_912449_ADDR, v) +#define HWIO_REG_912449_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_912449_ADDR, m, v,\ + HWIO_REG_912449_IN); +#define HWIO_REG_912449_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_912449_BASE_ADDR_SHFT 0 + +#define HWIO_REG_1065_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000678) +#define HWIO_REG_1065_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000678) +#define HWIO_REG_1065_RMSK 0x1ffff +#define HWIO_REG_1065_SHFT 0 +#define HWIO_REG_1065_IN in_dword_masked(\ + HWIO_REG_1065_ADDR, HWIO_REG_1065_RMSK) +#define HWIO_REG_1065_INM(m) \ + in_dword_masked(HWIO_REG_1065_ADDR, m) +#define HWIO_REG_1065_OUT(v) \ + out_dword(HWIO_REG_1065_ADDR, v) +#define HWIO_REG_1065_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_1065_ADDR, m, v,\ + HWIO_REG_1065_IN); +#define HWIO_REG_1065_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_1065_BASE_ADDR_SHFT 0 + +#define HWIO_REG_61838_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000067c) +#define HWIO_REG_61838_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000067c) +#define HWIO_REG_61838_RMSK 0x1ffff +#define HWIO_REG_61838_SHFT 0 +#define HWIO_REG_61838_IN in_dword_masked(\ + HWIO_REG_61838_ADDR, HWIO_REG_61838_RMSK) +#define HWIO_REG_61838_INM(m) \ + in_dword_masked(HWIO_REG_61838_ADDR, m) +#define HWIO_REG_61838_OUT(v) \ + out_dword(HWIO_REG_61838_ADDR, v) +#define HWIO_REG_61838_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_61838_ADDR, m, v,\ + HWIO_REG_61838_IN); +#define HWIO_REG_61838_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_61838_BASE_ADDR_SHFT 0 + +#define HWIO_REG_169838_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000680) +#define HWIO_REG_169838_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000680) +#define HWIO_REG_169838_RMSK 0x1ffff +#define HWIO_REG_169838_SHFT 0 +#define HWIO_REG_169838_IN in_dword_masked(\ + HWIO_REG_169838_ADDR, HWIO_REG_169838_RMSK) +#define HWIO_REG_169838_INM(m) \ + in_dword_masked(HWIO_REG_169838_ADDR, m) +#define HWIO_REG_169838_OUT(v) \ + out_dword(HWIO_REG_169838_ADDR, v) +#define HWIO_REG_169838_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_169838_ADDR, m, v,\ + HWIO_REG_169838_IN); +#define HWIO_REG_169838_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_169838_BASE_ADDR_SHFT 0 + +#define HWIO_REG_986147_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000684) +#define HWIO_REG_986147_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000684) +#define HWIO_REG_986147_RMSK 0x1ffff +#define HWIO_REG_986147_SHFT 0 +#define HWIO_REG_986147_IN in_dword_masked(\ + HWIO_REG_986147_ADDR, HWIO_REG_986147_RMSK) +#define HWIO_REG_986147_INM(m) \ + in_dword_masked(HWIO_REG_986147_ADDR, m) +#define HWIO_REG_986147_OUT(v) \ + out_dword(HWIO_REG_986147_ADDR, v) +#define HWIO_REG_986147_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_986147_ADDR, m, v,\ + HWIO_REG_986147_IN); +#define HWIO_REG_986147_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_986147_BASE_ADDR_SHFT 0 + +#define HWIO_REG_678637_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000688) +#define HWIO_REG_678637_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000688) +#define HWIO_REG_678637_RMSK 0x1ffff +#define HWIO_REG_678637_SHFT 0 +#define HWIO_REG_678637_IN in_dword_masked(\ + HWIO_REG_678637_ADDR, HWIO_REG_678637_RMSK) +#define HWIO_REG_678637_INM(m) \ + in_dword_masked(HWIO_REG_678637_ADDR, m) +#define HWIO_REG_678637_OUT(v) \ + out_dword(HWIO_REG_678637_ADDR, v) +#define HWIO_REG_678637_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_678637_ADDR, m, v,\ + HWIO_REG_678637_IN); +#define HWIO_REG_678637_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_678637_BASE_ADDR_SHFT 0 + +#define HWIO_REG_931311_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000068c) +#define HWIO_REG_931311_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000068c) +#define HWIO_REG_931311_RMSK 0x1ffff +#define HWIO_REG_931311_SHFT 0 +#define HWIO_REG_931311_IN in_dword_masked(\ + HWIO_REG_931311_ADDR, HWIO_REG_931311_RMSK) +#define HWIO_REG_931311_INM(m) \ + in_dword_masked(HWIO_REG_931311_ADDR, m) +#define HWIO_REG_931311_OUT(v) \ + out_dword(HWIO_REG_931311_ADDR, v) +#define HWIO_REG_931311_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_931311_ADDR, m, v,\ + HWIO_REG_931311_IN); +#define HWIO_REG_931311_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_931311_BASE_ADDR_SHFT 0 + +#define HWIO_REG_16277_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000690) +#define HWIO_REG_16277_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000690) +#define HWIO_REG_16277_RMSK 0x1ffff +#define HWIO_REG_16277_SHFT 0 +#define HWIO_REG_16277_IN in_dword_masked(\ + HWIO_REG_16277_ADDR, HWIO_REG_16277_RMSK) +#define HWIO_REG_16277_INM(m) \ + in_dword_masked(HWIO_REG_16277_ADDR, m) +#define HWIO_REG_16277_OUT(v) \ + out_dword(HWIO_REG_16277_ADDR, v) +#define HWIO_REG_16277_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_16277_ADDR, m, v,\ + HWIO_REG_16277_IN); +#define HWIO_REG_16277_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_16277_BASE_ADDR_SHFT 0 + +#define HWIO_REG_654169_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000694) +#define HWIO_REG_654169_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000694) +#define HWIO_REG_654169_RMSK 0x1ffff +#define HWIO_REG_654169_SHFT 0 +#define HWIO_REG_654169_IN in_dword_masked(\ + HWIO_REG_654169_ADDR, HWIO_REG_654169_RMSK) +#define HWIO_REG_654169_INM(m) \ + in_dword_masked(HWIO_REG_654169_ADDR, m) +#define HWIO_REG_654169_OUT(v) \ + out_dword(HWIO_REG_654169_ADDR, v) +#define HWIO_REG_654169_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_654169_ADDR, m, v,\ + HWIO_REG_654169_IN); +#define HWIO_REG_654169_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_654169_BASE_ADDR_SHFT 0 + +#define HWIO_REG_802794_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000698) +#define HWIO_REG_802794_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000698) +#define HWIO_REG_802794_RMSK 0x1ffff +#define HWIO_REG_802794_SHFT 0 +#define HWIO_REG_802794_IN in_dword_masked(\ + HWIO_REG_802794_ADDR, HWIO_REG_802794_RMSK) +#define HWIO_REG_802794_INM(m) \ + in_dword_masked(HWIO_REG_802794_ADDR, m) +#define HWIO_REG_802794_OUT(v) \ + out_dword(HWIO_REG_802794_ADDR, v) +#define HWIO_REG_802794_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_802794_ADDR, m, v,\ + HWIO_REG_802794_IN); +#define HWIO_REG_802794_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_802794_BASE_ADDR_SHFT 0 + +#define HWIO_REG_724376_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000069c) +#define HWIO_REG_724376_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000069c) +#define HWIO_REG_724376_RMSK 0x1ffff +#define HWIO_REG_724376_SHFT 0 +#define HWIO_REG_724376_IN in_dword_masked(\ + HWIO_REG_724376_ADDR, HWIO_REG_724376_RMSK) +#define HWIO_REG_724376_INM(m) \ + in_dword_masked(HWIO_REG_724376_ADDR, m) +#define HWIO_REG_724376_OUT(v) \ + out_dword(HWIO_REG_724376_ADDR, v) +#define HWIO_REG_724376_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_724376_ADDR, m, v,\ + HWIO_REG_724376_IN); +#define HWIO_REG_724376_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_724376_BASE_ADDR_SHFT 0 + +#define HWIO_REG_551674_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006a0) +#define HWIO_REG_551674_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006a0) +#define HWIO_REG_551674_RMSK 0x1ffff +#define HWIO_REG_551674_SHFT 0 +#define HWIO_REG_551674_IN in_dword_masked(\ + HWIO_REG_551674_ADDR, HWIO_REG_551674_RMSK) +#define HWIO_REG_551674_INM(m) \ + in_dword_masked(HWIO_REG_551674_ADDR, m) +#define HWIO_REG_551674_OUT(v) \ + out_dword(HWIO_REG_551674_ADDR, v) +#define HWIO_REG_551674_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_551674_ADDR, m, v,\ + HWIO_REG_551674_IN); +#define HWIO_REG_551674_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_551674_BASE_ADDR_SHFT 0 + +#define HWIO_REG_115991_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006a4) +#define HWIO_REG_115991_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006a4) +#define HWIO_REG_115991_RMSK 0x1ffff +#define HWIO_REG_115991_SHFT 0 +#define HWIO_REG_115991_IN in_dword_masked(\ + HWIO_REG_115991_ADDR, HWIO_REG_115991_RMSK) +#define HWIO_REG_115991_INM(m) \ + in_dword_masked(HWIO_REG_115991_ADDR, m) +#define HWIO_REG_115991_OUT(v) \ + out_dword(HWIO_REG_115991_ADDR, v) +#define HWIO_REG_115991_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_115991_ADDR, m, v,\ + HWIO_REG_115991_IN); +#define HWIO_REG_115991_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_115991_BASE_ADDR_SHFT 0 + +#define HWIO_REG_252167_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006a8) +#define HWIO_REG_252167_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006a8) +#define HWIO_REG_252167_RMSK 0x1ffff +#define HWIO_REG_252167_SHFT 0 +#define HWIO_REG_252167_IN in_dword_masked(\ + HWIO_REG_252167_ADDR, HWIO_REG_252167_RMSK) +#define HWIO_REG_252167_INM(m) \ + in_dword_masked(HWIO_REG_252167_ADDR, m) +#define HWIO_REG_252167_OUT(v) \ + out_dword(HWIO_REG_252167_ADDR, v) +#define HWIO_REG_252167_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_252167_ADDR, m, v,\ + HWIO_REG_252167_IN); +#define HWIO_REG_252167_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_252167_BASE_ADDR_SHFT 0 + +#define HWIO_REG_695516_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006ac) +#define HWIO_REG_695516_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006ac) +#define HWIO_REG_695516_RMSK 0x1ffff +#define HWIO_REG_695516_SHFT 0 +#define HWIO_REG_695516_IN in_dword_masked(\ + HWIO_REG_695516_ADDR, HWIO_REG_695516_RMSK) +#define HWIO_REG_695516_INM(m) \ + in_dword_masked(HWIO_REG_695516_ADDR, m) +#define HWIO_REG_695516_OUT(v) \ + out_dword(HWIO_REG_695516_ADDR, v) +#define HWIO_REG_695516_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_695516_ADDR, m, v,\ + HWIO_REG_695516_IN); +#define HWIO_REG_695516_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_695516_BASE_ADDR_SHFT 0 + +#define HWIO_REG_152193_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006b0) +#define HWIO_REG_152193_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006b0) +#define HWIO_REG_152193_RMSK 0x1ffff +#define HWIO_REG_152193_SHFT 0 +#define HWIO_REG_152193_IN in_dword_masked(\ + HWIO_REG_152193_ADDR, HWIO_REG_152193_RMSK) +#define HWIO_REG_152193_INM(m) \ + in_dword_masked(HWIO_REG_152193_ADDR, m) +#define HWIO_REG_152193_OUT(v) \ + out_dword(HWIO_REG_152193_ADDR, v) +#define HWIO_REG_152193_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_152193_ADDR, m, v,\ + HWIO_REG_152193_IN); +#define HWIO_REG_152193_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_152193_BASE_ADDR_SHFT 0 + +#define HWIO_REG_358705_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006b4) +#define HWIO_REG_358705_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006b4) +#define HWIO_REG_358705_RMSK 0x1ffff +#define HWIO_REG_358705_SHFT 0 +#define HWIO_REG_358705_IN in_dword_masked(\ + HWIO_REG_358705_ADDR, HWIO_REG_358705_RMSK) +#define HWIO_REG_358705_INM(m) \ + in_dword_masked(HWIO_REG_358705_ADDR, m) +#define HWIO_REG_358705_OUT(v) \ + out_dword(HWIO_REG_358705_ADDR, v) +#define HWIO_REG_358705_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_358705_ADDR, m, v,\ + HWIO_REG_358705_IN); +#define HWIO_REG_358705_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_358705_BASE_ADDR_SHFT 0 + +#define HWIO_REG_457068_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006b8) +#define HWIO_REG_457068_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006b8) +#define HWIO_REG_457068_RMSK 0x1ffff +#define HWIO_REG_457068_SHFT 0 +#define HWIO_REG_457068_IN in_dword_masked(\ + HWIO_REG_457068_ADDR, HWIO_REG_457068_RMSK) +#define HWIO_REG_457068_INM(m) \ + in_dword_masked(HWIO_REG_457068_ADDR, m) +#define HWIO_REG_457068_OUT(v) \ + out_dword(HWIO_REG_457068_ADDR, v) +#define HWIO_REG_457068_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_457068_ADDR, m, v,\ + HWIO_REG_457068_IN); +#define HWIO_REG_457068_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_457068_BASE_ADDR_SHFT 0 + +#define HWIO_REG_485412_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006bc) +#define HWIO_REG_485412_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006bc) +#define HWIO_REG_485412_RMSK 0x1ffff +#define HWIO_REG_485412_SHFT 0 +#define HWIO_REG_485412_IN in_dword_masked(\ + HWIO_REG_485412_ADDR, HWIO_REG_485412_RMSK) +#define HWIO_REG_485412_INM(m) \ + in_dword_masked(HWIO_REG_485412_ADDR, m) +#define HWIO_REG_485412_OUT(v) \ + out_dword(HWIO_REG_485412_ADDR, v) +#define HWIO_REG_485412_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_485412_ADDR, m, v,\ + HWIO_REG_485412_IN); +#define HWIO_REG_485412_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_485412_BASE_ADDR_SHFT 0 + +#define HWIO_REG_223131_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006c0) +#define HWIO_REG_223131_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006c0) +#define HWIO_REG_223131_RMSK 0x1ffff +#define HWIO_REG_223131_SHFT 0 +#define HWIO_REG_223131_IN in_dword_masked(\ + HWIO_REG_223131_ADDR, HWIO_REG_223131_RMSK) +#define HWIO_REG_223131_INM(m) \ + in_dword_masked(HWIO_REG_223131_ADDR, m) +#define HWIO_REG_223131_OUT(v) \ + out_dword(HWIO_REG_223131_ADDR, v) +#define HWIO_REG_223131_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_223131_ADDR, m, v,\ + HWIO_REG_223131_IN); +#define HWIO_REG_223131_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_223131_BASE_ADDR_SHFT 0 + +#define HWIO_REG_683737_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006c4) +#define HWIO_REG_683737_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006c4) +#define HWIO_REG_683737_RMSK 0x1ffff +#define HWIO_REG_683737_SHFT 0 +#define HWIO_REG_683737_IN in_dword_masked(\ + HWIO_REG_683737_ADDR, HWIO_REG_683737_RMSK) +#define HWIO_REG_683737_INM(m) \ + in_dword_masked(HWIO_REG_683737_ADDR, m) +#define HWIO_REG_683737_OUT(v) \ + out_dword(HWIO_REG_683737_ADDR, v) +#define HWIO_REG_683737_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_683737_ADDR, m, v,\ + HWIO_REG_683737_IN); +#define HWIO_REG_683737_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_683737_BASE_ADDR_SHFT 0 + +#define HWIO_REG_750474_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006c8) +#define HWIO_REG_750474_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006c8) +#define HWIO_REG_750474_RMSK 0x1ffff +#define HWIO_REG_750474_SHFT 0 +#define HWIO_REG_750474_IN in_dword_masked(\ + HWIO_REG_750474_ADDR, HWIO_REG_750474_RMSK) +#define HWIO_REG_750474_INM(m) \ + in_dword_masked(HWIO_REG_750474_ADDR, m) +#define HWIO_REG_750474_OUT(v) \ + out_dword(HWIO_REG_750474_ADDR, v) +#define HWIO_REG_750474_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_750474_ADDR, m, v,\ + HWIO_REG_750474_IN); +#define HWIO_REG_750474_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_750474_BASE_ADDR_SHFT 0 + +#define HWIO_REG_170086_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006cc) +#define HWIO_REG_170086_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006cc) +#define HWIO_REG_170086_RMSK 0x1ffff +#define HWIO_REG_170086_SHFT 0 +#define HWIO_REG_170086_IN in_dword_masked(\ + HWIO_REG_170086_ADDR, HWIO_REG_170086_RMSK) +#define HWIO_REG_170086_INM(m) \ + in_dword_masked(HWIO_REG_170086_ADDR, m) +#define HWIO_REG_170086_OUT(v) \ + out_dword(HWIO_REG_170086_ADDR, v) +#define HWIO_REG_170086_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_170086_ADDR, m, v,\ + HWIO_REG_170086_IN); +#define HWIO_REG_170086_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_170086_BASE_ADDR_SHFT 0 + +#define HWIO_REG_838595_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006d0) +#define HWIO_REG_838595_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006d0) +#define HWIO_REG_838595_RMSK 0x1ffff +#define HWIO_REG_838595_SHFT 0 +#define HWIO_REG_838595_IN in_dword_masked(\ + HWIO_REG_838595_ADDR, HWIO_REG_838595_RMSK) +#define HWIO_REG_838595_INM(m) \ + in_dword_masked(HWIO_REG_838595_ADDR, m) +#define HWIO_REG_838595_OUT(v) \ + out_dword(HWIO_REG_838595_ADDR, v) +#define HWIO_REG_838595_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_838595_ADDR, m, v,\ + HWIO_REG_838595_IN); +#define HWIO_REG_838595_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_838595_BASE_ADDR_SHFT 0 + +#define HWIO_REG_569788_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006d4) +#define HWIO_REG_569788_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006d4) +#define HWIO_REG_569788_RMSK 0x1ffff +#define HWIO_REG_569788_SHFT 0 +#define HWIO_REG_569788_IN in_dword_masked(\ + HWIO_REG_569788_ADDR, HWIO_REG_569788_RMSK) +#define HWIO_REG_569788_INM(m) \ + in_dword_masked(HWIO_REG_569788_ADDR, m) +#define HWIO_REG_569788_OUT(v) \ + out_dword(HWIO_REG_569788_ADDR, v) +#define HWIO_REG_569788_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_569788_ADDR, m, v,\ + HWIO_REG_569788_IN); +#define HWIO_REG_569788_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_569788_BASE_ADDR_SHFT 0 + +#define HWIO_REG_974527_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006d8) +#define HWIO_REG_974527_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006d8) +#define HWIO_REG_974527_RMSK 0x1ffff +#define HWIO_REG_974527_SHFT 0 +#define HWIO_REG_974527_IN in_dword_masked(\ + HWIO_REG_974527_ADDR, HWIO_REG_974527_RMSK) +#define HWIO_REG_974527_INM(m) \ + in_dword_masked(HWIO_REG_974527_ADDR, m) +#define HWIO_REG_974527_OUT(v) \ + out_dword(HWIO_REG_974527_ADDR, v) +#define HWIO_REG_974527_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_974527_ADDR, m, v,\ + HWIO_REG_974527_IN); +#define HWIO_REG_974527_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_974527_BASE_ADDR_SHFT 0 + +#define HWIO_REG_316806_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006dc) +#define HWIO_REG_316806_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006dc) +#define HWIO_REG_316806_RMSK 0x1ffff +#define HWIO_REG_316806_SHFT 0 +#define HWIO_REG_316806_IN in_dword_masked(\ + HWIO_REG_316806_ADDR, HWIO_REG_316806_RMSK) +#define HWIO_REG_316806_INM(m) \ + in_dword_masked(HWIO_REG_316806_ADDR, m) +#define HWIO_REG_316806_OUT(v) \ + out_dword(HWIO_REG_316806_ADDR, v) +#define HWIO_REG_316806_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_316806_ADDR, m, v,\ + HWIO_REG_316806_IN); +#define HWIO_REG_316806_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_316806_BASE_ADDR_SHFT 0 + +#define HWIO_REG_900472_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006e0) +#define HWIO_REG_900472_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006e0) +#define HWIO_REG_900472_RMSK 0x1ffff +#define HWIO_REG_900472_SHFT 0 +#define HWIO_REG_900472_IN in_dword_masked(\ + HWIO_REG_900472_ADDR, HWIO_REG_900472_RMSK) +#define HWIO_REG_900472_INM(m) \ + in_dword_masked(HWIO_REG_900472_ADDR, m) +#define HWIO_REG_900472_OUT(v) \ + out_dword(HWIO_REG_900472_ADDR, v) +#define HWIO_REG_900472_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_900472_ADDR, m, v,\ + HWIO_REG_900472_IN); +#define HWIO_REG_900472_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_900472_BASE_ADDR_SHFT 0 + +#define HWIO_REG_256156_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006e4) +#define HWIO_REG_256156_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006e4) +#define HWIO_REG_256156_RMSK 0x1ffff +#define HWIO_REG_256156_SHFT 0 +#define HWIO_REG_256156_IN in_dword_masked(\ + HWIO_REG_256156_ADDR, HWIO_REG_256156_RMSK) +#define HWIO_REG_256156_INM(m) \ + in_dword_masked(HWIO_REG_256156_ADDR, m) +#define HWIO_REG_256156_OUT(v) \ + out_dword(HWIO_REG_256156_ADDR, v) +#define HWIO_REG_256156_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_256156_ADDR, m, v,\ + HWIO_REG_256156_IN); +#define HWIO_REG_256156_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_256156_BASE_ADDR_SHFT 0 + +#define HWIO_REG_335729_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006e8) +#define HWIO_REG_335729_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006e8) +#define HWIO_REG_335729_RMSK 0x1ffff +#define HWIO_REG_335729_SHFT 0 +#define HWIO_REG_335729_IN in_dword_masked(\ + HWIO_REG_335729_ADDR, HWIO_REG_335729_RMSK) +#define HWIO_REG_335729_INM(m) \ + in_dword_masked(HWIO_REG_335729_ADDR, m) +#define HWIO_REG_335729_OUT(v) \ + out_dword(HWIO_REG_335729_ADDR, v) +#define HWIO_REG_335729_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_335729_ADDR, m, v,\ + HWIO_REG_335729_IN); +#define HWIO_REG_335729_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_335729_BASE_ADDR_SHFT 0 + +#define HWIO_REG_303383_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006ec) +#define HWIO_REG_303383_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006ec) +#define HWIO_REG_303383_RMSK 0x1ffff +#define HWIO_REG_303383_SHFT 0 +#define HWIO_REG_303383_IN in_dword_masked(\ + HWIO_REG_303383_ADDR, HWIO_REG_303383_RMSK) +#define HWIO_REG_303383_INM(m) \ + in_dword_masked(HWIO_REG_303383_ADDR, m) +#define HWIO_REG_303383_OUT(v) \ + out_dword(HWIO_REG_303383_ADDR, v) +#define HWIO_REG_303383_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_303383_ADDR, m, v,\ + HWIO_REG_303383_IN); +#define HWIO_REG_303383_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_303383_BASE_ADDR_SHFT 0 + +#define HWIO_REG_180871_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006f0) +#define HWIO_REG_180871_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006f0) +#define HWIO_REG_180871_RMSK 0x1ffff +#define HWIO_REG_180871_SHFT 0 +#define HWIO_REG_180871_IN in_dword_masked(\ + HWIO_REG_180871_ADDR, HWIO_REG_180871_RMSK) +#define HWIO_REG_180871_INM(m) \ + in_dword_masked(HWIO_REG_180871_ADDR, m) +#define HWIO_REG_180871_OUT(v) \ + out_dword(HWIO_REG_180871_ADDR, v) +#define HWIO_REG_180871_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_180871_ADDR, m, v,\ + HWIO_REG_180871_IN); +#define HWIO_REG_180871_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_180871_BASE_ADDR_SHFT 0 + +#define HWIO_REG_514148_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006f4) +#define HWIO_REG_514148_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006f4) +#define HWIO_REG_514148_RMSK 0x1ffff +#define HWIO_REG_514148_SHFT 0 +#define HWIO_REG_514148_IN in_dword_masked(\ + HWIO_REG_514148_ADDR, HWIO_REG_514148_RMSK) +#define HWIO_REG_514148_INM(m) \ + in_dword_masked(HWIO_REG_514148_ADDR, m) +#define HWIO_REG_514148_OUT(v) \ + out_dword(HWIO_REG_514148_ADDR, v) +#define HWIO_REG_514148_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_514148_ADDR, m, v,\ + HWIO_REG_514148_IN); +#define HWIO_REG_514148_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_514148_BASE_ADDR_SHFT 0 + +#define HWIO_REG_578636_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006f8) +#define HWIO_REG_578636_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006f8) +#define HWIO_REG_578636_RMSK 0x1ffff +#define HWIO_REG_578636_SHFT 0 +#define HWIO_REG_578636_IN in_dword_masked(\ + HWIO_REG_578636_ADDR, HWIO_REG_578636_RMSK) +#define HWIO_REG_578636_INM(m) \ + in_dword_masked(HWIO_REG_578636_ADDR, m) +#define HWIO_REG_578636_OUT(v) \ + out_dword(HWIO_REG_578636_ADDR, v) +#define HWIO_REG_578636_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_578636_ADDR, m, v,\ + HWIO_REG_578636_IN); +#define HWIO_REG_578636_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_578636_BASE_ADDR_SHFT 0 + +#define HWIO_REG_888116_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006fc) +#define HWIO_REG_888116_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006fc) +#define HWIO_REG_888116_RMSK 0x1ffff +#define HWIO_REG_888116_SHFT 0 +#define HWIO_REG_888116_IN in_dword_masked(\ + HWIO_REG_888116_ADDR, HWIO_REG_888116_RMSK) +#define HWIO_REG_888116_INM(m) \ + in_dword_masked(HWIO_REG_888116_ADDR, m) +#define HWIO_REG_888116_OUT(v) \ + out_dword(HWIO_REG_888116_ADDR, v) +#define HWIO_REG_888116_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_888116_ADDR, m, v,\ + HWIO_REG_888116_IN); +#define HWIO_REG_888116_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_888116_BASE_ADDR_SHFT 0 + +#define HWIO_REG_759068_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000700) +#define HWIO_REG_759068_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000700) +#define HWIO_REG_759068_RMSK 0x1ffff +#define HWIO_REG_759068_SHFT 0 +#define HWIO_REG_759068_IN in_dword_masked(\ + HWIO_REG_759068_ADDR, HWIO_REG_759068_RMSK) +#define HWIO_REG_759068_INM(m) \ + in_dword_masked(HWIO_REG_759068_ADDR, m) +#define HWIO_REG_759068_OUT(v) \ + out_dword(HWIO_REG_759068_ADDR, v) +#define HWIO_REG_759068_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_759068_ADDR, m, v,\ + HWIO_REG_759068_IN); +#define HWIO_REG_759068_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_759068_BASE_ADDR_SHFT 0 + +#define HWIO_REG_68356_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000704) +#define HWIO_REG_68356_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000704) +#define HWIO_REG_68356_RMSK 0x1ffff +#define HWIO_REG_68356_SHFT 0 +#define HWIO_REG_68356_IN in_dword_masked(\ + HWIO_REG_68356_ADDR, HWIO_REG_68356_RMSK) +#define HWIO_REG_68356_INM(m) \ + in_dword_masked(HWIO_REG_68356_ADDR, m) +#define HWIO_REG_68356_OUT(v) \ + out_dword(HWIO_REG_68356_ADDR, v) +#define HWIO_REG_68356_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_68356_ADDR, m, v,\ + HWIO_REG_68356_IN); +#define HWIO_REG_68356_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_68356_BASE_ADDR_SHFT 0 + +#define HWIO_REG_833502_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000708) +#define HWIO_REG_833502_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000708) +#define HWIO_REG_833502_RMSK 0x1ffff +#define HWIO_REG_833502_SHFT 0 +#define HWIO_REG_833502_IN in_dword_masked(\ + HWIO_REG_833502_ADDR, HWIO_REG_833502_RMSK) +#define HWIO_REG_833502_INM(m) \ + in_dword_masked(HWIO_REG_833502_ADDR, m) +#define HWIO_REG_833502_OUT(v) \ + out_dword(HWIO_REG_833502_ADDR, v) +#define HWIO_REG_833502_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_833502_ADDR, m, v,\ + HWIO_REG_833502_IN); +#define HWIO_REG_833502_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_833502_BASE_ADDR_SHFT 0 + +#define HWIO_REG_127855_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000070c) +#define HWIO_REG_127855_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000070c) +#define HWIO_REG_127855_RMSK 0x1ffff +#define HWIO_REG_127855_SHFT 0 +#define HWIO_REG_127855_IN in_dword_masked(\ + HWIO_REG_127855_ADDR, HWIO_REG_127855_RMSK) +#define HWIO_REG_127855_INM(m) \ + in_dword_masked(HWIO_REG_127855_ADDR, m) +#define HWIO_REG_127855_OUT(v) \ + out_dword(HWIO_REG_127855_ADDR, v) +#define HWIO_REG_127855_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_127855_ADDR, m, v,\ + HWIO_REG_127855_IN); +#define HWIO_REG_127855_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_127855_BASE_ADDR_SHFT 0 + +#define HWIO_REG_616802_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000710) +#define HWIO_REG_616802_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000710) +#define HWIO_REG_616802_RMSK 0x1ffff +#define HWIO_REG_616802_SHFT 0 +#define HWIO_REG_616802_IN in_dword_masked(\ + HWIO_REG_616802_ADDR, HWIO_REG_616802_RMSK) +#define HWIO_REG_616802_INM(m) \ + in_dword_masked(HWIO_REG_616802_ADDR, m) +#define HWIO_REG_616802_OUT(v) \ + out_dword(HWIO_REG_616802_ADDR, v) +#define HWIO_REG_616802_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_616802_ADDR, m, v,\ + HWIO_REG_616802_IN); +#define HWIO_REG_616802_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_616802_BASE_ADDR_SHFT 0 + +#define HWIO_REG_23318_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000714) +#define HWIO_REG_23318_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000714) +#define HWIO_REG_23318_RMSK 0x1ffff +#define HWIO_REG_23318_SHFT 0 +#define HWIO_REG_23318_IN in_dword_masked(\ + HWIO_REG_23318_ADDR, HWIO_REG_23318_RMSK) +#define HWIO_REG_23318_INM(m) \ + in_dword_masked(HWIO_REG_23318_ADDR, m) +#define HWIO_REG_23318_OUT(v) \ + out_dword(HWIO_REG_23318_ADDR, v) +#define HWIO_REG_23318_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_23318_ADDR, m, v,\ + HWIO_REG_23318_IN); +#define HWIO_REG_23318_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_23318_BASE_ADDR_SHFT 0 + +#define HWIO_REG_317106_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000718) +#define HWIO_REG_317106_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000718) +#define HWIO_REG_317106_RMSK 0x1ffff +#define HWIO_REG_317106_SHFT 0 +#define HWIO_REG_317106_IN in_dword_masked(\ + HWIO_REG_317106_ADDR, HWIO_REG_317106_RMSK) +#define HWIO_REG_317106_INM(m) \ + in_dword_masked(HWIO_REG_317106_ADDR, m) +#define HWIO_REG_317106_OUT(v) \ + out_dword(HWIO_REG_317106_ADDR, v) +#define HWIO_REG_317106_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_317106_ADDR, m, v,\ + HWIO_REG_317106_IN); +#define HWIO_REG_317106_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_317106_BASE_ADDR_SHFT 0 + +#define HWIO_REG_603772_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000071c) +#define HWIO_REG_603772_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000071c) +#define HWIO_REG_603772_RMSK 0x1ffff +#define HWIO_REG_603772_SHFT 0 +#define HWIO_REG_603772_IN in_dword_masked(\ + HWIO_REG_603772_ADDR, HWIO_REG_603772_RMSK) +#define HWIO_REG_603772_INM(m) \ + in_dword_masked(HWIO_REG_603772_ADDR, m) +#define HWIO_REG_603772_OUT(v) \ + out_dword(HWIO_REG_603772_ADDR, v) +#define HWIO_REG_603772_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_603772_ADDR, m, v,\ + HWIO_REG_603772_IN); +#define HWIO_REG_603772_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_603772_BASE_ADDR_SHFT 0 + +#define HWIO_REG_175929_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000720) +#define HWIO_REG_175929_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000720) +#define HWIO_REG_175929_RMSK 0x1ffff +#define HWIO_REG_175929_SHFT 0 +#define HWIO_REG_175929_IN in_dword_masked(\ + HWIO_REG_175929_ADDR, HWIO_REG_175929_RMSK) +#define HWIO_REG_175929_INM(m) \ + in_dword_masked(HWIO_REG_175929_ADDR, m) +#define HWIO_REG_175929_OUT(v) \ + out_dword(HWIO_REG_175929_ADDR, v) +#define HWIO_REG_175929_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_175929_ADDR, m, v,\ + HWIO_REG_175929_IN); +#define HWIO_REG_175929_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_175929_BASE_ADDR_SHFT 0 + +#define HWIO_REG_11928_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000724) +#define HWIO_REG_11928_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000724) +#define HWIO_REG_11928_RMSK 0x1ffff +#define HWIO_REG_11928_SHFT 0 +#define HWIO_REG_11928_IN in_dword_masked(\ + HWIO_REG_11928_ADDR, HWIO_REG_11928_RMSK) +#define HWIO_REG_11928_INM(m) \ + in_dword_masked(HWIO_REG_11928_ADDR, m) +#define HWIO_REG_11928_OUT(v) \ + out_dword(HWIO_REG_11928_ADDR, v) +#define HWIO_REG_11928_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_11928_ADDR, m, v,\ + HWIO_REG_11928_IN); +#define HWIO_REG_11928_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_11928_BASE_ADDR_SHFT 0 + +#define HWIO_REG_772678_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000728) +#define HWIO_REG_772678_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000728) +#define HWIO_REG_772678_RMSK 0x1ffff +#define HWIO_REG_772678_SHFT 0 +#define HWIO_REG_772678_IN in_dword_masked(\ + HWIO_REG_772678_ADDR, HWIO_REG_772678_RMSK) +#define HWIO_REG_772678_INM(m) \ + in_dword_masked(HWIO_REG_772678_ADDR, m) +#define HWIO_REG_772678_OUT(v) \ + out_dword(HWIO_REG_772678_ADDR, v) +#define HWIO_REG_772678_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_772678_ADDR, m, v,\ + HWIO_REG_772678_IN); +#define HWIO_REG_772678_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_772678_BASE_ADDR_SHFT 0 + +#define HWIO_REG_603389_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000072c) +#define HWIO_REG_603389_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000072c) +#define HWIO_REG_603389_RMSK 0x1ffff +#define HWIO_REG_603389_SHFT 0 +#define HWIO_REG_603389_IN in_dword_masked(\ + HWIO_REG_603389_ADDR, HWIO_REG_603389_RMSK) +#define HWIO_REG_603389_INM(m) \ + in_dword_masked(HWIO_REG_603389_ADDR, m) +#define HWIO_REG_603389_OUT(v) \ + out_dword(HWIO_REG_603389_ADDR, v) +#define HWIO_REG_603389_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_603389_ADDR, m, v,\ + HWIO_REG_603389_IN); +#define HWIO_REG_603389_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_603389_BASE_ADDR_SHFT 0 + +#define HWIO_REG_989918_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000730) +#define HWIO_REG_989918_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000730) +#define HWIO_REG_989918_RMSK 0x1ffff +#define HWIO_REG_989918_SHFT 0 +#define HWIO_REG_989918_IN in_dword_masked(\ + HWIO_REG_989918_ADDR, HWIO_REG_989918_RMSK) +#define HWIO_REG_989918_INM(m) \ + in_dword_masked(HWIO_REG_989918_ADDR, m) +#define HWIO_REG_989918_OUT(v) \ + out_dword(HWIO_REG_989918_ADDR, v) +#define HWIO_REG_989918_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_989918_ADDR, m, v,\ + HWIO_REG_989918_IN); +#define HWIO_REG_989918_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_989918_BASE_ADDR_SHFT 0 + +#define HWIO_REG_5460_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000734) +#define HWIO_REG_5460_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000734) +#define HWIO_REG_5460_RMSK 0x1ffff +#define HWIO_REG_5460_SHFT 0 +#define HWIO_REG_5460_IN in_dword_masked(\ + HWIO_REG_5460_ADDR, HWIO_REG_5460_RMSK) +#define HWIO_REG_5460_INM(m) \ + in_dword_masked(HWIO_REG_5460_ADDR, m) +#define HWIO_REG_5460_OUT(v) \ + out_dword(HWIO_REG_5460_ADDR, v) +#define HWIO_REG_5460_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_5460_ADDR, m, v,\ + HWIO_REG_5460_IN); +#define HWIO_REG_5460_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_5460_BASE_ADDR_SHFT 0 + +#define HWIO_REG_734724_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000738) +#define HWIO_REG_734724_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000738) +#define HWIO_REG_734724_RMSK 0x1ffff +#define HWIO_REG_734724_SHFT 0 +#define HWIO_REG_734724_IN in_dword_masked(\ + HWIO_REG_734724_ADDR, HWIO_REG_734724_RMSK) +#define HWIO_REG_734724_INM(m) \ + in_dword_masked(HWIO_REG_734724_ADDR, m) +#define HWIO_REG_734724_OUT(v) \ + out_dword(HWIO_REG_734724_ADDR, v) +#define HWIO_REG_734724_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_734724_ADDR, m, v,\ + HWIO_REG_734724_IN); +#define HWIO_REG_734724_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_734724_BASE_ADDR_SHFT 0 + +#define HWIO_REG_451742_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000073c) +#define HWIO_REG_451742_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000073c) +#define HWIO_REG_451742_RMSK 0x1ffff +#define HWIO_REG_451742_SHFT 0 +#define HWIO_REG_451742_IN in_dword_masked(\ + HWIO_REG_451742_ADDR, HWIO_REG_451742_RMSK) +#define HWIO_REG_451742_INM(m) \ + in_dword_masked(HWIO_REG_451742_ADDR, m) +#define HWIO_REG_451742_OUT(v) \ + out_dword(HWIO_REG_451742_ADDR, v) +#define HWIO_REG_451742_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_451742_ADDR, m, v,\ + HWIO_REG_451742_IN); +#define HWIO_REG_451742_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_451742_BASE_ADDR_SHFT 0 + +#define HWIO_REG_475648_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000740) +#define HWIO_REG_475648_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000740) +#define HWIO_REG_475648_RMSK 0x1ffff +#define HWIO_REG_475648_SHFT 0 +#define HWIO_REG_475648_IN in_dword_masked(\ + HWIO_REG_475648_ADDR, HWIO_REG_475648_RMSK) +#define HWIO_REG_475648_INM(m) \ + in_dword_masked(HWIO_REG_475648_ADDR, m) +#define HWIO_REG_475648_OUT(v) \ + out_dword(HWIO_REG_475648_ADDR, v) +#define HWIO_REG_475648_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_475648_ADDR, m, v,\ + HWIO_REG_475648_IN); +#define HWIO_REG_475648_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_475648_BASE_ADDR_SHFT 0 + +#define HWIO_REG_284758_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000744) +#define HWIO_REG_284758_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000744) +#define HWIO_REG_284758_RMSK 0x1ffff +#define HWIO_REG_284758_SHFT 0 +#define HWIO_REG_284758_IN in_dword_masked(\ + HWIO_REG_284758_ADDR, HWIO_REG_284758_RMSK) +#define HWIO_REG_284758_INM(m) \ + in_dword_masked(HWIO_REG_284758_ADDR, m) +#define HWIO_REG_284758_OUT(v) \ + out_dword(HWIO_REG_284758_ADDR, v) +#define HWIO_REG_284758_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_284758_ADDR, m, v,\ + HWIO_REG_284758_IN); +#define HWIO_REG_284758_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_284758_BASE_ADDR_SHFT 0 + +#define HWIO_REG_523659_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000748) +#define HWIO_REG_523659_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000748) +#define HWIO_REG_523659_RMSK 0x1ffff +#define HWIO_REG_523659_SHFT 0 +#define HWIO_REG_523659_IN in_dword_masked(\ + HWIO_REG_523659_ADDR, HWIO_REG_523659_RMSK) +#define HWIO_REG_523659_INM(m) \ + in_dword_masked(HWIO_REG_523659_ADDR, m) +#define HWIO_REG_523659_OUT(v) \ + out_dword(HWIO_REG_523659_ADDR, v) +#define HWIO_REG_523659_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_523659_ADDR, m, v,\ + HWIO_REG_523659_IN); +#define HWIO_REG_523659_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_523659_BASE_ADDR_SHFT 0 + +#define HWIO_REG_815580_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000074c) +#define HWIO_REG_815580_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000074c) +#define HWIO_REG_815580_RMSK 0x1ffff +#define HWIO_REG_815580_SHFT 0 +#define HWIO_REG_815580_IN in_dword_masked(\ + HWIO_REG_815580_ADDR, HWIO_REG_815580_RMSK) +#define HWIO_REG_815580_INM(m) \ + in_dword_masked(HWIO_REG_815580_ADDR, m) +#define HWIO_REG_815580_OUT(v) \ + out_dword(HWIO_REG_815580_ADDR, v) +#define HWIO_REG_815580_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_815580_ADDR, m, v,\ + HWIO_REG_815580_IN); +#define HWIO_REG_815580_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_815580_BASE_ADDR_SHFT 0 + +#define HWIO_REG_546551_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000750) +#define HWIO_REG_546551_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000750) +#define HWIO_REG_546551_RMSK 0x1ffff +#define HWIO_REG_546551_SHFT 0 +#define HWIO_REG_546551_IN in_dword_masked(\ + HWIO_REG_546551_ADDR, HWIO_REG_546551_RMSK) +#define HWIO_REG_546551_INM(m) \ + in_dword_masked(HWIO_REG_546551_ADDR, m) +#define HWIO_REG_546551_OUT(v) \ + out_dword(HWIO_REG_546551_ADDR, v) +#define HWIO_REG_546551_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_546551_ADDR, m, v,\ + HWIO_REG_546551_IN); +#define HWIO_REG_546551_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_546551_BASE_ADDR_SHFT 0 + +#define HWIO_REG_769851_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000754) +#define HWIO_REG_769851_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000754) +#define HWIO_REG_769851_RMSK 0x1ffff +#define HWIO_REG_769851_SHFT 0 +#define HWIO_REG_769851_IN in_dword_masked(\ + HWIO_REG_769851_ADDR, HWIO_REG_769851_RMSK) +#define HWIO_REG_769851_INM(m) \ + in_dword_masked(HWIO_REG_769851_ADDR, m) +#define HWIO_REG_769851_OUT(v) \ + out_dword(HWIO_REG_769851_ADDR, v) +#define HWIO_REG_769851_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_769851_ADDR, m, v,\ + HWIO_REG_769851_IN); +#define HWIO_REG_769851_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_769851_BASE_ADDR_SHFT 0 + +#define HWIO_REG_205028_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000758) +#define HWIO_REG_205028_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000758) +#define HWIO_REG_205028_RMSK 0x1ffff +#define HWIO_REG_205028_SHFT 0 +#define HWIO_REG_205028_IN in_dword_masked(\ + HWIO_REG_205028_ADDR, HWIO_REG_205028_RMSK) +#define HWIO_REG_205028_INM(m) \ + in_dword_masked(HWIO_REG_205028_ADDR, m) +#define HWIO_REG_205028_OUT(v) \ + out_dword(HWIO_REG_205028_ADDR, v) +#define HWIO_REG_205028_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_205028_ADDR, m, v,\ + HWIO_REG_205028_IN); +#define HWIO_REG_205028_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_205028_BASE_ADDR_SHFT 0 + +#define HWIO_REG_206835_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000075c) +#define HWIO_REG_206835_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000075c) +#define HWIO_REG_206835_RMSK 0x1ffff +#define HWIO_REG_206835_SHFT 0 +#define HWIO_REG_206835_IN in_dword_masked(\ + HWIO_REG_206835_ADDR, HWIO_REG_206835_RMSK) +#define HWIO_REG_206835_INM(m) \ + in_dword_masked(HWIO_REG_206835_ADDR, m) +#define HWIO_REG_206835_OUT(v) \ + out_dword(HWIO_REG_206835_ADDR, v) +#define HWIO_REG_206835_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_206835_ADDR, m, v,\ + HWIO_REG_206835_IN); +#define HWIO_REG_206835_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_206835_BASE_ADDR_SHFT 0 + +#define HWIO_REG_582575_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000760) +#define HWIO_REG_582575_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000760) +#define HWIO_REG_582575_RMSK 0x1ffff +#define HWIO_REG_582575_SHFT 0 +#define HWIO_REG_582575_IN in_dword_masked(\ + HWIO_REG_582575_ADDR, HWIO_REG_582575_RMSK) +#define HWIO_REG_582575_INM(m) \ + in_dword_masked(HWIO_REG_582575_ADDR, m) +#define HWIO_REG_582575_OUT(v) \ + out_dword(HWIO_REG_582575_ADDR, v) +#define HWIO_REG_582575_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_582575_ADDR, m, v,\ + HWIO_REG_582575_IN); +#define HWIO_REG_582575_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_582575_BASE_ADDR_SHFT 0 + +#define HWIO_REG_120885_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000764) +#define HWIO_REG_120885_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000764) +#define HWIO_REG_120885_RMSK 0x1ffff +#define HWIO_REG_120885_SHFT 0 +#define HWIO_REG_120885_IN in_dword_masked(\ + HWIO_REG_120885_ADDR, HWIO_REG_120885_RMSK) +#define HWIO_REG_120885_INM(m) \ + in_dword_masked(HWIO_REG_120885_ADDR, m) +#define HWIO_REG_120885_OUT(v) \ + out_dword(HWIO_REG_120885_ADDR, v) +#define HWIO_REG_120885_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_120885_ADDR, m, v,\ + HWIO_REG_120885_IN); +#define HWIO_REG_120885_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_120885_BASE_ADDR_SHFT 0 + +#define HWIO_REG_496067_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000768) +#define HWIO_REG_496067_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000768) +#define HWIO_REG_496067_RMSK 0x1ffff +#define HWIO_REG_496067_SHFT 0 +#define HWIO_REG_496067_IN in_dword_masked(\ + HWIO_REG_496067_ADDR, HWIO_REG_496067_RMSK) +#define HWIO_REG_496067_INM(m) \ + in_dword_masked(HWIO_REG_496067_ADDR, m) +#define HWIO_REG_496067_OUT(v) \ + out_dword(HWIO_REG_496067_ADDR, v) +#define HWIO_REG_496067_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_496067_ADDR, m, v,\ + HWIO_REG_496067_IN); +#define HWIO_REG_496067_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_496067_BASE_ADDR_SHFT 0 + +#define HWIO_REG_472919_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000076c) +#define HWIO_REG_472919_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000076c) +#define HWIO_REG_472919_RMSK 0x1ffff +#define HWIO_REG_472919_SHFT 0 +#define HWIO_REG_472919_IN in_dword_masked(\ + HWIO_REG_472919_ADDR, HWIO_REG_472919_RMSK) +#define HWIO_REG_472919_INM(m) \ + in_dword_masked(HWIO_REG_472919_ADDR, m) +#define HWIO_REG_472919_OUT(v) \ + out_dword(HWIO_REG_472919_ADDR, v) +#define HWIO_REG_472919_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_472919_ADDR, m, v,\ + HWIO_REG_472919_IN); +#define HWIO_REG_472919_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_472919_BASE_ADDR_SHFT 0 + +#define HWIO_REG_486985_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000770) +#define HWIO_REG_486985_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000770) +#define HWIO_REG_486985_RMSK 0x1ffff +#define HWIO_REG_486985_SHFT 0 +#define HWIO_REG_486985_IN in_dword_masked(\ + HWIO_REG_486985_ADDR, HWIO_REG_486985_RMSK) +#define HWIO_REG_486985_INM(m) \ + in_dword_masked(HWIO_REG_486985_ADDR, m) +#define HWIO_REG_486985_OUT(v) \ + out_dword(HWIO_REG_486985_ADDR, v) +#define HWIO_REG_486985_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_486985_ADDR, m, v,\ + HWIO_REG_486985_IN); +#define HWIO_REG_486985_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_486985_BASE_ADDR_SHFT 0 + +#define HWIO_REG_964692_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000774) +#define HWIO_REG_964692_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000774) +#define HWIO_REG_964692_RMSK 0x1ffff +#define HWIO_REG_964692_SHFT 0 +#define HWIO_REG_964692_IN in_dword_masked(\ + HWIO_REG_964692_ADDR, HWIO_REG_964692_RMSK) +#define HWIO_REG_964692_INM(m) \ + in_dword_masked(HWIO_REG_964692_ADDR, m) +#define HWIO_REG_964692_OUT(v) \ + out_dword(HWIO_REG_964692_ADDR, v) +#define HWIO_REG_964692_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_964692_ADDR, m, v,\ + HWIO_REG_964692_IN); +#define HWIO_REG_964692_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_964692_BASE_ADDR_SHFT 0 + +#define HWIO_REG_941116_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000778) +#define HWIO_REG_941116_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000778) +#define HWIO_REG_941116_RMSK 0x1ffff +#define HWIO_REG_941116_SHFT 0 +#define HWIO_REG_941116_IN in_dword_masked(\ + HWIO_REG_941116_ADDR, HWIO_REG_941116_RMSK) +#define HWIO_REG_941116_INM(m) \ + in_dword_masked(HWIO_REG_941116_ADDR, m) +#define HWIO_REG_941116_OUT(v) \ + out_dword(HWIO_REG_941116_ADDR, v) +#define HWIO_REG_941116_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_941116_ADDR, m, v,\ + HWIO_REG_941116_IN); +#define HWIO_REG_941116_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_941116_BASE_ADDR_SHFT 0 + +#define HWIO_REG_122567_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000077c) +#define HWIO_REG_122567_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000077c) +#define HWIO_REG_122567_RMSK 0x1ffff +#define HWIO_REG_122567_SHFT 0 +#define HWIO_REG_122567_IN in_dword_masked(\ + HWIO_REG_122567_ADDR, HWIO_REG_122567_RMSK) +#define HWIO_REG_122567_INM(m) \ + in_dword_masked(HWIO_REG_122567_ADDR, m) +#define HWIO_REG_122567_OUT(v) \ + out_dword(HWIO_REG_122567_ADDR, v) +#define HWIO_REG_122567_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_122567_ADDR, m, v,\ + HWIO_REG_122567_IN); +#define HWIO_REG_122567_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_122567_BASE_ADDR_SHFT 0 + +#define HWIO_REG_466192_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000780) +#define HWIO_REG_466192_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000780) +#define HWIO_REG_466192_RMSK 0x1ffff +#define HWIO_REG_466192_SHFT 0 +#define HWIO_REG_466192_IN in_dword_masked(\ + HWIO_REG_466192_ADDR, HWIO_REG_466192_RMSK) +#define HWIO_REG_466192_INM(m) \ + in_dword_masked(HWIO_REG_466192_ADDR, m) +#define HWIO_REG_466192_OUT(v) \ + out_dword(HWIO_REG_466192_ADDR, v) +#define HWIO_REG_466192_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_466192_ADDR, m, v,\ + HWIO_REG_466192_IN); +#define HWIO_REG_466192_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_466192_BASE_ADDR_SHFT 0 + +#define HWIO_REG_554890_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000784) +#define HWIO_REG_554890_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000784) +#define HWIO_REG_554890_RMSK 0x1ffff +#define HWIO_REG_554890_SHFT 0 +#define HWIO_REG_554890_IN in_dword_masked(\ + HWIO_REG_554890_ADDR, HWIO_REG_554890_RMSK) +#define HWIO_REG_554890_INM(m) \ + in_dword_masked(HWIO_REG_554890_ADDR, m) +#define HWIO_REG_554890_OUT(v) \ + out_dword(HWIO_REG_554890_ADDR, v) +#define HWIO_REG_554890_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_554890_ADDR, m, v,\ + HWIO_REG_554890_IN); +#define HWIO_REG_554890_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_554890_BASE_ADDR_SHFT 0 + +#define HWIO_REG_295616_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000788) +#define HWIO_REG_295616_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000788) +#define HWIO_REG_295616_RMSK 0x1ffff +#define HWIO_REG_295616_SHFT 0 +#define HWIO_REG_295616_IN in_dword_masked(\ + HWIO_REG_295616_ADDR, HWIO_REG_295616_RMSK) +#define HWIO_REG_295616_INM(m) \ + in_dword_masked(HWIO_REG_295616_ADDR, m) +#define HWIO_REG_295616_OUT(v) \ + out_dword(HWIO_REG_295616_ADDR, v) +#define HWIO_REG_295616_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_295616_ADDR, m, v,\ + HWIO_REG_295616_IN); +#define HWIO_REG_295616_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_295616_BASE_ADDR_SHFT 0 + +#define HWIO_REG_440836_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000078c) +#define HWIO_REG_440836_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000078c) +#define HWIO_REG_440836_RMSK 0x1ffff +#define HWIO_REG_440836_SHFT 0 +#define HWIO_REG_440836_IN in_dword_masked(\ + HWIO_REG_440836_ADDR, HWIO_REG_440836_RMSK) +#define HWIO_REG_440836_INM(m) \ + in_dword_masked(HWIO_REG_440836_ADDR, m) +#define HWIO_REG_440836_OUT(v) \ + out_dword(HWIO_REG_440836_ADDR, v) +#define HWIO_REG_440836_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_440836_ADDR, m, v,\ + HWIO_REG_440836_IN); +#define HWIO_REG_440836_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_440836_BASE_ADDR_SHFT 0 + +#define HWIO_REG_741154_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000790) +#define HWIO_REG_741154_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000790) +#define HWIO_REG_741154_RMSK 0x1ffff +#define HWIO_REG_741154_SHFT 0 +#define HWIO_REG_741154_IN in_dword_masked(\ + HWIO_REG_741154_ADDR,\ + HWIO_REG_741154_RMSK) +#define HWIO_REG_741154_INM(m) \ + in_dword_masked(HWIO_REG_741154_ADDR, m) +#define HWIO_REG_741154_OUT(v) \ + out_dword(HWIO_REG_741154_ADDR, v) +#define HWIO_REG_741154_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_741154_ADDR, m, v,\ + HWIO_REG_741154_IN); +#define HWIO_REG_741154_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_741154_BASE_ADDR_SHFT 0 + +#define HWIO_REG_753139_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000794) +#define HWIO_REG_753139_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000794) +#define HWIO_REG_753139_RMSK 0x1ffff +#define HWIO_REG_753139_SHFT 0 +#define HWIO_REG_753139_IN in_dword_masked(\ + HWIO_REG_753139_ADDR,\ + HWIO_REG_753139_RMSK) +#define HWIO_REG_753139_INM(m) \ + in_dword_masked(HWIO_REG_753139_ADDR, m) +#define HWIO_REG_753139_OUT(v) \ + out_dword(HWIO_REG_753139_ADDR, v) +#define HWIO_REG_753139_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_753139_ADDR, m, v,\ + HWIO_REG_753139_IN); +#define HWIO_REG_753139_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_753139_BASE_ADDR_SHFT 0 + +#define HWIO_REG_409994_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000798) +#define HWIO_REG_409994_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000798) +#define HWIO_REG_409994_RMSK 0x1ffff +#define HWIO_REG_409994_SHFT 0 +#define HWIO_REG_409994_IN in_dword_masked(\ + HWIO_REG_409994_ADDR,\ + HWIO_REG_409994_RMSK) +#define HWIO_REG_409994_INM(m) \ + in_dword_masked(HWIO_REG_409994_ADDR, m) +#define HWIO_REG_409994_OUT(v) \ + out_dword(HWIO_REG_409994_ADDR, v) +#define HWIO_REG_409994_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_409994_ADDR, m, v,\ + HWIO_REG_409994_IN); +#define HWIO_REG_409994_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_409994_BASE_ADDR_SHFT 0 + +#define HWIO_REG_492611_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000079c) +#define HWIO_REG_492611_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000079c) +#define HWIO_REG_492611_RMSK 0x1ffff +#define HWIO_REG_492611_SHFT 0 +#define HWIO_REG_492611_IN in_dword_masked(\ + HWIO_REG_492611_ADDR,\ + HWIO_REG_492611_RMSK) +#define HWIO_REG_492611_INM(m) \ + in_dword_masked(HWIO_REG_492611_ADDR, m) +#define HWIO_REG_492611_OUT(v) \ + out_dword(HWIO_REG_492611_ADDR, v) +#define HWIO_REG_492611_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_492611_ADDR, m, v,\ + HWIO_REG_492611_IN); +#define HWIO_REG_492611_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_492611_BASE_ADDR_SHFT 0 + +#define HWIO_REG_91427_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007a0) +#define HWIO_REG_91427_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007a0) +#define HWIO_REG_91427_RMSK 0x1ffff +#define HWIO_REG_91427_SHFT 0 +#define HWIO_REG_91427_IN in_dword_masked(\ + HWIO_REG_91427_ADDR,\ + HWIO_REG_91427_RMSK) +#define HWIO_REG_91427_INM(m) \ + in_dword_masked(HWIO_REG_91427_ADDR, m) +#define HWIO_REG_91427_OUT(v) \ + out_dword(HWIO_REG_91427_ADDR, v) +#define HWIO_REG_91427_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_91427_ADDR, m, v,\ + HWIO_REG_91427_IN); +#define HWIO_REG_91427_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_91427_BASE_ADDR_SHFT 0 + +#define HWIO_REG_617696_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007a4) +#define HWIO_REG_617696_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007a4) +#define HWIO_REG_617696_RMSK 0x1ffff +#define HWIO_REG_617696_SHFT 0 +#define HWIO_REG_617696_IN in_dword_masked(\ + HWIO_REG_617696_ADDR,\ + HWIO_REG_617696_RMSK) +#define HWIO_REG_617696_INM(m) \ + in_dword_masked(HWIO_REG_617696_ADDR, m) +#define HWIO_REG_617696_OUT(v) \ + out_dword(HWIO_REG_617696_ADDR, v) +#define HWIO_REG_617696_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_617696_ADDR, m, v,\ + HWIO_REG_617696_IN); +#define HWIO_REG_617696_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_617696_BASE_ADDR_SHFT 0 + +#define HWIO_REG_459602_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007a8) +#define HWIO_REG_459602_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007a8) +#define HWIO_REG_459602_RMSK 0x1ffff +#define HWIO_REG_459602_SHFT 0 +#define HWIO_REG_459602_IN in_dword_masked(\ + HWIO_REG_459602_ADDR,\ + HWIO_REG_459602_RMSK) +#define HWIO_REG_459602_INM(m) \ + in_dword_masked(HWIO_REG_459602_ADDR, m) +#define HWIO_REG_459602_OUT(v) \ + out_dword(HWIO_REG_459602_ADDR, v) +#define HWIO_REG_459602_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_459602_ADDR, m, v,\ + HWIO_REG_459602_IN); +#define HWIO_REG_459602_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_459602_BASE_ADDR_SHFT 0 + +#define HWIO_REG_758_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007ac) +#define HWIO_REG_758_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007ac) +#define HWIO_REG_758_RMSK 0x1ffff +#define HWIO_REG_758_SHFT 0 +#define HWIO_REG_758_IN in_dword_masked(\ + HWIO_REG_758_ADDR,\ + HWIO_REG_758_RMSK) +#define HWIO_REG_758_INM(m) \ + in_dword_masked(HWIO_REG_758_ADDR, m) +#define HWIO_REG_758_OUT(v) \ + out_dword(HWIO_REG_758_ADDR, v) +#define HWIO_REG_758_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_758_ADDR, m, v,\ + HWIO_REG_758_IN); +#define HWIO_REG_758_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_758_BASE_ADDR_SHFT 0 + +#define HWIO_REG_710606_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007b0) +#define HWIO_REG_710606_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007b0) +#define HWIO_REG_710606_RMSK 0x1ffff +#define HWIO_REG_710606_SHFT 0 +#define HWIO_REG_710606_IN in_dword_masked(\ + HWIO_REG_710606_ADDR,\ + HWIO_REG_710606_RMSK) +#define HWIO_REG_710606_INM(m) \ + in_dword_masked(HWIO_REG_710606_ADDR, m) +#define HWIO_REG_710606_OUT(v) \ + out_dword(HWIO_REG_710606_ADDR, v) +#define HWIO_REG_710606_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_710606_ADDR, m, v,\ + HWIO_REG_710606_IN); +#define HWIO_REG_710606_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_710606_BASE_ADDR_SHFT 0 + +#define HWIO_REG_122975_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007b4) +#define HWIO_REG_122975_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007b4) +#define HWIO_REG_122975_RMSK 0x1ffff +#define HWIO_REG_122975_SHFT 0 +#define HWIO_REG_122975_IN in_dword_masked(\ + HWIO_REG_122975_ADDR,\ + HWIO_REG_122975_RMSK) +#define HWIO_REG_122975_INM(m)\ + in_dword_masked(HWIO_REG_122975_ADDR, m) +#define HWIO_REG_122975_OUT(v)\ + out_dword(HWIO_REG_122975_ADDR, v) +#define HWIO_REG_122975_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_122975_ADDR, m, v,\ + HWIO_REG_122975_IN); +#define HWIO_REG_122975_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_122975_BASE_ADDR_SHFT 0 + +#define HWIO_REG_860205_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007b8) +#define HWIO_REG_860205_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007b8) +#define HWIO_REG_860205_RMSK 0x1ffff +#define HWIO_REG_860205_SHFT 0 +#define HWIO_REG_860205_IN in_dword_masked(\ + HWIO_REG_860205_ADDR,\ + HWIO_REG_860205_RMSK) +#define HWIO_REG_860205_INM(m) \ + in_dword_masked(HWIO_REG_860205_ADDR, m) +#define HWIO_REG_860205_OUT(v) \ + out_dword(HWIO_REG_860205_ADDR, v) +#define HWIO_REG_860205_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_860205_ADDR, m, v,\ + HWIO_REG_860205_IN); +#define HWIO_REG_860205_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_860205_BASE_ADDR_SHFT 0 + +#define HWIO_REG_366154_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007bc) +#define HWIO_REG_366154_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007bc) +#define HWIO_REG_366154_RMSK 0x1ffff +#define HWIO_REG_366154_SHFT 0 +#define HWIO_REG_366154_IN in_dword_masked(\ + HWIO_REG_366154_ADDR,\ + HWIO_REG_366154_RMSK) +#define HWIO_REG_366154_INM(m) \ + in_dword_masked(HWIO_REG_366154_ADDR, m) +#define HWIO_REG_366154_OUT(v) \ + out_dword(HWIO_REG_366154_ADDR, v) +#define HWIO_REG_366154_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_366154_ADDR, m, v,\ + HWIO_REG_366154_IN); +#define HWIO_REG_366154_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_366154_BASE_ADDR_SHFT 0 + +#define HWIO_REG_632247_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007c0) +#define HWIO_REG_632247_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007c0) +#define HWIO_REG_632247_RMSK 0x1ffff +#define HWIO_REG_632247_SHFT 0 +#define HWIO_REG_632247_IN in_dword_masked(\ + HWIO_REG_632247_ADDR,\ + HWIO_REG_632247_RMSK) +#define HWIO_REG_632247_INM(m) \ + in_dword_masked(HWIO_REG_632247_ADDR, m) +#define HWIO_REG_632247_OUT(v) \ + out_dword(HWIO_REG_632247_ADDR, v) +#define HWIO_REG_632247_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_632247_ADDR, m, v,\ + HWIO_REG_632247_IN); +#define HWIO_REG_632247_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_632247_BASE_ADDR_SHFT 0 + +#define HWIO_REG_709312_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007c4) +#define HWIO_REG_709312_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007c4) +#define HWIO_REG_709312_RMSK 0x1ffff +#define HWIO_REG_709312_SHFT 0 +#define HWIO_REG_709312_IN in_dword_masked(\ + HWIO_REG_709312_ADDR,\ + HWIO_REG_709312_RMSK) +#define HWIO_REG_709312_INM(m) \ + in_dword_masked(HWIO_REG_709312_ADDR, m) +#define HWIO_REG_709312_OUT(v) \ + out_dword(HWIO_REG_709312_ADDR, v) +#define HWIO_REG_709312_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_709312_ADDR, m, v,\ + HWIO_REG_709312_IN); +#define HWIO_REG_709312_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_709312_BASE_ADDR_SHFT 0 + +#define HWIO_REG_891367_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007c8) +#define HWIO_REG_891367_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007c8) +#define HWIO_REG_891367_RMSK 0x1ffff +#define HWIO_REG_891367_SHFT 0 +#define HWIO_REG_891367_IN in_dword_masked(\ + HWIO_REG_891367_ADDR,\ + HWIO_REG_891367_RMSK) +#define HWIO_REG_891367_INM(m) \ + in_dword_masked(HWIO_REG_891367_ADDR, m) +#define HWIO_REG_891367_OUT(v) \ + out_dword(HWIO_REG_891367_ADDR, v) +#define HWIO_REG_891367_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_891367_ADDR, m, v,\ + HWIO_REG_891367_IN); +#define HWIO_REG_891367_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_891367_BASE_ADDR_SHFT 0 + +#define HWIO_REG_628746_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007cc) +#define HWIO_REG_628746_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007cc) +#define HWIO_REG_628746_RMSK 0x1ffff +#define HWIO_REG_628746_SHFT 0 +#define HWIO_REG_628746_IN in_dword_masked(\ + HWIO_REG_628746_ADDR,\ + HWIO_REG_628746_RMSK) +#define HWIO_REG_628746_INM(m) \ + in_dword_masked(HWIO_REG_628746_ADDR, m) +#define HWIO_REG_628746_OUT(v) \ + out_dword(HWIO_REG_628746_ADDR, v) +#define HWIO_REG_628746_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_628746_ADDR, m, v,\ + HWIO_REG_628746_IN); +#define HWIO_REG_628746_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_628746_BASE_ADDR_SHFT 0 + +#define HWIO_REG_821010_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007d0) +#define HWIO_REG_821010_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007d0) +#define HWIO_REG_821010_RMSK 0x1ffff +#define HWIO_REG_821010_SHFT 0 +#define HWIO_REG_821010_IN in_dword_masked(\ + HWIO_REG_821010_ADDR,\ + HWIO_REG_821010_RMSK) +#define HWIO_REG_821010_INM(m) \ + in_dword_masked(HWIO_REG_821010_ADDR, m) +#define HWIO_REG_821010_OUT(v) \ + out_dword(HWIO_REG_821010_ADDR, v) +#define HWIO_REG_821010_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_821010_ADDR, m, v,\ + HWIO_REG_821010_IN); +#define HWIO_REG_821010_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_821010_BASE_ADDR_SHFT 0 + +#define HWIO_REG_902098_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007d4) +#define HWIO_REG_902098_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007d4) +#define HWIO_REG_902098_RMSK 0x1ffff +#define HWIO_REG_902098_SHFT 0 +#define HWIO_REG_902098_IN in_dword_masked(\ + HWIO_REG_902098_ADDR,\ + HWIO_REG_902098_RMSK) +#define HWIO_REG_902098_INM(m) \ + in_dword_masked(HWIO_REG_902098_ADDR, m) +#define HWIO_REG_902098_OUT(v) \ + out_dword(HWIO_REG_902098_ADDR, v) +#define HWIO_REG_902098_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_902098_ADDR, m, v,\ + HWIO_REG_902098_IN); +#define HWIO_REG_902098_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_902098_BASE_ADDR_SHFT 0 + +#define HWIO_REG_939091_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007d8) +#define HWIO_REG_939091_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007d8) +#define HWIO_REG_939091_RMSK 0x1ffff +#define HWIO_REG_939091_SHFT 0 +#define HWIO_REG_939091_IN in_dword_masked(\ + HWIO_REG_939091_ADDR,\ + HWIO_REG_939091_RMSK) +#define HWIO_REG_939091_INM(m) \ + in_dword_masked(HWIO_REG_939091_ADDR, m) +#define HWIO_REG_939091_OUT(v) \ + out_dword(HWIO_REG_939091_ADDR, v) +#define HWIO_REG_939091_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_939091_ADDR, m, v,\ + HWIO_REG_939091_IN); +#define HWIO_REG_939091_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_939091_BASE_ADDR_SHFT 0 + +#define HWIO_REG_261074_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007dc) +#define HWIO_REG_261074_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007dc) +#define HWIO_REG_261074_RMSK 0x1ffff +#define HWIO_REG_261074_SHFT 0 +#define HWIO_REG_261074_IN in_dword_masked(\ + HWIO_REG_261074_ADDR,\ + HWIO_REG_261074_RMSK) +#define HWIO_REG_261074_INM(m) \ + in_dword_masked(HWIO_REG_261074_ADDR, m) +#define HWIO_REG_261074_OUT(v) \ + out_dword(HWIO_REG_261074_ADDR, v) +#define HWIO_REG_261074_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_261074_ADDR, m, v,\ + HWIO_REG_261074_IN); +#define HWIO_REG_261074_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_261074_BASE_ADDR_SHFT 0 + +#define HWIO_REG_157718_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007e0) +#define HWIO_REG_157718_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007e0) +#define HWIO_REG_157718_RMSK 0x1ffff +#define HWIO_REG_157718_SHFT 0 +#define HWIO_REG_157718_IN in_dword_masked(\ + HWIO_REG_157718_ADDR,\ + HWIO_REG_157718_RMSK) +#define HWIO_REG_157718_INM(m) \ + in_dword_masked(HWIO_REG_157718_ADDR, m) +#define HWIO_REG_157718_OUT(v) \ + out_dword(HWIO_REG_157718_ADDR, v) +#define HWIO_REG_157718_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_157718_ADDR, m, v,\ + HWIO_REG_157718_IN); +#define HWIO_REG_5552391_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_5552391_BASE_ADDR_SHFT 0 + +#define HWIO_REG_148889_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007e8) +#define HWIO_REG_148889_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007e8) +#define HWIO_REG_148889_RMSK 0x1ffff +#define HWIO_REG_148889_SHFT 0 +#define HWIO_REG_148889_IN in_dword_masked(\ + HWIO_REG_148889_ADDR,\ + HWIO_REG_148889_RMSK) +#define HWIO_REG_148889_INM(m) \ + in_dword_masked(HWIO_REG_148889_ADDR, m) +#define HWIO_REG_148889_OUT(v) \ + out_dword(HWIO_REG_148889_ADDR, v) +#define HWIO_REG_148889_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_148889_ADDR, m, v,\ + HWIO_REG_148889_IN); +#define HWIO_REG_148889_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_148889_BASE_ADDR_SHFT 0 + +#define HWIO_REG_396380_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007ec) +#define HWIO_REG_396380_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007ec) +#define HWIO_REG_396380_RMSK 0x1ffff +#define HWIO_REG_396380_SHFT 0 +#define HWIO_REG_396380_IN in_dword_masked(\ + HWIO_REG_396380_ADDR,\ + HWIO_REG_396380_RMSK) +#define HWIO_REG_396380_INM(m) \ + in_dword_masked(HWIO_REG_396380_ADDR, m) +#define HWIO_REG_396380_OUT(v) \ + out_dword(HWIO_REG_396380_ADDR, v) +#define HWIO_REG_396380_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_396380_ADDR, m, v,\ + HWIO_REG_396380_IN); +#define HWIO_REG_396380_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_396380_BASE_ADDR_SHFT 0 + +#define HWIO_REG_351005_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007f0) +#define HWIO_REG_351005_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007f0) +#define HWIO_REG_351005_RMSK 0x1ffff +#define HWIO_REG_351005_SHFT 0 +#define HWIO_REG_351005_IN in_dword_masked(\ + HWIO_REG_351005_ADDR,\ + HWIO_REG_351005_RMSK) +#define HWIO_REG_351005_INM(m) \ + in_dword_masked(HWIO_REG_351005_ADDR, m) +#define HWIO_REG_351005_OUT(v) \ + out_dword(HWIO_REG_351005_ADDR, v) +#define HWIO_REG_351005_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_351005_ADDR, m, v,\ + HWIO_REG_351005_IN); +#define HWIO_REG_351005_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_351005_BASE_ADDR_SHFT 0 + +#define HWIO_REG_863263_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007f4) +#define HWIO_REG_863263_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007f4) +#define HWIO_REG_863263_RMSK 0x1ffff +#define HWIO_REG_863263_SHFT 0 +#define HWIO_REG_863263_IN in_dword_masked(\ + HWIO_REG_863263_ADDR,\ + HWIO_REG_863263_RMSK) +#define HWIO_REG_863263_INM(m) \ + in_dword_masked(HWIO_REG_863263_ADDR, m) +#define HWIO_REG_863263_OUT(v) \ + out_dword(HWIO_REG_863263_ADDR, v) +#define HWIO_REG_863263_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_863263_ADDR, m, v,\ + HWIO_REG_863263_IN); +#define HWIO_REG_863263_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_863263_BASE_ADDR_SHFT 0 + +#define HWIO_REG_135009_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007f8) +#define HWIO_REG_135009_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007f8) +#define HWIO_REG_135009_RMSK 0x1ffff +#define HWIO_REG_135009_SHFT 0 +#define HWIO_REG_135009_IN in_dword_masked(\ + HWIO_REG_135009_ADDR,\ + HWIO_REG_135009_RMSK) +#define HWIO_REG_135009_INM(m) \ + in_dword_masked(HWIO_REG_135009_ADDR, m) +#define HWIO_REG_135009_OUT(v) \ + out_dword(HWIO_REG_135009_ADDR, v) +#define HWIO_REG_135009_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_135009_ADDR, m, v,\ + HWIO_REG_135009_IN); +#define HWIO_REG_135009_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_135009_BASE_ADDR_SHFT 0 + +#define HWIO_REG_923883_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007fc) +#define HWIO_REG_923883_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007fc) +#define HWIO_REG_923883_RMSK 0x1ffff +#define HWIO_REG_923883_SHFT 0 +#define HWIO_REG_923883_IN in_dword_masked(\ + HWIO_REG_923883_ADDR,\ + HWIO_REG_923883_RMSK) +#define HWIO_REG_923883_INM(m) \ + in_dword_masked(HWIO_REG_923883_ADDR, m) +#define HWIO_REG_923883_OUT(v) \ + out_dword(HWIO_REG_923883_ADDR, v) +#define HWIO_REG_923883_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_923883_ADDR, m, v,\ + HWIO_REG_923883_IN); +#define HWIO_REG_923883_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_923883_BASE_ADDR_SHFT 0 + +#define HWIO_REG_934655_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000818) +#define HWIO_REG_934655_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000818) +#define HWIO_REG_934655_RMSK 0x1fff +#define HWIO_REG_934655_SHFT 0 +#define HWIO_REG_934655_IN \ + in_dword_masked(HWIO_REG_934655_ADDR, HWIO_REG_934655_RMSK) +#define HWIO_REG_934655_INM(m) \ + in_dword_masked(HWIO_REG_934655_ADDR, m) +#define HWIO_REG_934655_OUT(v) \ + out_dword(HWIO_REG_934655_ADDR, v) +#define HWIO_REG_934655_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_934655_ADDR, m, v, HWIO_REG_934655_IN); +#define HWIO_REG_934655_FRAME_WIDTH_BMSK 0x1fff +#define HWIO_REG_934655_FRAME_WIDTH_SHFT 0 + +#define HWIO_REG_179070_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000081c) +#define HWIO_REG_179070_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000081c) +#define HWIO_REG_179070_RMSK 0x1fff +#define HWIO_REG_179070_SHFT 0 +#define HWIO_REG_179070_IN in_dword_masked(\ + HWIO_REG_179070_ADDR, HWIO_REG_179070_RMSK) +#define HWIO_REG_179070_INM(m) \ + in_dword_masked(HWIO_REG_179070_ADDR, m) +#define HWIO_REG_179070_OUT(v) \ + out_dword(HWIO_REG_179070_ADDR, v) +#define HWIO_REG_179070_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_179070_ADDR, m, v, HWIO_REG_179070_IN); +#define HWIO_REG_179070_FRAME_HEIGHT_BMSK 0x1fff +#define HWIO_REG_179070_FRAME_HEIGHT_SHFT 0 + +#define HWIO_REG_63643_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000830) +#define HWIO_REG_63643_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000830) +#define HWIO_REG_63643_RMSK 0xff3f +#define HWIO_REG_63643_SHFT 0 +#define HWIO_REG_63643_IN in_dword_masked(\ + HWIO_REG_63643_ADDR, HWIO_REG_63643_RMSK) +#define HWIO_REG_63643_INM(m) \ + in_dword_masked(HWIO_REG_63643_ADDR, m) +#define HWIO_REG_63643_OUT(v) \ + out_dword(HWIO_REG_63643_ADDR, v) +#define HWIO_REG_63643_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_63643_ADDR, m, v, HWIO_REG_63643_IN); +#define HWIO_REG_63643_LEVEL_BMSK 0xff00 +#define HWIO_REG_63643_LEVEL_SHFT 0x8 +#define HWIO_REG_63643_PROFILE_BMSK 0x3f +#define HWIO_REG_63643_PROFILE_SHFT 0 + +#define HWIO_REG_786024_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000083c) +#define HWIO_REG_786024_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000083c) +#define HWIO_REG_786024_RMSK 0x1 +#define HWIO_REG_786024_SHFT 0 +#define HWIO_REG_786024_IN in_dword_masked(\ + HWIO_REG_786024_ADDR, HWIO_REG_786024_RMSK) +#define HWIO_REG_786024_INM(m) \ + in_dword_masked(HWIO_REG_786024_ADDR, m) +#define HWIO_REG_786024_OUT(v) \ + out_dword(HWIO_REG_786024_ADDR, v) +#define HWIO_REG_786024_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_786024_ADDR, m, v, HWIO_REG_786024_IN); +#define HWIO_REG_786024_FIELD_BMSK 0x1 +#define HWIO_REG_786024_FIELD_SHFT 0 + +#define HWIO_REG_152500_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000848) +#define HWIO_REG_152500_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000848) +#define HWIO_REG_152500_RMSK 0x3 +#define HWIO_REG_152500_SHFT 0 +#define HWIO_REG_152500_IN in_dword_masked(\ + HWIO_REG_152500_ADDR, HWIO_REG_152500_RMSK) +#define HWIO_REG_152500_INM(m) \ + in_dword_masked(HWIO_REG_152500_ADDR, m) +#define HWIO_REG_152500_OUT(v) \ + out_dword(HWIO_REG_152500_ADDR, v) +#define HWIO_REG_152500_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_152500_ADDR, m, v, HWIO_REG_152500_IN); +#define HWIO_REG_152500_LF_CONTROL_BMSK 0x3 +#define HWIO_REG_152500_LF_CONTROL_SHFT 0 + +#define HWIO_REG_266285_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000084c) +#define HWIO_REG_266285_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000084c) +#define HWIO_REG_266285_RMSK 0x1f +#define HWIO_REG_266285_SHFT 0 +#define HWIO_REG_266285_IN in_dword_masked(\ + HWIO_REG_266285_ADDR, HWIO_REG_266285_RMSK) +#define HWIO_REG_266285_INM(m) \ + in_dword_masked(HWIO_REG_266285_ADDR, m) +#define HWIO_REG_266285_OUT(v) \ + out_dword(HWIO_REG_266285_ADDR, v) +#define HWIO_REG_266285_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_266285_ADDR, m, v, HWIO_REG_266285_IN); +#define HWIO_REG_266285_LF_ALPHAS_OFF_BMSK 0x1f +#define HWIO_REG_266285_LF_ALPHAS_OFF_SHFT 0 + +#define HWIO_REG_964731_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000850) +#define HWIO_REG_964731_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000850) +#define HWIO_REG_964731_RMSK 0x1f +#define HWIO_REG_964731_SHFT 0 +#define HWIO_REG_964731_IN in_dword_masked(\ + HWIO_REG_964731_ADDR, HWIO_REG_964731_RMSK) +#define HWIO_REG_964731_INM(m) \ + in_dword_masked(HWIO_REG_964731_ADDR, m) +#define HWIO_REG_964731_OUT(v) \ + out_dword(HWIO_REG_964731_ADDR, v) +#define HWIO_REG_964731_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_964731_ADDR, m, v, HWIO_REG_964731_IN); +#define HWIO_REG_964731_LF_BETA_OFF_BMSK 0x1f +#define HWIO_REG_964731_LF_BETA_OFF_SHFT 0 + +#define HWIO_REG_919924_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000c30) +#define HWIO_REG_919924_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000c30) +#define HWIO_REG_919924_RMSK 0xffffffff +#define HWIO_REG_919924_SHFT 0 +#define HWIO_REG_919924_IN in_dword_masked(\ + HWIO_REG_919924_ADDR, HWIO_REG_919924_RMSK) +#define HWIO_REG_919924_INM(m) \ + in_dword_masked(HWIO_REG_919924_ADDR, m) +#define HWIO_REG_919924_OUT(v) \ + out_dword(HWIO_REG_919924_ADDR, v) +#define HWIO_REG_919924_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_919924_ADDR, m, v, HWIO_REG_919924_IN); +#define HWIO_REG_919924_VIDC_QP_OFFSET_BMSK 0xffffffff +#define HWIO_REG_919924_VIDC_QP_OFFSET_SHFT 0 + +#define HWIO_REG_143629_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000c34) +#define HWIO_REG_143629_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000c34) +#define HWIO_REG_143629_RMSK 0x1 +#define HWIO_REG_143629_SHFT 0 +#define HWIO_REG_143629_IN in_dword_masked(\ + HWIO_REG_143629_ADDR, HWIO_REG_143629_RMSK) +#define HWIO_REG_143629_INM(m) \ + in_dword_masked(HWIO_REG_143629_ADDR, m) +#define HWIO_REG_143629_OUT(v) \ + out_dword(HWIO_REG_143629_ADDR, v) +#define HWIO_REG_143629_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_143629_ADDR, m, v, HWIO_REG_143629_IN); +#define HWIO_REG_143629_REG_143629_BMSK 0x1 +#define HWIO_REG_143629_REG_143629_SHFT 0 + +#define HWIO_REG_607589_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002000) +#define HWIO_REG_607589_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002000) +#define HWIO_REG_607589_RMSK 0xffffffff +#define HWIO_REG_607589_SHFT 0 +#define HWIO_REG_607589_IN in_dword_masked(\ + HWIO_REG_607589_ADDR, HWIO_REG_607589_RMSK) +#define HWIO_REG_607589_INM(m) \ + in_dword_masked(HWIO_REG_607589_ADDR, m) +#define HWIO_REG_607589_OUT(v) \ + out_dword(HWIO_REG_607589_ADDR, v) +#define HWIO_REG_607589_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_607589_ADDR, m, v, HWIO_REG_607589_IN); +#define HWIO_REG_607589_RTN_CHID_BMSK 0xffffffff +#define HWIO_REG_607589_RTN_CHID_SHFT 0 + +#define HWIO_REG_845544_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002004) +#define HWIO_REG_845544_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002004) +#define HWIO_REG_845544_RMSK 0xffffffff +#define HWIO_REG_845544_SHFT 0 +#define HWIO_REG_845544_IN in_dword_masked(\ + HWIO_REG_845544_ADDR, HWIO_REG_845544_RMSK) +#define HWIO_REG_845544_INM(m) \ + in_dword_masked(HWIO_REG_845544_ADDR, m) +#define HWIO_REG_845544_OUT(v) \ + out_dword(HWIO_REG_845544_ADDR, v) +#define HWIO_REG_845544_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_845544_ADDR, m, v, HWIO_REG_845544_IN); +#define HWIO_REG_845544_REG_845544_BMSK 0xffffffff +#define HWIO_REG_845544_REG_845544_SHFT 0 + +#define HWIO_REG_859906_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002008) +#define HWIO_REG_859906_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002008) +#define HWIO_REG_859906_RMSK 0xffffffff +#define HWIO_REG_859906_SHFT 0 +#define HWIO_REG_859906_IN in_dword_masked(\ + HWIO_REG_859906_ADDR, HWIO_REG_859906_RMSK) +#define HWIO_REG_859906_INM(m) \ + in_dword_masked(HWIO_REG_859906_ADDR, m) +#define HWIO_REG_859906_OUT(v) \ + out_dword(HWIO_REG_859906_ADDR, v) +#define HWIO_REG_859906_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_859906_ADDR, m, v, HWIO_REG_859906_IN); +#define HWIO_REG_859906_REG_859906_BMSK 0xffffffff +#define HWIO_REG_859906_REG_859906_SHFT 0 + +#define HWIO_REG_490078_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000200c) +#define HWIO_REG_490078_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000200c) +#define HWIO_REG_490078_RMSK 0xffffffff +#define HWIO_REG_490078_SHFT 0 +#define HWIO_REG_490078_IN in_dword_masked(\ + HWIO_REG_490078_ADDR, HWIO_REG_490078_RMSK) +#define HWIO_REG_490078_INM(m) \ + in_dword_masked(HWIO_REG_490078_ADDR, m) +#define HWIO_REG_490078_OUT(v) \ + out_dword(HWIO_REG_490078_ADDR, v) +#define HWIO_REG_490078_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_490078_ADDR, m, v,\ + HWIO_REG_490078_IN); +#define HWIO_REG_490078_REG_490078_BMSK 0xffffffff +#define HWIO_REG_490078_REG_490078_SHFT 0 + +#define HWIO_REG_640904_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002010) +#define HWIO_REG_640904_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002010) +#define HWIO_REG_640904_RMSK 0xffffffff +#define HWIO_REG_640904_SHFT 0 +#define HWIO_REG_640904_IN in_dword_masked(\ + HWIO_REG_640904_ADDR, HWIO_REG_640904_RMSK) +#define HWIO_REG_640904_INM(m) \ + in_dword_masked(HWIO_REG_640904_ADDR, m) +#define HWIO_REG_640904_OUT(v) \ + out_dword(HWIO_REG_640904_ADDR, v) +#define HWIO_REG_640904_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_640904_ADDR, m, v, HWIO_REG_640904_IN); +#define HWIO_REG_640904_REG_640904_BMSK 0xffffffff +#define HWIO_REG_640904_REG_640904_SHFT 0 + +#define HWIO_REG_60114_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002014) +#define HWIO_REG_60114_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002014) +#define HWIO_REG_60114_RMSK 0xffffffff +#define HWIO_REG_60114_SHFT 0 +#define HWIO_REG_60114_IN in_dword_masked(\ + HWIO_REG_60114_ADDR, HWIO_REG_60114_RMSK) +#define HWIO_REG_60114_INM(m) \ + in_dword_masked(HWIO_REG_60114_ADDR, m) +#define HWIO_REG_60114_OUT(v) \ + out_dword(HWIO_REG_60114_ADDR, v) +#define HWIO_REG_60114_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_60114_ADDR, m, v, HWIO_REG_60114_IN); +#define HWIO_REG_60114_REG_60114_BMSK 0xffffffff +#define HWIO_REG_60114_REG_60114_SHFT 0 + +#define HWIO_REG_489688_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002018) +#define HWIO_REG_489688_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002018) +#define HWIO_REG_489688_RMSK 0xffffffff +#define HWIO_REG_489688_SHFT 0 +#define HWIO_REG_489688_IN in_dword_masked(\ + HWIO_REG_489688_ADDR, HWIO_REG_489688_RMSK) +#define HWIO_REG_489688_INM(m) \ + in_dword_masked(HWIO_REG_489688_ADDR, m) +#define HWIO_REG_489688_OUT(v) \ + out_dword(HWIO_REG_489688_ADDR, v) +#define HWIO_REG_489688_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_489688_ADDR, m, v, HWIO_REG_489688_IN); +#define HWIO_REG_489688_REG_489688_BMSK 0xffffffff +#define HWIO_REG_489688_REG_489688_SHFT 0 + +#define HWIO_REG_853667_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000201c) +#define HWIO_REG_853667_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000201c) +#define HWIO_REG_853667_RMSK 0xffffffff +#define HWIO_REG_853667_SHFT 0 +#define HWIO_REG_853667_IN in_dword_masked(\ + HWIO_REG_853667_ADDR, HWIO_REG_853667_RMSK) +#define HWIO_REG_853667_INM(m) \ + in_dword_masked(HWIO_REG_853667_ADDR, m) +#define HWIO_REG_853667_OUT(v) \ + out_dword(HWIO_REG_853667_ADDR, v) +#define HWIO_REG_853667_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_853667_ADDR, m, v, HWIO_REG_853667_IN); +#define HWIO_REG_853667_REG_853667_BMSK 0xffffffff +#define HWIO_REG_853667_REG_853667_SHFT 0 + +#define HWIO_REG_760102_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002020) +#define HWIO_REG_760102_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002020) +#define HWIO_REG_760102_RMSK 0xffffffff +#define HWIO_REG_760102_SHFT 0 +#define HWIO_REG_760102_IN in_dword_masked(\ + HWIO_REG_760102_ADDR, HWIO_REG_760102_RMSK) +#define HWIO_REG_760102_INM(m) \ + in_dword_masked(HWIO_REG_760102_ADDR, m) +#define HWIO_REG_760102_OUT(v) \ + out_dword(HWIO_REG_760102_ADDR, v) +#define HWIO_REG_760102_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_760102_ADDR, m, v, HWIO_REG_760102_IN); +#define HWIO_REG_760102_REG_760102_BMSK 0xffffffff +#define HWIO_REG_760102_REG_760102_SHFT 0 + +#define HWIO_REG_378318_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002024) +#define HWIO_REG_378318_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002024) +#define HWIO_REG_378318_RMSK 0xffffffff +#define HWIO_REG_378318_SHFT 0 +#define HWIO_REG_378318_IN in_dword_masked(\ + HWIO_REG_378318_ADDR, HWIO_REG_378318_RMSK) +#define HWIO_REG_378318_INM(m) \ + in_dword_masked(HWIO_REG_378318_ADDR, m) +#define HWIO_REG_378318_OUT(v) \ + out_dword(HWIO_REG_378318_ADDR, v) +#define HWIO_REG_378318_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_378318_ADDR, m, v, HWIO_REG_378318_IN); +#define HWIO_REG_378318_REG_378318_BMSK 0xffffffff +#define HWIO_REG_378318_REG_378318_SHFT 0 + +#define HWIO_REG_203487_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002028) +#define HWIO_REG_203487_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002028) +#define HWIO_REG_203487_RMSK 0xffffffff +#define HWIO_REG_203487_SHFT 0 +#define HWIO_REG_203487_IN in_dword_masked(\ + HWIO_REG_203487_ADDR, HWIO_REG_203487_RMSK) +#define HWIO_REG_203487_INM(m) \ + in_dword_masked(HWIO_REG_203487_ADDR, m) +#define HWIO_REG_203487_OUT(v) \ + out_dword(HWIO_REG_203487_ADDR, v) +#define HWIO_REG_203487_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_203487_ADDR, m, v, HWIO_REG_203487_IN); +#define HWIO_REG_203487_REG_203487_BMSK 0xffffffff +#define HWIO_REG_203487_REG_203487_SHFT 0 + +#define HWIO_REG_692991_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000202c) +#define HWIO_REG_692991_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000202c) +#define HWIO_REG_692991_RMSK 0xffffffff +#define HWIO_REG_692991_SHFT 0 +#define HWIO_REG_692991_IN in_dword_masked(\ + HWIO_REG_692991_ADDR, HWIO_REG_692991_RMSK) +#define HWIO_REG_692991_INM(m) \ + in_dword_masked(HWIO_REG_692991_ADDR, m) +#define HWIO_REG_692991_OUT(v) \ + out_dword(HWIO_REG_692991_ADDR, v) +#define HWIO_REG_692991_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_692991_ADDR, m, v, HWIO_REG_692991_IN); +#define HWIO_REG_692991_REG_692991_BMSK 0xffffffff +#define HWIO_REG_692991_REG_692991_SHFT 0 + +#define HWIO_REG_161740_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002030) +#define HWIO_REG_161740_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002030) +#define HWIO_REG_161740_RMSK 0xffffffff +#define HWIO_REG_161740_SHFT 0 +#define HWIO_REG_161740_IN in_dword_masked(\ + HWIO_REG_161740_ADDR, HWIO_REG_161740_RMSK) +#define HWIO_REG_161740_INM(m) \ + in_dword_masked(HWIO_REG_161740_ADDR, m) +#define HWIO_REG_161740_OUT(v) \ + out_dword(HWIO_REG_161740_ADDR, v) +#define HWIO_REG_161740_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_161740_ADDR, m, v, HWIO_REG_161740_IN); +#define HWIO_REG_161740_REG_161740_BMSK 0xffffffff +#define HWIO_REG_161740_REG_161740_SHFT 0 + +#define HWIO_REG_930239_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002034) +#define HWIO_REG_930239_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002034) +#define HWIO_REG_930239_RMSK 0xffffffff +#define HWIO_REG_930239_SHFT 0 +#define HWIO_REG_930239_IN in_dword_masked(\ + HWIO_REG_930239_ADDR, HWIO_REG_930239_RMSK) +#define HWIO_REG_930239_INM(m) \ + in_dword_masked(HWIO_REG_930239_ADDR, m) +#define HWIO_REG_930239_OUT(v) \ + out_dword(HWIO_REG_930239_ADDR, v) +#define HWIO_REG_930239_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_930239_ADDR, m, v, HWIO_REG_930239_IN); +#define HWIO_REG_930239_REG_930239_BMSK 0xffffffff +#define HWIO_REG_930239_REG_930239_SHFT 0 + +#define HWIO_REG_567827_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002038) +#define HWIO_REG_567827_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002038) +#define HWIO_REG_567827_RMSK 0xffffffff +#define HWIO_REG_567827_SHFT 0 +#define HWIO_REG_567827_IN in_dword_masked(\ + HWIO_REG_567827_ADDR, HWIO_REG_567827_RMSK) +#define HWIO_REG_567827_INM(m) \ + in_dword_masked(HWIO_REG_567827_ADDR, m) +#define HWIO_REG_567827_OUT(v) \ + out_dword(HWIO_REG_567827_ADDR, v) +#define HWIO_REG_567827_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_567827_ADDR, m, v, HWIO_REG_567827_IN); +#define HWIO_REG_567827_REG_567827_BMSK 0xffffffff +#define HWIO_REG_567827_REG_567827_SHFT 0 + +#define HWIO_REG_542997_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000203c) +#define HWIO_REG_542997_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000203c) +#define HWIO_REG_542997_RMSK 0xffffffff +#define HWIO_REG_542997_SHFT 0 +#define HWIO_REG_542997_IN in_dword_masked(\ + HWIO_REG_542997_ADDR, HWIO_REG_542997_RMSK) +#define HWIO_REG_542997_INM(m) \ + in_dword_masked(HWIO_REG_542997_ADDR, m) +#define HWIO_REG_542997_OUT(v) \ + out_dword(HWIO_REG_542997_ADDR, v) +#define HWIO_REG_542997_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_542997_ADDR, m, v, HWIO_REG_542997_IN); +#define HWIO_REG_542997_REG_542997_BMSK 0xffffffff +#define HWIO_REG_542997_REG_542997_SHFT 0 + +#define HWIO_REG_666957_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002040) +#define HWIO_REG_666957_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002040) +#define HWIO_REG_666957_RMSK 0x7ffff +#define HWIO_REG_666957_SHFT 0 +#define HWIO_REG_666957_IN in_dword_masked(\ + HWIO_REG_666957_ADDR, HWIO_REG_666957_RMSK) +#define HWIO_REG_666957_INM(m) \ + in_dword_masked(HWIO_REG_666957_ADDR, m) +#define HWIO_REG_666957_OUT(v) \ + out_dword(HWIO_REG_666957_ADDR, v) +#define HWIO_REG_666957_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_666957_ADDR, m, v, HWIO_REG_666957_IN); +#define HWIO_REG_666957_CH_DEC_TYPE_BMSK 0x70000 +#define HWIO_REG_666957_CH_DEC_TYPE_SHFT 0x10 +#define HWIO_REG_666957_CH_INST_ID_BMSK 0xffff +#define HWIO_REG_666957_CH_INST_ID_SHFT 0 + +#define HWIO_REG_117192_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002044) +#define HWIO_REG_117192_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002044) +#define HWIO_REG_117192_RMSK 0xffffffff +#define HWIO_REG_117192_SHFT 0 +#define HWIO_REG_117192_IN in_dword_masked(\ + HWIO_REG_117192_ADDR, HWIO_REG_117192_RMSK) +#define HWIO_REG_117192_INM(m) \ + in_dword_masked(HWIO_REG_117192_ADDR, m) +#define HWIO_REG_117192_OUT(v) \ + out_dword(HWIO_REG_117192_ADDR, v) +#define HWIO_REG_117192_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_117192_ADDR, m, v, HWIO_REG_117192_IN); +#define HWIO_REG_117192_REG_117192_BMSK 0xffffffff +#define HWIO_REG_117192_REG_117192_SHFT 0 + +#define HWIO_REG_145068_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002048) +#define HWIO_REG_145068_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002048) +#define HWIO_REG_145068_RMSK 0xffffffff +#define HWIO_REG_145068_SHFT 0 +#define HWIO_REG_145068_IN in_dword_masked(\ + HWIO_REG_145068_ADDR, HWIO_REG_145068_RMSK) +#define HWIO_REG_145068_INM(m) \ + in_dword_masked(HWIO_REG_145068_ADDR, m) +#define HWIO_REG_145068_OUT(v) \ + out_dword(HWIO_REG_145068_ADDR, v) +#define HWIO_REG_145068_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_145068_ADDR, m, v, HWIO_REG_145068_IN); +#define HWIO_REG_145068_REG_145068_BMSK 0xffffffff +#define HWIO_REG_145068_REG_145068_SHFT 0 + +#define HWIO_REG_921356_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000204c) +#define HWIO_REG_921356_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000204c) +#define HWIO_REG_921356_RMSK 0xffffffff +#define HWIO_REG_921356_SHFT 0 +#define HWIO_REG_921356_IN in_dword_masked(\ + HWIO_REG_921356_ADDR, HWIO_REG_921356_RMSK) +#define HWIO_REG_921356_INM(m) \ + in_dword_masked(HWIO_REG_921356_ADDR, m) +#define HWIO_REG_921356_OUT(v) \ + out_dword(HWIO_REG_921356_ADDR, v) +#define HWIO_REG_921356_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_921356_ADDR, m, v, HWIO_REG_921356_IN); +#define HWIO_REG_921356_REG_921356_BMSK 0xffffffff +#define HWIO_REG_921356_REG_921356_SHFT 0 + +#define HWIO_REG_612810_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002050) +#define HWIO_REG_612810_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002050) +#define HWIO_REG_612810_RMSK 0xffffffff +#define HWIO_REG_612810_SHFT 0 +#define HWIO_REG_612810_IN in_dword_masked(\ + HWIO_REG_612810_ADDR, HWIO_REG_612810_RMSK) +#define HWIO_REG_612810_INM(m) \ + in_dword_masked(HWIO_REG_612810_ADDR, m) +#define HWIO_REG_612810_OUT(v) \ + out_dword(HWIO_REG_612810_ADDR, v) +#define HWIO_REG_612810_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_612810_ADDR, m, v, HWIO_REG_612810_IN); +#define HWIO_REG_612810_REG_612810_BMSK 0xffffffff +#define HWIO_REG_612810_REG_612810_SHFT 0 + +#define HWIO_REG_175608_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002054) +#define HWIO_REG_175608_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002054) +#define HWIO_REG_175608_RMSK 0xffffffff +#define HWIO_REG_175608_SHFT 0 +#define HWIO_REG_175608_IN in_dword_masked(\ + HWIO_REG_175608_ADDR, HWIO_REG_175608_RMSK) +#define HWIO_REG_175608_INM(m) \ + in_dword_masked(HWIO_REG_175608_ADDR, m) +#define HWIO_REG_175608_OUT(v) \ + out_dword(HWIO_REG_175608_ADDR, v) +#define HWIO_REG_175608_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_175608_ADDR, m, v, HWIO_REG_175608_IN); +#define HWIO_REG_175608_REG_175608_BMSK 0xffffffff +#define HWIO_REG_175608_REG_175608_SHFT 0 + +#define HWIO_REG_190381_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002058) +#define HWIO_REG_190381_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002058) +#define HWIO_REG_190381_RMSK 0xffffffff +#define HWIO_REG_190381_SHFT 0 +#define HWIO_REG_190381_IN in_dword_masked(\ + HWIO_REG_190381_ADDR, HWIO_REG_190381_RMSK) +#define HWIO_REG_190381_INM(m) \ + in_dword_masked(HWIO_REG_190381_ADDR, m) +#define HWIO_REG_190381_OUT(v) \ + out_dword(HWIO_REG_190381_ADDR, v) +#define HWIO_REG_190381_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_190381_ADDR, m, v, HWIO_REG_190381_IN); +#define HWIO_REG_190381_REG_190381_BMSK 0xffffffff +#define HWIO_REG_190381_REG_190381_SHFT 0 + +#define HWIO_REG_85655_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000205c) +#define HWIO_REG_85655_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000205c) +#define HWIO_REG_85655_RMSK 0xffffffff +#define HWIO_REG_85655_SHFT 0 +#define HWIO_REG_85655_IN in_dword_masked(\ + HWIO_REG_85655_ADDR, HWIO_REG_85655_RMSK) +#define HWIO_REG_85655_INM(m) \ + in_dword_masked(HWIO_REG_85655_ADDR, m) +#define HWIO_REG_85655_OUT(v) \ + out_dword(HWIO_REG_85655_ADDR, v) +#define HWIO_REG_85655_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_85655_ADDR, m, v, HWIO_REG_85655_IN); +#define HWIO_REG_85655_REG_85655_BMSK 0xffffffff +#define HWIO_REG_85655_REG_85655_SHFT 0 + +#define HWIO_REG_86830_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002060) +#define HWIO_REG_86830_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002060) +#define HWIO_REG_86830_RMSK 0xffffffff +#define HWIO_REG_86830_SHFT 0 +#define HWIO_REG_86830_IN in_dword_masked(\ + HWIO_REG_86830_ADDR, HWIO_REG_86830_RMSK) +#define HWIO_REG_86830_INM(m) \ + in_dword_masked(HWIO_REG_86830_ADDR, m) +#define HWIO_REG_86830_OUT(v) \ + out_dword(HWIO_REG_86830_ADDR, v) +#define HWIO_REG_86830_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_86830_ADDR, m, v, HWIO_REG_86830_IN); +#define HWIO_REG_86830_REG_86830_BMSK 0xffffffff +#define HWIO_REG_86830_REG_86830_SHFT 0 + +#define HWIO_REG_889944_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002064) +#define HWIO_REG_889944_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002064) +#define HWIO_REG_889944_RMSK 0xffffffff +#define HWIO_REG_889944_SHFT 0 +#define HWIO_REG_889944_IN in_dword_masked(\ + HWIO_REG_889944_ADDR, HWIO_REG_889944_RMSK) +#define HWIO_REG_889944_INM(m) \ + in_dword_masked(HWIO_REG_889944_ADDR, m) +#define HWIO_REG_889944_OUT(v) \ + out_dword(HWIO_REG_889944_ADDR, v) +#define HWIO_REG_889944_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_889944_ADDR, m, v, HWIO_REG_889944_IN); +#define HWIO_REG_889944_HOST_WR_ADDR_BMSK 0xffffffff +#define HWIO_REG_889944_HOST_WR_ADSR_SHFT 0 + +#define HWIO_REG_404623_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002068) +#define HWIO_REG_404623_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002068) +#define HWIO_REG_404623_RMSK 0xffffffff +#define HWIO_REG_404623_SHFT 0 +#define HWIO_REG_404623_IN in_dword_masked(\ + HWIO_REG_404623_ADDR, HWIO_REG_404623_RMSK) +#define HWIO_REG_404623_INM(m) \ + in_dword_masked(HWIO_REG_404623_ADDR, m) +#define HWIO_REG_404623_OUT(v) \ + out_dword(HWIO_REG_404623_ADDR, v) +#define HWIO_REG_404623_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_404623_ADDR, m, v, HWIO_REG_404623_IN); +#define HWIO_REG_404623_REG_404623_BMSK 0xffffffff +#define HWIO_REG_404623_REG_404623_SHFT 0 + +#define HWIO_REG_397087_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000206c) +#define HWIO_REG_397087_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000206c) +#define HWIO_REG_397087_RMSK 0xffffffff +#define HWIO_REG_397087_SHFT 0 +#define HWIO_REG_397087_IN in_dword_masked(\ + HWIO_REG_397087_ADDR, HWIO_REG_397087_RMSK) +#define HWIO_REG_397087_INM(m) \ + in_dword_masked(HWIO_REG_397087_ADDR, m) +#define HWIO_REG_397087_OUT(v) \ + out_dword(HWIO_REG_397087_ADDR, v) +#define HWIO_REG_397087_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_397087_ADDR, m, v, HWIO_REG_397087_IN); +#define HWIO_REG_397087_CMD_SEQ_NUM_BMSK 0xffffffff +#define HWIO_REG_397087_CMD_SEQ_NUM_SHFT 0 + +#define HWIO_REG_212613_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002070) +#define HWIO_REG_212613_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002070) +#define HWIO_REG_212613_RMSK 0xffffffff +#define HWIO_REG_212613_SHFT 0 +#define HWIO_REG_212613_IN in_dword_masked(\ + HWIO_REG_212613_ADDR, HWIO_REG_212613_RMSK) +#define HWIO_REG_212613_INM(m) \ + in_dword_masked(HWIO_REG_212613_ADDR, m) +#define HWIO_REG_212613_OUT(v) \ + out_dword(HWIO_REG_212613_ADDR, v) +#define HWIO_REG_212613_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_212613_ADDR, m, v, HWIO_REG_212613_IN); +#define HWIO_REG_212613_REG_212613_BMSK 0xffffffff +#define HWIO_REG_212613_REG_212613_SHFT 0 + +#define HWIO_REG_840123_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002074) +#define HWIO_REG_840123_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002074) +#define HWIO_REG_840123_RMSK 0xffffffff +#define HWIO_REG_840123_SHFT 0 +#define HWIO_REG_840123_IN in_dword_masked(\ + HWIO_REG_840123_ADDR, HWIO_REG_840123_RMSK) +#define HWIO_REG_840123_INM(m) \ + in_dword_masked(HWIO_REG_840123_ADDR, m) +#define HWIO_REG_840123_OUT(v) \ + out_dword(HWIO_REG_840123_ADDR, v) +#define HWIO_REG_840123_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_840123_ADDR, m, v, HWIO_REG_840123_IN); +#define HWIO_REG_840123_REG_840123_BMSK 0xffffffff +#define HWIO_REG_840123_REG_840123_SHFT 0 + +#define HWIO_REG_520335_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002078) +#define HWIO_REG_520335_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002078) +#define HWIO_REG_520335_RMSK 0xffffffff +#define HWIO_REG_520335_SHFT 0 +#define HWIO_REG_520335_IN in_dword_masked(\ + HWIO_REG_520335_ADDR, HWIO_REG_520335_RMSK) +#define HWIO_REG_520335_INM(m) \ + in_dword_masked(HWIO_REG_520335_ADDR, m) +#define HWIO_REG_520335_OUT(v) \ + out_dword(HWIO_REG_520335_ADDR, v) +#define HWIO_REG_520335_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_520335_ADDR, m, v, HWIO_REG_520335_IN); +#define HWIO_REG_520335_REG_196943_BMSK 0xffffffff +#define HWIO_REG_520335_REG_196943_SHFT 0 + +#define HWIO_REG_196943_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000207c) +#define HWIO_REG_196943_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000207c) +#define HWIO_REG_196943_RMSK 0xffffffff +#define HWIO_REG_196943_SHFT 0 +#define HWIO_REG_196943_IN in_dword_masked(\ + HWIO_REG_196943_ADDR, HWIO_REG_196943_RMSK) +#define HWIO_REG_196943_INM(m) \ + in_dword_masked(HWIO_REG_196943_ADDR, m) +#define HWIO_REG_196943_OUT(v) \ + out_dword(HWIO_REG_196943_ADDR, v) +#define HWIO_REG_196943_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_196943_ADDR, m, v, HWIO_REG_196943_IN); +#define HWIO_REG_196943_REG_196943_BMSK 0xffffffff +#define HWIO_REG_196943_REG_196943_SHFT 0 + +#define HWIO_REG_313350_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002080) +#define HWIO_REG_313350_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002080) +#define HWIO_REG_313350_RMSK 0x7ffff +#define HWIO_REG_313350_SHFT 0 +#define HWIO_REG_313350_IN in_dword_masked(\ + HWIO_REG_313350_ADDR, HWIO_REG_313350_RMSK) +#define HWIO_REG_313350_INM(m) \ + in_dword_masked(HWIO_REG_313350_ADDR, m) +#define HWIO_REG_313350_OUT(v) \ + out_dword(HWIO_REG_313350_ADDR, v) +#define HWIO_REG_313350_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_313350_ADDR, m, v, HWIO_REG_313350_IN); +#define HWIO_REG_313350_CH_DEC_TYPE_BMSK 0x70000 +#define HWIO_REG_313350_CH_DEC_TYPE_SHFT 0x10 +#define HWIO_REG_313350_CH_INST_ID_BMSK 0xffff +#define HWIO_REG_313350_CH_INST_ID_SHFT 0 + +#define HWIO_REG_980194_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002084) +#define HWIO_REG_980194_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002084) +#define HWIO_REG_980194_RMSK 0xffffffff +#define HWIO_REG_980194_SHFT 0 +#define HWIO_REG_980194_IN in_dword_masked(\ + HWIO_REG_980194_ADDR, HWIO_REG_980194_RMSK) +#define HWIO_REG_980194_INM(m) \ + in_dword_masked(HWIO_REG_980194_ADDR, m) +#define HWIO_REG_980194_OUT(v) \ + out_dword(HWIO_REG_980194_ADDR, v) +#define HWIO_REG_980194_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_980194_ADDR, m, v, HWIO_REG_980194_IN); +#define HWIO_REG_980194_REG_980194_BMSK 0xffffffff +#define HWIO_REG_980194_REG_980194_SHFT 0 + +#define HWIO_REG_936704_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002088) +#define HWIO_REG_936704_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002088) +#define HWIO_REG_936704_RMSK 0xffffffff +#define HWIO_REG_936704_SHFT 0 +#define HWIO_REG_936704_IN in_dword_masked(\ + HWIO_REG_936704_ADDR, HWIO_REG_936704_RMSK) +#define HWIO_REG_936704_INM(m) \ + in_dword_masked(HWIO_REG_936704_ADDR, m) +#define HWIO_REG_936704_OUT(v) \ + out_dword(HWIO_REG_936704_ADDR, v) +#define HWIO_REG_936704_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_936704_ADDR, m, v, HWIO_REG_936704_IN); +#define HWIO_REG_936704_REG_936704_BMSK 0xffffffff +#define HWIO_REG_936704_REG_936704_SHFT 0 + +#define HWIO_REG_821977_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000208c) +#define HWIO_REG_821977_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000208c) +#define HWIO_REG_821977_RMSK 0xffffffff +#define HWIO_REG_821977_SHFT 0 +#define HWIO_REG_821977_IN in_dword_masked(\ + HWIO_REG_821977_ADDR, HWIO_REG_821977_RMSK) +#define HWIO_REG_821977_INM(m) \ + in_dword_masked(HWIO_REG_821977_ADDR, m) +#define HWIO_REG_821977_OUT(v) \ + out_dword(HWIO_REG_821977_ADDR, v) +#define HWIO_REG_821977_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_821977_ADDR, m, v, HWIO_REG_821977_IN); +#define HWIO_REG_821977_REG_821977_BMSK 0xffffffff +#define HWIO_REG_821977_REG_821977_SHFT 0 + +#define HWIO_REG_655721_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002090) +#define HWIO_REG_655721_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002090) +#define HWIO_REG_655721_RMSK 0xffffffff +#define HWIO_REG_655721_SHFT 0 +#define HWIO_REG_655721_IN in_dword_masked(\ + HWIO_REG_655721_ADDR, HWIO_REG_655721_RMSK) +#define HWIO_REG_655721_INM(m) \ + in_dword_masked(HWIO_REG_655721_ADDR, m) +#define HWIO_REG_655721_OUT(v) \ + out_dword(HWIO_REG_655721_ADDR, v) +#define HWIO_REG_655721_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_655721_ADDR, m, v, HWIO_REG_655721_IN); +#define HWIO_REG_655721_REG_655721_BMSK 0xffffffff +#define HWIO_REG_655721_REG_655721_SHFT 0 + +#define HWIO_REG_548308_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002094) +#define HWIO_REG_548308_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002094) +#define HWIO_REG_548308_RMSK 0xffffffff +#define HWIO_REG_548308_SHFT 0 +#define HWIO_REG_548308_IN in_dword_masked(\ + HWIO_REG_548308_ADDR, HWIO_REG_548308_RMSK) +#define HWIO_REG_548308_INM(m) \ + in_dword_masked(HWIO_REG_548308_ADDR, m) +#define HWIO_REG_548308_OUT(v) \ + out_dword(HWIO_REG_548308_ADDR, v) +#define HWIO_REG_548308_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_548308_ADDR, m, v, HWIO_REG_548308_IN); +#define HWIO_REG_548308_REG_548308_BMSK 0xffffffff +#define HWIO_REG_548308_REG_548308_SHFT 0 + +#define HWIO_REG_887095_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002098) +#define HWIO_REG_887095_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002098) +#define HWIO_REG_887095_RMSK 0xffffffff +#define HWIO_REG_887095_SHFT 0 +#define HWIO_REG_887095_IN in_dword_masked(\ + HWIO_REG_887095_ADDR, HWIO_REG_887095_RMSK) +#define HWIO_REG_887095_INM(m) \ + in_dword_masked(HWIO_REG_887095_ADDR, m) +#define HWIO_REG_887095_OUT(v) \ + out_dword(HWIO_REG_887095_ADDR, v) +#define HWIO_REG_887095_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_887095_ADDR, m, v, HWIO_REG_887095_IN); +#define HWIO_REG_887095_REG_887095_BMSK 0xffffffff +#define HWIO_REG_887095_REG_887095_SHFT 0 + +#define HWIO_REG_576987_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000209c) +#define HWIO_REG_576987_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000209c) +#define HWIO_REG_576987_RMSK 0xffffffff +#define HWIO_REG_576987_SHFT 0 +#define HWIO_REG_576987_IN in_dword_masked(\ + HWIO_REG_576987_ADDR, HWIO_REG_576987_RMSK) +#define HWIO_REG_576987_INM(m) \ + in_dword_masked(HWIO_REG_576987_ADDR, m) +#define HWIO_REG_576987_OUT(v) \ + out_dword(HWIO_REG_576987_ADDR, v) +#define HWIO_REG_576987_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_576987_ADDR, m, v, HWIO_REG_576987_IN); +#define HWIO_REG_576987_REG_576987_BMSK 0xffffffff +#define HWIO_REG_576987_REG_576987_SHFT 0 + +#define HWIO_REG_70448_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020a0) +#define HWIO_REG_70448_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020a0) +#define HWIO_REG_70448_RMSK 0xffffffff +#define HWIO_REG_70448_SHFT 0 +#define HWIO_REG_70448_IN in_dword_masked(\ + HWIO_REG_70448_ADDR, HWIO_REG_70448_RMSK) +#define HWIO_REG_70448_INM(m) \ + in_dword_masked(HWIO_REG_70448_ADDR, m) +#define HWIO_REG_70448_OUT(v) \ + out_dword(HWIO_REG_70448_ADDR, v) +#define HWIO_REG_70448_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_70448_ADDR, m, v, HWIO_REG_70448_IN); +#define HWIO_REG_70448_REG_70448_BMSK 0xffffffff +#define HWIO_REG_70448_REG_70448_SHFT 0 + +#define HWIO_REG_652528_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020a4) +#define HWIO_REG_652528_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020a4) +#define HWIO_REG_652528_RMSK 0xffffffff +#define HWIO_REG_652528_SHFT 0 +#define HWIO_REG_652528_IN in_dword_masked(\ + HWIO_REG_652528_ADDR, HWIO_REG_652528_RMSK) +#define HWIO_REG_652528_INM(m) \ + in_dword_masked(HWIO_REG_652528_ADDR, m) +#define HWIO_REG_652528_OUT(v) \ + out_dword(HWIO_REG_652528_ADDR, v) +#define HWIO_REG_652528_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_652528_ADDR, m, v , HWIO_REG_652528_IN); +#define HWIO_REG_652528_REG_652528_BMSK 0xffffffff +#define HWIO_REG_652528_REG_652528_SHFT 0 + +#define HWIO_REG_220637_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020a8) +#define HWIO_REG_220637_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020a8) +#define HWIO_REG_220637_RMSK 0xffffffff +#define HWIO_REG_220637_SHFT 0 +#define HWIO_REG_220637_IN in_dword_masked(\ + HWIO_REG_220637_ADDR, HWIO_REG_220637_RMSK) +#define HWIO_REG_220637_INM(m) \ + in_dword_masked(HWIO_REG_220637_ADDR, m) +#define HWIO_REG_220637_OUT(v) \ + out_dword(HWIO_REG_220637_ADDR, v) +#define HWIO_REG_220637_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_220637_ADDR, m, v, HWIO_REG_220637_IN); +#define HWIO_REG_220637_REG_220637_BMSK 0xffffffff +#define HWIO_REG_220637_REG_220637_SHFT 0 + +#define HWIO_REG_254093_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020ac) +#define HWIO_REG_254093_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020ac) +#define HWIO_REG_254093_RMSK 0xffffffff +#define HWIO_REG_254093_SHFT 0 +#define HWIO_REG_254093_IN in_dword_masked(\ + HWIO_REG_254093_ADDR, HWIO_REG_254093_RMSK) +#define HWIO_REG_254093_INM(m) \ + in_dword_masked(HWIO_REG_254093_ADDR, m) +#define HWIO_REG_254093_OUT(v) \ + out_dword(HWIO_REG_254093_ADDR, v) +#define HWIO_REG_254093_OUTM(m, v) out_dword_masked_ns\ + (HWIO_REG_254093_ADDR, m, v, HWIO_REG_254093_IN); +#define HWIO_REG_254093_REG_254093_BMSK 0xffffffff +#define HWIO_REG_254093_REG_254093_SHFT 0 + +#define HWIO_REG_160474_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020b0) +#define HWIO_REG_160474_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020b0) +#define HWIO_REG_160474_RMSK 0xffffffff +#define HWIO_REG_160474_SHFT 0 +#define HWIO_REG_160474_IN in_dword_masked(\ + HWIO_REG_160474_ADDR, HWIO_REG_160474_RMSK) +#define HWIO_REG_160474_INM(m) \ + in_dword_masked(HWIO_REG_160474_ADDR, m) +#define HWIO_REG_160474_OUT(v) \ + out_dword(HWIO_REG_160474_ADDR, v) +#define HWIO_REG_160474_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_160474_ADDR, m, v, HWIO_REG_160474_IN); +#define HWIO_REG_160474_REG_160474_BMSK 0xffffffff +#define HWIO_REG_160474_REG_160474_SHFT 0 + +#define HWIO_REG_39027_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020b4) +#define HWIO_REG_39027_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020b4) +#define HWIO_REG_39027_RMSK 0xffffffff +#define HWIO_REG_39027_SHFT 0 +#define HWIO_REG_39027_IN in_dword_masked(\ + HWIO_REG_39027_ADDR, HWIO_REG_39027_RMSK) +#define HWIO_REG_39027_INM(m) \ + in_dword_masked(HWIO_REG_39027_ADDR, m) +#define HWIO_REG_39027_OUT(v) \ + out_dword(HWIO_REG_39027_ADDR, v) +#define HWIO_REG_39027_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_39027_ADDR, m, v, HWIO_REG_39027_IN); +#define HWIO_REG_39027_REG_39027_BMSK 0xffffffff +#define HWIO_REG_39027_REG_39027_SHFT 0 + +#define HWIO_REG_74049_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020b8) +#define HWIO_REG_74049_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020b8) +#define HWIO_REG_74049_RMSK 0xffffffff +#define HWIO_REG_74049_SHFT 0 +#define HWIO_REG_74049_IN in_dword_masked(\ + HWIO_REG_74049_ADDR, HWIO_REG_74049_RMSK) +#define HWIO_REG_74049_INM(m) \ + in_dword_masked(HWIO_REG_74049_ADDR, m) +#define HWIO_REG_74049_OUT(v) \ + out_dword(HWIO_REG_74049_ADDR, v) +#define HWIO_REG_74049_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_74049_ADDR, m, v, HWIO_REG_74049_IN); +#define HWIO_REG_74049_REG_74049_BMSK 0xffffffff +#define HWIO_REG_74049_REG_74049_SHFT 0 + +#define HWIO_REG_697870_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020bc) +#define HWIO_REG_697870_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020bc) +#define HWIO_REG_697870_RMSK 0xffffffff +#define HWIO_REG_697870_SHFT 0 +#define HWIO_REG_697870_IN in_dword_masked(\ + HWIO_REG_697870_ADDR, HWIO_REG_697870_RMSK) +#define HWIO_REG_697870_INM(m) \ + in_dword_masked(HWIO_REG_697870_ADDR, m) +#define HWIO_REG_697870_OUT(v) \ + out_dword(HWIO_REG_697870_ADDR, v) +#define HWIO_REG_697870_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_697870_ADDR, m, v, HWIO_REG_697870_IN); +#define HWIO_REG_697870_REG_697870_BMSK 0xffffffff +#define HWIO_REG_697870_REG_697870_SHFT 0 + +#define HWIO_REG_783891_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c504) +#define HWIO_REG_783891_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c504) +#define HWIO_REG_783891_RMSK 0x7ffff +#define HWIO_REG_783891_SHFT 0 +#define HWIO_REG_783891_IN in_dword_masked(\ + HWIO_REG_783891_ADDR, HWIO_REG_783891_RMSK) +#define HWIO_REG_783891_INM(m) \ + in_dword_masked(HWIO_REG_783891_ADDR, m) +#define HWIO_REG_783891_OUT(v) \ + out_dword(HWIO_REG_783891_ADDR, v) +#define HWIO_REG_783891_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_783891_ADDR, m, v, HWIO_REG_783891_IN); +#define HWIO_REG_783891_ENC_PIC_TYPE_USE_BMSK 0x40000 +#define HWIO_REG_783891_ENC_PIC_TYPE_USE_SHFT 0x12 +#define HWIO_REG_783891_B_FRM_CTRL_BMSK 0x30000 +#define HWIO_REG_783891_B_FRM_CTRL_SHFT 0x10 +#define HWIO_REG_783891_I_FRM_CTRL_BMSK 0xffff +#define HWIO_REG_783891_I_FRM_CTRL_SHFT 0 + +#define HWIO_REG_226332_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c50c) +#define HWIO_REG_226332_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c50c) +#define HWIO_REG_226332_RMSK 0x7 +#define HWIO_REG_226332_SHFT 0 +#define HWIO_REG_226332_IN in_dword_masked(\ + HWIO_REG_226332_ADDR, HWIO_REG_226332_RMSK) +#define HWIO_REG_226332_INM(m) in_dword_masked(HWIO_REG_226332_ADDR, m) +#define HWIO_REG_226332_OUT(v) out_dword(HWIO_REG_226332_ADDR, v) +#define HWIO_REG_226332_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_226332_ADDR, m, v, HWIO_REG_226332_IN); +#define HWIO_REG_226332_MSLICE_MODE_BMSK 0x6 +#define HWIO_REG_226332_MSLICE_MODE_SHFT 0x1 +#define HWIO_REG_226332_MSLICE_ENA_BMSK 0x1 +#define HWIO_REG_226332_MSLICE_ENA_SHFT 0 + +#define HWIO_REG_696136_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c510) +#define HWIO_REG_696136_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c510) +#define HWIO_REG_696136_RMSK 0xffff +#define HWIO_REG_696136_SHFT 0 +#define HWIO_REG_696136_IN in_dword_masked(\ + HWIO_REG_696136_ADDR, HWIO_REG_696136_RMSK) +#define HWIO_REG_696136_INM(m) in_dword_masked(HWIO_REG_696136_ADDR, m) +#define HWIO_REG_696136_OUT(v) out_dword(HWIO_REG_696136_ADDR, v) +#define HWIO_REG_696136_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_696136_ADDR, m, v, HWIO_REG_696136_IN); +#define HWIO_REG_696136_MSLICE_MB_BMSK 0xffff +#define HWIO_REG_696136_MSLICE_MB_SHFT 0 + +#define HWIO_REG_515564_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c514) +#define HWIO_REG_515564_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c514) +#define HWIO_REG_515564_RMSK 0xffffffff +#define HWIO_REG_515564_SHFT 0 +#define HWIO_REG_515564_IN in_dword_masked(\ + HWIO_REG_515564_ADDR, HWIO_REG_515564_RMSK) +#define HWIO_REG_515564_INM(m) \ + in_dword_masked(HWIO_REG_515564_ADDR, m) +#define HWIO_REG_515564_OUT(v) out_dword(HWIO_REG_515564_ADDR, v) +#define HWIO_REG_515564_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_515564_ADDR, m, v, HWIO_REG_515564_IN); +#define HWIO_REG_515564_MSLICE_BIT_BMSK 0xffffffff +#define HWIO_REG_515564_MSLICE_BIT_SHFT 0 + +#define HWIO_REG_886210_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c518) +#define HWIO_REG_886210_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c518) +#define HWIO_REG_886210_RMSK 0xffff +#define HWIO_REG_886210_SHFT 0 +#define HWIO_REG_886210_IN in_dword_masked(\ + HWIO_REG_886210_ADDR, HWIO_REG_886210_RMSK) +#define HWIO_REG_886210_INM(m) in_dword_masked(HWIO_REG_886210_ADDR, m) +#define HWIO_REG_886210_OUT(v) out_dword(HWIO_REG_886210_ADDR, v) +#define HWIO_REG_886210_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_886210_ADDR, m, v, HWIO_REG_886210_IN); +#define HWIO_REG_886210_CIR_NUM_BMSK 0xffff +#define HWIO_REG_886210_CIR_NUM_SHFT 0 + +#define HWIO_REG_645603_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c51c) +#define HWIO_REG_645603_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c51c) +#define HWIO_REG_645603_RMSK 0x3 +#define HWIO_REG_645603_SHFT 0 +#define HWIO_REG_645603_IN in_dword_masked(\ + HWIO_REG_645603_ADDR, HWIO_REG_645603_RMSK) +#define HWIO_REG_645603_INM(m) \ + in_dword_masked(HWIO_REG_645603_ADDR, m) +#define HWIO_REG_645603_OUT(v) out_dword(HWIO_REG_645603_ADDR, v) +#define HWIO_REG_645603_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_645603_ADDR, m, v, HWIO_REG_645603_IN); +#define HWIO_REG_645603_REG_645603_BMSK 0x3 +#define HWIO_REG_645603_REG_645603_SHFT 0 + +#define HWIO_REG_811733_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c520) +#define HWIO_REG_811733_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c520) +#define HWIO_REG_811733_RMSK 0x80ffffff +#define HWIO_REG_811733_SHFT 0 +#define HWIO_REG_811733_IN in_dword_masked(\ + HWIO_REG_811733_ADDR, HWIO_REG_811733_RMSK) +#define HWIO_REG_811733_INM(m) \ + in_dword_masked(HWIO_REG_811733_ADDR, m) +#define HWIO_REG_811733_OUT(v) out_dword(HWIO_REG_811733_ADDR, v) +#define HWIO_REG_811733_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_811733_ADDR, m, v, HWIO_REG_811733_IN); +#define HWIO_REG_811733_PAD_CTRL_ON_BMSK 0x80000000 +#define HWIO_REG_811733_PAD_CTRL_ON_SHFT 0x1f +#define HWIO_REG_811733_CR_PAD_VIDC_BMSK 0xff0000 +#define HWIO_REG_811733_CR_PAD_VIDC_SHFT 0x10 +#define HWIO_REG_811733_CB_PAD_VIDC_BMSK 0xff00 +#define HWIO_REG_811733_CB_PAD_VIDC_SHFT 0x8 +#define HWIO_REG_811733_LUMA_PAD_VIDC_BMSK 0xff +#define HWIO_REG_811733_LUMA_PAD_VIDC_SHFT 0 + +#define HWIO_REG_676866_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c588) +#define HWIO_REG_676866_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c588) +#define HWIO_REG_676866_RMSK 0xffff +#define HWIO_REG_676866_SHFT 0 +#define HWIO_REG_676866_IN in_dword_masked(\ + HWIO_REG_676866_ADDR, HWIO_REG_676866_RMSK) +#define HWIO_REG_676866_INM(m) \ + in_dword_masked(HWIO_REG_676866_ADDR, m) +#define HWIO_REG_676866_OUT(v) \ + out_dword(HWIO_REG_676866_ADDR, v) +#define HWIO_REG_676866_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_676866_ADDR, m, v, HWIO_REG_676866_IN); +#define HWIO_REG_676866_REG_676866_BMSK 0xffff +#define HWIO_REG_676866_REG_676866_SHFT 0 + +#define HWIO_REG_54267_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000c58c) +#define HWIO_REG_54267_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c58c) +#define HWIO_REG_54267_RMSK 0xffff +#define HWIO_REG_54267_SHFT 0 +#define HWIO_REG_54267_IN in_dword_masked(\ + HWIO_REG_54267_ADDR,\ + HWIO_REG_54267_RMSK) +#define HWIO_REG_54267_INM(m) \ + in_dword_masked(HWIO_REG_54267_ADDR, m) +#define HWIO_REG_54267_OUT(v) \ + out_dword(HWIO_REG_54267_ADDR, v) +#define HWIO_REG_54267_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_54267_ADDR, m, v,\ + HWIO_REG_54267_IN); +#define HWIO_REG_54267_REG_54267_BMSK 0xffff +#define HWIO_REG_54267_REG_54267_SHFT 0 + +#define HWIO_REG_559908_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5a0) +#define HWIO_REG_559908_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5a0) +#define HWIO_REG_559908_RMSK 0x33f +#define HWIO_REG_559908_SHFT 0 +#define HWIO_REG_559908_IN in_dword_masked(\ + HWIO_REG_559908_ADDR, HWIO_REG_559908_RMSK) +#define HWIO_REG_559908_INM(m) in_dword_masked(HWIO_REG_559908_ADDR, m) +#define HWIO_REG_559908_OUT(v) out_dword(HWIO_REG_559908_ADDR, v) +#define HWIO_REG_559908_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_559908_ADDR, m, v, HWIO_REG_559908_IN); +#define HWIO_REG_559908_FR_RC_EN_BMSK 0x200 +#define HWIO_REG_559908_FR_RC_EN_SHFT 0x9 +#define HWIO_REG_559908_MB_RC_EN_BMSK 0x100 +#define HWIO_REG_559908_MB_RC_EN_SHFT 0x8 +#define HWIO_REG_559908_FRAME_QP_BMSK 0x3f +#define HWIO_REG_559908_FRAME_QP_SHFT 0 + +#define HWIO_REG_977937_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d0d0) +#define HWIO_REG_977937_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d0d0) +#define HWIO_REG_977937_RMSK 0xff +#define HWIO_REG_977937_SHFT 0 +#define HWIO_REG_977937_IN in_dword_masked(\ + HWIO_REG_977937_ADDR, HWIO_REG_977937_RMSK) +#define HWIO_REG_977937_INM(m) in_dword_masked(HWIO_REG_977937_ADDR, m) +#define HWIO_REG_977937_OUT(v) out_dword(HWIO_REG_977937_ADDR, v) +#define HWIO_REG_977937_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_977937_ADDR, m, v, HWIO_REG_977937_IN); +#define HWIO_REG_977937_FRAME_RATE_BMSK 0xff +#define HWIO_REG_977937_FRAME_RATE_SHFT 0 + +#define HWIO_REG_166135_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5a8) +#define HWIO_REG_166135_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5a8) +#define HWIO_REG_166135_RMSK 0xffffffff +#define HWIO_REG_166135_SHFT 0 +#define HWIO_REG_166135_IN in_dword_masked(\ + HWIO_REG_166135_ADDR, HWIO_REG_166135_RMSK) +#define HWIO_REG_166135_INM(m) in_dword_masked(HWIO_REG_166135_ADDR, m) +#define HWIO_REG_166135_OUT(v) out_dword(HWIO_REG_166135_ADDR, v) +#define HWIO_REG_166135_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_166135_ADDR, m, v, HWIO_REG_166135_IN); +#define HWIO_REG_166135_BIT_RATE_BMSK 0xffffffff +#define HWIO_REG_166135_BIT_RATE_SHFT 0 + +#define HWIO_REG_109072_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5ac) +#define HWIO_REG_109072_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5ac) +#define HWIO_REG_109072_RMSK 0x3fff +#define HWIO_REG_109072_SHFT 0 +#define HWIO_REG_109072_IN in_dword_masked(\ + HWIO_REG_109072_ADDR, HWIO_REG_109072_RMSK) +#define HWIO_REG_109072_INM(m) in_dword_masked(HWIO_REG_109072_ADDR, m) +#define HWIO_REG_109072_OUT(v) out_dword(HWIO_REG_109072_ADDR, v) +#define HWIO_REG_109072_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_109072_ADDR, m, v, HWIO_REG_109072_IN); +#define HWIO_REG_109072_MAX_QP_BMSK 0x3f00 +#define HWIO_REG_109072_MAX_QP_SHFT 0x8 +#define HWIO_REG_109072_MIN_QP_BMSK 0x3f +#define HWIO_REG_109072_MIN_QP_SHFT 0 + +#define HWIO_REG_550322_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5b0) +#define HWIO_REG_550322_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5b0) +#define HWIO_REG_550322_RMSK 0xffff +#define HWIO_REG_550322_SHFT 0 +#define HWIO_REG_550322_IN in_dword_masked(\ + HWIO_REG_550322_ADDR, HWIO_REG_550322_RMSK) +#define HWIO_REG_550322_INM(m) in_dword_masked(HWIO_REG_550322_ADDR, m) +#define HWIO_REG_550322_OUT(v) out_dword(HWIO_REG_550322_ADDR, v) +#define HWIO_REG_550322_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_550322_ADDR, m, v, HWIO_REG_550322_IN); +#define HWIO_REG_550322_REACT_PARA_BMSK 0xffff +#define HWIO_REG_550322_REACT_PARA_SHFT 0 + +#define HWIO_REG_949086_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5b4) +#define HWIO_REG_949086_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5b4) +#define HWIO_REG_949086_RMSK 0xf +#define HWIO_REG_949086_SHFT 0 +#define HWIO_REG_949086_IN in_dword_masked(\ + HWIO_REG_949086_ADDR, HWIO_REG_949086_RMSK) +#define HWIO_REG_949086_INM(m) in_dword_masked(HWIO_REG_949086_ADDR, m) +#define HWIO_REG_949086_OUT(v) out_dword(HWIO_REG_949086_ADDR, v) +#define HWIO_REG_949086_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_949086_ADDR, m, v, HWIO_REG_949086_IN); +#define HWIO_REG_949086_DARK_DISABLE_BMSK 0x8 +#define HWIO_REG_949086_DARK_DISABLE_SHFT 0x3 +#define HWIO_REG_949086_SMOOTH_DISABLE_BMSK 0x4 +#define HWIO_REG_949086_SMOOTH_DISABLE_SHFT 0x2 +#define HWIO_REG_949086_STATIC_DISABLE_BMSK 0x2 +#define HWIO_REG_949086_STATIC_DISABLE_SHFT 0x1 +#define HWIO_REG_949086_ACT_DISABLE_BMSK 0x1 +#define HWIO_REG_949086_ACT_DISABLE_SHFT 0 + +#define HWIO_REG_447796_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d004) +#define HWIO_REG_447796_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d004) +#define HWIO_REG_447796_RMSK 0x1 +#define HWIO_REG_447796_SHFT 0 +#define HWIO_REG_447796_IN in_dword_masked(\ + HWIO_REG_447796_ADDR, HWIO_REG_447796_RMSK) +#define HWIO_REG_447796_INM(m) \ + in_dword_masked(HWIO_REG_447796_ADDR, m) +#define HWIO_REG_447796_OUT(v) \ + out_dword(HWIO_REG_447796_ADDR, v) +#define HWIO_REG_447796_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_447796_ADDR, m, v, HWIO_REG_447796_IN); +#define HWIO_REG_447796_REG_447796_BMSK 0x1 +#define HWIO_REG_447796_REG_447796_SHFT 0 + +#define HWIO_REG_744348_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d010) +#define HWIO_REG_744348_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d010) +#define HWIO_REG_744348_RMSK 0x7f +#define HWIO_REG_744348_SHFT 0 +#define HWIO_REG_744348_IN in_dword_masked(\ + HWIO_REG_744348_ADDR, HWIO_REG_744348_RMSK) +#define HWIO_REG_744348_INM(m) \ + in_dword_masked(HWIO_REG_744348_ADDR, m) +#define HWIO_REG_744348_OUT(v) \ + out_dword(HWIO_REG_744348_ADDR, v) +#define HWIO_REG_744348_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_744348_ADDR, m, v, HWIO_REG_744348_IN); +#define HWIO_REG_744348_P_BMSK 0x60 +#define HWIO_REG_744348_P_SHFT 0x5 +#define HWIO_REG_744348_BMSK 0x1f +#define HWIO_REG_744348_SHFT 0 + +#define HWIO_REG_672163_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d034) +#define HWIO_REG_672163_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d034) +#define HWIO_REG_672163_RMSK 0x1 +#define HWIO_REG_672163_SHFT 0 +#define HWIO_REG_672163_IN in_dword_masked(\ + HWIO_REG_672163_ADDR, HWIO_REG_672163_RMSK) +#define HWIO_REG_672163_INM(m) \ + in_dword_masked(HWIO_REG_672163_ADDR, m) +#define HWIO_REG_672163_OUT(v) \ + out_dword(HWIO_REG_672163_ADDR, v) +#define HWIO_REG_672163_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_672163_ADDR, m, v,\ + HWIO_REG_672163_IN); +#define HWIO_REG_672163_ENC_TRANS_8X8_FLAG_BMSK 0x1 +#define HWIO_REG_672163_ENC_TRANS_8X8_FLAG_SHFT 0 + +#define HWIO_REG_780908_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d140) +#define HWIO_REG_780908_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d140) +#define HWIO_REG_780908_RMSK 0x1 +#define HWIO_REG_780908_SHFT 0 +#define HWIO_REG_780908_IN in_dword_masked(\ + HWIO_REG_780908_ADDR, HWIO_REG_780908_RMSK) +#define HWIO_REG_780908_INM(m) in_dword_masked(\ + HWIO_REG_780908_ADDR, m) +#define HWIO_REG_780908_OUT(v) out_dword(\ + HWIO_REG_780908_ADDR, v) +#define HWIO_REG_780908_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_780908_ADDR, m, v,\ + HWIO_REG_780908_IN) +#define HWIO_REG_780908_REG_780908_BMSK 0x1 +#define HWIO_REG_780908_REG_780908_SHFT 0 + +#define HWIO_REG_330132_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000e008) +#define HWIO_REG_330132_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000e008) +#define HWIO_REG_330132_RMSK 0x1 +#define HWIO_REG_330132_SHFT 0 +#define HWIO_REG_330132_IN in_dword_masked(\ + HWIO_REG_330132_ADDR, HWIO_REG_330132_RMSK) +#define HWIO_REG_330132_INM(m) \ + in_dword_masked(HWIO_REG_330132_ADDR, m) +#define HWIO_REG_330132_OUT(v) \ + out_dword(HWIO_REG_330132_ADDR, v) +#define HWIO_REG_330132_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_330132_ADDR, m, v, HWIO_REG_330132_IN); +#define HWIO_REG_330132_MPEG4_QUART_PXL_BMSK 0x1 +#define HWIO_REG_330132_MPEG4_QUART_PXL_SHFT 0 + + +#define VIDC_MGEN2MAXI_REG_BASE (VIDC_BASE + 0x00080000) +#define VIDC_MGEN2MAXI_REG_BASE_PHYS 0x04480000 + +#define HWIO_REG_916352_ADDR (VIDC_MGEN2MAXI_REG_BASE + 00000000) +#define HWIO_REG_916352_PHYS (VIDC_MGEN2MAXI_REG_BASE_PHYS + 00000000) +#define HWIO_REG_916352_RMSK 0xff +#define HWIO_REG_916352_SHFT 0 +#define HWIO_REG_916352_IN in_dword_masked(\ + HWIO_REG_916352_ADDR, HWIO_REG_916352_RMSK) +#define HWIO_REG_916352_INM(m) \ + in_dword_masked(HWIO_REG_916352_ADDR, m) +#define HWIO_REG_916352_VERSION_BMSK 0xff +#define HWIO_REG_916352_VERSION_SHFT 0 + +#define HWIO_REG_5519_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000004) +#define HWIO_REG_5519_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000004) +#define HWIO_REG_5519_RMSK 0x1 +#define HWIO_REG_5519_SHFT 0 +#define HWIO_REG_5519_IN in_dword_masked(\ + HWIO_REG_5519_ADDR, HWIO_REG_5519_RMSK) +#define HWIO_REG_5519_INM(m) \ + in_dword_masked(HWIO_REG_5519_ADDR, m) +#define HWIO_REG_5519_OUT(v) \ + out_dword(HWIO_REG_5519_ADDR, v) +#define HWIO_REG_5519_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_5519_ADDR, m, v, HWIO_REG_5519_IN); +#define HWIO_REG_5519_AXI_AOOORD_BMSK 0x1 +#define HWIO_REG_5519_AXI_AOOORD_SHFT 0 + +#define HWIO_REG_606364_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000008) +#define HWIO_REG_606364_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000008) +#define HWIO_REG_606364_RMSK 0x1 +#define HWIO_REG_606364_SHFT 0 +#define HWIO_REG_606364_IN in_dword_masked(\ + HWIO_REG_606364_ADDR, HWIO_REG_606364_RMSK) +#define HWIO_REG_606364_INM(m) \ + in_dword_masked(HWIO_REG_606364_ADDR, m) +#define HWIO_REG_606364_OUT(v) \ + out_dword(HWIO_REG_606364_ADDR, v) +#define HWIO_REG_606364_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_606364_ADDR, m, v, HWIO_REG_606364_IN); +#define HWIO_REG_606364_AXI_AOOOWR_BMSK 0x1 +#define HWIO_REG_606364_AXI_AOOOWR_SHFT 0 + +#define HWIO_REG_821472_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x0000000c) +#define HWIO_REG_821472_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x0000000c) +#define HWIO_REG_821472_RMSK 0xf +#define HWIO_REG_821472_SHFT 0 +#define HWIO_REG_821472_IN in_dword_masked(\ + HWIO_REG_821472_ADDR, HWIO_REG_821472_RMSK) +#define HWIO_REG_821472_INM(m) \ + in_dword_masked(HWIO_REG_821472_ADDR, m) +#define HWIO_REG_821472_OUT(v) \ + out_dword(HWIO_REG_821472_ADDR, v) +#define HWIO_REG_821472_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_821472_ADDR, m, v, HWIO_REG_821472_IN); +#define HWIO_REG_821472_AXI_TYPE_BMSK 0xf +#define HWIO_REG_821472_AXI_TYPE_SHFT 0 + +#define HWIO_REG_988424_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x00000010) +#define HWIO_REG_988424_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000010) +#define HWIO_REG_988424_RMSK 0x3 +#define HWIO_REG_988424_SHFT 0 +#define HWIO_REG_988424_IN in_dword_masked(\ + HWIO_REG_988424_ADDR,\ + HWIO_REG_988424_RMSK) +#define HWIO_REG_988424_INM(m) \ + in_dword_masked(HWIO_REG_988424_ADDR, m) +#define HWIO_REG_988424_OUT(v) \ + out_dword(HWIO_REG_988424_ADDR, v) +#define HWIO_REG_988424_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_988424_ADDR, m, v,\ + HWIO_REG_988424_IN); +#define HWIO_REG_988424_AXI_AREQPRIORITY_BMSK 0x3 +#define HWIO_REG_988424_AXI_AREQPRIORITY_SHFT 0 + +#define HWIO_REG_471159_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000014) +#define HWIO_REG_471159_PHYS (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000014) +#define HWIO_REG_471159_RMSK 0x801f1111 +#define HWIO_REG_471159_SHFT 0 +#define HWIO_REG_471159_IN in_dword_masked(\ + HWIO_REG_471159_ADDR, HWIO_REG_471159_RMSK) +#define HWIO_REG_471159_INM(m) \ + in_dword_masked(HWIO_REG_471159_ADDR, m) +#define HWIO_REG_471159_OUT(v) \ + out_dword(HWIO_REG_471159_ADDR, v) +#define HWIO_REG_471159_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_471159_ADDR, m, v, HWIO_REG_471159_IN); +#define HWIO_REG_471159_AXI_INTR_CLR_BMSK 0x80000000 +#define HWIO_REG_471159_AXI_INTR_CLR_SHFT 0x1f +#define HWIO_REG_471159_AXI_WDTIMEOUT_LOG2_BMSK 0x1e0000 +#define HWIO_REG_471159_AXI_WDTIMEOUT_LOG2_SHFT 0x11 +#define HWIO_REG_471159_AXI_HALT_ON_WDTIMEOUT_BMSK 0x10000 +#define HWIO_REG_471159_AXI_HALT_ON_WDTIMEOUT_SHFT 0x10 +#define HWIO_REG_471159_AXI_HALT_ON_WR_ERR_BMSK 0x1000 +#define HWIO_REG_471159_AXI_HALT_ON_WR_ERR_SHFT 0xc +#define HWIO_REG_471159_AXI_HALT_ON_RD_ERR_BMSK 0x100 +#define HWIO_REG_471159_AXI_HALT_ON_RD_ERR_SHFT 0x8 +#define HWIO_REG_471159_AXI_RESET_BMSK 0x10 +#define HWIO_REG_471159_AXI_RESET_SHFT 0x4 +#define HWIO_REG_471159_AXI_HALT_REQ_BMSK 0x1 +#define HWIO_REG_471159_AXI_HALT_REQ_SHFT 0 + +#define HWIO_REG_437878_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000018) +#define HWIO_REG_437878_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000018) +#define HWIO_REG_437878_RMSK 0x3333 +#define HWIO_REG_437878_SHFT 0 +#define HWIO_REG_437878_IN in_dword_masked(\ + HWIO_REG_437878_ADDR, HWIO_REG_437878_RMSK) +#define HWIO_REG_437878_INM(m) \ + in_dword_masked(HWIO_REG_437878_ADDR, m) +#define HWIO_REG_437878_AXI_WDTIMEOUT_INTR_BMSK 0x3000 +#define HWIO_REG_437878_AXI_WDTIMEOUT_INTR_SHFT 0xc +#define HWIO_REG_437878_AXI_ERR_INTR_BMSK 0x300 +#define HWIO_REG_437878_AXI_ERR_INTR_SHFT 0x8 +#define HWIO_REG_437878_AXI_IDLE_BMSK 0x30 +#define HWIO_REG_437878_AXI_IDLE_SHFT 0x4 +#define HWIO_REG_437878_AXI_HALT_ACK_BMSK 0x3 +#define HWIO_REG_437878_AXI_HALT_ACK_SHFT 0 + +#define HWIO_REG_736158_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x0000001c) +#define HWIO_REG_736158_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x0000001c) +#define HWIO_REG_736158_RMSK 0x10fff +#define HWIO_REG_736158_SHFT 0 +#define HWIO_REG_736158_IN in_dword_masked(\ + HWIO_REG_736158_ADDR,\ + HWIO_REG_736158_RMSK) +#define HWIO_REG_736158_INM(m) \ + in_dword_masked(HWIO_REG_736158_ADDR, m) +#define HWIO_REG_736158_AXI_WDTIMEOUT_BMSK 0x10000 +#define HWIO_REG_736158_AXI_WDTIMEOUT_SHFT 0x10 +#define HWIO_REG_736158_AXI_ERR_BMSK 0x800 +#define HWIO_REG_736158_AXI_ERR_SHFT 0xb +#define HWIO_REG_736158_AXI_ERR_TYPE_BMSK 0x400 +#define HWIO_REG_736158_AXI_ERR_TYPE_SHFT 0xa +#define HWIO_REG_736158_AXI_RESP_BMSK 0x300 +#define HWIO_REG_736158_AXI_RESP_SHFT 0x8 +#define HWIO_REG_736158_AXI_MID_BMSK 0xf0 +#define HWIO_REG_736158_AXI_MID_SHFT 0x4 +#define HWIO_REG_736158_AXI_TID_BMSK 0xf +#define HWIO_REG_736158_AXI_TID_SHFT 0 + +#define HWIO_REG_598415_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x00000020) +#define HWIO_REG_598415_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000020) +#define HWIO_REG_598415_RMSK 0x10fff +#define HWIO_REG_598415_SHFT 0 +#define HWIO_REG_598415_IN in_dword_masked(\ + HWIO_REG_598415_ADDR,\ + HWIO_REG_598415_RMSK) +#define HWIO_REG_598415_INM(m) \ + in_dword_masked(HWIO_REG_598415_ADDR, m) +#define HWIO_REG_598415_AXI_WDTIMEOUT_BMSK 0x10000 +#define HWIO_REG_598415_AXI_WDTIMEOUT_SHFT 0x10 +#define HWIO_REG_598415_AXI_ERR_BMSK 0x800 +#define HWIO_REG_598415_AXI_ERR_SHFT 0xb +#define HWIO_REG_598415_AXI_ERR_TYPE_BMSK 0x400 +#define HWIO_REG_598415_AXI_ERR_TYPE_SHFT 0xa +#define HWIO_REG_598415_AXI_RESP_BMSK 0x300 +#define HWIO_REG_598415_AXI_RESP_SHFT 0x8 +#define HWIO_REG_598415_AXI_MID_BMSK 0xf0 +#define HWIO_REG_598415_AXI_MID_SHFT 0x4 +#define HWIO_REG_598415_AXI_TID_BMSK 0xf +#define HWIO_REG_598415_AXI_TID_SHFT 0 + +#define HWIO_REG_439061_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000024) +#define HWIO_REG_439061_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000024) +#define HWIO_REG_439061_RMSK 0x11111ff +#define HWIO_REG_439061_SHFT 0 +#define HWIO_REG_439061_IN in_dword_masked(\ + HWIO_REG_439061_ADDR, HWIO_REG_439061_RMSK) +#define HWIO_REG_439061_INM(m) \ + in_dword_masked(HWIO_REG_439061_ADDR, m) +#define HWIO_REG_439061_OUT(v) \ + out_dword(HWIO_REG_439061_ADDR, v) +#define HWIO_REG_439061_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_439061_ADDR, m, v, HWIO_REG_439061_IN); +#define HWIO_REG_439061_AXI_RD_LAT_REP_EN_BMSK 0x1000000 +#define HWIO_REG_439061_AXI_RD_LAT_REP_EN_SHFT 0x18 +#define HWIO_REG_439061_AXI_LSFR_EN_BMSK 0x100000 +#define HWIO_REG_439061_AXI_LSFR_EN_SHFT 0x14 +#define HWIO_REG_439061_AXI_MISR_RES_BMSK 0x10000 +#define HWIO_REG_439061_AXI_MISR_RES_SHFT 0x10 +#define HWIO_REG_439061_AXI_MISR_EN_BMSK 0x1000 +#define HWIO_REG_439061_AXI_MISR_EN_SHFT 0xc +#define HWIO_REG_439061_AXI_MISR_WD_BMSK 0x100 +#define HWIO_REG_439061_AXI_MISR_WD_SHFT 0x8 +#define HWIO_REG_439061_AXI_CTR_EN_BMSK 0x80 +#define HWIO_REG_439061_AXI_CTR_EN_SHFT 0x7 +#define HWIO_REG_439061_AXI_CTR_RES_BMSK 0x40 +#define HWIO_REG_439061_AXI_CTR_RES_SHFT 0x6 +#define HWIO_REG_439061_AXI_TEST_ARB_SEL_BMSK 0x30 +#define HWIO_REG_439061_AXI_TEST_ARB_SEL_SHFT 0x4 +#define HWIO_REG_439061_AXI_TEST_OUT_SEL_BMSK 0xf +#define HWIO_REG_439061_AXI_TEST_OUT_SEL_SHFT 0 + +#define HWIO_REG_573121_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x00000028) +#define HWIO_REG_573121_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000028) +#define HWIO_REG_573121_RMSK 0xffffffff +#define HWIO_REG_573121_SHFT 0 +#define HWIO_REG_573121_IN in_dword_masked(\ + HWIO_REG_573121_ADDR,\ + HWIO_REG_573121_RMSK) +#define HWIO_REG_573121_INM(m) \ + in_dword_masked(HWIO_REG_573121_ADDR, m) +#define HWIO_REG_573121_AXI_TEST_OUT_BMSK 0xffffffff +#define HWIO_REG_573121_AXI_TEST_OUT_SHFT 0 + +#define HWIO_REG_806413_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x0000002c) +#define HWIO_REG_806413_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x0000002c) +#define HWIO_REG_806413_RMSK 0xffffffff +#define HWIO_REG_806413_SHFT 0 +#define HWIO_REG_806413_IN in_dword_masked(\ + HWIO_REG_806413_ADDR,\ + HWIO_REG_806413_RMSK) +#define HWIO_REG_806413_INM(m) \ + in_dword_masked(HWIO_REG_806413_ADDR, m) +#define HWIO_REG_806413_AXI_TEST_OUT_BMSK 0xffffffff +#define HWIO_REG_806413_AXI_TEST_OUT_SHFT 0 + +#define HWIO_REG_804110_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000030) +#define HWIO_REG_804110_PHYS (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000030) +#define HWIO_REG_804110_RMSK 0xc00fffff +#define HWIO_REG_804110_SHFT 0 +#define HWIO_REG_804110_IN in_dword_masked(\ + HWIO_REG_804110_ADDR, HWIO_REG_804110_RMSK) +#define HWIO_REG_804110_INM(m) \ + in_dword_masked(HWIO_REG_804110_ADDR, m) +#define HWIO_REG_804110_OUT(v) out_dword(HWIO_REG_804110_ADDR, v) +#define HWIO_REG_804110_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_804110_ADDR, m, v, HWIO_REG_804110_IN); +#define HWIO_REG_804110_ENABLE_BMSK 0x80000000 +#define HWIO_REG_804110_ENABLE_SHFT 0x1f +#define HWIO_REG_804110_CONST_VIDC_BMSK 0x40000000 +#define HWIO_REG_804110_CONST_VIDC_SHFT 0x1e +#define HWIO_REG_804110_VIDCV_1080P_VERSION_BMSK 0xff000 +#define HWIO_REG_804110_VIDCV_1080P_VERSION_SHFT 0xc +#define HWIO_REG_804110_MGEN2MAXI_DATA_SEL_BMSK 0xf00 +#define HWIO_REG_804110_MGEN2MAXI_DATA_SEL_SHFT 0x8 +#define HWIO_REG_804110_MGEN2MAXI_XIN_SEL_BMSK 0x80 +#define HWIO_REG_804110_MGEN2MAXI_XIN_SEL_SHFT 0x7 +#define HWIO_REG_804110_MGEN2MAXI_ARB_SEL_BMSK 0x40 +#define HWIO_REG_804110_MGEN2MAXI_ARB_SEL_SHFT 0x6 +#define HWIO_REG_804110_MGEN2MAXI_TESTBUS_SEL_BMSK 0x30 +#define HWIO_REG_804110_MGEN2MAXI_TESTBUS_SEL_SHFT 0x4 +#define HWIO_REG_804110_AHB2AHB_TESTBUS_SEL_BMSK 0x8 +#define HWIO_REG_804110_AHB2AHB_TESTBUS_SEL_SHFT 0x3 +#define HWIO_REG_804110_MGEN2MAXI_AXI_SEL_BMSK 0x4 +#define HWIO_REG_804110_MGEN2MAXI_AXI_SEL_SHFT 0x2 +#define HWIO_REG_804110_SELECT_BMSK 0x3 +#define HWIO_REG_804110_SELECT_SHFT 0 + +#define HWIO_REG_616440_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x00000034) +#define HWIO_REG_616440_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000034) +#define HWIO_REG_616440_RMSK 0xffff +#define HWIO_REG_616440_SHFT 0 +#define HWIO_REG_616440_IN in_dword_masked(\ + HWIO_REG_616440_ADDR,\ + HWIO_REG_616440_RMSK) +#define HWIO_REG_616440_INM(m) \ + in_dword_masked(HWIO_REG_616440_ADDR, m) +#define HWIO_REG_616440_OUT(v) \ + out_dword(HWIO_REG_616440_ADDR, v) +#define HWIO_REG_616440_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_616440_ADDR, m, v,\ + HWIO_REG_616440_IN); +#define HWIO_REG_616440_XBAR_IN_RD_LIM_BMSK 0xff00 +#define HWIO_REG_616440_XBAR_IN_RD_LIM_SHFT 0x8 +#define HWIO_REG_616440_XBAR_IN_WR_LIM_BMSK 0xff +#define HWIO_REG_616440_XBAR_IN_WR_LIM_SHFT 0 + +#define HWIO_REG_527219_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x00000038) +#define HWIO_REG_527219_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000038) +#define HWIO_REG_527219_RMSK 0xffff +#define HWIO_REG_527219_SHFT 0 +#define HWIO_REG_527219_IN in_dword_masked(\ + HWIO_REG_527219_ADDR,\ + HWIO_REG_527219_RMSK) +#define HWIO_REG_527219_INM(m) \ + in_dword_masked(HWIO_REG_527219_ADDR, m) +#define HWIO_REG_527219_OUT(v) \ + out_dword(HWIO_REG_527219_ADDR, v) +#define HWIO_REG_527219_OUTM(m, v) \out_dword_masked_ns(\ + HWIO_REG_527219_ADDR, m, v,\ + HWIO_REG_527219_IN); +#define HWIO_REG_527219_XBAR_OUT_RD_LIM_BMSK 0xff00 +#define HWIO_REG_527219_XBAR_OUT_RD_LIM_SHFT 0x8 +#define HWIO_REG_527219_XBAR_OUT_WR_LIM_BMSK 0xff +#define HWIO_REG_527219_XBAR_OUT_WR_LIM_SHFT 0 + +#define HWIO_REG_922106_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x0000003c) +#define HWIO_REG_922106_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x0000003c) +#define HWIO_REG_922106_RMSK 0xffff +#define HWIO_REG_922106_SHFT 0 +#define HWIO_REG_922106_IN in_dword_masked(\ + HWIO_REG_922106_ADDR,\ + HWIO_REG_922106_RMSK) +#define HWIO_REG_922106_INM(m) \ + in_dword_masked(HWIO_REG_922106_ADDR, m) +#define HWIO_REG_922106_OUT(v) \ + out_dword(HWIO_REG_922106_ADDR, v) +#define HWIO_REG_922106_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_922106_ADDR, m, v,\ + HWIO_REG_922106_IN); +#define HWIO_REG_922106_XBAR_OUT_MAX_RD_BURST_BMSK 0xff00 +#define HWIO_REG_922106_XBAR_OUT_MAX_RD_BURST_SHFT 0x8 +#define HWIO_REG_922106_XBAR_OUT_MAX_WR_BURST_BMSK 0xff +#define HWIO_REG_922106_XBAR_OUT_MAX_WR_BURST_SHFT 0 + +#define VIDC_ENHANCE_REG_BASE (VIDC_BASE + 0x000c0000) +#define VIDC_ENHANCE_REG_BASE_PHYS 0x044c0000 + +#define HWIO_REG_261029_ADDR (VIDC_ENHANCE_REG_BASE + 00000000) +#define HWIO_REG_261029_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 00000000) +#define HWIO_REG_261029_RMSK 0x10f +#define HWIO_REG_261029_SHFT 0 +#define HWIO_REG_261029_IN in_dword_masked(\ + HWIO_REG_261029_ADDR, HWIO_REG_261029_RMSK) +#define HWIO_REG_261029_INM(m) \ + in_dword_masked(HWIO_REG_261029_ADDR, m) +#define HWIO_REG_261029_OUT(v) \ + out_dword(HWIO_REG_261029_ADDR, v) +#define HWIO_REG_261029_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_261029_ADDR, m, v, HWIO_REG_261029_IN); +#define HWIO_REG_261029_AUTO_INC_EN_BMSK 0x100 +#define HWIO_REG_261029_AUTO_INC_EN_SHFT 0x8 +#define HWIO_REG_261029_DMI_RAM_SEL_BMSK 0xf +#define HWIO_REG_261029_DMI_RAM_SEL_SHFT 0 + +#define HWIO_REG_576200_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000004) +#define HWIO_REG_576200_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000004) +#define HWIO_REG_576200_RMSK 0x7ff +#define HWIO_REG_576200_SHFT 0 +#define HWIO_REG_576200_IN in_dword_masked(\ + HWIO_REG_576200_ADDR, HWIO_REG_576200_RMSK) +#define HWIO_REG_576200_INM(m) \ + in_dword_masked(HWIO_REG_576200_ADDR, m) +#define HWIO_REG_576200_OUT(v) \ + out_dword(HWIO_REG_576200_ADDR, v) +#define HWIO_REG_576200_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_576200_ADDR, m, v, HWIO_REG_576200_IN); +#define HWIO_REG_576200_DMI_ADDR_BMSK 0x7ff +#define HWIO_REG_576200_DMI_ADDR_SHFT 0 + +#define HWIO_REG_917583_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000008) +#define HWIO_REG_917583_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000008) +#define HWIO_REG_917583_RMSK 0xffffffff +#define HWIO_REG_917583_SHFT 0 +#define HWIO_REG_917583_IN in_dword_masked(\ + HWIO_REG_917583_ADDR, HWIO_REG_917583_RMSK) +#define HWIO_REG_917583_INM(m) \ + in_dword_masked(HWIO_REG_917583_ADDR, m) +#define HWIO_REG_917583_OUT(v) \ + out_dword(HWIO_REG_917583_ADDR, v) +#define HWIO_REG_917583_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_917583_ADDR, m, v, HWIO_REG_917583_IN); +#define HWIO_REG_917583_DMI_DATA_HI_BMSK 0xffffffff +#define HWIO_REG_917583_DMI_DATA_HI_SHFT 0 + +#define HWIO_REG_556274_ADDR (VIDC_ENHANCE_REG_BASE + 0x0000000c) +#define HWIO_REG_556274_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 0x0000000c) +#define HWIO_REG_556274_RMSK 0xffffffff +#define HWIO_REG_556274_SHFT 0 +#define HWIO_REG_556274_IN in_dword_masked(\ + HWIO_REG_556274_ADDR, HWIO_REG_556274_RMSK) +#define HWIO_REG_556274_INM(m) \ + in_dword_masked(HWIO_REG_556274_ADDR, m) +#define HWIO_REG_556274_OUT(v) \ + out_dword(HWIO_REG_556274_ADDR, v) +#define HWIO_REG_556274_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_556274_ADDR, m, v, HWIO_REG_556274_IN); +#define HWIO_REG_556274_DMI_DATA_LO_BMSK 0xffffffff +#define HWIO_REG_556274_DMI_DATA_LO_SHFT 0 + +#define HWIO_REG_39703_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000010) +#define HWIO_REG_39703_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000010) +#define HWIO_REG_39703_RMSK 0x1f +#define HWIO_REG_39703_SHFT 0 +#define HWIO_REG_39703_IN in_dword_masked(\ + HWIO_REG_39703_ADDR, HWIO_REG_39703_RMSK) +#define HWIO_REG_39703_INM(m) \ + in_dword_masked(HWIO_REG_39703_ADDR, m) +#define HWIO_REG_39703_OUT(v) \ + out_dword(HWIO_REG_39703_ADDR, v) +#define HWIO_REG_39703_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_39703_ADDR, m, v, HWIO_REG_39703_IN); +#define HWIO_REG_39703_PIX_CACHE_TB_SEL_BMSK 0x1f +#define HWIO_REG_39703_PIX_CACHE_TB_SEL_SHFT 0 + +#define HWIO_REG_169013_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000014) +#define HWIO_REG_169013_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000014) +#define HWIO_REG_169013_RMSK 0x3 +#define HWIO_REG_169013_SHFT 0 +#define HWIO_REG_169013_IN in_dword_masked(\ + HWIO_REG_169013_ADDR, HWIO_REG_169013_RMSK) +#define HWIO_REG_169013_INM(m) \ + in_dword_masked(HWIO_REG_169013_ADDR, m) +#define HWIO_REG_169013_OUT(v) \ + out_dword(HWIO_REG_169013_ADDR, v) +#define HWIO_REG_169013_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_169013_ADDR, m, v, HWIO_REG_169013_IN); +#define HWIO_REG_169013_PIX_CACHE_SW_RESET_BMSK 0x2 +#define HWIO_REG_169013_PIX_CACHE_SW_RESET_SHFT 0x1 +#define HWIO_REG_169013_CRIF_RESET_BMSK 0x1 +#define HWIO_REG_169013_CRIF_RESET_SHFT 0 + +#define HWIO_REG_22756_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000018) +#define HWIO_REG_22756_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000018) +#define HWIO_REG_22756_RMSK 0x133f +#define HWIO_REG_22756_SHFT 0 +#define HWIO_REG_22756_IN in_dword_masked(\ + HWIO_REG_22756_ADDR, HWIO_REG_22756_RMSK) +#define HWIO_REG_22756_INM(m) \ + in_dword_masked(HWIO_REG_22756_ADDR, m) +#define HWIO_REG_22756_OUT(v) \ + out_dword(HWIO_REG_22756_ADDR, v) +#define HWIO_REG_22756_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_22756_ADDR, m, v, HWIO_REG_22756_IN); +#define HWIO_REG_22756_CACHE_HALT_BMSK 0x1000 +#define HWIO_REG_22756_CACHE_HALT_SHFT 0xc +#define HWIO_REG_22756_PAGE_SIZE_BMSK 0x300 +#define HWIO_REG_22756_PAGE_SIZE_SHFT 0x8 +#define HWIO_REG_22756_STATISTICS_OFF_BMSK 0x20 +#define HWIO_REG_22756_STATISTICS_OFF_SHFT 0x5 +#define HWIO_REG_22756_CACHE_PORT_SELECT_BMSK 0x10 +#define HWIO_REG_22756_CACHE_PORT_SELECT_SHFT 0x4 +#define HWIO_REG_22756_PREFETCH_EN_BMSK 0x8 +#define HWIO_REG_22756_PREFETCH_EN_SHFT 0x3 +#define HWIO_REG_22756_SS_TILE_FORMAT_BMSK 0x4 +#define HWIO_REG_22756_SS_TILE_FORMAT_SHFT 0x2 +#define HWIO_REG_22756_CACHE_EN_BMSK 0x2 +#define HWIO_REG_22756_CACHE_EN_SHFT 0x1 +#define HWIO_REG_22756_CACHE_TAG_CLEAR_BMSK 0x1 +#define HWIO_REG_22756_CACHE_TAG_CLEAR_SHFT 0 + +#define HWIO_REG_951731_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x0000001c) +#define HWIO_REG_951731_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x0000001c) +#define HWIO_REG_951731_RMSK 0x7ff07ff +#define HWIO_REG_951731_SHFT 0 +#define HWIO_REG_951731_IN in_dword_masked(\ + HWIO_REG_951731_ADDR,\ + HWIO_REG_951731_RMSK) +#define HWIO_REG_951731_INM(m) \ + in_dword_masked(HWIO_REG_951731_ADDR, m) +#define HWIO_REG_951731_OUT(v) \ + out_dword(HWIO_REG_951731_ADDR, v) +#define HWIO_REG_951731_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_951731_ADDR, m, v,\ + HWIO_REG_951731_IN); +#define HWIO_REG_951731_FRAME_HEIGHT_BMSK 0x7ff0000 +#define HWIO_REG_951731_FRAME_HEIGHT_SHFT 0x10 +#define HWIO_REG_951731_FRAME_WIDTH_BMSK 0x7ff +#define HWIO_REG_951731_FRAME_WIDTH_SHFT 0 + +#define HWIO_REG_905239_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x00000020) +#define HWIO_REG_905239_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000020) +#define HWIO_REG_905239_RMSK 0x3ffff +#define HWIO_REG_905239_SHFT 0 +#define HWIO_REG_905239_IN in_dword_masked(\ + HWIO_REG_905239_ADDR,\ + HWIO_REG_905239_RMSK) +#define HWIO_REG_905239_INM(m) \ + in_dword_masked(HWIO_REG_905239_ADDR, m) +#define HWIO_REG_905239_OUT(v) \ + out_dword(HWIO_REG_905239_ADDR, v) +#define HWIO_REG_905239_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_905239_ADDR, m, v,\ + HWIO_REG_905239_IN); +#define HWIO_REG_905239_LINEAR_LUMA_BMSK 0x3ffff +#define HWIO_REG_905239_LINEAR_LUMA_SHFT 0 +#define HWIO_REG_905239_TILE_LUMA_BMSK 0xff00 +#define HWIO_REG_905239_TILE_LUMA_SHFT 0x8 +#define HWIO_REG_905239_TILE_CHROMA_BMSK 0xff +#define HWIO_REG_905239_TILE_CHROMA_SHFT 0 + +#define HWIO_REG_804925_ADDR(n) \ + (VIDC_ENHANCE_REG_BASE + 0x00000024 + 4 * (n)) +#define HWIO_REG_804925_PHYS(n) \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000024 + 4 * (n)) +#define HWIO_REG_804925_RMSK 0xfffffff8 +#define HWIO_REG_804925_SHFT 0 +#define HWIO_REG_804925_MAXn 0x12 +#define HWIO_REG_804925_INI(n) \ + in_dword(HWIO_REG_804925_ADDR(n)) +#define HWIO_REG_804925_INMI(n, mask) \ + in_dword_masked(HWIO_REG_804925_ADDR(n), mask) +#define HWIO_REG_804925_OUTI(n, val) \ + out_dword(HWIO_REG_804925_ADDR(n), val) +#define HWIO_REG_804925_OUTMI(n, mask, val) \ + out_dword_masked_ns(HWIO_REG_804925_ADDR(n),\ + mask, val, HWIO_REG_804925_INI(n)); +#define HWIO_REG_804925_ADDR_BMSK 0xfffffff8 +#define HWIO_REG_804925_ADDR_SHFT 0x3 + +#define HWIO_REG_41909_ADDR(n) \ + (VIDC_ENHANCE_REG_BASE + 0x00000070 + 4 * (n)) +#define HWIO_REG_41909_PHYS(n) \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000070 + 4 * (n)) +#define HWIO_REG_41909_RMSK 0xfffffff8 +#define HWIO_REG_41909_SHFT 0 +#define HWIO_REG_41909_MAXn 0x12 +#define HWIO_REG_41909_INI(n) \ + in_dword(HWIO_REG_41909_ADDR(n)) +#define HWIO_REG_41909_INMI(n, mask) \ + in_dword_masked(HWIO_REG_41909_ADDR(n), mask) +#define HWIO_REG_41909_OUTI(n, val) \ + out_dword(HWIO_REG_41909_ADDR(n), val) +#define HWIO_REG_41909_OUTMI(n, mask, val) \ + out_dword_masked_ns(HWIO_REG_41909_ADDR(n),\ + mask, val, HWIO_REG_41909_INI(n)); +#define HWIO_REG_41909_ADDR_BMSK 0xfffffff8 +#define HWIO_REG_41909_ADDR_SHFT 0x3 + +#define HWIO_REG_919904_ADDR (VIDC_ENHANCE_REG_BASE + 0x000000bc) +#define HWIO_REG_919904_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000bc) +#define HWIO_REG_919904_RMSK 0x1 +#define HWIO_REG_919904_SHFT 0 +#define HWIO_REG_919904_IN in_dword_masked(\ + HWIO_REG_919904_ADDR,\ + HWIO_REG_919904_RMSK) +#define HWIO_REG_919904_INM(m) \ + in_dword_masked(HWIO_REG_919904_ADDR, m) +#define HWIO_REG_919904_IDLE_BMSK 0x1 +#define HWIO_REG_919904_IDLE_SHFT 0 + +#define HWIO_REG_278310_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000c0) +#define HWIO_REG_278310_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000c0) +#define HWIO_REG_278310_RMSK 0xffffffff +#define HWIO_REG_278310_SHFT 0 +#define HWIO_REG_278310_IN in_dword_masked(\ + HWIO_REG_278310_ADDR,\ + HWIO_REG_278310_RMSK) +#define HWIO_REG_278310_INM(m) \ + in_dword_masked(HWIO_REG_278310_ADDR, m) +#define HWIO_REG_278310_MISS_COUNT_BMSK 0xffffffff +#define HWIO_REG_278310_MISS_COUNT_SHFT 0 + +#define HWIO_REG_421222_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000c4) +#define HWIO_REG_421222_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000c4) +#define HWIO_REG_421222_RMSK 0xffffffff +#define HWIO_REG_421222_SHFT 0 +#define HWIO_REG_421222_IN in_dword_masked(\ + HWIO_REG_421222_ADDR,\ + HWIO_REG_421222_RMSK) +#define HWIO_REG_421222_INM(m) \ + in_dword_masked(HWIO_REG_421222_ADDR, m) +#define HWIO_REG_421222_HIT_COUNT_BMSK 0xffffffff +#define HWIO_REG_421222_HIT_COUNT_SHFT 0 + +#define HWIO_REG_609607_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000c8) +#define HWIO_REG_609607_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000c8) +#define HWIO_REG_609607_RMSK 0xffffffff +#define HWIO_REG_609607_SHFT 0 +#define HWIO_REG_609607_IN in_dword_masked(\ + HWIO_REG_609607_ADDR,\ + HWIO_REG_609607_RMSK) +#define HWIO_REG_609607_INM(m) \ + in_dword_masked(HWIO_REG_609607_ADDR, m) +#define HWIO_REG_609607_AXI_REQUEST_COUNT_BMSK 0xffffffff +#define HWIO_REG_609607_AXI_REQUEST_COUNT_SHFT 0 + +#define HWIO_REG_395232_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000cc) +#define HWIO_REG_395232_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000cc) +#define HWIO_REG_395232_RMSK 0xffffffff +#define HWIO_REG_395232_SHFT 0 +#define HWIO_REG_395232_IN in_dword_masked(\ + HWIO_REG_395232_ADDR,\ + HWIO_REG_395232_RMSK) +#define HWIO_REG_395232_INM(m) \ + in_dword_masked(HWIO_REG_395232_ADDR, m) +#define HWIO_REG_395232_CORE_REQUEST_COUNT_BMSK \ + 0xffffffff +#define HWIO_REG_395232_CORE_REQUEST_COUNT_SHFT 0 + +#define HWIO_REG_450146_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000d0) +#define HWIO_REG_450146_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000d0) +#define HWIO_REG_450146_RMSK 0xffffffff +#define HWIO_REG_450146_SHFT 0 +#define HWIO_REG_450146_IN in_dword_masked(\ + HWIO_REG_450146_ADDR,\ + HWIO_REG_450146_RMSK) +#define HWIO_REG_450146_INM(m) \ + in_dword_masked(HWIO_REG_450146_ADDR, m) +#define HWIO_REG_450146_AXI_BEAT_COUNT_BMSK 0xffffffff +#define HWIO_REG_450146_AXI_BEAT_COUNT_SHFT 0 + +#define HWIO_REG_610651_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000d4) +#define HWIO_REG_610651_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000d4) +#define HWIO_REG_610651_RMSK 0xffffffff +#define HWIO_REG_610651_SHFT 0 +#define HWIO_REG_610651_IN in_dword_masked(\ + HWIO_REG_610651_ADDR,\ + HWIO_REG_610651_RMSK) +#define HWIO_REG_610651_INM(m) \ + in_dword_masked(HWIO_REG_610651_ADDR, m) +#define HWIO_REG_610651_CORE_BEAT_COUNT_BMSK 0xffffffff +#define HWIO_REG_610651_CORE_BEAT_COUNT_SHFT 0 + +#define HWIO_REG_883784_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000d8) +#define HWIO_REG_883784_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000d8) +#define HWIO_REG_883784_RMSK 0xffffffff +#define HWIO_REG_883784_SHFT 0 +#define HWIO_REG_883784_IN in_dword_masked(\ + HWIO_REG_883784_ADDR,\ + HWIO_REG_883784_RMSK) +#define HWIO_REG_883784_INM(m) \ + in_dword_masked(HWIO_REG_883784_ADDR, m) +#define HWIO_REG_883784_OUT(v) \ + out_dword(HWIO_REG_883784_ADDR, v) +#define HWIO_REG_883784_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_883784_ADDR, m, v,\ + HWIO_REG_883784_IN); +#define HWIO_REG_883784_COUNTER_BMSK 0xffffff00 +#define HWIO_REG_883784_COUNTER_SHFT 0x8 +#define HWIO_REG_883784_ID_BMSK 0xf0 +#define HWIO_REG_883784_ID_SHFT 0x4 +#define HWIO_REG_883784_IGNORE_ID_BMSK 0x8 +#define HWIO_REG_883784_IGNORE_ID_SHFT 0x3 +#define HWIO_REG_883784_INPUT_SEL_BMSK 0x6 +#define HWIO_REG_883784_INPUT_SEL_SHFT 0x1 +#define HWIO_REG_883784_MISR_EN_BMSK 0x1 +#define HWIO_REG_883784_MISR_EN_SHFT 0 + +#define HWIO_REG_651391_ADDR(n) \ + (VIDC_ENHANCE_REG_BASE + 0x000000dc + 4 * (n)) +#define HWIO_REG_651391_PHYS(n) \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000dc + 4 * (n)) +#define HWIO_REG_651391_RMSK 0xffffffff +#define HWIO_REG_651391_SHFT 0 +#define HWIO_REG_651391_MAXn 0x1 +#define HWIO_REG_651391_INI(n) \ + in_dword(HWIO_REG_651391_ADDR(n)) +#define HWIO_REG_651391_INMI(n, mask) \ + in_dword_masked(HWIO_REG_651391_ADDR(n), mask) +#define HWIO_REG_651391_OUTI(n, val) \ + out_dword(HWIO_REG_651391_ADDR(n), val) +#define HWIO_REG_651391_SIGNATURE_BMSK 0xffffffff +#define HWIO_REG_651391_SIGNATURE_SHFT 0 + +#endif + diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c new file mode 100644 index 0000000000000000000000000000000000000000..de294fd423e9993ae2667cfca2bb5f30283136b0 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c @@ -0,0 +1,349 @@ +/* Copyright (c) 2010, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "vidc_hwio_reg.h" +#include "vidc_hwio.h" +#include "vidc_pix_cache.h" + + +#define VIDC_1080P_MAX_DEC_DPB 19 +#define VIDC_TILE_MULTIPLY_FACTOR 8192 + +void vidc_pix_cache_sw_reset(void) +{ + u32 sw_reset_value = 0; + + VIDC_HWIO_IN(REG_169013, &sw_reset_value); + sw_reset_value |= HWIO_REG_169013_PIX_CACHE_SW_RESET_BMSK; + VIDC_HWIO_OUT(REG_169013, sw_reset_value); + VIDC_HWIO_IN(REG_169013, &sw_reset_value); + sw_reset_value &= (~HWIO_REG_169013_PIX_CACHE_SW_RESET_BMSK); + VIDC_HWIO_OUT(REG_169013, sw_reset_value); +} + +void vidc_pix_cache_init_luma_chroma_base_addr(u32 dpb, + u32 *pn_dpb_luma_offset, u32 *pn_dpb_chroma_offset) +{ + u32 count, num_dpb_used = dpb; + u32 dpb_reset_value = VIDC_1080P_DEC_DPB_RESET_VALUE; + + if (num_dpb_used > VIDC_1080P_MAX_DEC_DPB) + num_dpb_used = VIDC_1080P_MAX_DEC_DPB; + for (count = 0; count < VIDC_1080P_MAX_DEC_DPB; count++) { + if (count < num_dpb_used) { + if (pn_dpb_luma_offset) { + VIDC_HWIO_OUTI( + REG_804925, + count, pn_dpb_luma_offset[count]); + } else { + VIDC_HWIO_OUTI( + REG_804925, + count, dpb_reset_value); + } + if (pn_dpb_chroma_offset) { + VIDC_HWIO_OUTI( + REG_41909, + count, pn_dpb_chroma_offset[count]); + } else { + VIDC_HWIO_OUTI( + REG_41909, + count, dpb_reset_value); + } + } else { + VIDC_HWIO_OUTI(REG_804925, + count, dpb_reset_value); + VIDC_HWIO_OUTI(REG_41909, + count, dpb_reset_value); + } + } +} + +void vidc_pix_cache_set_frame_range(u32 luma_size, u32 chroma_size) +{ + u32 frame_range; + + frame_range = + (((luma_size / VIDC_TILE_MULTIPLY_FACTOR) & 0xFF) << 8)| + ((chroma_size / VIDC_TILE_MULTIPLY_FACTOR) & 0xFF); + VIDC_HWIO_OUT(REG_905239, frame_range); +} +void vidc_pix_cache_set_frame_size(u32 frame_width, u32 frame_height) +{ + u32 frame_size; + frame_size = (((u32) (frame_height << HWIO_REG_951731_FRAME_HEIGHT_SHFT) & + HWIO_REG_951731_FRAME_HEIGHT_BMSK) | + ((u32) (frame_width << HWIO_REG_951731_FRAME_WIDTH_SHFT) & + HWIO_REG_951731_FRAME_WIDTH_BMSK)); + VIDC_HWIO_OUT(REG_951731, frame_size); +} + +void vidc_pix_cache_init_config( + struct vidc_1080P_pix_cache_config *config) +{ + u32 cfg_reg = 0; + + if (config->cache_enable) + cfg_reg |= HWIO_REG_22756_CACHE_EN_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_CACHE_EN_BMSK); + if (config->port_select == VIDC_1080P_PIX_CACHE_PORT_A) + cfg_reg &= + (~HWIO_REG_22756_CACHE_PORT_SELECT_BMSK); + else + cfg_reg |= HWIO_REG_22756_CACHE_PORT_SELECT_BMSK; + if (!config->statistics_off) + cfg_reg |= HWIO_REG_22756_STATISTICS_OFF_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_STATISTICS_OFF_BMSK); + if (config->prefetch_en) + cfg_reg |= HWIO_REG_22756_PREFETCH_EN_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_PREFETCH_EN_BMSK); + cfg_reg &= (~HWIO_REG_22756_PAGE_SIZE_BMSK); + cfg_reg |= VIDC_SETFIELD(config->page_size, + HWIO_REG_22756_PAGE_SIZE_SHFT, + HWIO_REG_22756_PAGE_SIZE_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_set_prefetch_page_limit(u32 page_size_limit) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + cfg_reg &= (~HWIO_REG_22756_PAGE_SIZE_BMSK); + cfg_reg |= VIDC_SETFIELD(page_size_limit, + HWIO_REG_22756_PAGE_SIZE_SHFT, + HWIO_REG_22756_PAGE_SIZE_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_enable_prefetch(u32 prefetch_enable) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + if (prefetch_enable) + cfg_reg |= HWIO_REG_22756_PREFETCH_EN_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_PREFETCH_EN_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_disable_statistics(u32 statistics_off) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + if (!statistics_off) + cfg_reg |= HWIO_REG_22756_STATISTICS_OFF_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_STATISTICS_OFF_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_set_port( + enum vidc_1080P_pix_cache_port_sel port_select) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + if (port_select == VIDC_1080P_PIX_CACHE_PORT_A) + cfg_reg &= + (~HWIO_REG_22756_CACHE_PORT_SELECT_BMSK); + else + cfg_reg |= HWIO_REG_22756_CACHE_PORT_SELECT_BMSK; + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_enable_cache(u32 cache_enable) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + if (cache_enable) + cfg_reg |= HWIO_REG_22756_CACHE_EN_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_CACHE_EN_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_clear_cache_tags(void) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + cfg_reg |= HWIO_REG_22756_CACHE_TAG_CLEAR_BMSK; + VIDC_HWIO_OUT(REG_22756, cfg_reg); + VIDC_HWIO_IN(REG_22756, &cfg_reg); + cfg_reg &= (~HWIO_REG_22756_CACHE_TAG_CLEAR_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_set_halt(u32 halt_enable) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + if (halt_enable) + cfg_reg |= HWIO_REG_22756_CACHE_HALT_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_CACHE_HALT_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_get_status_idle(u32 *idle_status) +{ + VIDC_HWIO_IN(REG_919904, idle_status); +} + +void vidc_pix_cache_set_ram(u32 ram_select) +{ + u32 dmi_cfg_reg = 0; + + VIDC_HWIO_IN(REG_261029, &dmi_cfg_reg); + dmi_cfg_reg &= (~HWIO_REG_261029_DMI_RAM_SEL_BMSK); + dmi_cfg_reg |= VIDC_SETFIELD(ram_select, + HWIO_REG_261029_AUTO_INC_EN_SHFT, + HWIO_REG_261029_DMI_RAM_SEL_BMSK); + VIDC_HWIO_OUT(REG_261029, dmi_cfg_reg); +} + +void vidc_pix_cache_set_auto_inc_ram_addr(u32 auto_inc_enable) +{ + u32 dmi_cfg_reg = 0; + + VIDC_HWIO_IN(REG_261029, &dmi_cfg_reg); + if (auto_inc_enable) + dmi_cfg_reg |= HWIO_REG_261029_AUTO_INC_EN_BMSK; + else + dmi_cfg_reg &= (~HWIO_REG_261029_AUTO_INC_EN_BMSK); + VIDC_HWIO_OUT(REG_261029, dmi_cfg_reg); +} + + +void vidc_pix_cache_read_ram_data(u32 src_ram_address, + u32 ram_size, u32 *dest_address) +{ + u32 count, dmi_cfg_reg = 0; + + VIDC_HWIO_IN(REG_261029, &dmi_cfg_reg); + VIDC_HWIO_OUT(REG_576200, src_ram_address); + vidc_pix_cache_set_auto_inc_ram_addr(1); + for (count = 0; count < ram_size; count++) { + VIDC_HWIO_IN(REG_556274, dest_address); + dest_address++; + VIDC_HWIO_IN(REG_917583, dest_address); + dest_address++; + } + VIDC_HWIO_OUT(REG_261029, dmi_cfg_reg); +} + +void vidc_pix_cache_write_ram_data(u32 *src_address, + u32 ram_size, u32 dest_ram_address) +{ + u32 count, dmi_cfg_reg = 0; + + VIDC_HWIO_IN(REG_261029, &dmi_cfg_reg); + VIDC_HWIO_OUT(REG_576200, dest_ram_address); + vidc_pix_cache_set_auto_inc_ram_addr(1); + for (count = 0; count < ram_size; count++) { + VIDC_HWIO_OUT(REG_917583, *src_address); + src_address++; + VIDC_HWIO_OUT(REG_556274, *src_address); + src_address++; + } + VIDC_HWIO_OUT(REG_261029, dmi_cfg_reg); +} + +void vidc_pix_cache_get_statistics( + struct vidc_1080P_pix_cache_statistics *statistics) +{ + VIDC_HWIO_IN(REG_278310, + &statistics->access_miss); + VIDC_HWIO_IN(REG_421222, + &statistics->access_hit); + VIDC_HWIO_IN(REG_609607, + &statistics->axi_req); + VIDC_HWIO_IN(REG_395232, + &statistics->core_req); + VIDC_HWIO_IN(REG_450146, + &statistics->axi_bus); + VIDC_HWIO_IN(REG_610651, + &statistics->core_bus); +} + +void vidc_pix_cache_enable_misr(u32 misr_enable) +{ + u32 misr_cfg_reg = 0; + + VIDC_HWIO_IN(REG_883784, &misr_cfg_reg); + if (misr_enable) + misr_cfg_reg |= HWIO_REG_883784_MISR_EN_BMSK; + else + misr_cfg_reg &= + (~HWIO_REG_883784_MISR_EN_BMSK); + VIDC_HWIO_OUT(REG_261029, misr_cfg_reg); +} + +void vidc_pix_cache_set_misr_interface(u32 input_select) +{ + u32 misr_cfg_reg = 0; + + VIDC_HWIO_IN(REG_883784, &misr_cfg_reg); + misr_cfg_reg &= (~HWIO_REG_883784_INPUT_SEL_BMSK); + misr_cfg_reg |= VIDC_SETFIELD(input_select, + HWIO_REG_883784_INPUT_SEL_SHFT, + HWIO_REG_883784_INPUT_SEL_BMSK); + VIDC_HWIO_OUT(REG_261029, misr_cfg_reg); +} + +void vidc_pix_cache_set_misr_id_filtering( + struct vidc_1080P_pix_cache_misr_id_filtering *filter_id) +{ + u32 misr_cfg_reg = 0; + + VIDC_HWIO_IN(REG_883784, &misr_cfg_reg); + if (filter_id->ignore_id) + misr_cfg_reg |= + HWIO_REG_883784_IGNORE_ID_BMSK; + else + misr_cfg_reg &= + (~HWIO_REG_883784_IGNORE_ID_BMSK); + misr_cfg_reg &= (~HWIO_REG_883784_ID_BMSK); + misr_cfg_reg |= VIDC_SETFIELD(filter_id->id, + HWIO_REG_883784_ID_SHFT, + HWIO_REG_883784_ID_BMSK); + VIDC_HWIO_OUT(REG_261029, misr_cfg_reg); +} + +void vidc_pix_cache_set_misr_filter_trans(u32 no_of_trans) +{ + u32 misr_cfg_reg = 0; + + VIDC_HWIO_IN(REG_883784, &misr_cfg_reg); + misr_cfg_reg &= (~HWIO_REG_883784_COUNTER_BMSK); + misr_cfg_reg |= VIDC_SETFIELD(no_of_trans, + HWIO_REG_883784_COUNTER_SHFT, + HWIO_REG_883784_COUNTER_BMSK); + VIDC_HWIO_OUT(REG_261029, misr_cfg_reg); +} + +void vidc_pix_cache_get_misr_signatures( + struct vidc_1080P_pix_cache_misr_signature *signatures) +{ + VIDC_HWIO_INI(REG_651391, 0, + &signatures->signature0); + VIDC_HWIO_INI(REG_651391, 1, + &signatures->signature1); +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h new file mode 100644 index 0000000000000000000000000000000000000000..c70b1131d5d5c770673ce05ddba809ac95a53028 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h @@ -0,0 +1,87 @@ +/* Copyright (c) 2010, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VIDEO_CORE_PIXCACHE_ +#define _VIDEO_CORE_PIXCACHE_ + + +#include "vidc.h" + +#define VIDC_1080P_DEC_DPB_RESET_VALUE 0xFFFFFFF8 + +enum vidc_1080P_pix_cache_port_sel{ + VIDC_1080P_PIX_CACHE_PORT_A = 0, + VIDC_1080P_PIX_CACHE_PORT_B = 1, + VIDC_1080P_PIX_CACHE_PORT_32BIT = 0x7FFFFFFF +}; +enum vidc_1080P_pix_cache_page_size{ + VIDC_1080P_PIX_CACHE_PAGE_SIZE_1K = 0, + VIDC_1080P_PIX_CACHE_PAGE_SIZE_2K = 1, + VIDC_1080P_PIX_CACHE_PAGE_SIZE_4K = 2 +}; +struct vidc_1080P_pix_cache_config{ + u32 cache_enable; + u32 prefetch_en; + enum vidc_1080P_pix_cache_port_sel port_select; + u32 statistics_off; + enum vidc_1080P_pix_cache_page_size page_size; +}; +struct vidc_1080P_pix_cache_statistics{ + u32 access_miss; + u32 access_hit; + u32 axi_req; + u32 core_req; + u32 axi_bus; + u32 core_bus; +}; +struct vidc_1080P_pix_cache_misr_id_filtering{ + u32 ignore_id; + u32 id; +}; +struct vidc_1080P_pix_cache_misr_signature{ + u32 signature0; + u32 signature1; +}; + +void vidc_pix_cache_sw_reset(void); +void vidc_pix_cache_init_luma_chroma_base_addr(u32 dpb, + u32 *pn_dpb_luma_offset, u32 *pn_dpb_chroma_offset); +void vidc_pix_cache_set_frame_range(u32 luma_size, u32 chroma_size); +void vidc_pix_cache_set_frame_size(u32 frame_width, u32 frame_height); +void vidc_pix_cache_init_config( + struct vidc_1080P_pix_cache_config *config); +void vidc_pix_cache_set_prefetch_page_limit(u32 page_size_limit); +void vidc_pix_cache_enable_prefetch(u32 prefetch_enable); +void vidc_pix_cache_disable_statistics(u32 statistics_off); +void vidc_pix_cache_set_port( + enum vidc_1080P_pix_cache_port_sel port_select); +void vidc_pix_cache_enable_cache(u32 cache_enable); +void vidc_pix_cache_clear_cache_tags(void); +void vidc_pix_cache_set_halt(u32 halt_enable); +void vidc_pix_cache_get_status_idle(u32 *idle_status); +void vidc_pix_cache_set_ram(u32 ram_select); +void vidc_pix_cache_set_auto_inc_ram_addr(u32 auto_inc_enable); +void vidc_pix_cache_read_ram_data(u32 src_ram_address, u32 ram_size, + u32 *dest_address); +void vidc_pix_cache_write_ram_data(u32 *src_address, u32 ram_size, + u32 dest_ram_address); +void vidc_pix_cache_get_statistics( + struct vidc_1080P_pix_cache_statistics *statistics); +void vidc_pix_cache_enable_misr(u32 misr_enable); +void vidc_pix_cache_set_misr_interface(u32 input_select); +void vidc_pix_cache_set_misr_id_filtering( + struct vidc_1080P_pix_cache_misr_id_filtering *filter_id); +void vidc_pix_cache_set_misr_filter_trans(u32 no_of_trans); +void vidc_pix_cache_get_misr_signatures( + struct vidc_1080P_pix_cache_misr_signature *signatures); +#endif diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c new file mode 100644 index 0000000000000000000000000000000000000000..36059520edf8824f21f155faa7877a74452ac1b0 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c @@ -0,0 +1,1023 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vidc.h" +#include "vcd_res_tracker.h" + +#define PIL_FW_BASE_ADDR 0x9fe00000 +#define PIL_FW_SIZE 0x200000 + +static unsigned int vidc_clk_table[4] = { + 48000000, 133330000, 200000000, 228570000, +}; +static unsigned int restrk_mmu_subsystem[] = { + MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE}; +static struct res_trk_context resource_context; + +#define VIDC_FW "vidc_1080p.fw" +#define VIDC_FW_SIZE SZ_1M + +struct res_trk_vidc_mmu_clk { + char *mmu_clk_name; + struct clk *mmu_clk; +}; + +static struct res_trk_vidc_mmu_clk vidc_mmu_clks[] = { + {"mdp_iommu_clk"}, {"rot_iommu_clk"}, + {"vcodec_iommu0_clk"}, {"vcodec_iommu1_clk"}, + {"smmu_iface_clk"} +}; + +unsigned char *vidc_video_codec_fw; +u32 vidc_video_codec_fw_size; +static u32 res_trk_get_clk(void); +static void res_trk_put_clk(void); + +static void *res_trk_pmem_map + (struct ddl_buf_addr *addr, size_t sz, u32 alignment) +{ + u32 offset = 0, flags = 0; + u32 index = 0; + struct ddl_context *ddl_context; + struct msm_mapped_buffer *mapped_buffer = NULL; + int ret = 0; + unsigned long iova = 0; + unsigned long buffer_size = 0; + unsigned long *kernel_vaddr = NULL; + + ddl_context = ddl_get_context(); + if (res_trk_get_enable_ion() && addr->alloc_handle) { + kernel_vaddr = (unsigned long *) ion_map_kernel( + ddl_context->video_ion_client, + addr->alloc_handle, UNCACHED); + if (IS_ERR_OR_NULL(kernel_vaddr)) { + DDL_MSG_ERROR("%s():DDL ION client map failed\n", + __func__); + goto ion_bail_out; + } + addr->virtual_base_addr = (u8 *) kernel_vaddr; + ret = ion_map_iommu(ddl_context->video_ion_client, + addr->alloc_handle, + VIDEO_DOMAIN, + VIDEO_FIRMWARE_POOL, + SZ_4K, + 0, + &iova, + &buffer_size, + UNCACHED, 0); + if (ret) { + DDL_MSG_ERROR("%s():DDL ION client iommu map failed\n", + __func__); + goto ion_unmap_bail_out; + } + addr->mapped_buffer = NULL; + addr->physical_base_addr = (u8 *)iova; + addr->align_physical_addr = (u8 *) DDL_ALIGN((u32) + addr->physical_base_addr, alignment); + offset = (u32)(addr->align_physical_addr - + addr->physical_base_addr); + addr->align_virtual_addr = addr->virtual_base_addr + offset; + addr->buffer_size = buffer_size; + } else { + if (!res_trk_check_for_sec_session()) { + if (!addr->alloced_phys_addr) { + pr_err(" %s() alloced addres NULL", __func__); + goto bail_out; + } + flags = MSM_SUBSYSTEM_MAP_IOVA | + MSM_SUBSYSTEM_MAP_KADDR; + if (alignment == DDL_KILO_BYTE(128)) + index = 1; + else if (alignment > SZ_4K) + flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K; + addr->mapped_buffer = + msm_subsystem_map_buffer( + (unsigned long)addr->alloced_phys_addr, + sz, flags, &restrk_mmu_subsystem[index], + sizeof(restrk_mmu_subsystem[index])/ + sizeof(unsigned int)); + if (IS_ERR(addr->mapped_buffer)) { + pr_err(" %s() buffer map failed", __func__); + goto bail_out; + } + mapped_buffer = addr->mapped_buffer; + if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) { + pr_err("%s() map buffers failed\n", __func__); + goto bail_out; + } + addr->physical_base_addr = + (u8 *)mapped_buffer->iova[0]; + addr->virtual_base_addr = + mapped_buffer->vaddr; + } else { + addr->physical_base_addr = + (u8 *) addr->alloced_phys_addr; + addr->virtual_base_addr = + (u8 *)addr->alloced_phys_addr; + } + addr->align_physical_addr = (u8 *) DDL_ALIGN((u32) + addr->physical_base_addr, alignment); + offset = (u32)(addr->align_physical_addr - + addr->physical_base_addr); + addr->align_virtual_addr = addr->virtual_base_addr + offset; + addr->buffer_size = sz; + } + return addr->virtual_base_addr; +bail_out: + if (IS_ERR(addr->mapped_buffer)) + msm_subsystem_unmap_buffer(addr->mapped_buffer); + return NULL; +ion_unmap_bail_out: + if (!IS_ERR_OR_NULL(addr->alloc_handle)) { + ion_unmap_kernel(resource_context. + res_ion_client, addr->alloc_handle); + } +ion_bail_out: + return NULL; +} + +static void res_trk_pmem_free(struct ddl_buf_addr *addr) +{ + struct ddl_context *ddl_context; + ddl_context = ddl_get_context(); + if (ddl_context->video_ion_client) { + if (addr && addr->alloc_handle) { + ion_free(ddl_context->video_ion_client, + addr->alloc_handle); + addr->alloc_handle = NULL; + } + } else { + if (addr->mapped_buffer) + msm_subsystem_unmap_buffer(addr->mapped_buffer); + if (addr->alloced_phys_addr) + free_contiguous_memory_by_paddr( + (unsigned long)addr->alloced_phys_addr); + } + memset(addr, 0 , sizeof(struct ddl_buf_addr)); +} +static int res_trk_pmem_alloc + (struct ddl_buf_addr *addr, size_t sz, u32 alignment) +{ + u32 alloc_size; + struct ddl_context *ddl_context; + int rc = 0; + DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz); + if (!addr) { + DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__); + rc = -EINVAL; + goto bail_out; + } + ddl_context = ddl_get_context(); + res_trk_set_mem_type(addr->mem_type); + alloc_size = (sz + alignment); + if (res_trk_get_enable_ion()) { + if (!res_trk_is_cp_enabled() || + !res_trk_check_for_sec_session()) { + if (!ddl_context->video_ion_client) + ddl_context->video_ion_client = + res_trk_get_ion_client(); + if (!ddl_context->video_ion_client) { + DDL_MSG_ERROR( + "%s() :DDL ION Client Invalid handle\n", + __func__); + rc = -ENOMEM; + goto bail_out; + } + alloc_size = (alloc_size+4095) & ~4095; + addr->alloc_handle = ion_alloc( + ddl_context->video_ion_client, + alloc_size, SZ_4K, + res_trk_get_mem_type()); + if (IS_ERR_OR_NULL(addr->alloc_handle)) { + DDL_MSG_ERROR("%s() :DDL ION alloc failed\n", + __func__); + rc = -ENOMEM; + goto bail_out; + } + } else { + addr->alloc_handle = NULL; + addr->alloced_phys_addr = PIL_FW_BASE_ADDR; + addr->buffer_size = sz; + } + } else { + addr->alloced_phys_addr = (phys_addr_t) + allocate_contiguous_memory_nomap(alloc_size, + res_trk_get_mem_type(), SZ_4K); + if (!addr->alloced_phys_addr) { + DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n", + __func__, alloc_size); + rc = -ENOMEM; + goto bail_out; + } + addr->buffer_size = sz; + return rc; + } +bail_out: + return rc; +} + +static void res_trk_pmem_unmap(struct ddl_buf_addr *addr) +{ + if (!addr) { + pr_err("%s() invalid args\n", __func__); + return; + } + if (!IS_ERR_OR_NULL(addr->alloc_handle)) { + if (addr->physical_base_addr) { + ion_unmap_kernel(resource_context.res_ion_client, + addr->alloc_handle); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu(resource_context.res_ion_client, + addr->alloc_handle, + VIDEO_DOMAIN, + VIDEO_FIRMWARE_POOL); + } + addr->virtual_base_addr = NULL; + addr->physical_base_addr = NULL; + } + } else if (addr->mapped_buffer) + msm_subsystem_unmap_buffer(addr->mapped_buffer); + addr->mapped_buffer = NULL; +} + +static u32 res_trk_get_clk() +{ + if (resource_context.vcodec_clk || + resource_context.vcodec_pclk) { + VCDRES_MSG_ERROR("%s() Clock reference exists\n", + __func__); + goto bail_out; + } + resource_context.vcodec_clk = clk_get(resource_context.device, + "core_clk"); + if (IS_ERR(resource_context.vcodec_clk)) { + VCDRES_MSG_ERROR("%s(): core_clk get failed\n", + __func__); + goto bail_out; + } + resource_context.vcodec_pclk = clk_get(resource_context.device, + "iface_clk"); + if (IS_ERR(resource_context.vcodec_pclk)) { + VCDRES_MSG_ERROR("%s(): iface_clk get failed\n", + __func__); + goto release_vcodec_clk; + } + if (clk_set_rate(resource_context.vcodec_clk, + vidc_clk_table[0])) { + VCDRES_MSG_ERROR("%s(): set rate failed in power up\n", + __func__); + goto release_vcodec_pclk; + } + return true; +release_vcodec_pclk: + clk_put(resource_context.vcodec_pclk); + resource_context.vcodec_pclk = NULL; +release_vcodec_clk: + clk_put(resource_context.vcodec_clk); + resource_context.vcodec_clk = NULL; +bail_out: + return false; +} + +static void res_trk_put_clk() +{ + if (resource_context.vcodec_clk) + clk_put(resource_context.vcodec_clk); + if (resource_context.vcodec_pclk) + clk_put(resource_context.vcodec_pclk); + resource_context.vcodec_clk = NULL; + resource_context.vcodec_pclk = NULL; +} + +static u32 res_trk_shutdown_vidc(void) +{ + mutex_lock(&resource_context.lock); + if (resource_context.clock_enabled) { + mutex_unlock(&resource_context.lock); + VCDRES_MSG_LOW("\n Calling CLK disable in Power Down\n"); + res_trk_disable_clocks(); + mutex_lock(&resource_context.lock); + } + res_trk_put_clk(); + if (resource_context.footswitch) { + if (regulator_disable(resource_context.footswitch)) + VCDRES_MSG_ERROR("Regulator disable failed\n"); + regulator_put(resource_context.footswitch); + resource_context.footswitch = NULL; + } + if (pm_runtime_put(resource_context.device) < 0) + VCDRES_MSG_ERROR("Error : pm_runtime_put failed"); + mutex_unlock(&resource_context.lock); + return true; +} + +u32 res_trk_enable_clocks(void) +{ + VCDRES_MSG_LOW("\n in res_trk_enable_clocks()"); + mutex_lock(&resource_context.lock); + if (!resource_context.clock_enabled) { + VCDRES_MSG_LOW("Enabling IRQ in %s()\n", __func__); + enable_irq(resource_context.irq_num); + VCDRES_MSG_LOW("%s(): Enabling the clocks\n", __func__); + if (resource_context.vcodec_clk && + resource_context.vcodec_pclk) { + if (clk_prepare_enable(resource_context.vcodec_pclk)) { + VCDRES_MSG_ERROR("vidc pclk Enable fail\n"); + goto bail_out; + } + if (clk_prepare_enable(resource_context.vcodec_clk)) { + VCDRES_MSG_ERROR("vidc core clk Enable fail\n"); + goto vidc_disable_pclk; + } + + VCDRES_MSG_LOW("%s(): Clocks enabled!\n", __func__); + } else { + VCDRES_MSG_ERROR("%s(): Clocks enable failed!\n", + __func__); + goto bail_out; + } + } + resource_context.clock_enabled = 1; + mutex_unlock(&resource_context.lock); + return true; +vidc_disable_pclk: + clk_disable_unprepare(resource_context.vcodec_pclk); +bail_out: + mutex_unlock(&resource_context.lock); + return false; +} + +static u32 res_trk_sel_clk_rate(unsigned long hclk_rate) +{ + u32 status = true; + mutex_lock(&resource_context.lock); + if (clk_set_rate(resource_context.vcodec_clk, + hclk_rate)) { + VCDRES_MSG_ERROR("vidc hclk set rate failed\n"); + status = false; + } else + resource_context.vcodec_clk_rate = hclk_rate; + mutex_unlock(&resource_context.lock); + return status; +} + +u32 res_trk_get_clk_rate(unsigned long *phclk_rate) +{ + u32 status = true; + mutex_lock(&resource_context.lock); + if (phclk_rate) { + *phclk_rate = clk_get_rate(resource_context.vcodec_clk); + if (!(*phclk_rate)) { + VCDRES_MSG_ERROR("vidc hclk get rate failed\n"); + status = false; + } + } else + status = false; + mutex_unlock(&resource_context.lock); + return status; +} + +u32 res_trk_disable_clocks(void) +{ + u32 status = false; + VCDRES_MSG_LOW("in res_trk_disable_clocks()\n"); + mutex_lock(&resource_context.lock); + if (resource_context.clock_enabled) { + VCDRES_MSG_LOW("Disabling IRQ in %s()\n", __func__); + disable_irq_nosync(resource_context.irq_num); + VCDRES_MSG_LOW("%s(): Disabling the clocks ...\n", __func__); + resource_context.clock_enabled = 0; + if (resource_context.vcodec_clk) + clk_disable_unprepare(resource_context.vcodec_clk); + if (resource_context.vcodec_pclk) + clk_disable_unprepare(resource_context.vcodec_pclk); + status = true; + } + mutex_unlock(&resource_context.lock); + return status; +} + +static u32 res_trk_vidc_pwr_up(void) +{ + mutex_lock(&resource_context.lock); + + if (pm_runtime_get(resource_context.device) < 0) { + VCDRES_MSG_ERROR("Error : pm_runtime_get failed\n"); + goto bail_out; + } + if (!resource_context.footswitch) + resource_context.footswitch = + regulator_get(resource_context.device, "vdd"); + if (IS_ERR(resource_context.footswitch)) { + VCDRES_MSG_ERROR("foot switch get failed\n"); + resource_context.footswitch = NULL; + } else + regulator_enable(resource_context.footswitch); + if (!res_trk_get_clk()) + goto rel_vidc_pm_runtime; + mutex_unlock(&resource_context.lock); + return true; + +rel_vidc_pm_runtime: + if (pm_runtime_put(resource_context.device) < 0) + VCDRES_MSG_ERROR("Error : pm_runtime_put failed"); +bail_out: + mutex_unlock(&resource_context.lock); + return false; +} + +static struct ion_client *res_trk_create_ion_client(void){ + struct ion_client *video_client; + video_client = msm_ion_client_create(-1, "video_client"); + return video_client; +} + +int res_trk_enable_footswitch(void) +{ + int rc = 0; + mutex_lock(&resource_context.lock); + if (!resource_context.footswitch) + resource_context.footswitch = regulator_get(NULL, "fs_ved"); + if (IS_ERR(resource_context.footswitch)) { + VCDRES_MSG_ERROR("foot switch get failed\n"); + resource_context.footswitch = NULL; + rc = -EINVAL; + } else + rc = regulator_enable(resource_context.footswitch); + mutex_unlock(&resource_context.lock); + return rc; +} + +int res_trk_disable_footswitch(void) +{ + mutex_lock(&resource_context.lock); + if (resource_context.footswitch) { + if (regulator_disable(resource_context.footswitch)) + VCDRES_MSG_ERROR("Regulator disable failed\n"); + regulator_put(resource_context.footswitch); + resource_context.footswitch = NULL; + } + mutex_unlock(&resource_context.lock); + return 0; +} + +u32 res_trk_power_up(void) +{ + VCDRES_MSG_LOW("clk_regime_rail_enable"); + VCDRES_MSG_LOW("clk_regime_sel_rail_control"); +#ifdef CONFIG_MSM_BUS_SCALING + resource_context.pcl = 0; + if (resource_context.vidc_bus_client_pdata) { + resource_context.pcl = msm_bus_scale_register_client( + resource_context.vidc_bus_client_pdata); + VCDRES_MSG_LOW("%s(), resource_context.pcl = %x", __func__, + resource_context.pcl); + } + if (resource_context.pcl == 0) { + dev_err(resource_context.device, + "register bus client returned NULL\n"); + return false; + } +#endif + return res_trk_vidc_pwr_up(); +} + +u32 res_trk_power_down(void) +{ + VCDRES_MSG_LOW("clk_regime_rail_disable"); + res_trk_pmem_unmap(&resource_context.firmware_addr); + res_trk_pmem_free(&resource_context.firmware_addr); +#ifdef CONFIG_MSM_BUS_SCALING + msm_bus_scale_client_update_request(resource_context.pcl, 0); + msm_bus_scale_unregister_client(resource_context.pcl); +#endif + VCDRES_MSG_MED("res_trk_power_down():: Calling " + "res_trk_shutdown_vidc()\n"); + return res_trk_shutdown_vidc(); +} + +u32 res_trk_get_max_perf_level(u32 *pn_max_perf_lvl) +{ + if (!pn_max_perf_lvl) { + VCDRES_MSG_ERROR("%s(): pn_max_perf_lvl is NULL\n", + __func__); + return false; + } + *pn_max_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; + return true; +} + +#ifdef CONFIG_MSM_BUS_SCALING +int res_trk_update_bus_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_level) +{ + struct vcd_clnt_ctxt *cctxt_itr = NULL; + u32 enc_perf_level = 0, dec_perf_level = 0; + u32 bus_clk_index, client_type = 0; + int rc = 0; + + cctxt_itr = dev_ctxt->cctxt_list_head; + while (cctxt_itr) { + if (cctxt_itr->decoding) + dec_perf_level += cctxt_itr->reqd_perf_lvl; + else + enc_perf_level += cctxt_itr->reqd_perf_lvl; + cctxt_itr = cctxt_itr->next; + } + + if (!enc_perf_level) + client_type = 1; + if (perf_level <= RESTRK_1080P_VGA_PERF_LEVEL) + bus_clk_index = 0; + else if (perf_level <= RESTRK_1080P_720P_PERF_LEVEL) + bus_clk_index = 1; + else if (perf_level <= RESTRK_1080P_MAX_PERF_LEVEL) + bus_clk_index = 2; + else + bus_clk_index = 3; + + if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0) + bus_clk_index = 2; + else if (resource_context.vidc_platform_data->disable_turbo + && bus_clk_index == 3) { + VCDRES_MSG_ERROR("Warning: Turbo mode not supported " + " falling back to 1080p bus\n"); + bus_clk_index = 2; + } + + bus_clk_index = (bus_clk_index << 1) + (client_type + 1); + VCDRES_MSG_LOW("%s(), bus_clk_index = %d", __func__, bus_clk_index); + VCDRES_MSG_LOW("%s(),context.pcl = %x", __func__, resource_context.pcl); + VCDRES_MSG_LOW("%s(), bus_perf_level = %x", __func__, perf_level); + rc = msm_bus_scale_client_update_request(resource_context.pcl, + bus_clk_index); + return rc; +} +#endif + +u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl, + struct vcd_dev_ctxt *dev_ctxt) +{ + u32 vidc_freq = 0; + if (!pn_set_perf_lvl || !dev_ctxt) { + VCDRES_MSG_ERROR("%s(): NULL pointer! dev_ctxt(%p)\n", + __func__, dev_ctxt); + return false; + } + VCDRES_MSG_LOW("%s(), req_perf_lvl = %d", __func__, req_perf_lvl); + + if (resource_context.vidc_platform_data->disable_turbo + && req_perf_lvl > RESTRK_1080P_MAX_PERF_LEVEL) { + VCDRES_MSG_ERROR("%s(): Turbo not supported! dev_ctxt(%p)\n", + __func__, dev_ctxt); + } + +#ifdef CONFIG_MSM_BUS_SCALING + if (!res_trk_update_bus_perf_level(dev_ctxt, req_perf_lvl) < 0) { + VCDRES_MSG_ERROR("%s(): update buf perf level failed\n", + __func__); + return false; + } + +#endif + if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0) + req_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; + + if (req_perf_lvl <= RESTRK_1080P_VGA_PERF_LEVEL) { + vidc_freq = vidc_clk_table[0]; + *pn_set_perf_lvl = RESTRK_1080P_VGA_PERF_LEVEL; + } else if (req_perf_lvl <= RESTRK_1080P_720P_PERF_LEVEL) { + vidc_freq = vidc_clk_table[1]; + *pn_set_perf_lvl = RESTRK_1080P_720P_PERF_LEVEL; + } else if (req_perf_lvl <= RESTRK_1080P_MAX_PERF_LEVEL) { + vidc_freq = vidc_clk_table[2]; + *pn_set_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; + } else { + vidc_freq = vidc_clk_table[3]; + *pn_set_perf_lvl = RESTRK_1080P_TURBO_PERF_LEVEL; + } + + if (resource_context.vidc_platform_data->disable_turbo && + *pn_set_perf_lvl == RESTRK_1080P_TURBO_PERF_LEVEL) { + VCDRES_MSG_ERROR("Warning: Turbo mode not supported " + " falling back to 1080p clocks\n"); + vidc_freq = vidc_clk_table[2]; + *pn_set_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; + } + + resource_context.perf_level = *pn_set_perf_lvl; + VCDRES_MSG_MED("VIDC: vidc_freq = %u, req_perf_lvl = %u\n", + vidc_freq, req_perf_lvl); +#ifdef USE_RES_TRACKER + if (req_perf_lvl != RESTRK_1080P_MIN_PERF_LEVEL) { + VCDRES_MSG_MED("%s(): Setting vidc freq to %u\n", + __func__, vidc_freq); + if (!res_trk_sel_clk_rate(vidc_freq)) { + VCDRES_MSG_ERROR("%s(): res_trk_sel_clk_rate FAILED\n", + __func__); + *pn_set_perf_lvl = 0; + return false; + } + } +#endif + VCDRES_MSG_MED("%s() set perl level : %d", __func__, *pn_set_perf_lvl); + return true; +} + +u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl) +{ + unsigned long freq; + + if (!pn_perf_lvl) { + VCDRES_MSG_ERROR("%s(): pn_perf_lvl is NULL\n", + __func__); + return false; + } + VCDRES_MSG_LOW("clk_regime_msm_get_clk_freq_hz"); + if (!res_trk_get_clk_rate(&freq)) { + VCDRES_MSG_ERROR("%s(): res_trk_get_clk_rate FAILED\n", + __func__); + *pn_perf_lvl = 0; + return false; + } + *pn_perf_lvl = resource_context.perf_level; + VCDRES_MSG_MED("%s(): freq = %lu, *pn_perf_lvl = %u", __func__, + freq, *pn_perf_lvl); + return true; +} + +u32 res_trk_download_firmware(void) +{ + const struct firmware *fw_video = NULL; + int rc = 0; + u32 status = true; + + VCDRES_MSG_HIGH("%s(): Request firmware download\n", + __func__); + mutex_lock(&resource_context.lock); + rc = request_firmware(&fw_video, VIDC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_FW, rc); + status = false; + goto bail_out; + } + vidc_video_codec_fw = (unsigned char *)fw_video->data; + vidc_video_codec_fw_size = (u32) fw_video->size; +bail_out: + mutex_unlock(&resource_context.lock); + return status; +} + +void res_trk_init(struct device *device, u32 irq) +{ + if (resource_context.device || resource_context.irq_num || + !device) { + VCDRES_MSG_ERROR("%s() Resource Tracker Init error\n", + __func__); + } else { + memset(&resource_context, 0, sizeof(resource_context)); + mutex_init(&resource_context.lock); + mutex_init(&resource_context.secure_lock); + resource_context.device = device; + resource_context.irq_num = irq; + resource_context.vidc_platform_data = + (struct msm_vidc_platform_data *) device->platform_data; + if (resource_context.vidc_platform_data) { + resource_context.memtype = + resource_context.vidc_platform_data->memtype; + resource_context.fw_mem_type = + resource_context.vidc_platform_data->memtype; + resource_context.cmd_mem_type = + resource_context.vidc_platform_data->memtype; + if (resource_context.vidc_platform_data->enable_ion) { + resource_context.res_ion_client = + res_trk_create_ion_client(); + if (!(resource_context.res_ion_client)) { + VCDRES_MSG_ERROR("%s()ION createfail\n", + __func__); + return; + } + resource_context.fw_mem_type = + ION_MM_FIRMWARE_HEAP_ID; + resource_context.cmd_mem_type = + ION_CP_MFC_HEAP_ID; + } + resource_context.disable_dmx = + resource_context.vidc_platform_data->disable_dmx; + resource_context.disable_fullhd = + resource_context.vidc_platform_data->disable_fullhd; +#ifdef CONFIG_MSM_BUS_SCALING + resource_context.vidc_bus_client_pdata = + resource_context.vidc_platform_data-> + vidc_bus_client_pdata; +#endif + } else { + resource_context.memtype = -1; + resource_context.disable_dmx = 0; + } + resource_context.core_type = VCD_CORE_1080P; + resource_context.firmware_addr.mem_type = DDL_FW_MEM; + } +} + +u32 res_trk_get_core_type(void){ + return resource_context.core_type; +} + +u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr) +{ + int rc = 0; + size_t size = 0; + if (!firm_addr || resource_context.firmware_addr.mapped_buffer) { + pr_err("%s() invalid params", __func__); + return -EINVAL; + } + if (res_trk_is_cp_enabled() && res_trk_check_for_sec_session()) + size = PIL_FW_SIZE; + else + size = VIDC_FW_SIZE; + + if (res_trk_pmem_alloc(&resource_context.firmware_addr, + size, DDL_KILO_BYTE(128))) { + pr_err("%s() Firmware buffer allocation failed", + __func__); + memset(&resource_context.firmware_addr, 0, + sizeof(resource_context.firmware_addr)); + rc = -ENOMEM; + goto fail_alloc; + } + if (!res_trk_pmem_map(&resource_context.firmware_addr, + resource_context.firmware_addr.buffer_size, + DDL_KILO_BYTE(128))) { + pr_err("%s() Firmware buffer mapping failed", + __func__); + rc = -ENOMEM; + goto fail_map; + } + memcpy(firm_addr, &resource_context.firmware_addr, + sizeof(struct ddl_buf_addr)); + return 0; +fail_map: + res_trk_pmem_free(&resource_context.firmware_addr); +fail_alloc: + return rc; +} + +void res_trk_release_fw_addr(void) +{ + res_trk_pmem_unmap(&resource_context.firmware_addr); + res_trk_pmem_free(&resource_context.firmware_addr); +} + +int res_trk_check_for_sec_session(void) +{ + int rc; + mutex_lock(&resource_context.secure_lock); + rc = resource_context.secure_session; + mutex_unlock(&resource_context.secure_lock); + return rc; +} + +int res_trk_get_mem_type(void) +{ + int mem_type = -1; + switch (resource_context.res_mem_type) { + case DDL_FW_MEM: + mem_type = ION_HEAP(resource_context.fw_mem_type); + return mem_type; + case DDL_MM_MEM: + mem_type = resource_context.memtype; + break; + case DDL_CMD_MEM: + if (res_trk_check_for_sec_session()) + mem_type = resource_context.cmd_mem_type; + else + mem_type = resource_context.memtype; + break; + default: + return mem_type; + } + if (resource_context.vidc_platform_data->enable_ion) { + if (res_trk_check_for_sec_session()) { + mem_type = ION_HEAP(mem_type); + if (resource_context.res_mem_type != DDL_FW_MEM) + mem_type |= ION_SECURE; + else if (res_trk_is_cp_enabled()) + mem_type |= ION_SECURE; + } else + mem_type = (ION_HEAP(mem_type) | + ION_HEAP(ION_IOMMU_HEAP_ID)); + } + return mem_type; +} + +u32 res_trk_is_cp_enabled(void) +{ + if (resource_context.vidc_platform_data->cp_enabled) + return 1; + else + return 0; +} + +u32 res_trk_get_enable_ion(void) +{ + if (resource_context.vidc_platform_data->enable_ion) + return 1; + else + return 0; +} + +struct ion_client *res_trk_get_ion_client(void) +{ + return resource_context.res_ion_client; +} + +u32 res_trk_get_disable_dmx(void){ + return resource_context.disable_dmx; +} + +u32 res_trk_get_min_dpb_count(void){ + return resource_context.vidc_platform_data->cont_mode_dpb_count; +} + +void res_trk_set_mem_type(enum ddl_mem_area mem_type) +{ + resource_context.res_mem_type = mem_type; + return; +} + +u32 res_trk_get_disable_fullhd(void) +{ + return resource_context.disable_fullhd; +} + +int res_trk_enable_iommu_clocks(void) +{ + int ret = 0, i; + if (resource_context.mmu_clks_on) { + pr_err(" %s: Clocks are already on", __func__); + return -EINVAL; + } + resource_context.mmu_clks_on = 1; + for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) { + vidc_mmu_clks[i].mmu_clk = clk_get(resource_context.device, + vidc_mmu_clks[i].mmu_clk_name); + if (IS_ERR(vidc_mmu_clks[i].mmu_clk)) { + pr_err(" %s: Get failed for clk %s", __func__, + vidc_mmu_clks[i].mmu_clk_name); + ret = PTR_ERR(vidc_mmu_clks[i].mmu_clk); + } + if (!ret) { + ret = clk_prepare_enable(vidc_mmu_clks[i].mmu_clk); + if (ret) { + clk_put(vidc_mmu_clks[i].mmu_clk); + vidc_mmu_clks[i].mmu_clk = NULL; + } + } + if (ret) { + for (i--; i >= 0; i--) { + clk_disable_unprepare(vidc_mmu_clks[i].mmu_clk); + clk_put(vidc_mmu_clks[i].mmu_clk); + vidc_mmu_clks[i].mmu_clk = NULL; + } + resource_context.mmu_clks_on = 0; + pr_err("%s() clocks enable failed", __func__); + break; + } + } + return ret; +} + +int res_trk_disable_iommu_clocks(void) +{ + int i; + if (!resource_context.mmu_clks_on) { + pr_err(" %s: clks are already off", __func__); + return -EINVAL; + } + resource_context.mmu_clks_on = 0; + for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) { + clk_disable_unprepare(vidc_mmu_clks[i].mmu_clk); + clk_put(vidc_mmu_clks[i].mmu_clk); + vidc_mmu_clks[i].mmu_clk = NULL; + } + return 0; +} + +void res_trk_secure_unset(void) +{ + mutex_lock(&resource_context.secure_lock); + resource_context.secure_session--; + mutex_unlock(&resource_context.secure_lock); +} + +void res_trk_secure_set(void) +{ + mutex_lock(&resource_context.secure_lock); + resource_context.secure_session++; + mutex_unlock(&resource_context.secure_lock); +} + +int res_trk_open_secure_session() +{ + int rc; + + if (res_trk_check_for_sec_session() == 1) { + mutex_lock(&resource_context.secure_lock); + pr_err("Securing...\n"); + rc = res_trk_enable_iommu_clocks(); + if (rc) { + pr_err("IOMMU clock enabled failed while open"); + goto error_open; + } + msm_ion_secure_heap(ION_HEAP(resource_context.memtype)); + msm_ion_secure_heap(ION_HEAP(resource_context.cmd_mem_type)); + res_trk_disable_iommu_clocks(); + mutex_unlock(&resource_context.secure_lock); + } + return 0; +error_open: + mutex_unlock(&resource_context.secure_lock); + return rc; +} + +int res_trk_close_secure_session() +{ + int rc; + if (res_trk_check_for_sec_session() == 1) { + pr_err("Unsecuring....\n"); + mutex_lock(&resource_context.secure_lock); + rc = res_trk_enable_iommu_clocks(); + if (rc) { + pr_err("IOMMU clock enabled failed while close"); + goto error_close; + } + msm_ion_unsecure_heap(ION_HEAP(resource_context.cmd_mem_type)); + msm_ion_unsecure_heap(ION_HEAP(resource_context.memtype)); + res_trk_disable_iommu_clocks(); + mutex_unlock(&resource_context.secure_lock); + } + return 0; +error_close: + mutex_unlock(&resource_context.secure_lock); + return rc; +} + +u32 get_res_trk_perf_level(enum vcd_perf_level perf_level) +{ + u32 res_trk_perf_level; + switch (perf_level) { + case VCD_PERF_LEVEL0: + res_trk_perf_level = RESTRK_1080P_VGA_PERF_LEVEL; + break; + case VCD_PERF_LEVEL1: + res_trk_perf_level = RESTRK_1080P_720P_PERF_LEVEL; + break; + case VCD_PERF_LEVEL2: + res_trk_perf_level = RESTRK_1080P_MAX_PERF_LEVEL; + break; + case VCD_PERF_LEVEL_TURBO: + res_trk_perf_level = RESTRK_1080P_TURBO_PERF_LEVEL; + break; + default: + VCD_MSG_ERROR("Invalid perf level: %d\n", perf_level); + res_trk_perf_level = -EINVAL; + } + return res_trk_perf_level; +} + +u32 res_trk_estimate_perf_level(u32 pn_perf_lvl) +{ + VCDRES_MSG_MED("%s(), req_perf_lvl = %d", __func__, pn_perf_lvl); + if ((pn_perf_lvl >= RESTRK_1080P_VGA_PERF_LEVEL) && + (pn_perf_lvl < RESTRK_1080P_720P_PERF_LEVEL)) { + return RESTRK_1080P_720P_PERF_LEVEL; + } else if ((pn_perf_lvl >= RESTRK_1080P_720P_PERF_LEVEL) && + (pn_perf_lvl < RESTRK_1080P_MAX_PERF_LEVEL)) { + return RESTRK_1080P_MAX_PERF_LEVEL; + } else { + return pn_perf_lvl; + } +} diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h new file mode 100644 index 0000000000000000000000000000000000000000..ff0411a1da7fd0269a9c44eb4a798cdb505ab0bd --- /dev/null +++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h @@ -0,0 +1,78 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VIDEO_720P_RESOURCE_TRACKER_H_ +#define _VIDEO_720P_RESOURCE_TRACKER_H_ + +#include +#include +#include "vcd_res_tracker_api.h" +#ifdef CONFIG_MSM_BUS_SCALING +#include +#include +#endif +#include + +#define RESTRK_1080P_VGA_PERF_LEVEL VCD_MIN_PERF_LEVEL +#define RESTRK_1080P_720P_PERF_LEVEL 108000 +#define RESTRK_1080P_1080P_PERF_LEVEL 244800 + +#define RESTRK_1080P_MIN_PERF_LEVEL RESTRK_1080P_VGA_PERF_LEVEL +#define RESTRK_1080P_MAX_PERF_LEVEL RESTRK_1080P_1080P_PERF_LEVEL +#define RESTRK_1080P_TURBO_PERF_LEVEL (RESTRK_1080P_MAX_PERF_LEVEL + 1) + +struct res_trk_context { + struct device *device; + u32 irq_num; + struct mutex lock; + struct clk *vcodec_clk; + struct clk *vcodec_pclk; + unsigned long vcodec_clk_rate; + unsigned int clock_enabled; + unsigned int perf_level; + struct regulator *footswitch; + struct msm_vidc_platform_data *vidc_platform_data; + int memtype; + int fw_mem_type; + int cmd_mem_type; +#ifdef CONFIG_MSM_BUS_SCALING + struct msm_bus_scale_pdata *vidc_bus_client_pdata; + uint32_t pcl; +#endif + u32 core_type; + struct ddl_buf_addr firmware_addr; + struct ion_client *res_ion_client; + u32 disable_dmx; + u32 disable_fullhd; + enum ddl_mem_area res_mem_type; + u32 mmu_clks_on; + u32 secure_session; + struct mutex secure_lock; +}; + +#if DEBUG + +#define VCDRES_MSG_LOW(xx_fmt...) printk(KERN_INFO "\n\t* " xx_fmt) +#define VCDRES_MSG_MED(xx_fmt...) printk(KERN_INFO "\n * " xx_fmt) + +#else + +#define VCDRES_MSG_LOW(xx_fmt...) +#define VCDRES_MSG_MED(xx_fmt...) + +#endif + +#define VCDRES_MSG_HIGH(xx_fmt...) printk(KERN_WARNING "\n" xx_fmt) +#define VCDRES_MSG_ERROR(xx_fmt...) printk(KERN_ERR "\n err: " xx_fmt) +#define VCDRES_MSG_FATAL(xx_fmt...) printk(KERN_ERR "\n " xx_fmt) + +#endif diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h new file mode 100644 index 0000000000000000000000000000000000000000..26c20c502615c71d51f66edb5494a9a7714fa280 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VIDEO_720P_RESOURCE_TRACKER_API_H_ +#define _VIDEO_720P_RESOURCE_TRACKER_API_H_ + +#include "vcd_core.h" +#include "vcd_ddl.h" +#include "vcd_ddl_utils.h" + +void res_trk_init(struct device *device, u32 irq); +u32 res_trk_power_up(void); +u32 res_trk_power_down(void); +u32 res_trk_enable_clocks(void); +u32 res_trk_disable_clocks(void); +u32 res_trk_get_max_perf_level(u32 *pn_max_perf_lvl); +u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl, + struct vcd_dev_ctxt *dev_ctxt); +u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl); +u32 res_trk_download_firmware(void); +u32 res_trk_get_core_type(void); +u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr); +int res_trk_get_mem_type(void); +u32 res_trk_get_enable_ion(void); +u32 res_trk_is_cp_enabled(void); +u32 res_trk_get_disable_fullhd(void); +struct ion_client *res_trk_get_ion_client(void); +u32 res_trk_get_disable_dmx(void); +u32 res_trk_get_min_dpb_count(void); +void res_trk_set_mem_type(enum ddl_mem_area mem_type); +int res_trk_enable_iommu_clocks(void); +int res_trk_disable_iommu_clocks(void); +int res_trk_check_for_sec_session(void); +int res_trk_open_secure_session(void); +int res_trk_close_secure_session(void); +void res_trk_secure_set(void); +void res_trk_secure_unset(void); +u32 get_res_trk_perf_level(enum vcd_perf_level); +int res_trk_enable_footswitch(void); +int res_trk_disable_footswitch(void); +void res_trk_release_fw_addr(void); +u32 res_trk_estimate_perf_level(u32 pn_perf_lvl); +u32 res_trk_get_clk_rate(unsigned long *phclk_rate); +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c new file mode 100644 index 0000000000000000000000000000000000000000..f8be339912db2d378fa49c812d6ac0e923bbf8c2 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c @@ -0,0 +1,628 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "vcd_ddl_utils.h" +#include "vcd_ddl_metadata.h" +#include "vcd_res_tracker_api.h" + +u32 ddl_device_init(struct ddl_init_config *ddl_init_config, + void *client_data) +{ + struct ddl_context *ddl_context; + u32 status = VCD_S_SUCCESS; + + if ((!ddl_init_config) || + (!ddl_init_config->ddl_callback) || + (!ddl_init_config->core_virtual_base_addr) + ) { + VIDC_LOGERR_STRING("ddl_dev_init:Bad_argument"); + return VCD_ERR_ILLEGAL_PARM; + } + + ddl_context = ddl_get_context(); + + if (DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dev_init:Multiple_init"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dev_init:Ddl_busy"); + return VCD_ERR_BUSY; + } + + DDL_MEMSET(ddl_context, 0, sizeof(struct ddl_context)); + + DDL_BUSY(ddl_context); + ddl_context->memtype = res_trk_get_mem_type(); + if (ddl_context->memtype == -1) { + VIDC_LOGERR_STRING("ddl_dev_init:Invalid Memtype"); + return VCD_ERR_ILLEGAL_PARM; + } + ddl_context->ddl_callback = ddl_init_config->ddl_callback; + ddl_context->interrupt_clr = ddl_init_config->interrupt_clr; + ddl_context->core_virtual_base_addr = + ddl_init_config->core_virtual_base_addr; + ddl_context->client_data = client_data; + + vidc_720p_set_device_virtual_base(ddl_context-> + core_virtual_base_addr); + + ddl_context->current_ddl = NULL; + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + + ddl_client_transact(DDL_INIT_CLIENTS, NULL); + + ddl_pmem_alloc(&ddl_context->context_buf_addr, + DDL_CONTEXT_MEMORY, DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!ddl_context->context_buf_addr.virtual_base_addr) { + VIDC_LOGERR_STRING("ddl_dev_init:Context_alloc_fail"); + status = VCD_ERR_ALLOC_FAIL; + } + if (!status) { + ddl_pmem_alloc(&ddl_context->db_line_buffer, + DDL_DB_LINE_BUF_SIZE, + DDL_TILE_BUFFER_ALIGN_BYTES); + if (!ddl_context->db_line_buffer.virtual_base_addr) { + VIDC_LOGERR_STRING("ddl_dev_init:Line_buf_alloc_fail"); + status = VCD_ERR_ALLOC_FAIL; + } + } + + if (!status) { + ddl_pmem_alloc(&ddl_context->data_partition_tempbuf, + DDL_MPEG4_DATA_PARTITION_BUF_SIZE, + DDL_TILE_BUFFER_ALIGN_BYTES); + if (ddl_context->data_partition_tempbuf.virtual_base_addr \ + == NULL) { + VIDC_LOGERR_STRING + ("ddl_dev_init:Data_partition_buf_alloc_fail"); + status = VCD_ERR_ALLOC_FAIL; + } + } + + if (!status) { + + ddl_pmem_alloc(&ddl_context->metadata_shared_input, + DDL_METADATA_TOTAL_INPUTBUFSIZE, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!ddl_context->metadata_shared_input.virtual_base_addr) { + VIDC_LOGERR_STRING + ("ddl_dev_init:metadata_shared_input_alloc_fail"); + status = VCD_ERR_ALLOC_FAIL; + } + } + + if (!status) { + ddl_pmem_alloc(&ddl_context->dbg_core_dump, \ + DDL_DBG_CORE_DUMP_SIZE, \ + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!ddl_context->dbg_core_dump.virtual_base_addr) { + VIDC_LOGERR_STRING + ("ddl_dev_init:dbg_core_dump_alloc_failed"); + status = VCD_ERR_ALLOC_FAIL; + } + ddl_context->enable_dbg_core_dump = 0; + } + + if (!status && !vcd_fw_init()) { + VIDC_LOGERR_STRING("ddl_dev_init:fw_init_failed"); + status = VCD_ERR_ALLOC_FAIL; + } + if (status) { + ddl_release_context_buffers(ddl_context); + DDL_IDLE(ddl_context); + return status; + } + + ddl_move_command_state(ddl_context, DDL_CMD_DMA_INIT); + + ddl_core_init(ddl_context); + + return status; +} + +u32 ddl_device_release(void *client_data) +{ + struct ddl_context *ddl_context; + + ddl_context = ddl_get_context(); + + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dev_rel:Ddl_busy"); + return VCD_ERR_BUSY; + } + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dev_rel:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + + if (!ddl_client_transact(DDL_ACTIVE_CLIENT, NULL)) { + VIDC_LOGERR_STRING("ddl_dev_rel:Client_present_err"); + return VCD_ERR_CLIENT_PRESENT; + } + DDL_BUSY(ddl_context); + + ddl_context->device_state = DDL_DEVICE_NOTINIT; + ddl_context->client_data = client_data; + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + vidc_720p_stop_fw(); + + VIDC_LOG_STRING("FW_ENDDONE"); + ddl_release_context_buffers(ddl_context); + + DDL_IDLE(ddl_context); + + return VCD_S_SUCCESS; +} + +u32 ddl_open(u32 **ddl_handle, u32 decoding) +{ + struct ddl_context *ddl_context; + struct ddl_client_context *ddl; + u32 status; + + if (!ddl_handle) { + VIDC_LOGERR_STRING("ddl_open:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + + ddl_context = ddl_get_context(); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_open:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + + status = ddl_client_transact(DDL_GET_CLIENT, &ddl); + + if (status) { + VIDC_LOGERR_STRING("ddl_open:Client_trasac_failed"); + return status; + } + + ddl_move_client_state(ddl, DDL_CLIENT_OPEN); + + ddl->codec_data.hdr.decoding = decoding; + ddl->decoding = decoding; + + ddl_set_default_meta_data_hdr(ddl); + + ddl_set_initial_default_values(ddl); + + *ddl_handle = (u32 *) ddl; + return VCD_S_SUCCESS; +} + +u32 ddl_close(u32 **ddl_handle) +{ + struct ddl_context *ddl_context; + struct ddl_client_context **ddl = + (struct ddl_client_context **)ddl_handle; + + if (!ddl || !*ddl) { + VIDC_LOGERR_STRING("ddl_close:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + + ddl_context = ddl_get_context(); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_close:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + + if (!DDLCLIENT_STATE_IS(*ddl, DDL_CLIENT_OPEN)) { + VIDC_LOGERR_STRING("ddl_close:Not_in_open_state"); + return VCD_ERR_ILLEGAL_OP; + } + + ddl_move_client_state(*ddl, DDL_CLIENT_INVALID); + if ((*ddl)->decoding) { + vcd_fw_transact(false, true, + (*ddl)->codec_data.decoder.codec.codec); + } else { + vcd_fw_transact(false, false, + (*ddl)->codec_data.encoder.codec.codec); + } + ddl_client_transact(DDL_FREE_CLIENT, ddl); + + return VCD_S_SUCCESS; +} + +u32 ddl_encode_start(u32 *ddl_handle, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + struct ddl_context *ddl_context; + struct ddl_encoder_data *encoder; + u32 dpb_size; + + ddl_context = ddl_get_context(); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_enc_start:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_enc_start:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || ddl->decoding) { + VIDC_LOGERR_STRING("ddl_enc_start:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + VIDC_LOGERR_STRING("ddl_enc_start:Not_opened"); + return VCD_ERR_ILLEGAL_OP; + } + + if (!ddl_encoder_ready_to_start(ddl)) { + VIDC_LOGERR_STRING("ddl_enc_start:Err_param_settings"); + return VCD_ERR_ILLEGAL_OP; + } + + encoder = &ddl->codec_data.encoder; + + dpb_size = ddl_get_yuv_buffer_size(&encoder->frame_size, + &encoder->re_con_buf_format, false, + encoder->codec.codec); + + dpb_size *= DDL_ENC_NUM_DPB_BUFFERS; + ddl_pmem_alloc(&encoder->enc_dpb_addr, + dpb_size, DDL_TILE_BUFFER_ALIGN_BYTES); + if (!encoder->enc_dpb_addr.virtual_base_addr) { + VIDC_LOGERR_STRING("ddl_enc_start:Dpb_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + + if ((encoder->codec.codec == VCD_CODEC_MPEG4 && + !encoder->short_header.short_header) || + encoder->codec.codec == VCD_CODEC_H264) { + ddl_pmem_alloc(&encoder->seq_header, + DDL_ENC_SEQHEADER_SIZE, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!encoder->seq_header.virtual_base_addr) { + ddl_pmem_free(&encoder->enc_dpb_addr); + VIDC_LOGERR_STRING + ("ddl_enc_start:Seq_hdr_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + } else { + encoder->seq_header.buffer_size = 0; + encoder->seq_header.virtual_base_addr = 0; + } + + DDL_BUSY(ddl_context); + + ddl_context->current_ddl = ddl; + ddl_context->client_data = client_data; + ddl_channel_set(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_decode_start(u32 *ddl_handle, + struct vcd_sequence_hdr *header, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + struct ddl_context *ddl_context; + struct ddl_decoder_data *decoder; + + ddl_context = ddl_get_context(); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dec_start:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dec_start:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || !ddl->decoding) { + VIDC_LOGERR_STRING("ddl_dec_start:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + VIDC_LOGERR_STRING("ddl_dec_start:Not_in_opened_state"); + return VCD_ERR_ILLEGAL_OP; + } + + if ((header) && + ((!header->sequence_header_len) || + (!header->sequence_header) + ) + ) { + VIDC_LOGERR_STRING("ddl_dec_start:Bad_param_seq_header"); + return VCD_ERR_ILLEGAL_PARM; + } + + if (!ddl_decoder_ready_to_start(ddl, header)) { + VIDC_LOGERR_STRING("ddl_dec_start:Err_param_settings"); + return VCD_ERR_ILLEGAL_OP; + } + + DDL_BUSY(ddl_context); + + decoder = &ddl->codec_data.decoder; + if (header) { + decoder->header_in_start = true; + decoder->decode_config = *header; + } else { + decoder->header_in_start = false; + decoder->decode_config.sequence_header_len = 0; + } + + if (decoder->codec.codec == VCD_CODEC_H264) { + ddl_pmem_alloc(&decoder->h264Vsp_temp_buffer, + DDL_DECODE_H264_VSPTEMP_BUFSIZE, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!decoder->h264Vsp_temp_buffer.virtual_base_addr) { + DDL_IDLE(ddl_context); + VIDC_LOGERR_STRING + ("ddl_dec_start:H264Sps_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + } + + ddl_context->current_ddl = ddl; + ddl_context->client_data = client_data; + + ddl_channel_set(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_decode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_bits, void *client_data) +{ + u32 vcd_status = VCD_S_SUCCESS; + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + struct ddl_context *ddl_context = ddl_get_context(); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dec_frame:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dec_frame:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || !ddl->decoding) { + VIDC_LOGERR_STRING("ddl_dec_frame:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!input_bits || + ((!input_bits->vcd_frm.physical || + !input_bits->vcd_frm.data_len) && + (!(VCD_FRAME_FLAG_EOS & input_bits->vcd_frm.flags)) + ) + ) { + VIDC_LOGERR_STRING("ddl_dec_frame:Bad_input_param"); + return VCD_ERR_ILLEGAL_PARM; + } + + DDL_BUSY(ddl_context); + + ddl_context->current_ddl = ddl; + ddl_context->client_data = client_data; + + ddl->input_frame = *input_bits; + + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) { + ddl_decode_frame_run(ddl); + } else { + if (!ddl->codec_data.decoder.dp_buf.no_of_dec_pic_buf) { + VIDC_LOGERR_STRING("ddl_dec_frame:Dpbs_requied"); + vcd_status = VCD_ERR_ILLEGAL_OP; + } else if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) { + vcd_status = ddl_decode_set_buffers(ddl); + } else + if (DDLCLIENT_STATE_IS + (ddl, DDL_CLIENT_WAIT_FOR_INITCODEC)) { + ddl->codec_data.decoder.decode_config. + sequence_header = + ddl->input_frame.vcd_frm.physical; + ddl->codec_data.decoder.decode_config. + sequence_header_len = + ddl->input_frame.vcd_frm.data_len; + ddl_decode_init_codec(ddl); + } else { + VIDC_LOGERR_STRING("Dec_frame:Wrong_state"); + vcd_status = VCD_ERR_ILLEGAL_OP; + } + if (vcd_status) + DDL_IDLE(ddl_context); + } + return vcd_status; +} + +u32 ddl_encode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_frame, + struct ddl_frame_data_tag *output_bit, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + struct ddl_context *ddl_context = ddl_get_context(); + + if (vidc_msg_timing) + ddl_set_core_start_time(__func__, ENC_OP_TIME); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_enc_frame:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_enc_frame:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || ddl->decoding) { + VIDC_LOGERR_STRING("ddl_enc_frame:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!input_frame || + !input_frame->vcd_frm.physical || + !input_frame->vcd_frm.data_len) { + VIDC_LOGERR_STRING("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) + ) + ) { + VIDC_LOGERR_STRING + ("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) { + VIDC_LOGERR_STRING("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) { + VIDC_LOGERR_STRING + ("ddl_enc_frame:offset_large, Exceeds_min_buf_size"); + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) { + VIDC_LOGERR_STRING("ddl_enc_frame:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + + DDL_BUSY(ddl_context); + + ddl_context->current_ddl = ddl; + ddl_context->client_data = client_data; + + ddl->input_frame = *input_frame; + ddl->output_frame = *output_bit; + + ddl_encode_frame_run(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_decode_end(u32 *ddl_handle, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + struct ddl_context *ddl_context; + + ddl_context = ddl_get_context(); + + if (vidc_msg_timing) { + ddl_reset_core_time_variables(DEC_OP_TIME); + ddl_reset_core_time_variables(DEC_IP_TIME); + } + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dec_end:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dec_end:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || !ddl->decoding) { + VIDC_LOGERR_STRING("ddl_dec_end:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_FATAL_ERROR) + ) { + VIDC_LOGERR_STRING("ddl_dec_end:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + DDL_BUSY(ddl_context); + + ddl_context->current_ddl = ddl; + ddl_context->client_data = client_data; + + ddl_channel_end(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_encode_end(u32 *ddl_handle, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + struct ddl_context *ddl_context; + + ddl_context = ddl_get_context(); + + if (vidc_msg_timing) + ddl_reset_core_time_variables(ENC_OP_TIME); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_enc_end:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_enc_end:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || ddl->decoding) { + VIDC_LOGERR_STRING("ddl_enc_end:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_FATAL_ERROR)) { + VIDC_LOGERR_STRING("ddl_enc_end:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + DDL_BUSY(ddl_context); + + ddl_context->current_ddl = ddl; + ddl_context->client_data = client_data; + + ddl_channel_end(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_reset_hw(u32 mode) +{ + struct ddl_context *ddl_context; + struct ddl_client_context *ddl; + int i_client_num; + + VIDC_LOG_STRING("ddl_reset_hw:called"); + ddl_context = ddl_get_context(); + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + DDL_BUSY(ddl_context); + + if (ddl_context->core_virtual_base_addr) + vidc_720p_do_sw_reset(); + + ddl_context->device_state = DDL_DEVICE_NOTINIT; + for (i_client_num = 0; i_client_num < VCD_MAX_NO_CLIENT; + ++i_client_num) { + ddl = ddl_context->ddl_clients[i_client_num]; + ddl_context->ddl_clients[i_client_num] = NULL; + if (ddl) { + ddl_release_client_internal_buffers(ddl); + ddl_client_transact(DDL_FREE_CLIENT, &ddl); + } + } + + ddl_release_context_buffers(ddl_context); + DDL_MEMSET(ddl_context, 0, sizeof(struct ddl_context)); + + return true; +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h new file mode 100644 index 0000000000000000000000000000000000000000..44d5b0dd927a20428279bb12beec8c48fb8eb40f --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h @@ -0,0 +1,292 @@ +/* Copyright (c) 2010, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_DDL_H_ +#define _VCD_DDL_H_ +#include +#include "vcd_ddl_api.h" +#include "vcd_ddl_utils.h" +#include "vcd_ddl_firmware.h" +#include "vidc.h" + +#undef DDL_INLINE +#define DDL_INLINE + +#define DDL_BUSY_STATE 1 +#define DDL_IDLE_STATE 0 +#define DDL_ERROR_STATE 2 +#define DDL_IS_BUSY(ddl_context) \ + (((ddl_context)->ddl_busy != DDL_IDLE_STATE)) +#define DDL_BUSY(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_BUSY_STATE) +#define DDL_IDLE(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_IDLE_STATE) +#define DDL_ERROR(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_ERROR_STATE) + +#define DDL_DEVICE_NOTINIT 0 +#define DDL_DEVICE_INITED 1 +#define DDL_DEVICE_HWFATAL 2 +#define DDL_IS_INITIALIZED(ddl_context) \ +(ddl_context->device_state == DDL_DEVICE_INITED) + +#define DDLCOMMAND_STATE_IS(ddl_context, command_state) \ +(command_state == (ddl_context)->cmd_state) + +#define DDLCLIENT_STATE_IS(ddl, current_state) \ +(current_state == (ddl)->client_state) + +#define DDL_DPB_OP_INIT 1 +#define DDL_DPB_OP_MARK_FREE 2 +#define DDL_DPB_OP_MARK_BUSY 3 +#define DDL_DPB_OP_SET_MASK 4 +#define DDL_DPB_OP_RETRIEVE 5 + +#define DDL_INIT_CLIENTS 0 +#define DDL_GET_CLIENT 1 +#define DDL_FREE_CLIENT 2 +#define DDL_ACTIVE_CLIENT 3 + +#define DDL_INVALID_CHANNEL_ID ((u32)~0) +#define DDL_INVALID_CODEC_TYPE ((u32)~0) + +#define DDL_ENC_REQ_IFRAME 0x01 +#define DDL_ENC_CHANGE_IPERIOD 0x02 +#define DDL_ENC_CHANGE_BITRATE 0x04 +#define DDL_ENC_CHANGE_FRAMERATE 0x08 +#define DDL_ENC_CHANGE_CIR 0x10 + +#define DDL_DEC_REQ_OUTPUT_FLUSH 0x1 + +enum ddl_mem_area { + DDL_MM_MEM = 0x0 +}; + +struct ddl_buf_addr { + u32 *physical_base_addr; + u32 *virtual_base_addr; + u32 *align_physical_addr; + u32 *align_virtual_addr; + struct msm_mapped_buffer *mapped_buffer; + u32 buffer_size; + enum ddl_mem_area mem_type; +}; + +enum ddl_cmd_state { + DDL_CMD_INVALID = 0x0, + DDL_CMD_DMA_INIT = 0x1, + DDL_CMD_CPU_RESET = 0x2, + DDL_CMD_CHANNEL_SET = 0x3, + DDL_CMD_INIT_CODEC = 0x4, + DDL_CMD_HEADER_PARSE = 0x5, + DDL_CMD_DECODE_SET_DPB = 0x6, + DDL_CMD_DECODE_FRAME = 0x7, + DDL_CMD_ENCODE_FRAME = 0x8, + DDL_CMD_EOS = 0x9, + DDL_CMD_CHANNEL_END = 0xA, + DDL_CMD_32BIT = 0x7FFFFFFF +}; + +enum ddl_client_state { + DDL_CLIENT_INVALID = 0x0, + DDL_CLIENT_OPEN = 0x1, + DDL_CLIENT_WAIT_FOR_CHDONE = 0x2, + DDL_CLIENT_WAIT_FOR_INITCODEC = 0x3, + DDL_CLIENT_WAIT_FOR_INITCODECDONE = 0x4, + DDL_CLIENT_WAIT_FOR_DPB = 0x5, + DDL_CLIENT_WAIT_FOR_DPBDONE = 0x6, + DDL_CLIENT_WAIT_FOR_FRAME = 0x7, + DDL_CLIENT_WAIT_FOR_FRAME_DONE = 0x8, + DDL_CLIENT_WAIT_FOR_EOS_DONE = 0x9, + DDL_CLIENT_WAIT_FOR_CHEND = 0xA, + DDL_CLIENT_FATAL_ERROR = 0xB, + DDL_CLIENT_32BIT = 0x7FFFFFFF +}; + +struct ddl_mask { + u32 client_mask; + u32 hw_mask; +}; + +struct ddl_context; + +struct ddl_client_context; + +struct ddl_codec_data_hdr { + u32 decoding; +}; + +struct ddl_encoder_data { + struct ddl_codec_data_hdr hdr; + struct vcd_property_codec codec; + struct vcd_property_frame_size frame_size; + struct vcd_property_frame_rate frame_rate; + struct vcd_property_target_bitrate target_bit_rate; + struct vcd_property_profile profile; + struct vcd_property_level level; + struct vcd_property_rate_control rc; + struct vcd_property_multi_slice multi_slice; + u32 meta_data_enable_flag; + u32 suffix; + struct ddl_buf_addr meta_data_input; + u32 meta_data_offset; + struct vcd_property_short_header short_header; + struct vcd_property_vop_timing vop_timing; + u32 hdr_ext_control; + struct vcd_property_db_config db_control; + struct vcd_property_entropy_control entropy_control; + struct vcd_property_i_period i_period; + struct vcd_property_session_qp session_qp; + struct vcd_property_qp_range qp_range; + struct vcd_property_rc_level rc_level; + u32 r_cframe_skip; + u32 vb_vbuffer_size; + struct vcd_property_frame_level_rc_params frame_level_rc; + struct vcd_property_adaptive_rc_params adaptive_rc; + struct vcd_property_intra_refresh_mb_number intra_refresh; + struct vcd_property_buffer_format buf_format; + struct vcd_property_buffer_format re_con_buf_format; + u32 dynamic_prop_change; + u32 dynmic_prop_change_req; + u32 ext_enc_control_val; + struct vidc_720p_enc_frame_info enc_frame_info; + struct ddl_buf_addr enc_dpb_addr; + struct ddl_buf_addr seq_header; + struct vcd_buffer_requirement input_buf_req; + struct vcd_buffer_requirement output_buf_req; + struct vcd_buffer_requirement client_input_buf_req; + struct vcd_buffer_requirement client_output_buf_req; +}; + +struct ddl_decoder_data { + struct ddl_codec_data_hdr hdr; + struct vcd_property_codec codec; + struct vcd_property_buffer_format buf_format; + struct vcd_property_frame_size frame_size; + struct vcd_property_frame_size client_frame_size; + struct vcd_property_profile profile; + struct vcd_property_level level; + u32 progressive_only; + u32 output_order; + u32 meta_data_enable_flag; + u32 suffix; + struct ddl_buf_addr meta_data_input; + struct ddl_buf_addr ref_buffer; + u32 meta_data_offset; + struct vcd_property_post_filter post_filter; + struct vcd_sequence_hdr decode_config; + u32 header_in_start; + u32 min_dpb_num; + u32 y_cb_cr_size; + struct ddl_property_dec_pic_buffers dp_buf; + struct ddl_mask dpb_mask; + u32 dynamic_prop_change; + u32 dynmic_prop_change_req; + struct vidc_720p_dec_disp_info dec_disp_info; + struct ddl_buf_addr dpb_comv_buffer; + struct ddl_buf_addr h264Vsp_temp_buffer; + struct vcd_buffer_requirement actual_input_buf_req; + struct vcd_buffer_requirement min_input_buf_req; + struct vcd_buffer_requirement client_input_buf_req; + struct vcd_buffer_requirement actual_output_buf_req; + struct vcd_buffer_requirement min_output_buf_req; + struct vcd_buffer_requirement client_output_buf_req; + u32 idr_only_decoding; +}; + +union ddl_codec_data { + struct ddl_codec_data_hdr hdr; + struct ddl_decoder_data decoder; + struct ddl_encoder_data encoder; +}; + +struct ddl_context { + int memtype; + u8 *core_virtual_base_addr; + void (*ddl_callback) (u32 event, u32 status, void *payload, size_t sz, + u32 *ddl_handle, void *const client_data); + void *client_data; + void (*interrupt_clr) (void); + enum ddl_cmd_state cmd_state; + struct ddl_client_context *current_ddl; + struct ddl_buf_addr context_buf_addr; + struct ddl_buf_addr db_line_buffer; + struct ddl_buf_addr data_partition_tempbuf; + struct ddl_buf_addr metadata_shared_input; + struct ddl_buf_addr dbg_core_dump; + u32 enable_dbg_core_dump; + struct ddl_client_context *ddl_clients[VCD_MAX_NO_CLIENT]; + u32 device_state; + u32 ddl_busy; + u32 intr_status; + u32 cmd_err_status; + u32 disp_pic_err_status; + u32 op_failed; +}; + +struct ddl_client_context { + struct ddl_context *ddl_context; + enum ddl_client_state client_state; + u32 decoding; + u32 channel_id; + struct ddl_frame_data_tag input_frame; + struct ddl_frame_data_tag output_frame; + union ddl_codec_data codec_data; +}; + +DDL_INLINE struct ddl_context *ddl_get_context(void); +DDL_INLINE void ddl_move_command_state(struct ddl_context *ddl_context, + enum ddl_cmd_state command_state); +DDL_INLINE void ddl_move_client_state(struct ddl_client_context *ddl, + enum ddl_client_state client_state); +void ddl_core_init(struct ddl_context *); +void ddl_core_start_cpu(struct ddl_context *); +void ddl_channel_set(struct ddl_client_context *); +void ddl_channel_end(struct ddl_client_context *); +void ddl_encode_init_codec(struct ddl_client_context *); +void ddl_decode_init_codec(struct ddl_client_context *); +void ddl_encode_frame_run(struct ddl_client_context *); +void ddl_decode_frame_run(struct ddl_client_context *); +void ddl_decode_eos_run(struct ddl_client_context *); +void ddl_release_context_buffers(struct ddl_context *); +void ddl_release_client_internal_buffers(struct ddl_client_context *ddl); +u32 ddl_decode_set_buffers(struct ddl_client_context *); +u32 ddl_decoder_dpb_transact(struct ddl_decoder_data *decoder, + struct ddl_frame_data_tag *in_out_frame, + u32 operation); +u32 ddl_client_transact(u32, struct ddl_client_context **); +void ddl_set_default_decoder_buffer_req + (struct ddl_decoder_data *decoder, u32 estimate); +void ddl_set_default_encoder_buffer_req + (struct ddl_encoder_data *encoder); +void ddl_set_default_dec_property(struct ddl_client_context *); +u32 ddl_encoder_ready_to_start(struct ddl_client_context *); +u32 ddl_decoder_ready_to_start(struct ddl_client_context *, + struct vcd_sequence_hdr *); +u32 ddl_get_yuv_buffer_size + (struct vcd_property_frame_size *frame_size, + struct vcd_property_buffer_format *buf_format, u32 inter_lace, + enum vcd_codec codec); +void ddl_calculate_stride(struct vcd_property_frame_size *frame_size, + u32 inter_lace, enum vcd_codec codec); +void ddl_encode_dynamic_property(struct ddl_client_context *ddl, + u32 enable); +void ddl_decode_dynamic_property(struct ddl_client_context *ddl, + u32 enable); +void ddl_set_initial_default_values(struct ddl_client_context *ddl); +u32 ddl_handle_core_errors(struct ddl_context *ddl_context); +void ddl_client_fatal_cb(struct ddl_context *ddl_context); +void ddl_hw_fatal_cb(struct ddl_context *ddl_context); +u32 ddl_hal_engine_reset(struct ddl_context *ddl_context); +void ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment); +void ddl_pmem_free(struct ddl_buf_addr *addr); +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h new file mode 100644 index 0000000000000000000000000000000000000000..3796e8f7ab5bbdd6be2ed1a5cec96f6c13472742 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2010, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_DDL_API_H_ +#define _VCD_DDL_API_H_ +#include "vcd_ddl_internal_property.h" + +struct ddl_init_config { + int memtype; + u8 *core_virtual_base_addr; + void (*interrupt_clr) (void); + void (*ddl_callback) (u32 event, u32 status, void *payload, size_t sz, + u32 *ddl_handle, void *const client_data); +}; + +struct ddl_frame_data_tag { + struct vcd_frame_data vcd_frm; + u32 frm_trans_end; + u32 frm_delta; +}; + +u32 ddl_device_init(struct ddl_init_config *ddl_init_config, + void *client_data); +u32 ddl_device_release(void *client_data); +u32 ddl_open(u32 **ddl_handle, u32 decoding); +u32 ddl_close(u32 **ddl_handle); +u32 ddl_encode_start(u32 *ddl_handle, void *client_data); +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_end(u32 *ddl_handle, void *client_data); +u32 ddl_decode_start(u32 *ddl_handle, struct vcd_sequence_hdr *header, + void *client_data); +u32 ddl_decode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_bits, void *client_data); +u32 ddl_decode_end(u32 *ddl_handle, void *client_data); +u32 ddl_set_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value); +u32 ddl_get_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value); +void ddl_read_and_clear_interrupt(void); +u32 ddl_process_core_response(void); +u32 ddl_reset_hw(u32 mode); +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h new file mode 100644 index 0000000000000000000000000000000000000000..78b05ec1d04b6b2beff2f018d625da7c11d950dd --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h @@ -0,0 +1,99 @@ +/* Copyright (c) 2010-2011, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_DDL_CORE_H_ +#define _VCD_DDL_CORE_H_ + +#define DDL_LINEAR_BUF_ALIGN_MASK 0xFFFFFFF8U +#define DDL_LINEAR_BUF_ALIGN_GUARD_BYTES 0x7 +#define DDL_LINEAR_BUFFER_ALIGN_BYTES 8 + +#define DDL_TILE_BUF_ALIGN_MASK 0xFFFFE000U +#define DDL_TILE_BUF_ALIGN_GUARD_BYTES 0x1FFF +#define DDL_TILE_BUFFER_ALIGN_BYTES 8192 + +#define DDL_MAX_FRAME_WIDTH (1280) +#define DDL_MAX_FRAME_HEIGHT (720) + +#define DDL_MAX_DP_FRAME_WIDTH 352 +#define DDL_MAX_DP_FRAME_HEIGHT 288 + +#define DDL_MAX_BIT_RATE (14*1000*1000) + +#define DDL_SW_RESET_SLEEP 10 + +#define VCD_MAX_NO_CLIENT 4 +#define VCD_FRAME_COMMAND_DEPTH 1 +#define VCD_GENERAL_COMMAND_DEPTH 1 +#define VCD_COMMAND_EXCLUSIVE true + +#define DDL_HW_TIMEOUT_IN_MS 1000 + +#define DDL_STREAMBUF_ALIGN_GUARD_BYTES 0x7 + +#define DDL_CONTEXT_MEMORY (1024 * 15 * (VCD_MAX_NO_CLIENT + 1)) +#define DDL_DB_LINE_BUF_SIZE \ +(((((DDL_MAX_FRAME_WIDTH * 4) - 1) / 256) + 1) * 8 * 1024) +#define DDL_MPEG4_DATA_PARTITION_BUF_SIZE (64 * 1024) +#define DDL_DECODE_H264_VSPTEMP_BUFSIZE 0x59c00 +#define DDL_ENC_NUM_DPB_BUFFERS 2 + +#define DDL_DBG_CORE_DUMP_SIZE (10 * 1024) + +#define DDL_BUFEND_PAD 256 +#define DDL_ENC_SEQHEADER_SIZE (256+DDL_BUFEND_PAD) +#define DDL_MAX_BUFFER_COUNT 32 + +#define DDL_MPEG_REFBUF_COUNT 2 + +#define DDL_MPEG_COMV_BUF_NO 2 +#define DDL_H263_COMV_BUF_NO 2 +#define DDL_COMV_BUFLINE_NO 128 +#define DDL_VC1_COMV_BUFLINE_NO 32 +#define DDL_MINIMUM_BYTE_PER_SLICE 1920 + +#define DDL_MAX_H264_QP 51 +#define DDL_MAX_MPEG4_QP 31 + +#define DDL_PADDING_HACK(addr) \ + (addr) = (u32)((((u32)(addr) + DDL_STREAMBUF_ALIGN_GUARD_BYTES) & \ + ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES)) + DDL_BUFEND_PAD) + +#define DDL_QCIF_MBS 99 +#define DDL_CIF_MBS 396 +#define DDL_QVGA_MBS 300 +#define DDL_VGA_MBS 1200 +#define DDL_WVGA_MBS 1500 +#define DDL_720P_MBS 3600 + +#define DDL_FRAMESIZE_DIV_FACTOR (0xF) + +#define DDL_NO_OF_MB(width, height) \ + (((width + 15) >> 4) * ((height + 15) >> 4)) + +#define DDL_ALLOW_ENC_FRAMESIZE(width, height) \ +((DDL_NO_OF_MB(width, height) <= DDL_720P_MBS) \ + && (((width) <= DDL_MAX_FRAME_WIDTH) && \ + ((height) <= DDL_MAX_FRAME_WIDTH)) \ + && ((width) >= 32 && (height) >= 32)) + +#define DDL_VALIDATE_ENC_FRAMESIZE(width, height) \ + (!((width) & DDL_FRAMESIZE_DIV_FACTOR) && \ + !((height) & DDL_FRAMESIZE_DIV_FACTOR)) + +#define DDL_TILE_ALIGN_WIDTH 128 +#define DDL_TILE_ALIGN_HEIGHT 32 +#define DDL_TILE_MULTIPLY_FACTOR 8192 +#define DDL_TILE_ALIGN(val, grid) \ + (((val) + (grid) - 1) / (grid) * (grid)) + +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c new file mode 100644 index 0000000000000000000000000000000000000000..17416fb47e3280abcfd9c769f66c4bc7681e3858 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c @@ -0,0 +1,609 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "vcd_ddl_utils.h" +#include "vcd_ddl.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define ERR(x...) printk(KERN_ERR x) + +#define INVALID_CHANNEL_NUMBER 1 +#define INVALID_COMMAND_ID 2 +#define CHANNEL_ALREADY_IN_USE 3 +#define CHANNEL_NOT_SET_BEFORE_CHANNEL_CLOSE 4 +#define CHANNEL_SET_ERROR_INIT_CODEC 5 +#define INIT_CODEC_ALREADY_CALLED 6 +#define CHANNEL_SET_ERROR_INIT_BUFFERS 7 +#define INIT_CODEC_ERROR_INIT_BUFFERS 8 +#define INIT_BUFFER_ALREADY_CALLED 9 +#define CHANNEL_SET_ERROR_FRAME_RUN 10 +#define INIT_CODEC_ERROR_FRAME_RUN 11 +#define INIT_BUFFERS_ERROR_FRAME_RUN 12 +#define CODEC_LIMIT_EXCEEDED 13 +#define FIRMWARE_SIZE_ZERO 14 +#define FIRMWARE_ADDRESS_EXT_ZERO 15 +#define CONTEXT_DMA_IN_ERROR 16 +#define CONTEXT_DMA_OUT_ERROR 17 +#define PROGRAM_DMA_ERROR 18 +#define CONTEXT_STORE_EXT_ADD_ZERO 19 +#define MEM_ALLOCATION_FAILED 20 + + +#define UNSUPPORTED_FEATURE_IN_PROFILE 27 +#define RESOLUTION_NOT_SUPPORTED 28 +#define HEADER_NOT_FOUND 52 +#define MB_NUM_INVALID 61 +#define FRAME_RATE_NOT_SUPPORTED 62 +#define INVALID_QP_VALUE 63 +#define INVALID_RC_REACTION_COEFFICIENT 64 +#define INVALID_CPB_SIZE_AT_GIVEN_LEVEL 65 + +#define ALLOC_DPB_SIZE_NOT_SUFFICIENT 71 +#define ALLOC_DB_SIZE_NOT_SUFFICIENT 72 +#define ALLOC_COMV_SIZE_NOT_SUFFICIENT 73 +#define NUM_BUF_OUT_OF_RANGE 74 +#define NULL_CONTEXT_POINTER 75 +#define NULL_COMAMND_CONTROL_COMM_POINTER 76 +#define NULL_METADATA_INPUT_POINTER 77 +#define NULL_DPB_POINTER 78 +#define NULL_DB_POINTER 79 +#define NULL_COMV_POINTER 80 + +#define DIVIDE_BY_ZERO 81 +#define BIT_STREAM_BUF_EXHAUST 82 +#define DMA_NOT_STOPPED 83 +#define DMA_TX_NOT_COMPLETE 84 + +#define MB_HEADER_NOT_DONE 85 +#define MB_COEFF_NOT_DONE 86 +#define CODEC_SLICE_NOT_DONE 87 +#define VME_NOT_READY 88 +#define VC1_BITPLANE_DECODE_ERR 89 + + +#define VSP_NOT_READY 90 +#define BUFFER_FULL_STATE 91 + +#define RESOLUTION_MISMATCH 112 +#define NV_QUANT_ERR 113 +#define SYNC_MARKER_ERR 114 +#define FEATURE_NOT_SUPPORTED 115 +#define MEM_CORRUPTION 116 +#define INVALID_REFERENCE_FRAME 117 +#define PICTURE_CODING_TYPE_ERR 118 +#define MV_RANGE_ERR 119 +#define PICTURE_STRUCTURE_ERR 120 +#define SLICE_ADDR_INVALID 121 +#define NON_PAIRED_FIELD_NOT_SUPPORTED 122 +#define NON_FRAME_DATA_RECEIVED 123 +#define INCOMPLETE_FRAME 124 +#define NO_BUFFER_RELEASED_FROM_HOST 125 +#define PICTURE_MANAGEMENT_ERROR 128 +#define INVALID_MMCO 129 +#define INVALID_PIC_REORDERING 130 +#define INVALID_POC_TYPE 131 +#define ACTIVE_SPS_NOT_PRESENT 132 +#define ACTIVE_PPS_NOT_PRESENT 133 +#define INVALID_SPS_ID 134 +#define INVALID_PPS_ID 135 + + +#define METADATA_NO_SPACE_QP 151 +#define METADATA_NO_SAPCE_CONCEAL_MB 152 +#define METADATA_NO_SPACE_VC1_PARAM 153 +#define METADATA_NO_SPACE_SEI 154 +#define METADATA_NO_SPACE_VUI 155 +#define METADATA_NO_SPACE_EXTRA 156 +#define METADATA_NO_SPACE_DATA_NONE 157 +#define FRAME_RATE_UNKNOWN 158 +#define ASPECT_RATIO_UNKOWN 159 +#define COLOR_PRIMARIES_UNKNOWN 160 +#define TRANSFER_CHAR_UNKWON 161 +#define MATRIX_COEFF_UNKNOWN 162 +#define NON_SEQ_SLICE_ADDR 163 +#define BROKEN_LINK 164 +#define FRAME_CONCEALED 165 +#define PROFILE_UNKOWN 166 +#define LEVEL_UNKOWN 167 +#define BIT_RATE_NOT_SUPPORTED 168 +#define COLOR_DIFF_FORMAT_NOT_SUPPORTED 169 +#define NULL_EXTRA_METADATA_POINTER 170 +#define SYNC_POINT_NOT_RECEIVED_STARTED_DECODING 171 +#define NULL_FW_DEBUG_INFO_POINTER 172 +#define ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT 173 +#define MAX_STAGE_COUNTER_EXCEEDED 174 + +#define METADATA_NO_SPACE_MB_INFO 180 +#define METADATA_NO_SPACE_SLICE_SIZE 181 +#define RESOLUTION_WARNING 182 + +static void ddl_handle_npf_decoding_error( + struct ddl_context *ddl_context); + +static u32 ddl_handle_seqhdr_fail_error( + struct ddl_context *ddl_context); + +void ddl_hw_fatal_cb(struct ddl_context *ddl_context) +{ + /* Invalidate the command state */ + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + ddl_context->device_state = DDL_DEVICE_HWFATAL; + + /* callback to the client to indicate hw fatal error */ + ddl_context->ddl_callback(VCD_EVT_IND_HWERRFATAL, + VCD_ERR_HW_FATAL, NULL, 0, + (void *)ddl_context->current_ddl, + ddl_context->client_data); + + DDL_IDLE(ddl_context); +} + +static u32 ddl_handle_hw_fatal_errors(struct ddl_context + *ddl_context) +{ + u32 status = false; + + switch (ddl_context->cmd_err_status) { + + case INVALID_CHANNEL_NUMBER: + case INVALID_COMMAND_ID: + case CHANNEL_ALREADY_IN_USE: + case CHANNEL_NOT_SET_BEFORE_CHANNEL_CLOSE: + case CHANNEL_SET_ERROR_INIT_CODEC: + case INIT_CODEC_ALREADY_CALLED: + case CHANNEL_SET_ERROR_INIT_BUFFERS: + case INIT_CODEC_ERROR_INIT_BUFFERS: + case INIT_BUFFER_ALREADY_CALLED: + case CHANNEL_SET_ERROR_FRAME_RUN: + case INIT_CODEC_ERROR_FRAME_RUN: + case INIT_BUFFERS_ERROR_FRAME_RUN: + case CODEC_LIMIT_EXCEEDED: + case FIRMWARE_SIZE_ZERO: + case FIRMWARE_ADDRESS_EXT_ZERO: + + case CONTEXT_DMA_IN_ERROR: + case CONTEXT_DMA_OUT_ERROR: + case PROGRAM_DMA_ERROR: + case CONTEXT_STORE_EXT_ADD_ZERO: + case MEM_ALLOCATION_FAILED: + + case DIVIDE_BY_ZERO: + case DMA_NOT_STOPPED: + case DMA_TX_NOT_COMPLETE: + + case VSP_NOT_READY: + case BUFFER_FULL_STATE: + case NULL_DB_POINTER: + ERR("HW FATAL ERROR"); + ddl_hw_fatal_cb(ddl_context); + status = true; + break; + } + return status; +} + +void ddl_client_fatal_cb(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = + ddl_context->current_ddl; + + if (ddl_context->cmd_state == DDL_CMD_DECODE_FRAME) + ddl_decode_dynamic_property(ddl, false); + else if (ddl_context->cmd_state == DDL_CMD_ENCODE_FRAME) + ddl_encode_dynamic_property(ddl, false); + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + + ddl_move_client_state(ddl, DDL_CLIENT_FATAL_ERROR); + + ddl_context->ddl_callback + ( + VCD_EVT_IND_HWERRFATAL, + VCD_ERR_CLIENT_FATAL, + NULL, + 0, + (void *)ddl, + ddl_context->client_data + ); + + DDL_IDLE(ddl_context); +} + +static u32 ddl_handle_client_fatal_errors(struct ddl_context + *ddl_context) +{ + u32 status = false; + + switch (ddl_context->cmd_err_status) { + case MB_NUM_INVALID: + case FRAME_RATE_NOT_SUPPORTED: + case INVALID_QP_VALUE: + case INVALID_RC_REACTION_COEFFICIENT: + case INVALID_CPB_SIZE_AT_GIVEN_LEVEL: + + case ALLOC_DPB_SIZE_NOT_SUFFICIENT: + case ALLOC_DB_SIZE_NOT_SUFFICIENT: + case ALLOC_COMV_SIZE_NOT_SUFFICIENT: + case NUM_BUF_OUT_OF_RANGE: + case NULL_CONTEXT_POINTER: + case NULL_COMAMND_CONTROL_COMM_POINTER: + case NULL_METADATA_INPUT_POINTER: + case NULL_DPB_POINTER: + case NULL_COMV_POINTER: + { + status = true; + break; + } + } + + if (!status) + ERR("UNKNOWN-OP-FAILED"); + + ddl_client_fatal_cb(ddl_context); + + return true; +} + +static void ddl_input_failed_cb(struct ddl_context *ddl_context, + u32 vcd_event, u32 vcd_status) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + + if (ddl->decoding) + ddl_decode_dynamic_property(ddl, false); + else + ddl_encode_dynamic_property(ddl, false); + + ddl_context->ddl_callback(vcd_event, + vcd_status, &ddl->input_frame, + sizeof(struct ddl_frame_data_tag), + (void *)ddl, ddl_context->client_data); + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); +} + +static u32 ddl_handle_core_recoverable_errors(struct ddl_context \ + *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + u32 vcd_status = VCD_S_SUCCESS; + u32 vcd_event = VCD_EVT_RESP_INPUT_DONE; + u32 eos = false, pending_display = 0, release_mask = 0; + + if (ddl->decoding) + if (ddl_handle_seqhdr_fail_error(ddl_context)) + return true; + + if (ddl_context->cmd_state != DDL_CMD_DECODE_FRAME && + ddl_context->cmd_state != DDL_CMD_ENCODE_FRAME) { + return false; + } + switch (ddl_context->cmd_err_status) { + case NON_PAIRED_FIELD_NOT_SUPPORTED: + { + ddl_handle_npf_decoding_error(ddl_context); + return true; + } + case NO_BUFFER_RELEASED_FROM_HOST: + { + /* lets check sanity of this error */ + release_mask = + ddl->codec_data.decoder.dpb_mask.hw_mask; + while (release_mask > 0) { + if ((release_mask & 0x1)) + pending_display += 1; + release_mask >>= 1; + } + + if (pending_display >= + ddl->codec_data.decoder.min_dpb_num) { + DBG("FWISSUE-REQBUF!!"); + /* callback to client for client fatal error */ + ddl_client_fatal_cb(ddl_context); + return true ; + } + vcd_event = VCD_EVT_RESP_OUTPUT_REQ; + break; + } + case BIT_STREAM_BUF_EXHAUST: + case MB_HEADER_NOT_DONE: + case MB_COEFF_NOT_DONE: + case CODEC_SLICE_NOT_DONE: + case VME_NOT_READY: + case VC1_BITPLANE_DECODE_ERR: + { + u32 reset_core; + /* need to reset the internal core hw engine */ + reset_core = ddl_hal_engine_reset(ddl_context); + if (!reset_core) + return true; + /* fall through to process bitstream error handling */ + } + case RESOLUTION_MISMATCH: + case NV_QUANT_ERR: + case SYNC_MARKER_ERR: + case FEATURE_NOT_SUPPORTED: + case MEM_CORRUPTION: + case INVALID_REFERENCE_FRAME: + case PICTURE_CODING_TYPE_ERR: + case MV_RANGE_ERR: + case PICTURE_STRUCTURE_ERR: + case SLICE_ADDR_INVALID: + case NON_FRAME_DATA_RECEIVED: + case INCOMPLETE_FRAME: + case PICTURE_MANAGEMENT_ERROR: + case INVALID_MMCO: + case INVALID_PIC_REORDERING: + case INVALID_POC_TYPE: + { + vcd_status = VCD_ERR_BITSTREAM_ERR; + break; + } + case ACTIVE_SPS_NOT_PRESENT: + case ACTIVE_PPS_NOT_PRESENT: + { + if (ddl->codec_data.decoder.idr_only_decoding) { + DBG("Consider warnings as errors in idr mode"); + ddl_client_fatal_cb(ddl_context); + return true; + } + vcd_status = VCD_ERR_BITSTREAM_ERR; + break; + } + case PROFILE_UNKOWN: + if (ddl->decoding) + vcd_status = VCD_ERR_BITSTREAM_ERR; + break; + } + + if (!vcd_status && vcd_event == VCD_EVT_RESP_INPUT_DONE) + return false; + + ddl->input_frame.frm_trans_end = true; + + eos = ((vcd_event == VCD_EVT_RESP_INPUT_DONE) && + ((VCD_FRAME_FLAG_EOS & ddl->input_frame. + vcd_frm.flags))); + + if ((ddl->decoding && eos) || + (!ddl->decoding)) + ddl->input_frame.frm_trans_end = false; + + if (vcd_event == VCD_EVT_RESP_INPUT_DONE && + ddl->decoding && + !ddl->codec_data.decoder.header_in_start && + !ddl->codec_data.decoder.dec_disp_info.img_size_x && + !ddl->codec_data.decoder.dec_disp_info.img_size_y + ) { + /* this is first frame seq. header only case */ + vcd_status = VCD_S_SUCCESS; + ddl->input_frame.vcd_frm.flags |= + VCD_FRAME_FLAG_CODECCONFIG; + ddl->input_frame.frm_trans_end = !eos; + /* put just some non - zero value */ + ddl->codec_data.decoder.dec_disp_info.img_size_x = 0xff; + } + /* inform client about input failed */ + ddl_input_failed_cb(ddl_context, vcd_event, vcd_status); + + /* for Encoder case, we need to send output done also */ + if (!ddl->decoding) { + /* transaction is complete after this callback */ + ddl->output_frame.frm_trans_end = !eos; + /* error case: NO data present */ + ddl->output_frame.vcd_frm.data_len = 0; + /* call back to client for output frame done */ + ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_ERR_FAIL, &(ddl->output_frame), + sizeof(struct ddl_frame_data_tag), + (void *)ddl, ddl_context->client_data); + + if (eos) { + DBG("ENC-EOS_DONE"); + /* send client EOS DONE callback */ + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, 0, (void *)ddl, + ddl_context->client_data); + } + } + + /* if it is decoder EOS case */ + if (ddl->decoding && eos) + ddl_decode_eos_run(ddl); + else + DDL_IDLE(ddl_context); + + return true; +} + +static u32 ddl_handle_core_warnings(u32 err_status) +{ + u32 status = false; + + switch (err_status) { + case FRAME_RATE_UNKNOWN: + case ASPECT_RATIO_UNKOWN: + case COLOR_PRIMARIES_UNKNOWN: + case TRANSFER_CHAR_UNKWON: + case MATRIX_COEFF_UNKNOWN: + case NON_SEQ_SLICE_ADDR: + case BROKEN_LINK: + case FRAME_CONCEALED: + case PROFILE_UNKOWN: + case LEVEL_UNKOWN: + case BIT_RATE_NOT_SUPPORTED: + case COLOR_DIFF_FORMAT_NOT_SUPPORTED: + case NULL_EXTRA_METADATA_POINTER: + case SYNC_POINT_NOT_RECEIVED_STARTED_DECODING: + + case NULL_FW_DEBUG_INFO_POINTER: + case ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT: + case MAX_STAGE_COUNTER_EXCEEDED: + + case METADATA_NO_SPACE_MB_INFO: + case METADATA_NO_SPACE_SLICE_SIZE: + case RESOLUTION_WARNING: + + /* decoder warnings */ + case METADATA_NO_SPACE_QP: + case METADATA_NO_SAPCE_CONCEAL_MB: + case METADATA_NO_SPACE_VC1_PARAM: + case METADATA_NO_SPACE_SEI: + case METADATA_NO_SPACE_VUI: + case METADATA_NO_SPACE_EXTRA: + case METADATA_NO_SPACE_DATA_NONE: + { + status = true; + DBG("CMD-WARNING-IGNORED!!"); + break; + } + } + return status; +} + +u32 ddl_handle_core_errors(struct ddl_context *ddl_context) +{ + u32 status = false; + + if (!ddl_context->cmd_err_status && + !ddl_context->disp_pic_err_status && + !ddl_context->op_failed) + return false; + + if (ddl_context->cmd_state == DDL_CMD_INVALID) { + DBG("SPURIOUS_INTERRUPT_ERROR"); + return true; + } + + if (!ddl_context->op_failed) { + u32 disp_status; + status = ddl_handle_core_warnings(ddl_context-> + cmd_err_status); + disp_status = ddl_handle_core_warnings( + ddl_context->disp_pic_err_status); + if (!status && !disp_status) + DBG("ddl_warning:Unknown"); + + return false; + } + + ERR("\n %s(): OPFAILED!!", __func__); + ERR("\n CMD_ERROR_STATUS = %u, DISP_ERR_STATUS = %u", + ddl_context->cmd_err_status, + ddl_context->disp_pic_err_status); + + status = ddl_handle_hw_fatal_errors(ddl_context); + + if (!status) + status = ddl_handle_core_recoverable_errors(ddl_context); + + if (!status) + status = ddl_handle_client_fatal_errors(ddl_context); + + return status; +} + +void ddl_handle_npf_decoding_error(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + if (!ddl->decoding) { + ERR("FWISSUE-ENC-NPF!!!"); + ddl_client_fatal_cb(ddl_context); + return; + } + vidc_720p_decode_display_info(&decoder->dec_disp_info); + ddl_decode_dynamic_property(ddl, false); + ddl->output_frame.vcd_frm.ip_frm_tag = + decoder->dec_disp_info.tag_top; + ddl->output_frame.vcd_frm.physical = NULL; + ddl->output_frame.frm_trans_end = false; + ddl->ddl_context->ddl_callback( + VCD_EVT_RESP_OUTPUT_DONE, + VCD_ERR_INTRLCD_FIELD_DROP, + &ddl->output_frame, + sizeof(struct ddl_frame_data_tag), + (void *)ddl, + ddl->ddl_context->client_data); + ddl_decode_frame_run(ddl); +} + +u32 ddl_handle_seqhdr_fail_error(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + u32 status = false; + if (ddl_context->cmd_state == DDL_CMD_HEADER_PARSE && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { + switch (ddl_context->cmd_err_status) { + case UNSUPPORTED_FEATURE_IN_PROFILE: + case HEADER_NOT_FOUND: + case INVALID_SPS_ID: + case INVALID_PPS_ID: + case RESOLUTION_NOT_SUPPORTED: + case PROFILE_UNKOWN: + ERR("SEQ-HDR-FAILED!!!"); + if ((ddl_context->cmd_err_status == + RESOLUTION_NOT_SUPPORTED) && + (decoder->codec.codec == VCD_CODEC_H264 || + decoder->codec.codec == VCD_CODEC_H263 || + decoder->codec.codec == VCD_CODEC_MPEG4 || + decoder->codec.codec == VCD_CODEC_VC1_RCV || + decoder->codec.codec == VCD_CODEC_VC1)) { + ddl_client_fatal_cb(ddl_context); + status = true; + break; + } + if (decoder->header_in_start) { + decoder->header_in_start = false; + ddl_context->ddl_callback(VCD_EVT_RESP_START, + VCD_ERR_SEQHDR_PARSE_FAIL, + NULL, 0, (void *)ddl, + ddl_context->client_data); + } else { + if (ddl->input_frame.vcd_frm.flags & + VCD_FRAME_FLAG_EOS) + ddl->input_frame.frm_trans_end = false; + else + ddl->input_frame.frm_trans_end = true; + ddl_decode_dynamic_property(ddl, false); + ddl_context->ddl_callback( + VCD_EVT_RESP_INPUT_DONE, + VCD_ERR_SEQHDR_PARSE_FAIL, + &ddl->input_frame, + sizeof(struct ddl_frame_data_tag), + (void *)ddl, ddl_context->client_data); + if (ddl->input_frame.vcd_frm.flags & + VCD_FRAME_FLAG_EOS) + ddl_context->ddl_callback( + VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, + 0, (void *)ddl, + ddl_context->client_data); + } + ddl_move_client_state(ddl, + DDL_CLIENT_WAIT_FOR_INITCODEC); + DDL_IDLE(ddl_context); + status = true; + } + } + return status; +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c new file mode 100644 index 0000000000000000000000000000000000000000..23948d4e8f54645ebafbf6fdd28250121a660af0 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c @@ -0,0 +1,352 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "vcd_ddl_firmware.h" +#include "vcd_ddl_utils.h" + +#define VCDFW_TOTALNUM_IMAGE 7 +#define VCDFW_MAX_NO_IMAGE 2 + +struct vcd_firmware { + u32 active_fw_img[VCDFW_TOTALNUM_IMAGE]; + struct ddl_buf_addr boot_code; + + struct ddl_buf_addr enc_mpeg4; + struct ddl_buf_addr encH264; + + struct ddl_buf_addr dec_mpeg4; + struct ddl_buf_addr decH264; + struct ddl_buf_addr decH263; + struct ddl_buf_addr dec_mpeg2; + struct ddl_buf_addr dec_vc1; +}; + +static struct vcd_firmware vcd_firmware; + + +static void vcd_fw_change_endian(unsigned char *fw, u32 fw_size) +{ + u32 i = 0; + unsigned char temp; + for (i = 0; i < fw_size; i = i + 4) { + temp = fw[i]; + fw[i] = fw[i + 3]; + fw[i + 3] = temp; + + temp = fw[i + 1]; + fw[i + 1] = fw[i + 2]; + fw[i + 2] = temp; + } + return; +} + +static u32 vcd_fw_prepare(struct ddl_buf_addr *fw_details, + const unsigned char fw_array[], + const unsigned int fw_array_size, u32 change_endian) +{ + u32 *buffer; + + ddl_pmem_alloc(fw_details, fw_array_size, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!fw_details->virtual_base_addr) + return false; + + fw_details->buffer_size = fw_array_size / 4; + + buffer = fw_details->align_virtual_addr; + + memcpy(buffer, fw_array, fw_array_size); + if (change_endian) + vcd_fw_change_endian((unsigned char *)buffer, fw_array_size); + return true; +} + +u32 vcd_fw_init(void) +{ + u32 status = false; + + status = vcd_fw_prepare(&vcd_firmware.boot_code, + vidc_command_control_fw, + vidc_command_control_fw_size, false); + + if (status) { + status = vcd_fw_prepare(&vcd_firmware.dec_mpeg4, + vidc_mpg4_dec_fw, + vidc_mpg4_dec_fw_size, true); + } + + if (status) { + status = vcd_fw_prepare(&vcd_firmware.decH264, + vidc_h264_dec_fw, + vidc_h264_dec_fw_size, true); + } + + if (status) { + status = vcd_fw_prepare(&vcd_firmware.decH263, + vidc_h263_dec_fw, + vidc_h263_dec_fw_size, true); + } + + if (status) { + status = vcd_fw_prepare(&vcd_firmware.enc_mpeg4, + vidc_mpg4_enc_fw, + vidc_mpg4_enc_fw_size, true); + } + + if (status) { + status = vcd_fw_prepare(&vcd_firmware.encH264, + vidc_h264_enc_fw, + vidc_h264_enc_fw_size, true); + } + + if (status) { + status = vcd_fw_prepare(&vcd_firmware.dec_vc1, + vidc_vc1_dec_fw, + vidc_vc1_dec_fw_size, true); + } + return status; +} + + +static u32 get_dec_fw_image(struct vcd_fw_details *fw_details) +{ + u32 status = true; + switch (fw_details->codec) { + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + case VCD_CODEC_MPEG4: + { + fw_details->fw_buffer_addr = + vcd_firmware.dec_mpeg4.align_physical_addr; + fw_details->fw_size = + vcd_firmware.dec_mpeg4.buffer_size; + break; + } + case VCD_CODEC_H264: + { + fw_details->fw_buffer_addr = + vcd_firmware.decH264.align_physical_addr; + fw_details->fw_size = + vcd_firmware.decH264.buffer_size; + break; + } + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + { + fw_details->fw_buffer_addr = + vcd_firmware.dec_vc1.align_physical_addr; + fw_details->fw_size = + vcd_firmware.dec_vc1.buffer_size; + break; + } + case VCD_CODEC_MPEG2: + { + fw_details->fw_buffer_addr = + vcd_firmware.dec_mpeg2.align_physical_addr; + fw_details->fw_size = + vcd_firmware.dec_mpeg2.buffer_size; + break; + } + case VCD_CODEC_H263: + { + fw_details->fw_buffer_addr = + vcd_firmware.decH263.align_physical_addr; + fw_details->fw_size = + vcd_firmware.decH263.buffer_size; + break; + } + default: + { + status = false; + break; + } + } + return status; +} + +static u32 get_enc_fw_image(struct vcd_fw_details *fw_details) +{ + u32 status = true; + switch (fw_details->codec) { + case VCD_CODEC_H263: + case VCD_CODEC_MPEG4: + { + fw_details->fw_buffer_addr = + vcd_firmware.enc_mpeg4.align_physical_addr; + fw_details->fw_size = + vcd_firmware.enc_mpeg4.buffer_size; + break; + } + case VCD_CODEC_H264: + { + fw_details->fw_buffer_addr = + vcd_firmware.encH264.align_physical_addr; + fw_details->fw_size = + vcd_firmware.encH264.buffer_size; + break; + } + default: + { + status = false; + break; + } + } + return status; +} + +u32 vcd_get_fw_property(u32 prop_id, void *prop_details) +{ + u32 status = true; + struct vcd_fw_details *fw_details; + switch (prop_id) { + case VCD_FW_ENDIAN: + { + *(u32 *) prop_details = VCD_FW_BIG_ENDIAN; + break; + } + case VCD_FW_BOOTCODE: + { + fw_details = + (struct vcd_fw_details *)prop_details; + fw_details->fw_buffer_addr = + vcd_firmware.boot_code.align_physical_addr; + fw_details->fw_size = + vcd_firmware.boot_code.buffer_size; + break; + } + case VCD_FW_DECODE: + { + fw_details = + (struct vcd_fw_details *)prop_details; + status = get_dec_fw_image(fw_details); + break; + } + case VCD_FW_ENCODE: + { + fw_details = + (struct vcd_fw_details *)prop_details; + status = get_enc_fw_image(fw_details); + break; + } + default: + { + status = false; + break; + } + } + return status; +} + +u32 vcd_fw_transact(u32 add, u32 decoding, enum vcd_codec codec) +{ + u32 status = true; + u32 index = 0, active_fw = 0, loop_count; + + if (decoding) { + switch (codec) { + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + case VCD_CODEC_MPEG4: + { + index = 0; + break; + } + case VCD_CODEC_H264: + { + index = 1; + break; + } + case VCD_CODEC_H263: + { + index = 2; + break; + } + case VCD_CODEC_MPEG2: + { + index = 3; + break; + } + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + { + index = 4; + break; + } + default: + { + status = false; + break; + } + } + } else { + switch (codec) { + case VCD_CODEC_H263: + case VCD_CODEC_MPEG4: + { + index = 5; + break; + } + case VCD_CODEC_H264: + { + index = 6; + break; + } + default: + { + status = false; + break; + } + } + } + + if (!status) + return status; + + if (!add && + vcd_firmware.active_fw_img[index] + ) { + --vcd_firmware.active_fw_img[index]; + return status; + } + + for (loop_count = 0; loop_count < VCDFW_TOTALNUM_IMAGE; + ++loop_count) { + if (vcd_firmware.active_fw_img[loop_count]) + ++active_fw; + } + + if (active_fw < VCDFW_MAX_NO_IMAGE || + vcd_firmware.active_fw_img[index] > 0) { + ++vcd_firmware.active_fw_img[index]; + } else { + status = false; + } + return status; +} + +void vcd_fw_release(void) +{ + ddl_pmem_free(&vcd_firmware.boot_code); + ddl_pmem_free(&vcd_firmware.enc_mpeg4); + ddl_pmem_free(&vcd_firmware.encH264); + ddl_pmem_free(&vcd_firmware.dec_mpeg4); + ddl_pmem_free(&vcd_firmware.decH264); + ddl_pmem_free(&vcd_firmware.decH263); + ddl_pmem_free(&vcd_firmware.dec_mpeg2); + ddl_pmem_free(&vcd_firmware.dec_vc1); +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h new file mode 100644 index 0000000000000000000000000000000000000000..ba8dbcbfcce42f63ad1d0d67e2958e6832a1c167 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_DDL_FIRMWARE_H_ +#define _VCD_DDL_FIRMWARE_H_ +#include + +#define VCD_FW_BIG_ENDIAN 0x0 +#define VCD_FW_LITTLE_ENDIAN 0x1 + +struct vcd_fw_details { + enum vcd_codec codec; + u32 *fw_buffer_addr; + u32 fw_size; +}; + +#define VCD_FW_PROP_BASE 0x0 + +#define VCD_FW_ENDIAN (VCD_FW_PROP_BASE + 0x1) +#define VCD_FW_BOOTCODE (VCD_FW_PROP_BASE + 0x2) +#define VCD_FW_DECODE (VCD_FW_PROP_BASE + 0x3) +#define VCD_FW_ENCODE (VCD_FW_PROP_BASE + 0x4) + +extern unsigned char *vidc_command_control_fw; +extern u32 vidc_command_control_fw_size; +extern unsigned char *vidc_mpg4_dec_fw; +extern u32 vidc_mpg4_dec_fw_size; +extern unsigned char *vidc_h263_dec_fw; +extern u32 vidc_h263_dec_fw_size; +extern unsigned char *vidc_h264_dec_fw; +extern u32 vidc_h264_dec_fw_size; +extern unsigned char *vidc_mpg4_enc_fw; +extern u32 vidc_mpg4_enc_fw_size; +extern unsigned char *vidc_h264_enc_fw; +extern u32 vidc_h264_enc_fw_size; +extern unsigned char *vidc_vc1_dec_fw; +extern u32 vidc_vc1_dec_fw_size; + +u32 vcd_fw_init(void); +u32 vcd_get_fw_property(u32 prop_id, void *prop_details); +u32 vcd_fw_transact(u32 add, u32 decoding, enum vcd_codec codec); +void vcd_fw_release(void); + +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c new file mode 100644 index 0000000000000000000000000000000000000000..4cbd984a47cabc26900cc76dae286acd06aa28f5 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c @@ -0,0 +1,971 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include + +#include "vcd_ddl_utils.h" +#include "vcd_ddl_metadata.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define DBG_INFO(x...) pr_info(x) + +void ddl_core_init(struct ddl_context *ddl_context) +{ + char *psz_version; + struct vcd_fw_details fw_details; + u32 fw_endianness; + enum vidc_720p_endian dma_endian; + u32 interrupt_off; + enum vidc_720p_interrupt_level_selection interrupt_sel; + u32 intr_mask = 0x0; + + vcd_get_fw_property(VCD_FW_BOOTCODE, &fw_details); + vcd_get_fw_property(VCD_FW_ENDIAN, &fw_endianness); + if (fw_endianness == VCD_FW_BIG_ENDIAN) + dma_endian = VIDC_720P_BIG_ENDIAN; + else + dma_endian = VIDC_720P_LITTLE_ENDIAN; + + interrupt_off = false; + interrupt_sel = VIDC_720P_INTERRUPT_LEVEL_SEL; + + intr_mask |= VIDC_720P_INTR_BUFFER_FULL; + intr_mask |= VIDC_720P_INTR_FW_DONE; + intr_mask |= VIDC_720P_INTR_DMA_DONE; + intr_mask |= VIDC_720P_INTR_FRAME_DONE; + + vidc_720p_do_sw_reset(); + + DBG_INFO("Loading CONTROL_FW of FW_SIZE %u\n", + fw_details.fw_size*4); + + vidc_720p_init(&psz_version, + fw_details.fw_size, + fw_details.fw_buffer_addr, + dma_endian, + interrupt_off, interrupt_sel, intr_mask); + return; +} + +void ddl_core_start_cpu(struct ddl_context *ddl_context) +{ + u32 fw_endianness; + enum vidc_720p_endian dma_endian; + u32 dbg_core_dump_buf_size = 0; + + vcd_get_fw_property(VCD_FW_ENDIAN, &fw_endianness); + if (fw_endianness == VCD_FW_BIG_ENDIAN) + dma_endian = VIDC_720P_LITTLE_ENDIAN; + else + dma_endian = VIDC_720P_BIG_ENDIAN; + + ddl_move_command_state(ddl_context, DDL_CMD_CPU_RESET); + + DBG("VSP_BUF_ADDR_SIZE %d", + ddl_context->context_buf_addr.buffer_size); + if (ddl_context->enable_dbg_core_dump) { + dbg_core_dump_buf_size = ddl_context->dbg_core_dump. + buffer_size; + } + + vidc_720p_start_cpu(dma_endian, + ddl_context->context_buf_addr.align_physical_addr, + ddl_context->dbg_core_dump.align_physical_addr, + dbg_core_dump_buf_size); + + VIDC_DEBUG_REGISTER_LOG; +} + +void ddl_channel_set(struct ddl_client_context *ddl) +{ + enum vidc_720p_enc_dec_selection enc_dec_sel; + enum vidc_720p_codec codec; + enum vcd_codec *vcd_codec; + u32 fw_property_id; + struct vcd_fw_details fw_details; + + if (ddl->decoding) { + if (vidc_msg_timing) + ddl_set_core_start_time(__func__, DEC_OP_TIME); + enc_dec_sel = VIDC_720P_DECODER; + fw_property_id = VCD_FW_DECODE; + vcd_codec = &(ddl->codec_data.decoder.codec.codec); + } else { + enc_dec_sel = VIDC_720P_ENCODER; + fw_property_id = VCD_FW_ENCODE; + vcd_codec = &(ddl->codec_data.encoder.codec.codec); + } + switch (*vcd_codec) { + default: + case VCD_CODEC_MPEG4: + { + codec = VIDC_720P_MPEG4; + + if (ddl->decoding) { + vidc_720p_decode_set_mpeg4_data_partitionbuffer + (ddl->ddl_context->data_partition_tempbuf. + align_physical_addr); + } + + break; + } + case VCD_CODEC_H264: + { + codec = VIDC_720P_H264; + break; + } + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + { + codec = VIDC_720P_DIVX; + break; + } + case VCD_CODEC_XVID: + { + codec = VIDC_720P_XVID; + break; + } + case VCD_CODEC_H263: + { + codec = VIDC_720P_H263; + break; + } + case VCD_CODEC_MPEG2: + { + codec = VIDC_720P_MPEG2; + break; + } + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + { + codec = VIDC_720P_VC1; + break; + } + } + + fw_details.codec = *vcd_codec; + vcd_get_fw_property(fw_property_id, &fw_details); + VIDC_DEBUG_REGISTER_LOG; + + ddl_move_command_state(ddl->ddl_context, DDL_CMD_CHANNEL_SET); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_CHDONE); + + DBG_INFO("Loading firmware for CODEC:%u of FW_SIZE:%u\n", + fw_details.codec, fw_details.fw_size*4); + + vidc_720p_set_channel(ddl->channel_id, + enc_dec_sel, + codec, + fw_details.fw_buffer_addr, + fw_details.fw_size); +} + +void ddl_decode_init_codec(struct ddl_client_context *ddl) +{ + u32 seq_h = 0, seq_e = 0, start_byte_num = 0; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vcd_sequence_hdr *seq_hdr = &decoder->decode_config; + enum vidc_720p_memory_access_method mem_access_method; + if (vidc_msg_timing) + ddl_set_core_start_time(__func__, DEC_OP_TIME); + ddl_metadata_enable(ddl); + + vidc_720p_decode_set_error_control(true); + + vidc_720p_decode_set_mpeg4Post_filter(decoder->post_filter. + post_filter); + + if (decoder->codec.codec == VCD_CODEC_H264) { + vidc_720p_decode_setH264VSPBuffer(decoder-> + h264Vsp_temp_buffer. + align_physical_addr); + VIDC_LOG1("VSP_BUF_ADDR_SIZE", + decoder->h264Vsp_temp_buffer.buffer_size); + } + + if (decoder->codec.codec == VCD_CODEC_VC1_RCV || + decoder->codec.codec == VCD_CODEC_VC1) { + vidc_720p_set_frame_size(decoder->client_frame_size.width, + decoder->client_frame_size.height); + } else { + vidc_720p_set_frame_size(0x0, 0x0); + } + + switch (decoder->buf_format.buffer_format) { + default: + case VCD_BUFFER_FORMAT_NV12: + { + mem_access_method = VIDC_720P_TILE_LINEAR; + break; + } + case VCD_BUFFER_FORMAT_TILE_4x2: + { + mem_access_method = VIDC_720P_TILE_64x32; + break; + } + } + VIDC_LOG_STRING("HEADER-PARSE-START"); + VIDC_DEBUG_REGISTER_LOG; + seq_h = (u32) seq_hdr->sequence_header; + start_byte_num = 8 - (seq_h & DDL_STREAMBUF_ALIGN_GUARD_BYTES); + seq_e = seq_h + seq_hdr->sequence_header_len; + seq_h &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + DDL_PADDING_HACK(seq_e); + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE); + ddl_move_command_state(ddl->ddl_context, DDL_CMD_HEADER_PARSE); + + vidc_720p_decode_bitstream_header(ddl->channel_id, + seq_hdr->sequence_header_len, + start_byte_num, + seq_h, + seq_e, + mem_access_method, + decoder->output_order); +} + +void ddl_decode_dynamic_property(struct ddl_client_context *ddl, + u32 enable) +{ + uint8_t *temp = NULL; + u32 extra_datastart = 0; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vcd_frame_data *bit_stream = + &(ddl->input_frame.vcd_frm); + + if (!enable) { + if (decoder->dynmic_prop_change_req) { + decoder->dynmic_prop_change_req = false; + vidc_720p_decode_dynamic_req_reset(); + } + return; + } + if ((decoder->dynamic_prop_change & + DDL_DEC_REQ_OUTPUT_FLUSH)) { + decoder->dynmic_prop_change_req = true; + decoder->dynamic_prop_change &= ~(DDL_DEC_REQ_OUTPUT_FLUSH); + decoder->dpb_mask.hw_mask = 0; + vidc_720p_decode_dynamic_req_set(VIDC_720P_FLUSH_REQ); + } + if (((decoder->meta_data_enable_flag & VCD_METADATA_PASSTHROUGH)) + && ((VCD_FRAME_FLAG_EXTRADATA & bit_stream->flags)) + ) { + + temp = ((uint8_t *)bit_stream->physical + + bit_stream->offset + + bit_stream->data_len + 3); + + extra_datastart = (u32) ((u32)temp & ~3); + decoder->dynmic_prop_change_req = true; + + vidc_720p_decode_setpassthrough_start(extra_datastart); + + vidc_720p_decode_dynamic_req_set(VIDC_720P_EXTRADATA); + } +} + +void ddl_encode_dynamic_property(struct ddl_client_context *ddl, + u32 enable) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + u32 enc_param_change = 0; + + if (!enable) { + if (encoder->dynmic_prop_change_req) { + encoder->dynmic_prop_change_req = false; + encoder->ext_enc_control_val &= + ~(VIDC_720P_ENC_IFRAME_REQ); + vidc_720p_encode_set_control_param + (encoder->ext_enc_control_val); + vidc_720p_encoder_set_param_change(enc_param_change); + } + return; + } + if ((encoder->dynamic_prop_change & DDL_ENC_REQ_IFRAME)) { + encoder->dynamic_prop_change &= ~(DDL_ENC_REQ_IFRAME); + encoder->ext_enc_control_val |= VIDC_720P_ENC_IFRAME_REQ; + vidc_720p_encode_set_control_param + (encoder->ext_enc_control_val); + } + if ((encoder->dynamic_prop_change & DDL_ENC_CHANGE_BITRATE)) { + vidc_720p_encode_set_bit_rate( + encoder->target_bit_rate.target_bitrate); + enc_param_change |= VIDC_720P_ENC_BITRATE_CHANGE; + encoder->dynamic_prop_change &= ~(DDL_ENC_CHANGE_BITRATE); + } + if ((encoder->dynamic_prop_change & DDL_ENC_CHANGE_CIR)) { + vidc_720p_encode_set_intra_refresh_mb_number( + encoder->intra_refresh.cir_mb_number); + encoder->dynamic_prop_change &= ~(DDL_ENC_CHANGE_CIR); + } + if ((encoder->dynamic_prop_change & DDL_ENC_CHANGE_IPERIOD)) { + vidc_720p_encode_set_i_period + (encoder->i_period.p_frames); + enc_param_change |= VIDC_720P_ENC_IPERIOD_CHANGE; + encoder->dynamic_prop_change &= ~(DDL_ENC_CHANGE_IPERIOD); + } + if ((encoder->dynamic_prop_change & + DDL_ENC_CHANGE_FRAMERATE)) { + vidc_720p_encode_set_fps + ((encoder->frame_rate.fps_numerator * 1000) / + encoder->frame_rate.fps_denominator); + enc_param_change |= VIDC_720P_ENC_FRAMERATE_CHANGE; + encoder->dynamic_prop_change &= ~(DDL_ENC_CHANGE_FRAMERATE); + } + if (enc_param_change) + vidc_720p_encoder_set_param_change(enc_param_change); +} + +static void ddl_encode_set_profile_level(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + u32 profile; + u32 level; + + switch (encoder->profile.profile) { + default: + case VCD_PROFILE_MPEG4_SP: + { + profile = VIDC_720P_PROFILE_MPEG4_SP; + break; + } + case VCD_PROFILE_MPEG4_ASP: + { + profile = VIDC_720P_PROFILE_MPEG4_ASP; + break; + } + case VCD_PROFILE_H264_BASELINE: + { + profile = VIDC_720P_PROFILE_H264_CPB; + break; + } + case VCD_PROFILE_H264_MAIN: + { + profile = VIDC_720P_PROFILE_H264_MAIN; + break; + } + case VCD_PROFILE_H264_HIGH: + { + profile = VIDC_720P_PROFILE_H264_HIGH; + break; + } + case VCD_PROFILE_H263_BASELINE: + { + profile = VIDC_720P_PROFILE_H263_BASELINE; + break; + } + } + switch (encoder->level.level) { + default: + case VCD_LEVEL_MPEG4_0: + { + level = VIDC_720P_MPEG4_LEVEL0; + break; + } + case VCD_LEVEL_MPEG4_0b: + { + level = VIDC_720P_MPEG4_LEVEL0b; + break; + } + case VCD_LEVEL_MPEG4_1: + { + level = VIDC_720P_MPEG4_LEVEL1; + break; + } + case VCD_LEVEL_MPEG4_2: + { + level = VIDC_720P_MPEG4_LEVEL2; + break; + } + case VCD_LEVEL_MPEG4_3: + { + level = VIDC_720P_MPEG4_LEVEL3; + break; + } + case VCD_LEVEL_MPEG4_3b: + { + level = VIDC_720P_MPEG4_LEVEL3b; + break; + } + + case VCD_LEVEL_MPEG4_4: + case VCD_LEVEL_MPEG4_4a: + { + level = VIDC_720P_MPEG4_LEVEL4a; + break; + } + case VCD_LEVEL_MPEG4_5: + { + level = VIDC_720P_MPEG4_LEVEL5; + break; + } + case VCD_LEVEL_MPEG4_6: + { + level = VIDC_720P_MPEG4_LEVEL6; + break; + } + case VCD_LEVEL_H264_1: + { + level = VIDC_720P_H264_LEVEL1; + break; + } + case VCD_LEVEL_H264_1b: + { + level = VIDC_720P_H264_LEVEL1b; + break; + } + case VCD_LEVEL_H264_1p1: + { + level = VIDC_720P_H264_LEVEL1p1; + break; + } + case VCD_LEVEL_H264_1p2: + { + level = VIDC_720P_H264_LEVEL1p2; + break; + } + case VCD_LEVEL_H264_1p3: + { + level = VIDC_720P_H264_LEVEL1p3; + break; + } + case VCD_LEVEL_H264_2: + { + level = VIDC_720P_H264_LEVEL2; + break; + } + case VCD_LEVEL_H264_2p1: + { + level = VIDC_720P_H264_LEVEL2p1; + break; + } + case VCD_LEVEL_H264_2p2: + { + level = VIDC_720P_H264_LEVEL2p2; + break; + } + case VCD_LEVEL_H264_3: + { + level = VIDC_720P_H264_LEVEL3; + break; + } + case VCD_LEVEL_H264_3p1: + { + level = VIDC_720P_H264_LEVEL3p1; + break; + } + case VCD_LEVEL_H263_10: + { + level = VIDC_720P_H263_LEVEL10; + break; + } + case VCD_LEVEL_H263_20: + { + level = VIDC_720P_H263_LEVEL20; + break; + } + case VCD_LEVEL_H263_30: + { + level = VIDC_720P_H263_LEVEL30; + break; + } + case VCD_LEVEL_H263_40: + { + level = VIDC_720P_H263_LEVEL40; + break; + } + case VCD_LEVEL_H263_45: + { + level = VIDC_720P_H263_LEVEL45; + break; + } + case VCD_LEVEL_H263_50: + { + level = VIDC_720P_H263_LEVEL50; + break; + } + case VCD_LEVEL_H263_60: + { + level = VIDC_720P_H263_LEVEL60; + break; + } + case VCD_LEVEL_H263_70: + { + level = VIDC_720P_H263_LEVEL70; + break; + } + } + vidc_720p_encode_set_profile(profile, level); +} + +void ddl_encode_init_codec(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + enum vidc_720p_memory_access_method mem_access_method; + enum vidc_720p_DBConfig db_config; + enum vidc_720p_MSlice_selection m_slice_sel; + + ddl_encode_set_profile_level(ddl); + + vidc_720p_set_frame_size + (encoder->frame_size.width, encoder->frame_size.height); + vidc_720p_encode_set_qp_params + (encoder->qp_range.max_qp, encoder->qp_range.min_qp); + vidc_720p_encode_set_rc_config + (encoder->rc_level.frame_level_rc, + encoder->rc_level.mb_level_rc, + encoder->session_qp.i_frame_qp, + encoder->session_qp.p_frame_qp); + + if (encoder->r_cframe_skip) { + if (encoder->vb_vbuffer_size) { + encoder->ext_enc_control_val = (0x2 << 0x2) | + (encoder->vb_vbuffer_size << 0x10); + } else + encoder->ext_enc_control_val = (0x1 << 2); + } else + encoder->ext_enc_control_val = 0; + + vidc_720p_encode_set_fps + ((encoder->frame_rate.fps_numerator * 1000) / + encoder->frame_rate.fps_denominator); + + vidc_720p_encode_set_vop_time( + encoder->vop_timing.vop_time_resolution, 0); + + if (encoder->rc_level.frame_level_rc) { + vidc_720p_encode_set_bit_rate + (encoder->target_bit_rate.target_bitrate); + + vidc_720p_encode_set_frame_level_rc_params + (encoder->frame_level_rc.reaction_coeff); + } + if (encoder->rc_level.mb_level_rc) { + vidc_720p_encode_set_mb_level_rc_params + (encoder->adaptive_rc.dark_region_as_flag, + encoder->adaptive_rc.smooth_region_as_flag, + encoder->adaptive_rc.static_region_as_flag, + encoder->adaptive_rc.activity_region_flag); + } + if (encoder->codec.codec == VCD_CODEC_MPEG4) { + vidc_720p_encode_set_short_header + (encoder->short_header.short_header); + + if (encoder->hdr_ext_control) { + vidc_720p_encode_set_hec_period + (encoder->hdr_ext_control); + encoder->ext_enc_control_val |= (0x1 << 0x1); + } + } + /* set extended encoder control settings */ + vidc_720p_encode_set_control_param + (encoder->ext_enc_control_val); + + if (encoder->codec.codec == VCD_CODEC_H264) { + enum vidc_720p_entropy_sel entropy_sel; + enum vidc_720p_cabac_model cabac_model_number; + switch (encoder->entropy_control.entropy_sel) { + default: + case VCD_ENTROPY_SEL_CAVLC: + { + entropy_sel = VIDC_720P_ENTROPY_SEL_CAVLC; + break; + } + case VCD_ENTROPY_SEL_CABAC: + { + entropy_sel = VIDC_720P_ENTROPY_SEL_CABAC; + break; + } + } + switch (encoder->entropy_control.cabac_model) { + default: + case VCD_CABAC_MODEL_NUMBER_0: + { + cabac_model_number = + VIDC_720P_CABAC_MODEL_NUMBER_0; + break; + } + case VCD_CABAC_MODEL_NUMBER_1: + { + cabac_model_number = + VIDC_720P_CABAC_MODEL_NUMBER_1; + break; + } + case VCD_CABAC_MODEL_NUMBER_2: + { + cabac_model_number = + VIDC_720P_CABAC_MODEL_NUMBER_2; + break; + } + } + vidc_720p_encode_set_entropy_control + (entropy_sel, cabac_model_number); + switch (encoder->db_control.db_config) { + default: + case VCD_DB_ALL_BLOCKING_BOUNDARY: + { + db_config = + VIDC_720P_DB_ALL_BLOCKING_BOUNDARY; + break; + } + case VCD_DB_DISABLE: + { + db_config = + VIDC_720P_DB_DISABLE; + break; + } + case VCD_DB_SKIP_SLICE_BOUNDARY: + { + db_config = + VIDC_720P_DB_SKIP_SLICE_BOUNDARY; + break; + } + } + vidc_720p_encode_set_db_filter_control + (db_config, + encoder->db_control.slice_alpha_offset, + encoder->db_control.slice_beta_offset); + } + + vidc_720p_encode_set_intra_refresh_mb_number + (encoder->intra_refresh.cir_mb_number); + + switch (encoder->multi_slice.m_slice_sel) { + default: + case VCD_MSLICE_OFF: + m_slice_sel = VIDC_720P_MSLICE_OFF; + break; + case VCD_MSLICE_BY_MB_COUNT: + { + m_slice_sel = VIDC_720P_MSLICE_BY_MB_COUNT; + break; + } + case VCD_MSLICE_BY_BYTE_COUNT: + { + m_slice_sel = VIDC_720P_MSLICE_BY_BYTE_COUNT; + break; + } + case VCD_MSLICE_BY_GOB: + { + m_slice_sel = VIDC_720P_MSLICE_BY_GOB; + break; + } + } + vidc_720p_encode_set_multi_slice_info + (m_slice_sel, encoder->multi_slice.m_slice_size); + + vidc_720p_encode_set_dpb_buffer + (encoder->enc_dpb_addr.align_physical_addr, + encoder->enc_dpb_addr.buffer_size); + + VIDC_LOG1("ENC_DPB_ADDR_SIZE", encoder->enc_dpb_addr.buffer_size); + + vidc_720p_encode_set_i_period(encoder->i_period.p_frames); + + ddl_metadata_enable(ddl); + + if (encoder->seq_header.virtual_base_addr) { + u32 ext_buffer_start, ext_buffer_end, start_byte_num; + ext_buffer_start = + (u32) encoder->seq_header.align_physical_addr; + ext_buffer_end = + ext_buffer_start + encoder->seq_header.buffer_size; + start_byte_num = + (ext_buffer_start & DDL_STREAMBUF_ALIGN_GUARD_BYTES); + ext_buffer_start &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + ext_buffer_end &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + VIDC_LOG1("ENC_SEQHDR_ALLOC_SIZE", + encoder->seq_header.buffer_size); + vidc_720p_encode_set_seq_header_buffer(ext_buffer_start, + ext_buffer_end, + start_byte_num); + } + + if (encoder->re_con_buf_format.buffer_format == + VCD_BUFFER_FORMAT_NV12) + mem_access_method = VIDC_720P_TILE_LINEAR; + else + mem_access_method = VIDC_720P_TILE_16x16; + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE); + ddl_move_command_state(ddl->ddl_context, DDL_CMD_INIT_CODEC); + + vidc_720p_encode_init_codec(ddl->channel_id, mem_access_method); +} + +void ddl_channel_end(struct ddl_client_context *ddl) +{ + VIDC_DEBUG_REGISTER_LOG; + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_CHEND); + ddl_move_command_state(ddl->ddl_context, DDL_CMD_CHANNEL_END); + + vidc_720p_submit_command(ddl->channel_id, VIDC_720P_CMD_CHEND); +} + +void ddl_encode_frame_run(struct ddl_client_context *ddl) +{ + u32 ext_buffer_start, ext_buffer_end; + u32 y_addr, c_addr; + u32 start_byte_number = 0; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + struct vcd_frame_data *stream = &(ddl->output_frame.vcd_frm); + + ext_buffer_start = (u32) stream->physical + stream->offset; + ext_buffer_end = ddl_encode_set_metadata_output_buf(ddl); + start_byte_number = + (ext_buffer_start & DDL_STREAMBUF_ALIGN_GUARD_BYTES); + if (start_byte_number) { + u32 upper_data, lower_data; + u32 *align_virtual_addr; + ext_buffer_start &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + align_virtual_addr = (u32 *) (((u32) stream->virtual + + stream->offset) - + start_byte_number); + upper_data = *align_virtual_addr; + align_virtual_addr++; + lower_data = *align_virtual_addr; + vidc_720p_encode_unalign_bitstream(upper_data, lower_data); + } + + y_addr = (u32) ddl->input_frame.vcd_frm.physical + + ddl->input_frame.vcd_frm.offset; + c_addr = (y_addr + (encoder->frame_size.scan_lines * + encoder->frame_size.stride)); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE); + ddl_move_command_state(ddl->ddl_context, DDL_CMD_ENCODE_FRAME); + + if (encoder->dynamic_prop_change) { + encoder->dynmic_prop_change_req = true; + ddl_encode_dynamic_property(ddl, true); + } + vidc_720p_encode_set_vop_time( + encoder->vop_timing.vop_time_resolution, + ddl->input_frame.frm_delta + ); + + vidc_720p_encode_frame(ddl->channel_id, + ext_buffer_start, + ext_buffer_end, + start_byte_number, y_addr, c_addr); +} + +u32 ddl_decode_set_buffers(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + u32 comv_buf_size = DDL_COMV_BUFLINE_NO, comv_buf_no = 0; + u32 ref_buf_no = 0; + struct ddl_context *ddl_ctxt = NULL; + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) { + VIDC_LOG_STRING("STATE-CRITICAL"); + return VCD_ERR_FAIL; + } + if (vidc_msg_timing) + ddl_set_core_start_time(__func__, DEC_OP_TIME); + switch (decoder->codec.codec) { + default: + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + case VCD_CODEC_MPEG2: + case VCD_CODEC_MPEG4: + { + comv_buf_no = DDL_MPEG_COMV_BUF_NO; + ref_buf_no = DDL_MPEG_REFBUF_COUNT; + break; + } + case VCD_CODEC_H263: + { + comv_buf_no = DDL_H263_COMV_BUF_NO; + break; + } + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + { + comv_buf_no = + decoder->client_output_buf_req.actual_count + 1; + comv_buf_size = DDL_VC1_COMV_BUFLINE_NO; + break; + } + case VCD_CODEC_H264: + { + if (decoder->idr_only_decoding) + comv_buf_no = decoder->min_dpb_num; + else + comv_buf_no = + decoder-> + client_output_buf_req. + actual_count; + break; + } + } + + if (comv_buf_no) { + comv_buf_size *= (comv_buf_no * + (decoder->client_frame_size.stride >> 4) * + ((decoder->client_frame_size.scan_lines >> 4) + 1)); + if (decoder->dpb_comv_buffer.virtual_base_addr) + ddl_pmem_free(&decoder->dpb_comv_buffer); + ddl_pmem_alloc(&decoder->dpb_comv_buffer, comv_buf_size, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!decoder->dpb_comv_buffer.virtual_base_addr) { + VIDC_LOGERR_STRING + ("Dec_set_buf:Comv_buf_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + vidc_720p_decode_set_comv_buffer(decoder->dpb_comv_buffer. + align_physical_addr, + decoder->dpb_comv_buffer. + buffer_size); + } + decoder->ref_buffer.align_physical_addr = NULL; + if (ref_buf_no) { + size_t sz, align_bytes, y_sz, frm_sz; + u32 i = 0; + sz = decoder->dp_buf.dec_pic_buffers[0].vcd_frm.alloc_len; + frm_sz = sz; + y_sz = decoder->client_frame_size.height * + decoder->client_frame_size.width; + sz *= ref_buf_no; + align_bytes = decoder->client_output_buf_req.align; + if (decoder->ref_buffer.virtual_base_addr) + ddl_pmem_free(&decoder->ref_buffer); + ddl_pmem_alloc(&decoder->ref_buffer, sz, align_bytes); + if (!decoder->ref_buffer.virtual_base_addr) { + ddl_pmem_free(&decoder->dpb_comv_buffer); + VIDC_LOGERR_STRING + ("Dec_set_buf:mpeg_ref_buf_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + memset((u8 *)decoder->ref_buffer.virtual_base_addr, + 0x80, sz); + for (i = 0; i < ref_buf_no; i++) + memset((u8 *)decoder->ref_buffer.align_virtual_addr + + i*frm_sz, 0x10, y_sz); + } + ddl_decode_set_metadata_output(decoder); + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_INIT); + ddl_ctxt = ddl_get_context(); + vidc_720p_set_deblock_line_buffer( + ddl_ctxt->db_line_buffer.align_physical_addr, + ddl_ctxt->db_line_buffer.buffer_size); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_DPBDONE); + ddl_move_command_state(ddl->ddl_context, DDL_CMD_DECODE_SET_DPB); + + vidc_720p_submit_command(ddl->channel_id, + VIDC_720P_CMD_INITBUFFERS); + return VCD_S_SUCCESS; +} + +void ddl_decode_frame_run(struct ddl_client_context *ddl) +{ + u32 ext_buffer_start = 0, ext_buffer_end = 0; + u32 start_byte_num = 8; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct vcd_frame_data *bit_stream = + &(ddl->input_frame.vcd_frm); + if (vidc_msg_timing) { + ddl_set_core_start_time(__func__, DEC_OP_TIME); + ddl_set_core_start_time(__func__, DEC_IP_TIME); + } + if (!bit_stream->data_len || + !bit_stream->physical) { + ddl_decode_eos_run(ddl); + return; + } + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE); + + ddl_decode_dynamic_property(ddl, true); + + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK); + + ext_buffer_start = (u32)bit_stream->physical + + bit_stream->offset; + start_byte_num = 8 - (ext_buffer_start & + DDL_STREAMBUF_ALIGN_GUARD_BYTES); + ext_buffer_end = ext_buffer_start + bit_stream->data_len; + ext_buffer_start &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + DDL_PADDING_HACK(ext_buffer_end); + + ddl_move_command_state(ddl->ddl_context, DDL_CMD_DECODE_FRAME); + + vidc_720p_decode_frame(ddl->channel_id, + ext_buffer_start, + ext_buffer_end, + bit_stream->data_len, + start_byte_num, bit_stream->ip_frm_tag); +} + +void ddl_decode_eos_run(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE); + + ddl_decode_dynamic_property(ddl, true); + + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK); + + decoder->dynmic_prop_change_req = true; + + ddl_move_command_state(ddl->ddl_context, DDL_CMD_EOS); + + vidc_720p_issue_eos(ddl->channel_id); +} + +u32 ddl_hal_engine_reset(struct ddl_context *ddl_context) +{ + u32 eng_reset; + u32 channel_id = 0; + u32 fw_endianness; + enum vidc_720p_endian dma_endian; + enum vidc_720p_interrupt_level_selection interrupt_sel; + u32 intr_mask = 0x0; + + if (ddl_context->current_ddl) + channel_id = ddl_context->current_ddl->channel_id; + + interrupt_sel = VIDC_720P_INTERRUPT_LEVEL_SEL; + /* Enable all the supported interrupt */ + intr_mask |= VIDC_720P_INTR_BUFFER_FULL; + intr_mask |= VIDC_720P_INTR_FW_DONE; + intr_mask |= VIDC_720P_INTR_DMA_DONE; + intr_mask |= VIDC_720P_INTR_FRAME_DONE; + + vcd_get_fw_property(VCD_FW_ENDIAN, &fw_endianness); + /* Reverse the endianness settings after boot code download */ + if (fw_endianness == VCD_FW_BIG_ENDIAN) + dma_endian = VIDC_720P_LITTLE_ENDIAN; + else + dma_endian = VIDC_720P_BIG_ENDIAN; + + /* Need to reset MFC silently */ + eng_reset = vidc_720p_engine_reset( + channel_id, + dma_endian, interrupt_sel, + intr_mask); + if (!eng_reset) { + /* call the hw fatal callback if engine reset fails */ + ddl_hw_fatal_cb(ddl_context); + } + return eng_reset ; +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c new file mode 100644 index 0000000000000000000000000000000000000000..b97fae6a32f7669081bef5154de8e7c8081e90bb --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c @@ -0,0 +1,297 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "vcd_ddl_utils.h" + +DDL_INLINE struct ddl_context *ddl_get_context(void) +{ + static struct ddl_context ddl_context; + return &ddl_context; +} + +DDL_INLINE void ddl_move_client_state(struct ddl_client_context *ddl, + enum ddl_client_state client_state) +{ + ddl->client_state = client_state; +} + +DDL_INLINE void ddl_move_command_state(struct ddl_context *ddl_context, + enum ddl_cmd_state command_state) +{ + ddl_context->cmd_state = command_state; +} + +u32 ddl_client_transact(u32 operation, + struct ddl_client_context **pddl_client) +{ + u32 ret_status = VCD_ERR_FAIL; + u32 counter; + struct ddl_context *ddl_context; + + ddl_context = ddl_get_context(); + switch (operation) { + case DDL_FREE_CLIENT: + { + if (pddl_client && *pddl_client) { + u32 channel_id; + channel_id = (*pddl_client)->channel_id; + if (channel_id < VCD_MAX_NO_CLIENT) { + ddl_context-> + ddl_clients[channel_id] = NULL; + } else { + VIDC_LOG_STRING("CHID_CORRUPTION"); + } + DDL_FREE(*pddl_client); + ret_status = VCD_S_SUCCESS; + } + break; + } + case DDL_GET_CLIENT: + { + ret_status = VCD_ERR_MAX_CLIENT; + for (counter = 0; counter < VCD_MAX_NO_CLIENT && + ret_status == VCD_ERR_MAX_CLIENT; ++counter) { + if (!ddl_context->ddl_clients[counter]) { + *pddl_client = + (struct ddl_client_context *) + DDL_MALLOC(sizeof + (struct ddl_client_context) + ); + if (!*pddl_client) { + ret_status = VCD_ERR_ALLOC_FAIL; + } else { + DDL_MEMSET(*pddl_client, 0, + sizeof(struct + ddl_client_context)); + ddl_context-> + ddl_clients[counter] = + *pddl_client; + (*pddl_client)->channel_id = + counter; + (*pddl_client)->ddl_context = + ddl_context; + ret_status = VCD_S_SUCCESS; + } + } + } + break; + } + case DDL_INIT_CLIENTS: + { + for (counter = 0; counter < VCD_MAX_NO_CLIENT; + ++counter) { + ddl_context->ddl_clients[counter] = NULL; + } + ret_status = VCD_S_SUCCESS; + break; + } + case DDL_ACTIVE_CLIENT: + { + for (counter = 0; counter < VCD_MAX_NO_CLIENT; + ++counter) { + if (ddl_context->ddl_clients[counter]) { + ret_status = VCD_S_SUCCESS; + break; + } + } + break; + } + default: + { + ret_status = VCD_ERR_ILLEGAL_PARM; + break; + } + } + return ret_status; +} + +u32 ddl_decoder_dpb_transact(struct ddl_decoder_data *decoder, + struct ddl_frame_data_tag *in_out_frame, + u32 operation) +{ + u32 vcd_status = VCD_S_SUCCESS; + u32 loopc; + struct ddl_frame_data_tag *found_frame = NULL; + struct ddl_mask *dpb_mask = &decoder->dpb_mask; + u32 temp_mask; + + switch (operation) { + case DDL_DPB_OP_MARK_BUSY: + case DDL_DPB_OP_MARK_FREE: + { + for (loopc = 0; !found_frame && + loopc < decoder->dp_buf.no_of_dec_pic_buf; + ++loopc) { + if (in_out_frame->vcd_frm.physical == + decoder->dp_buf. + dec_pic_buffers[loopc].vcd_frm. + physical) { + found_frame = + &(decoder->dp_buf. + dec_pic_buffers[loopc]); + break; + } + } + + if (found_frame) { + if (operation == DDL_DPB_OP_MARK_BUSY) { + temp_mask = (~(0x1 << loopc)); + if (decoder->idr_only_decoding) + temp_mask = ~(0xffffffff); + dpb_mask->hw_mask &= temp_mask; + *in_out_frame = *found_frame; + } else if (operation == + DDL_DPB_OP_MARK_FREE) { + temp_mask = (0x1 << loopc); + if (decoder->idr_only_decoding) + temp_mask = 0xffffffff; + dpb_mask->client_mask |= temp_mask; + *found_frame = *in_out_frame; + } + } else { + in_out_frame->vcd_frm.physical = NULL; + in_out_frame->vcd_frm.virtual = NULL; + vcd_status = VCD_ERR_BAD_POINTER; + VIDC_LOG_STRING("BUF_NOT_FOUND"); + } + break; + } + case DDL_DPB_OP_SET_MASK: + { + dpb_mask->hw_mask |= dpb_mask->client_mask; + dpb_mask->client_mask = 0; + vidc_720p_decode_set_dpb_release_buffer_mask + (dpb_mask->hw_mask); + break; + } + case DDL_DPB_OP_INIT: + { + u32 dpb_size, index, num_dpb; + dpb_size = (!decoder->meta_data_offset) ? + decoder->dp_buf.dec_pic_buffers[0].vcd_frm. + alloc_len : decoder->meta_data_offset; + if (decoder->idr_only_decoding) + num_dpb = decoder->min_dpb_num; + else + num_dpb = decoder->dp_buf.no_of_dec_pic_buf; + vidc_720p_decode_set_dpb_details( + num_dpb, + dpb_size, + decoder->ref_buffer. + align_physical_addr); + for (loopc = 0; loopc < num_dpb; ++loopc) { + if (decoder->idr_only_decoding) + index = 0; + else + index = loopc; + vidc_720p_decode_set_dpb_buffers(loopc, + (u32 *) + decoder-> + dp_buf. + dec_pic_buffers + [index]. + vcd_frm. + physical); + VIDC_LOG1("DEC_DPB_BUFn_SIZE=%d", + decoder->dp_buf. + dec_pic_buffers[index].vcd_frm. + alloc_len); + } + break; + } + case DDL_DPB_OP_RETRIEVE: + { + u32 position; + if (dpb_mask->client_mask) { + position = 0x1; + for (loopc = 0; + loopc < + decoder->dp_buf.no_of_dec_pic_buf + && !found_frame; ++loopc) { + if (dpb_mask-> + client_mask & position) { + found_frame = + &decoder->dp_buf. + dec_pic_buffers[loopc]; + dpb_mask->client_mask &= + ~(position); + } + position <<= 1; + } + } else if (dpb_mask->hw_mask) { + position = 0x1; + for (loopc = 0; + loopc < + decoder->dp_buf.no_of_dec_pic_buf + && !found_frame; ++loopc) { + if (dpb_mask->hw_mask + & position) { + found_frame = + &decoder->dp_buf. + dec_pic_buffers[loopc]; + dpb_mask->hw_mask &= + ~(position); + } + position <<= 1; + } + } + if (found_frame) + *in_out_frame = *found_frame; + else { + in_out_frame->vcd_frm.physical = NULL; + in_out_frame->vcd_frm.virtual = NULL; + } + break; + } + } + return vcd_status; +} + +void ddl_release_context_buffers(struct ddl_context *ddl_context) +{ + ddl_pmem_free(&ddl_context->context_buf_addr); + ddl_pmem_free(&ddl_context->db_line_buffer); + ddl_pmem_free(&ddl_context->data_partition_tempbuf); + ddl_pmem_free(&ddl_context->metadata_shared_input); + ddl_pmem_free(&ddl_context->dbg_core_dump); + + vcd_fw_release(); +} + +void ddl_release_client_internal_buffers(struct ddl_client_context *ddl) +{ + if (ddl->decoding) { + struct ddl_decoder_data *decoder = + &(ddl->codec_data.decoder); + ddl_pmem_free(&decoder->h264Vsp_temp_buffer); + ddl_pmem_free(&decoder->dpb_comv_buffer); + ddl_pmem_free(&decoder->ref_buffer); + DDL_FREE(decoder->dp_buf.dec_pic_buffers); + ddl_decode_dynamic_property(ddl, false); + decoder->decode_config.sequence_header_len = 0; + decoder->decode_config.sequence_header = NULL; + decoder->dpb_mask.client_mask = 0; + decoder->dpb_mask.hw_mask = 0; + decoder->dp_buf.no_of_dec_pic_buf = 0; + decoder->dynamic_prop_change = 0; + + } else { + struct ddl_encoder_data *encoder = + &(ddl->codec_data.encoder); + ddl_pmem_free(&encoder->enc_dpb_addr); + ddl_pmem_free(&encoder->seq_header); + ddl_encode_dynamic_property(ddl, false); + encoder->dynamic_prop_change = 0; + } +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..32a40477581dc9c99145379817d0d50e1e6f2f4e --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h @@ -0,0 +1,81 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_DDL_INTERNAL_PROPERTY_H_ +#define _VCD_DDL_INTERNAL_PROPERTY_H_ +#include + +#define VCD_EVT_RESP_DDL_BASE 0x3000 +#define VCD_EVT_RESP_DEVICE_INIT (VCD_EVT_RESP_DDL_BASE + 0x1) +#define VCD_EVT_RESP_OUTPUT_REQ (VCD_EVT_RESP_DDL_BASE + 0x2) +#define VCD_EVT_RESP_EOS_DONE (VCD_EVT_RESP_DDL_BASE + 0x3) +#define VCD_EVT_RESP_TRANSACTION_PENDING (VCD_EVT_RESP_DDL_BASE + 0x4) + +#define VCD_S_DDL_ERR_BASE 0x90000000 +#define VCD_ERR_MAX_NO_CODEC (VCD_S_DDL_ERR_BASE + 0x1) +#define VCD_ERR_CLIENT_PRESENT (VCD_S_DDL_ERR_BASE + 0x2) +#define VCD_ERR_CLIENT_FATAL (VCD_S_DDL_ERR_BASE + 0x3) + +#define VCD_I_CUSTOM_BASE (VCD_I_RESERVED_BASE) +#define VCD_I_RC_LEVEL_CONFIG (VCD_I_CUSTOM_BASE + 0x1) +#define VCD_I_FRAME_LEVEL_RC (VCD_I_CUSTOM_BASE + 0x2) +#define VCD_I_ADAPTIVE_RC (VCD_I_CUSTOM_BASE + 0x3) +#define VCD_I_CUSTOM_DDL_BASE (VCD_I_RESERVED_BASE + 0x100) +#define DDL_I_INPUT_BUF_REQ (VCD_I_CUSTOM_DDL_BASE + 0x1) +#define DDL_I_OUTPUT_BUF_REQ (VCD_I_CUSTOM_DDL_BASE + 0x2) +#define DDL_I_DPB (VCD_I_CUSTOM_DDL_BASE + 0x3) +#define DDL_I_DPB_RELEASE (VCD_I_CUSTOM_DDL_BASE + 0x4) +#define DDL_I_DPB_RETRIEVE (VCD_I_CUSTOM_DDL_BASE + 0x5) +#define DDL_I_REQ_OUTPUT_FLUSH (VCD_I_CUSTOM_DDL_BASE + 0x6) +#define DDL_I_SEQHDR_ALIGN_BYTES (VCD_I_CUSTOM_DDL_BASE + 0x7) +#define DDL_I_SEQHDR_PRESENT (VCD_I_CUSTOM_DDL_BASE + 0xb) +#define DDL_I_CAPABILITY (VCD_I_CUSTOM_DDL_BASE + 0x8) +#define DDL_I_FRAME_PROC_UNITS (VCD_I_CUSTOM_DDL_BASE + 0x9) + +struct vcd_property_rc_level { + u32 frame_level_rc; + u32 mb_level_rc; +}; + +struct vcd_property_frame_level_rc_params { + u32 reaction_coeff; +}; + +struct vcd_property_adaptive_rc_params { + u32 dark_region_as_flag; + u32 smooth_region_as_flag; + u32 static_region_as_flag; + 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 { + struct ddl_frame_data_tag *dec_pic_buffers; + u32 no_of_dec_pic_buf; +}; + +struct ddl_property_capability { + u32 max_num_client; + u32 general_command_depth; + u32 frame_command_depth; + u32 exclusive; + u32 ddl_time_out_in_ms; +}; + +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c new file mode 100644 index 0000000000000000000000000000000000000000..eea4c762889c0e330ec77a599483ccb8614309c7 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c @@ -0,0 +1,1130 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "vidc.h" +#include "vcd_ddl_utils.h" +#include "vcd_ddl_metadata.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +static void ddl_decoder_input_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end); +static u32 ddl_decoder_output_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end); + +static u32 ddl_get_frame + (struct vcd_frame_data *frame, u32 frame_type); + +static void ddl_getdec_profilelevel +(struct ddl_decoder_data *decoder, u32 profile, u32 level); + +static void ddl_dma_done_callback(struct ddl_context *ddl_context) +{ + if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_DMA_INIT)) { + VIDC_LOGERR_STRING("UNKWN_DMADONE"); + return; + } + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + VIDC_LOG_STRING("DMA_DONE"); + ddl_core_start_cpu(ddl_context); +} + +static void ddl_cpu_started_callback(struct ddl_context *ddl_context) +{ + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + VIDC_LOG_STRING("CPU-STARTED"); + + if (!vidc_720p_cpu_start()) { + ddl_hw_fatal_cb(ddl_context); + return; + } + + vidc_720p_set_deblock_line_buffer( + ddl_context->db_line_buffer.align_physical_addr, + ddl_context->db_line_buffer.buffer_size); + ddl_context->device_state = DDL_DEVICE_INITED; + ddl_context->ddl_callback(VCD_EVT_RESP_DEVICE_INIT, VCD_S_SUCCESS, + NULL, 0, NULL, ddl_context->client_data); + DDL_IDLE(ddl_context); +} + + +static u32 ddl_eos_done_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + u32 displaystatus, resl_change; + + if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_EOS)) { + VIDC_LOGERR_STRING("UNKWN_EOSDONE"); + ddl_client_fatal_cb(ddl_context); + return true; + } + + if (!ddl || + !ddl->decoding || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-EOSDONE"); + ddl_client_fatal_cb(ddl_context); + return true; + } + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + + vidc_720p_eos_info(&displaystatus, &resl_change); + if ((enum vidc_720p_display_status)displaystatus + != VIDC_720P_EMPTY_BUFFER) { + VIDC_LOG_STRING("EOSDONE-EMPTYBUF-ISSUE"); + } + + ddl_decode_dynamic_property(ddl, false); + if (resl_change == 0x1) { + ddl->codec_data.decoder.header_in_start = false; + ddl->codec_data.decoder.decode_config.sequence_header = + ddl->input_frame.vcd_frm.physical; + ddl->codec_data.decoder.decode_config.sequence_header_len = + ddl->input_frame.vcd_frm.data_len; + ddl_decode_init_codec(ddl); + return false; + } + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); + VIDC_LOG_STRING("EOS_DONE"); + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, VCD_S_SUCCESS, + NULL, 0, (u32 *) ddl, ddl_context->client_data); + DDL_IDLE(ddl_context); + + return true; +} + +static u32 ddl_channel_set_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + u32 return_status = false; + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + VIDC_DEBUG_REGISTER_LOG; + + if (!ddl || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHDONE) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-CHSET"); + DDL_IDLE(ddl_context); + return return_status; + } + VIDC_LOG_STRING("Channel-set"); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC); + + if (ddl->decoding) { + if (vidc_msg_timing) + ddl_calc_core_proc_time(__func__, DEC_OP_TIME); + if (ddl->codec_data.decoder.header_in_start) { + ddl_decode_init_codec(ddl); + } else { + ddl_context->ddl_callback(VCD_EVT_RESP_START, + VCD_S_SUCCESS, NULL, + 0, (u32 *) ddl, + ddl_context->client_data); + + DDL_IDLE(ddl_context); + return_status = true; + } + } else { + ddl_encode_init_codec(ddl); + } + return return_status; +} + +static void ddl_init_codec_done_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct ddl_encoder_data *encoder; + + if (!ddl || + ddl->decoding || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-INITCODEC"); + ddl_client_fatal_cb(ddl_context); + return; + } + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); + VIDC_LOG_STRING("INIT_CODEC_DONE"); + + encoder = &ddl->codec_data.encoder; + if (encoder->seq_header.virtual_base_addr) { + vidc_720p_encode_get_header(&encoder->seq_header. + buffer_size); + } + + ddl_context->ddl_callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, NULL, + 0, (u32 *) ddl, ddl_context->client_data); + + DDL_IDLE(ddl_context); +} + +static u32 ddl_header_done_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct ddl_decoder_data *decoder; + struct vidc_720p_seq_hdr_info seq_hdr_info; + + u32 process_further = true; + u32 seq_hdr_only_frame = false; + u32 need_reconfig = true; + struct vcd_frame_data *input_vcd_frm; + struct ddl_frame_data_tag *reconfig_payload = NULL; + u32 reconfig_payload_size = 0; + + if (!ddl || + !ddl->decoding || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-HDDONE"); + ddl_client_fatal_cb(ddl_context); + return true; + } + if (vidc_msg_timing) + ddl_calc_core_proc_time(__func__, DEC_OP_TIME); + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_DPB); + VIDC_LOG_STRING("HEADER_DONE"); + VIDC_DEBUG_REGISTER_LOG; + + vidc_720p_decode_get_seq_hdr_info(&seq_hdr_info); + + decoder = &(ddl->codec_data.decoder); + decoder->frame_size.width = seq_hdr_info.img_size_x; + decoder->frame_size.height = seq_hdr_info.img_size_y; + decoder->min_dpb_num = seq_hdr_info.min_num_dpb; + decoder->y_cb_cr_size = seq_hdr_info.min_dpb_size; + decoder->progressive_only = 1 - seq_hdr_info.progressive; + if (!seq_hdr_info.img_size_x || !seq_hdr_info.img_size_y) { + VIDC_LOGERR_STRING("FATAL: ZeroImageSize"); + ddl_client_fatal_cb(ddl_context); + return process_further; + } + if (seq_hdr_info.data_partitioned == 0x1 && + decoder->codec.codec == VCD_CODEC_MPEG4 && + seq_hdr_info.img_size_x > DDL_MAX_DP_FRAME_WIDTH && + seq_hdr_info.img_size_y > DDL_MAX_DP_FRAME_HEIGHT) { + ddl_client_fatal_cb(ddl_context); + return process_further; + } + ddl_getdec_profilelevel(decoder, seq_hdr_info.profile, + seq_hdr_info.level); + ddl_calculate_stride(&decoder->frame_size, + !decoder->progressive_only, + decoder->codec.codec); + if (decoder->buf_format.buffer_format == VCD_BUFFER_FORMAT_TILE_4x2) { + decoder->frame_size.stride = + DDL_TILE_ALIGN(decoder->frame_size.width, + DDL_TILE_ALIGN_WIDTH); + decoder->frame_size.scan_lines = + DDL_TILE_ALIGN(decoder->frame_size.height, + DDL_TILE_ALIGN_HEIGHT); + } + if (seq_hdr_info.crop_exists) { + decoder->frame_size.width -= + (seq_hdr_info.crop_right_offset + + seq_hdr_info.crop_left_offset); + decoder->frame_size.height -= + (seq_hdr_info.crop_top_offset + + seq_hdr_info.crop_bottom_offset); + } + ddl_set_default_decoder_buffer_req(decoder, false); + + if (decoder->header_in_start) { + decoder->client_frame_size = decoder->frame_size; + decoder->client_output_buf_req = + decoder->actual_output_buf_req; + decoder->client_input_buf_req = + decoder->actual_input_buf_req; + ddl_context->ddl_callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, + NULL, 0, (u32 *) ddl, ddl_context->client_data); + DDL_IDLE(ddl_context); + } else { + DBG("%s(): Client data: WxH(%u x %u) SxSL(%u x %u) Sz(%u)\n", + __func__, decoder->client_frame_size.width, + decoder->client_frame_size.height, + decoder->client_frame_size.stride, + decoder->client_frame_size.scan_lines, + decoder->client_output_buf_req.sz); + DBG("%s(): DDL data: WxH(%u x %u) SxSL(%u x %u) Sz(%u)\n", + __func__, decoder->frame_size.width, + decoder->frame_size.height, + decoder->frame_size.stride, + decoder->frame_size.scan_lines, + decoder->actual_output_buf_req.sz); + DBG("%s(): min_dpb_num = %d actual_count = %d\n", __func__, + decoder->min_dpb_num, + decoder->client_output_buf_req.actual_count); + + input_vcd_frm = &(ddl->input_frame.vcd_frm); + + if (decoder->frame_size.width == + decoder->client_frame_size.width + && decoder->frame_size.height == + decoder->client_frame_size.height + && decoder->frame_size.stride == + decoder->client_frame_size.stride + && decoder->frame_size.scan_lines == + decoder->client_frame_size.scan_lines + && decoder->actual_output_buf_req.sz <= + decoder->client_output_buf_req.sz + && decoder->actual_output_buf_req.actual_count <= + decoder->client_output_buf_req.actual_count + && decoder->progressive_only) + need_reconfig = false; + if (input_vcd_frm->flags & VCD_FRAME_FLAG_EOS) + need_reconfig = false; + if ((input_vcd_frm->data_len <= seq_hdr_info.dec_frm_size || + (input_vcd_frm->flags & VCD_FRAME_FLAG_CODECCONFIG)) && + (!need_reconfig || + !(input_vcd_frm->flags & VCD_FRAME_FLAG_EOS))) { + input_vcd_frm->flags |= + VCD_FRAME_FLAG_CODECCONFIG; + seq_hdr_only_frame = true; + input_vcd_frm->data_len = 0; + ddl->input_frame.frm_trans_end = !need_reconfig; + ddl_context->ddl_callback( + VCD_EVT_RESP_INPUT_DONE, + VCD_S_SUCCESS, &ddl->input_frame, + sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, + ddl->ddl_context->client_data); + } else if (decoder->codec.codec != VCD_CODEC_H263) { + input_vcd_frm->offset += seq_hdr_info.dec_frm_size; + input_vcd_frm->data_len -= seq_hdr_info.dec_frm_size; + } + if (need_reconfig) { + decoder->client_frame_size = decoder->frame_size; + decoder->client_output_buf_req = + decoder->actual_output_buf_req; + decoder->client_input_buf_req = + decoder->actual_input_buf_req; + if (!seq_hdr_only_frame) { + reconfig_payload = &ddl->input_frame; + reconfig_payload_size = + sizeof(struct ddl_frame_data_tag); + } + ddl_context->ddl_callback(VCD_EVT_IND_OUTPUT_RECONFIG, + VCD_S_SUCCESS, reconfig_payload, + reconfig_payload_size, + (u32 *) ddl, + ddl_context->client_data); + } + if (!need_reconfig && !seq_hdr_only_frame) { + if (ddl_decode_set_buffers(ddl) == VCD_S_SUCCESS) + process_further = false; + else + ddl_client_fatal_cb(ddl_context); + } else + DDL_IDLE(ddl_context); + } + return process_further; +} + +static u32 ddl_dpb_buffers_set_done_callback(struct ddl_context + *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + if (!ddl || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPBDONE) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-DPBDONE"); + ddl_client_fatal_cb(ddl_context); + return true; + } + if (vidc_msg_timing) { + ddl_calc_core_proc_time(__func__, DEC_OP_TIME); + ddl_reset_core_time_variables(DEC_OP_TIME); + } + VIDC_LOG_STRING("INTR_DPBDONE"); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); + ddl->codec_data.decoder.dec_disp_info.img_size_x = 0; + ddl->codec_data.decoder.dec_disp_info.img_size_y = 0; + ddl_decode_frame_run(ddl); + return false; +} + +static void ddl_encoder_frame_run_callback(struct ddl_context + *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + u32 eos_present = false; + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-ENCFRMRUN"); + ddl_client_fatal_cb(ddl_context); + return; + } + + VIDC_LOG_STRING("ENC_FRM_RUN_DONE"); + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + vidc_720p_enc_frame_info(&encoder->enc_frame_info); + + ddl->output_frame.vcd_frm.ip_frm_tag = + ddl->input_frame.vcd_frm.ip_frm_tag; + ddl->output_frame.vcd_frm.data_len = + encoder->enc_frame_info.enc_size; + ddl->output_frame.vcd_frm.flags |= VCD_FRAME_FLAG_ENDOFFRAME; + ddl_get_frame + (&(ddl->output_frame.vcd_frm), + encoder->enc_frame_info.frame); + ddl_process_encoder_metadata(ddl); + + ddl_encode_dynamic_property(ddl, false); + + ddl->input_frame.frm_trans_end = false; + ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE, VCD_S_SUCCESS, + &(ddl->input_frame), sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, ddl_context->client_data); + + if (vidc_msg_timing) + ddl_calc_core_proc_time(__func__, ENC_OP_TIME); + + /* check the presence of EOS */ + eos_present = + ((VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags)); + + ddl->output_frame.frm_trans_end = !eos_present; + ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, VCD_S_SUCCESS, + &(ddl->output_frame), sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, ddl_context->client_data); + + if (eos_present) { + VIDC_LOG_STRING("ENC-EOS_DONE"); + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, + ddl_context->client_data); + } + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); + DDL_IDLE(ddl_context); +} + +static u32 ddl_decoder_frame_run_callback(struct ddl_context + *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct vidc_720p_dec_disp_info *dec_disp_info = + &(ddl->codec_data.decoder.dec_disp_info); + u32 callback_end = false; + u32 status = true, eos_present = false;; + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)) { + VIDC_LOG_STRING("STATE-CRITICAL-DECFRMRUN"); + ddl_client_fatal_cb(ddl_context); + return true; + } + + VIDC_LOG_STRING("DEC_FRM_RUN_DONE"); + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + + vidc_720p_decode_display_info(dec_disp_info); + + ddl_decode_dynamic_property(ddl, false); + + if (dec_disp_info->resl_change) { + VIDC_LOG_STRING + ("DEC_FRM_RUN_DONE: RECONFIG"); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE); + ddl_move_command_state(ddl_context, DDL_CMD_EOS); + vidc_720p_submit_command(ddl->channel_id, + VIDC_720P_CMD_FRAMERUN_REALLOCATE); + return false; + } + + if ((VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags)) { + callback_end = false; + eos_present = true; + } + + + if (dec_disp_info->disp_status == VIDC_720P_DECODE_ONLY || + dec_disp_info->disp_status + == VIDC_720P_DECODE_AND_DISPLAY) { + if (!eos_present) + callback_end = (dec_disp_info->disp_status + == VIDC_720P_DECODE_ONLY); + + ddl_decoder_input_done_callback(ddl, callback_end); + } + + if (dec_disp_info->disp_status == VIDC_720P_DECODE_AND_DISPLAY + || dec_disp_info->disp_status == VIDC_720P_DISPLAY_ONLY) { + if (!eos_present) + callback_end = + (dec_disp_info->disp_status + == VIDC_720P_DECODE_AND_DISPLAY); + + if (ddl_decoder_output_done_callback(ddl, callback_end) + != VCD_S_SUCCESS) + return true; + } + + if (dec_disp_info->disp_status == VIDC_720P_DISPLAY_ONLY || + dec_disp_info->disp_status == VIDC_720P_EMPTY_BUFFER) { + /* send the same input once again for decoding */ + ddl_decode_frame_run(ddl); + /* client need to ignore the interrupt */ + status = false; + } else if (eos_present) { + /* send EOS command to HW */ + ddl_decode_eos_run(ddl); + /* client need to ignore the interrupt */ + status = false; + } else { + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); + /* move to Idle */ + DDL_IDLE(ddl_context); + } + return status; +} + +static u32 ddl_eos_frame_done_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vidc_720p_dec_disp_info *dec_disp_info = + &(decoder->dec_disp_info); + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) { + VIDC_LOGERR_STRING("STATE-CRITICAL-EOSFRMRUN"); + ddl_client_fatal_cb(ddl_context); + return true; + } + VIDC_LOG_STRING("EOS_FRM_RUN_DONE"); + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + + vidc_720p_decode_display_info(dec_disp_info); + + ddl_decode_dynamic_property(ddl, false); + + if (dec_disp_info->disp_status == VIDC_720P_DISPLAY_ONLY) { + if (ddl_decoder_output_done_callback(ddl, false) + != VCD_S_SUCCESS) + return true; + } else + VIDC_LOG_STRING("STATE-CRITICAL-WRONG-DISP-STATUS"); + + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK); + ddl_move_command_state(ddl_context, DDL_CMD_EOS); + vidc_720p_submit_command(ddl->channel_id, + VIDC_720P_CMD_FRAMERUN); + return false; +} + +static void ddl_channel_end_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + VIDC_LOG_STRING("CH_END_DONE"); + + ddl = ddl_context->current_ddl; + if (!ddl || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHEND) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-CHEND"); + DDL_IDLE(ddl_context); + return; + } + + ddl_release_client_internal_buffers(ddl); + ddl_context->ddl_callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS, + NULL, 0, (u32 *) ddl, ddl_context->client_data); + ddl_move_client_state(ddl, DDL_CLIENT_OPEN); + DDL_IDLE(ddl_context); +} + +static u32 ddl_operation_done_callback(struct ddl_context *ddl_context) +{ + u32 return_status = true; + + switch (ddl_context->cmd_state) { + case DDL_CMD_DECODE_FRAME: + { + return_status = ddl_decoder_frame_run_callback( + ddl_context); + break; + } + case DDL_CMD_ENCODE_FRAME: + { + ddl_encoder_frame_run_callback(ddl_context); + break; + } + case DDL_CMD_CHANNEL_SET: + { + return_status = ddl_channel_set_callback( + ddl_context); + break; + } + case DDL_CMD_INIT_CODEC: + { + ddl_init_codec_done_callback(ddl_context); + break; + } + case DDL_CMD_HEADER_PARSE: + { + return_status = ddl_header_done_callback( + ddl_context); + break; + } + case DDL_CMD_DECODE_SET_DPB: + { + return_status = ddl_dpb_buffers_set_done_callback( + ddl_context); + break; + } + case DDL_CMD_CHANNEL_END: + { + ddl_channel_end_callback(ddl_context); + break; + } + case DDL_CMD_EOS: + { + return_status = ddl_eos_frame_done_callback( + ddl_context); + break; + } + case DDL_CMD_CPU_RESET: + { + ddl_cpu_started_callback(ddl_context); + break; + } + default: + { + VIDC_LOG_STRING("UNKWN_OPDONE"); + return_status = false; + break; + } + } + return return_status; +} + +static u32 ddl_process_intr_status(struct ddl_context *ddl_context, + u32 int_status) +{ + u32 status = true; + switch (int_status) { + case VIDC_720P_INTR_FRAME_DONE: + { + status = ddl_operation_done_callback(ddl_context); + break; + } + case VIDC_720P_INTR_DMA_DONE: + { + ddl_dma_done_callback(ddl_context); + status = false; + break; + } + case VIDC_720P_INTR_FW_DONE: + { + status = ddl_eos_done_callback(ddl_context); + break; + } + case VIDC_720P_INTR_BUFFER_FULL: + { + VIDC_LOGERR_STRING("BUF_FULL_INTR"); + ddl_hw_fatal_cb(ddl_context); + break; + } + default: + { + VIDC_LOGERR_STRING("UNKWN_INTR"); + break; + } + } + return status; +} + +void ddl_read_and_clear_interrupt(void) +{ + struct ddl_context *ddl_context; + + ddl_context = ddl_get_context(); + if (!ddl_context->core_virtual_base_addr) { + VIDC_LOGERR_STRING("SPURIOUS_INTERRUPT"); + return; + } + vidc_720p_get_interrupt_status(&ddl_context->intr_status, + &ddl_context->cmd_err_status, + &ddl_context->disp_pic_err_status, + &ddl_context->op_failed + ); + + vidc_720p_interrupt_done_clear(); + +} + +u32 ddl_process_core_response(void) +{ + struct ddl_context *ddl_context; + u32 return_status = true; + + ddl_context = ddl_get_context(); + if (!ddl_context->core_virtual_base_addr) { + VIDC_LOGERR_STRING("UNKWN_INTR"); + return false; + } + + if (!ddl_handle_core_errors(ddl_context)) { + return_status = ddl_process_intr_status(ddl_context, + ddl_context->intr_status); + } + + if (ddl_context->interrupt_clr) + (*ddl_context->interrupt_clr)(); + + return return_status; +} + +static void ddl_decoder_input_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end) +{ + struct vidc_720p_dec_disp_info *dec_disp_info = + &(ddl->codec_data.decoder.dec_disp_info); + struct vcd_frame_data *input_vcd_frm = + &(ddl->input_frame.vcd_frm); + ddl_get_frame(input_vcd_frm, dec_disp_info-> + input_frame); + + input_vcd_frm->interlaced = (dec_disp_info-> + input_is_interlace); + + input_vcd_frm->offset += dec_disp_info->input_bytes_consumed; + input_vcd_frm->data_len -= dec_disp_info->input_bytes_consumed; + + ddl->input_frame.frm_trans_end = frame_transact_end; + if (vidc_msg_timing) + ddl_calc_core_proc_time(__func__, DEC_IP_TIME); + ddl->ddl_context->ddl_callback( + VCD_EVT_RESP_INPUT_DONE, + VCD_S_SUCCESS, + &ddl->input_frame, + sizeof(struct ddl_frame_data_tag), + (void *)ddl, + ddl->ddl_context->client_data); +} + +static u32 ddl_decoder_output_done_callback( + struct ddl_client_context *ddl, + u32 frame_transact_end) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vidc_720p_dec_disp_info *dec_disp_info = + &(decoder->dec_disp_info); + struct ddl_frame_data_tag *output_frame = + &ddl->output_frame; + struct vcd_frame_data *output_vcd_frm = + &(output_frame->vcd_frm); + u32 vcd_status; + u32 free_luma_dpb = 0; + + output_vcd_frm->physical = (u8 *)dec_disp_info->y_addr; + + if (decoder->codec.codec == VCD_CODEC_MPEG4 || + decoder->codec.codec == VCD_CODEC_VC1 || + decoder->codec.codec == VCD_CODEC_VC1_RCV || + (decoder->codec.codec >= VCD_CODEC_DIVX_3 && + decoder->codec.codec <= VCD_CODEC_XVID)){ + vidc_720p_decode_skip_frm_details(&free_luma_dpb); + if (free_luma_dpb) + output_vcd_frm->physical = (u8 *) free_luma_dpb; + } + + + vcd_status = ddl_decoder_dpb_transact( + decoder, + output_frame, + DDL_DPB_OP_MARK_BUSY); + + if (vcd_status != VCD_S_SUCCESS) { + VIDC_LOGERR_STRING("CorruptedOutputBufferAddress"); + ddl_hw_fatal_cb(ddl->ddl_context); + return vcd_status; + } + + output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top; + if (dec_disp_info->crop_exists == 0x1) { + output_vcd_frm->dec_op_prop.disp_frm.left = + dec_disp_info->crop_left_offset; + output_vcd_frm->dec_op_prop.disp_frm.top = + dec_disp_info->crop_top_offset; + output_vcd_frm->dec_op_prop.disp_frm.right = + dec_disp_info->img_size_x - + dec_disp_info->crop_right_offset; + output_vcd_frm->dec_op_prop.disp_frm.bottom = + dec_disp_info->img_size_y - + dec_disp_info->crop_bottom_offset; + } else { + output_vcd_frm->dec_op_prop.disp_frm.left = 0; + output_vcd_frm->dec_op_prop.disp_frm.top = 0; + output_vcd_frm->dec_op_prop.disp_frm.right = + dec_disp_info->img_size_x; + output_vcd_frm->dec_op_prop.disp_frm.bottom = + dec_disp_info->img_size_y; + } + if (!dec_disp_info->disp_is_interlace) { + output_vcd_frm->interlaced = false; + output_vcd_frm->intrlcd_ip_frm_tag = VCD_FRAMETAG_INVALID; + } else { + output_vcd_frm->interlaced = true; + output_vcd_frm->intrlcd_ip_frm_tag = + dec_disp_info->tag_bottom; + } + + output_vcd_frm->offset = 0; + output_vcd_frm->data_len = decoder->y_cb_cr_size; + if (free_luma_dpb) { + output_vcd_frm->data_len = 0; + output_vcd_frm->flags |= VCD_FRAME_FLAG_DECODEONLY; + } + output_vcd_frm->flags |= VCD_FRAME_FLAG_ENDOFFRAME; + ddl_process_decoder_metadata(ddl); + output_frame->frm_trans_end = frame_transact_end; + + if (vidc_msg_timing) + ddl_calc_core_proc_time(__func__, DEC_OP_TIME); + + ddl->ddl_context->ddl_callback( + VCD_EVT_RESP_OUTPUT_DONE, + vcd_status, + output_frame, + sizeof(struct ddl_frame_data_tag), + (void *)ddl, + ddl->ddl_context->client_data); + return vcd_status; +} + +static u32 ddl_get_frame + (struct vcd_frame_data *frame, u32 frametype) { + enum vidc_720p_frame vidc_frame = + (enum vidc_720p_frame)frametype; + u32 status = true; + + switch (vidc_frame) { + case VIDC_720P_IFRAME: + { + frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; + frame->frame = VCD_FRAME_I; + break; + } + case VIDC_720P_PFRAME: + { + frame->frame = VCD_FRAME_P; + break; + } + case VIDC_720P_BFRAME: + { + frame->frame = VCD_FRAME_B; + break; + } + case VIDC_720P_NOTCODED: + { + frame->frame = VCD_FRAME_NOTCODED; + frame->data_len = 0; + break; + } + case VIDC_720P_IDRFRAME: + { + frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; + frame->frame = VCD_FRAME_IDR; + break; + } + default: + { + VIDC_LOG_STRING("CRITICAL-FRAMETYPE"); + status = false; + break; + } + } + return status; +} + +static void ddl_getmpeg4_declevel(enum vcd_codec_level *codec_level, + u32 level) +{ + switch (level) { + case VIDC_720P_MPEG4_LEVEL0: + { + *codec_level = VCD_LEVEL_MPEG4_0; + break; + } + case VIDC_720P_MPEG4_LEVEL0b: + { + *codec_level = VCD_LEVEL_MPEG4_0b; + break; + } + case VIDC_720P_MPEG4_LEVEL1: + { + *codec_level = VCD_LEVEL_MPEG4_1; + break; + } + case VIDC_720P_MPEG4_LEVEL2: + { + *codec_level = VCD_LEVEL_MPEG4_2; + break; + } + case VIDC_720P_MPEG4_LEVEL3: + { + *codec_level = VCD_LEVEL_MPEG4_3; + break; + } + case VIDC_720P_MPEG4_LEVEL3b: + { + *codec_level = VCD_LEVEL_MPEG4_3b; + break; + } + case VIDC_720P_MPEG4_LEVEL4a: + { + *codec_level = VCD_LEVEL_MPEG4_4a; + break; + } + case VIDC_720P_MPEG4_LEVEL5: + { + *codec_level = VCD_LEVEL_MPEG4_5; + break; + } + case VIDC_720P_MPEG4_LEVEL6: + { + *codec_level = VCD_LEVEL_MPEG4_6; + break; + } + } +} + +static void ddl_geth264_declevel(enum vcd_codec_level *codec_level, + u32 level) +{ + switch (level) { + case VIDC_720P_H264_LEVEL1: + { + *codec_level = VCD_LEVEL_H264_1; + break; + } + case VIDC_720P_H264_LEVEL1b: + { + *codec_level = VCD_LEVEL_H264_1b; + break; + } + case VIDC_720P_H264_LEVEL1p1: + { + *codec_level = VCD_LEVEL_H264_1p1; + break; + } + case VIDC_720P_H264_LEVEL1p2: + { + *codec_level = VCD_LEVEL_H264_1p2; + break; + } + case VIDC_720P_H264_LEVEL1p3: + { + *codec_level = VCD_LEVEL_H264_1p3; + break; + } + case VIDC_720P_H264_LEVEL2: + { + *codec_level = VCD_LEVEL_H264_2; + break; + } + case VIDC_720P_H264_LEVEL2p1: + { + *codec_level = VCD_LEVEL_H264_2p1; + break; + } + case VIDC_720P_H264_LEVEL2p2: + { + *codec_level = VCD_LEVEL_H264_2p2; + break; + } + case VIDC_720P_H264_LEVEL3: + { + *codec_level = VCD_LEVEL_H264_3; + break; + } + case VIDC_720P_H264_LEVEL3p1: + { + *codec_level = VCD_LEVEL_H264_3p1; + break; + } + case VIDC_720P_H264_LEVEL3p2: + { + *codec_level = VCD_LEVEL_H264_3p2; + break; + } + + } +} + +static void ddl_get_vc1_dec_level( + enum vcd_codec_level *codec_level, u32 level, + enum vcd_codec_profile vc1_profile) +{ + if (vc1_profile == VCD_PROFILE_VC1_ADVANCE) { + switch (level) { + case VIDC_720P_VC1_LEVEL0: + { + *codec_level = VCD_LEVEL_VC1_A_0; + break; + } + case VIDC_720P_VC1_LEVEL1: + { + *codec_level = VCD_LEVEL_VC1_A_1; + break; + } + case VIDC_720P_VC1_LEVEL2: + { + *codec_level = VCD_LEVEL_VC1_A_2; + break; + } + case VIDC_720P_VC1_LEVEL3: + { + *codec_level = VCD_LEVEL_VC1_A_3; + break; + } + case VIDC_720P_VC1_LEVEL4: + { + *codec_level = VCD_LEVEL_VC1_A_4; + break; + } + } + return; + } else if (vc1_profile == VCD_PROFILE_VC1_MAIN) { + switch (level) { + case VIDC_720P_VC1_LEVEL_LOW: + { + *codec_level = VCD_LEVEL_VC1_M_LOW; + break; + } + case VIDC_720P_VC1_LEVEL_MED: + { + *codec_level = VCD_LEVEL_VC1_M_MEDIUM; + break; + } + case VIDC_720P_VC1_LEVEL_HIGH: + { + *codec_level = VCD_LEVEL_VC1_M_HIGH; + break; + } + } + } else if (vc1_profile == VCD_PROFILE_VC1_SIMPLE) { + switch (level) { + case VIDC_720P_VC1_LEVEL_LOW: + { + *codec_level = VCD_LEVEL_VC1_S_LOW; + break; + } + case VIDC_720P_VC1_LEVEL_MED: + { + *codec_level = VCD_LEVEL_VC1_S_MEDIUM; + break; + } + } + } +} + +static void ddl_get_mpeg2_dec_level(enum vcd_codec_level *codec_level, + u32 level) +{ + switch (level) { + case VIDCL_720P_MPEG2_LEVEL_LOW: + { + *codec_level = VCD_LEVEL_MPEG2_LOW; + break; + } + case VIDCL_720P_MPEG2_LEVEL_MAIN: + { + *codec_level = VCD_LEVEL_MPEG2_MAIN; + break; + } + case VIDCL_720P_MPEG2_LEVEL_HIGH14: + { + *codec_level = VCD_LEVEL_MPEG2_HIGH_14; + break; + } + } +} + +static void ddl_getdec_profilelevel(struct ddl_decoder_data *decoder, + u32 profile, u32 level) +{ + enum vcd_codec_profile codec_profile = VCD_PROFILE_UNKNOWN; + enum vcd_codec_level codec_level = VCD_LEVEL_UNKNOWN; + + switch (decoder->codec.codec) { + case VCD_CODEC_MPEG4: + { + if (profile == VIDC_720P_PROFILE_MPEG4_SP) + codec_profile = VCD_PROFILE_MPEG4_SP; + else if (profile == VIDC_720P_PROFILE_MPEG4_ASP) + codec_profile = VCD_PROFILE_MPEG4_ASP; + + ddl_getmpeg4_declevel(&codec_level, level); + break; + } + case VCD_CODEC_H264: + { + if (profile == VIDC_720P_PROFILE_H264_BASELINE) + codec_profile = VCD_PROFILE_H264_BASELINE; + else if (profile == VIDC_720P_PROFILE_H264_MAIN) + codec_profile = VCD_PROFILE_H264_MAIN; + else if (profile == VIDC_720P_PROFILE_H264_HIGH) + codec_profile = VCD_PROFILE_H264_HIGH; + ddl_geth264_declevel(&codec_level, level); + break; + } + default: + case VCD_CODEC_H263: + { + break; + } + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + { + if (profile == VIDC_720P_PROFILE_VC1_SP) + codec_profile = VCD_PROFILE_VC1_SIMPLE; + else if (profile == VIDC_720P_PROFILE_VC1_MAIN) + codec_profile = VCD_PROFILE_VC1_MAIN; + else if (profile == VIDC_720P_PROFILE_VC1_ADV) + codec_profile = VCD_PROFILE_VC1_ADVANCE; + ddl_get_vc1_dec_level(&codec_level, level, profile); + break; + } + case VCD_CODEC_MPEG2: + { + if (profile == VIDC_720P_PROFILE_MPEG2_MAIN) + codec_profile = VCD_PROFILE_MPEG2_MAIN; + else if (profile == VIDC_720P_PROFILE_MPEG2_SP) + codec_profile = VCD_PROFILE_MPEG2_SIMPLE; + ddl_get_mpeg2_dec_level(&codec_level, level); + break; + } + } + + decoder->profile.profile = codec_profile; + decoder->level.level = codec_level; +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c new file mode 100644 index 0000000000000000000000000000000000000000..5d8753324365819afccc0b3358018defa1be91be --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c @@ -0,0 +1,580 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "vcd_ddl_utils.h" +#include "vcd_ddl_metadata.h" + +static u32 *ddl_metadata_hdr_entry(struct ddl_client_context *ddl, + u32 meta_data) +{ + u32 skip_words = 0; + u32 *buffer; + + if (ddl->decoding) { + buffer = (u32 *) + ddl->codec_data.decoder.meta_data_input. + align_virtual_addr; + skip_words = 32 + 1; + buffer += skip_words; + + switch (meta_data) { + default: + case VCD_METADATA_DATANONE: + { + skip_words = 0; + break; + } + case VCD_METADATA_QPARRAY: + { + skip_words = 3; + break; + } + case VCD_METADATA_CONCEALMB: + { + skip_words = 6; + break; + } + case VCD_METADATA_VC1: + { + skip_words = 9; + break; + } + case VCD_METADATA_SEI: + { + skip_words = 12; + break; + } + case VCD_METADATA_VUI: + { + skip_words = 15; + break; + } + case VCD_METADATA_PASSTHROUGH: + { + skip_words = 18; + break; + } + case VCD_METADATA_QCOMFILLER: + { + skip_words = 21; + break; + } + } + } else { + buffer = (u32 *) + ddl->codec_data.encoder.meta_data_input. + align_virtual_addr; + skip_words = 2; + buffer += skip_words; + + switch (meta_data) { + default: + case VCD_METADATA_DATANONE: + { + skip_words = 0; + break; + } + case VCD_METADATA_ENC_SLICE: + { + skip_words = 3; + break; + } + case VCD_METADATA_QCOMFILLER: + { + skip_words = 6; + break; + } + } + + } + + buffer += skip_words; + return buffer; +} + +void ddl_set_default_meta_data_hdr(struct ddl_client_context *ddl) +{ + struct ddl_buf_addr *main_buffer = + &ddl->ddl_context->metadata_shared_input; + struct ddl_buf_addr *client_buffer; + u32 *hdr_entry; + + if (ddl->decoding) + client_buffer = &(ddl->codec_data.decoder.meta_data_input); + else + client_buffer = &(ddl->codec_data.encoder.meta_data_input); + + DDL_METADATA_CLIENT_INPUTBUF(main_buffer, client_buffer, + ddl->channel_id); + + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QCOMFILLER); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_QCOMFILLER; + + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_DATANONE); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_DATANONE; + + if (ddl->decoding) { + hdr_entry = + ddl_metadata_hdr_entry(ddl, VCD_METADATA_QPARRAY); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_QPARRAY; + + hdr_entry = + ddl_metadata_hdr_entry(ddl, VCD_METADATA_CONCEALMB); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_CONCEALMB; + + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_SEI); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_SEI; + + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_VUI); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_VUI; + + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_VC1); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_VC1; + + hdr_entry = + ddl_metadata_hdr_entry(ddl, VCD_METADATA_PASSTHROUGH); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = + VCD_METADATA_PASSTHROUGH; + + } else { + hdr_entry = + ddl_metadata_hdr_entry(ddl, VCD_METADATA_ENC_SLICE); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = + VCD_METADATA_ENC_SLICE; + } +} + +static u32 ddl_supported_metadata_flag(struct ddl_client_context *ddl) +{ + u32 flag = 0; + + if (ddl->decoding) { + enum vcd_codec codec = + ddl->codec_data.decoder.codec.codec; + + flag |= (VCD_METADATA_CONCEALMB | + VCD_METADATA_PASSTHROUGH | VCD_METADATA_QPARRAY); + if (codec == VCD_CODEC_H264) { + flag |= (VCD_METADATA_SEI | VCD_METADATA_VUI); + } else if (codec == VCD_CODEC_VC1 || + codec == VCD_CODEC_VC1_RCV) { + flag |= VCD_METADATA_VC1; + } + } else { + flag |= VCD_METADATA_ENC_SLICE; + } + + return flag; +} + +void ddl_set_default_metadata_flag(struct ddl_client_context *ddl) +{ + if (ddl->decoding) + ddl->codec_data.decoder.meta_data_enable_flag = 0; + else + ddl->codec_data.encoder.meta_data_enable_flag = 0; +} + +void ddl_set_default_decoder_metadata_buffer_size( + struct ddl_decoder_data *decoder, + struct vcd_property_frame_size *frame_size, + struct vcd_buffer_requirement *output_buf_req) +{ + u32 flag = decoder->meta_data_enable_flag; + u32 suffix = 0; + size_t sz = 0; + + if (!flag) { + decoder->suffix = 0; + return; + } + + if (flag & VCD_METADATA_QPARRAY) { + u32 num_of_mb = + ((frame_size->width * frame_size->height) >> 8); + sz = DDL_METADATA_HDR_SIZE; + sz += num_of_mb; + DDL_METADATA_ALIGNSIZE(sz); + suffix += sz; + } + if (flag & VCD_METADATA_CONCEALMB) { + u32 num_of_mb = + ((frame_size->width * frame_size->height) >> 8); + sz = DDL_METADATA_HDR_SIZE + (num_of_mb >> 3); + DDL_METADATA_ALIGNSIZE(sz); + suffix += sz; + } + if (flag & VCD_METADATA_VC1) { + sz = DDL_METADATA_HDR_SIZE; + sz += DDL_METADATA_VC1_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(sz); + suffix += sz; + } + if (flag & VCD_METADATA_SEI) { + sz = DDL_METADATA_HDR_SIZE; + sz += DDL_METADATA_SEI_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(sz); + suffix += (sz * DDL_METADATA_SEI_MAX); + } + if (flag & VCD_METADATA_VUI) { + sz = DDL_METADATA_HDR_SIZE; + sz += DDL_METADATA_VUI_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(sz); + suffix += (sz); + } + if (flag & VCD_METADATA_PASSTHROUGH) { + sz = DDL_METADATA_HDR_SIZE; + sz += DDL_METADATA_PASSTHROUGH_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(sz); + suffix += (sz); + } + sz = DDL_METADATA_EXTRADATANONE_SIZE; + DDL_METADATA_ALIGNSIZE(sz); + suffix += (sz); + + suffix += DDL_METADATA_EXTRAPAD_SIZE; + DDL_METADATA_ALIGNSIZE(suffix); + + decoder->suffix = suffix; + output_buf_req->sz += suffix; + return; +} + +void ddl_set_default_encoder_metadata_buffer_size(struct ddl_encoder_data + *encoder) +{ + u32 flag = encoder->meta_data_enable_flag; + u32 suffix = 0; + size_t sz = 0; + + if (!flag) { + encoder->suffix = 0; + return; + } + + if (flag & VCD_METADATA_ENC_SLICE) { + u32 num_of_mb = (encoder->frame_size.width * + encoder->frame_size.height / 16 / 16); + sz = DDL_METADATA_HDR_SIZE; + + sz += 4; + + sz += (8 * num_of_mb); + DDL_METADATA_ALIGNSIZE(sz); + suffix += sz; + } + + sz = DDL_METADATA_EXTRADATANONE_SIZE; + DDL_METADATA_ALIGNSIZE(sz); + suffix += (sz); + + suffix += DDL_METADATA_EXTRAPAD_SIZE; + DDL_METADATA_ALIGNSIZE(suffix); + + encoder->suffix = suffix; + encoder->output_buf_req.sz += suffix; +} + +u32 ddl_set_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, + void *property_value) +{ + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + if (property_hdr->prop_id == VCD_I_METADATA_ENABLE) { + struct vcd_property_meta_data_enable *meta_data_enable = + (struct vcd_property_meta_data_enable *) + property_value; + u32 *meta_data_enable_flag; + enum vcd_codec codec; + if (ddl->decoding) { + meta_data_enable_flag = + &(ddl->codec_data.decoder. + meta_data_enable_flag); + codec = ddl->codec_data.decoder.codec.codec; + } else { + meta_data_enable_flag = + &(ddl->codec_data.encoder. + meta_data_enable_flag); + codec = ddl->codec_data.encoder.codec.codec; + } + if (sizeof(struct vcd_property_meta_data_enable) == + property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + codec) { + u32 flag = ddl_supported_metadata_flag(ddl); + flag &= (meta_data_enable->meta_data_enable_flag); + if (flag) + flag |= DDL_METADATA_MANDATORY; + if (flag != *meta_data_enable_flag) { + *meta_data_enable_flag = flag; + if (ddl->decoding) { + ddl_set_default_decoder_buffer_req + (&ddl->codec_data.decoder, + true); + } else { + ddl_set_default_encoder_buffer_req + (&ddl->codec_data.encoder); + } + } + vcd_status = VCD_S_SUCCESS; + } + } else if (property_hdr->prop_id == VCD_I_METADATA_HEADER) { + struct vcd_property_metadata_hdr *hdr = + (struct vcd_property_metadata_hdr *)property_value; + if (sizeof(struct vcd_property_metadata_hdr) == + property_hdr->sz) { + u32 flag = ddl_supported_metadata_flag(ddl); + flag |= DDL_METADATA_MANDATORY; + flag &= hdr->meta_data_id; + if (!(flag & (flag - 1))) { + u32 *hdr_entry = + ddl_metadata_hdr_entry(ddl, flag); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = + hdr->version; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = + hdr->port_index; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = + hdr->type; + vcd_status = VCD_S_SUCCESS; + } + } + } + return vcd_status; +} + +u32 ddl_get_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, + void *property_value) +{ + u32 vcd_status = VCD_ERR_ILLEGAL_PARM ; + if (property_hdr->prop_id == VCD_I_METADATA_ENABLE && + sizeof(struct vcd_property_meta_data_enable) + == property_hdr->sz) { + struct vcd_property_meta_data_enable *meta_data_enable = + (struct vcd_property_meta_data_enable *) + property_value; + meta_data_enable->meta_data_enable_flag = + ((ddl->decoding) ? + (ddl->codec_data.decoder.meta_data_enable_flag) + : (ddl->codec_data.encoder.meta_data_enable_flag)); + vcd_status = VCD_S_SUCCESS; + } else if (property_hdr->prop_id == VCD_I_METADATA_HEADER && + sizeof(struct vcd_property_metadata_hdr) == + property_hdr->sz) { + struct vcd_property_metadata_hdr *hdr = + (struct vcd_property_metadata_hdr *) + property_value; + u32 flag = ddl_supported_metadata_flag(ddl); + flag |= DDL_METADATA_MANDATORY; + flag &= hdr->meta_data_id; + if (!(flag & (flag - 1))) { + u32 *hdr_entry = ddl_metadata_hdr_entry(ddl, + flag); + hdr->version = + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX]; + hdr->port_index = + hdr_entry[DDL_METADATA_HDR_PORT_INDEX]; + hdr->type = + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX]; + vcd_status = VCD_S_SUCCESS; + } + } + return vcd_status; +} + +void ddl_metadata_enable(struct ddl_client_context *ddl) +{ + u32 flag, hal_flag = 0; + u32 *metadata_input; + if (ddl->decoding) { + flag = ddl->codec_data.decoder.meta_data_enable_flag; + metadata_input = + ddl->codec_data.decoder.meta_data_input. + align_physical_addr; + } else { + flag = ddl->codec_data.encoder.meta_data_enable_flag; + metadata_input = + ddl->codec_data.encoder.meta_data_input. + align_physical_addr; + } + if (flag) { + if (flag & VCD_METADATA_QPARRAY) + hal_flag |= VIDC_720P_METADATA_ENABLE_QP; + if (flag & VCD_METADATA_CONCEALMB) + hal_flag |= VIDC_720P_METADATA_ENABLE_CONCEALMB; + if (flag & VCD_METADATA_VC1) + hal_flag |= VIDC_720P_METADATA_ENABLE_VC1; + if (flag & VCD_METADATA_SEI) + hal_flag |= VIDC_720P_METADATA_ENABLE_SEI; + if (flag & VCD_METADATA_VUI) + hal_flag |= VIDC_720P_METADATA_ENABLE_VUI; + if (flag & VCD_METADATA_ENC_SLICE) + hal_flag |= VIDC_720P_METADATA_ENABLE_ENCSLICE; + if (flag & VCD_METADATA_PASSTHROUGH) + hal_flag |= VIDC_720P_METADATA_ENABLE_PASSTHROUGH; + } else { + metadata_input = 0; + } + vidc_720p_metadata_enable(hal_flag, metadata_input); +} + +u32 ddl_encode_set_metadata_output_buf(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &ddl->codec_data.encoder; + u32 *buffer; + struct vcd_frame_data *stream = &(ddl->output_frame.vcd_frm); + u32 ext_buffer_end, hw_metadata_start; + + ext_buffer_end = (u32) stream->physical + stream->alloc_len; + if (!encoder->meta_data_enable_flag) { + ext_buffer_end &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + return ext_buffer_end; + } + hw_metadata_start = (ext_buffer_end - encoder->suffix) & + ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + + ext_buffer_end = (hw_metadata_start - 1) & + ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + + buffer = encoder->meta_data_input.align_virtual_addr; + + *buffer++ = encoder->suffix; + + *buffer = hw_metadata_start; + + encoder->meta_data_offset = + hw_metadata_start - (u32) stream->physical; + + return ext_buffer_end; +} + +void ddl_decode_set_metadata_output(struct ddl_decoder_data *decoder) +{ + u32 *buffer; + u32 loopc; + + if (!decoder->meta_data_enable_flag) { + decoder->meta_data_offset = 0; + return; + } + + decoder->meta_data_offset = ddl_get_yuv_buffer_size( + &decoder->client_frame_size, &decoder->buf_format, + (!decoder->progressive_only), decoder->codec.codec); + + buffer = decoder->meta_data_input.align_virtual_addr; + + *buffer++ = decoder->suffix; + + for (loopc = 0; loopc < decoder->dp_buf.no_of_dec_pic_buf; + ++loopc) { + *buffer++ = (u32) (decoder->meta_data_offset + (u8 *) + decoder->dp_buf. + dec_pic_buffers[loopc].vcd_frm. + physical); + } +} + +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; + + if (!encoder->meta_data_enable_flag) { + out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + + if (!encoder->enc_frame_info.metadata_exists) { + out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + out_frame->flags |= VCD_FRAME_FLAG_EXTRADATA; + + 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) +{ + 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; + + if (!decoder->meta_data_enable_flag) { + output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + + if (!decoder->dec_disp_info.metadata_exists) { + output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + output_frame->flags |= VCD_FRAME_FLAG_EXTRADATA; + + if (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); + } +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h new file mode 100644 index 0000000000000000000000000000000000000000..7c9ac951bfe296559b100a483c00485aa7681671 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h @@ -0,0 +1,79 @@ +/* Copyright (c) 2010, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_DDL_METADATA_H_ +#define _VCD_DDL_METADATA_H_ + +#define DDL_MAX_DEC_METADATATYPE (8) +#define DDL_MAX_ENC_METADATATYPE (3) + +#define DDL_METADATA_EXTRAPAD_SIZE (256) +#define DDL_METADATA_HDR_SIZE (20) + +#define DDL_METADATA_EXTRADATANONE_SIZE (24) + +#define DDL_METADATA_ALIGNSIZE(x) ((x) = (((x) + 0x7) & ~0x7)) + +#define DDL_METADATA_MANDATORY (VCD_METADATA_DATANONE | \ + VCD_METADATA_QCOMFILLER) + +#define DDL_METADATA_VC1_PAYLOAD_SIZE (38*4) + +#define DDL_METADATA_SEI_PAYLOAD_SIZE (100) +#define DDL_METADATA_SEI_MAX (5) + +#define DDL_METADATA_VUI_PAYLOAD_SIZE (256) + +#define DDL_METADATA_PASSTHROUGH_PAYLOAD_SIZE (68) + +#define DDL_METADATA_CLIENT_INPUTBUFSIZE (256) +#define DDL_METADATA_TOTAL_INPUTBUFSIZE \ + (DDL_METADATA_CLIENT_INPUTBUFSIZE * VCD_MAX_NO_CLIENT) + +#define DDL_METADATA_CLIENT_INPUTBUF(main_buffer, client_buffer, \ + channel_id) \ +{ \ + (client_buffer)->align_physical_addr = (u32 *)\ + ((u8 *)(main_buffer)->align_physical_addr + \ + (DDL_METADATA_CLIENT_INPUTBUFSIZE * (channel_id)) \ + ); \ + (client_buffer)->align_virtual_addr = (u32 *)\ + ((u8 *)(main_buffer)->align_virtual_addr + \ + (DDL_METADATA_CLIENT_INPUTBUFSIZE * (channel_id)) \ + ); \ + (client_buffer)->virtual_base_addr = 0; \ +} + +#define DDL_METADATA_HDR_VERSION_INDEX 0 +#define DDL_METADATA_HDR_PORT_INDEX 1 +#define DDL_METADATA_HDR_TYPE_INDEX 2 + + +void ddl_set_default_meta_data_hdr(struct ddl_client_context *ddl); +u32 ddl_get_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value); +u32 ddl_set_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, + void *property_value); +void ddl_set_default_metadata_flag(struct ddl_client_context *ddl); +void ddl_set_default_decoder_metadata_buffer_size + (struct ddl_decoder_data *decoder, + struct vcd_property_frame_size *frame_size, + struct vcd_buffer_requirement *output_buf_req); +void ddl_set_default_encoder_metadata_buffer_size(struct ddl_encoder_data + *encoder); +void ddl_metadata_enable(struct ddl_client_context *ddl); +u32 ddl_encode_set_metadata_output_buf(struct ddl_client_context *ddl); +void ddl_decode_set_metadata_output(struct ddl_decoder_data *decoder); +void ddl_process_encoder_metadata(struct ddl_client_context *ddl); +void ddl_process_decoder_metadata(struct ddl_client_context *ddl); +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c new file mode 100644 index 0000000000000000000000000000000000000000..cdb6313da70b7ffd5ad0d4a2943557dcc940c41c --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c @@ -0,0 +1,1943 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "vcd_ddl_utils.h" +#include "vcd_ddl_metadata.h" + +static u32 ddl_set_dec_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, + void *property_value); +static u32 ddl_set_enc_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, + void *property_value); +static u32 ddl_get_dec_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, + void *property_value); +static u32 ddl_get_enc_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, + void *property_value); +static u32 ddl_set_enc_dynamic_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, + void *property_value); +static void ddl_set_default_enc_property(struct ddl_client_context *ddl); +static void ddl_set_default_enc_profile(struct ddl_encoder_data + *encoder); +static void ddl_set_default_enc_level(struct ddl_encoder_data *encoder); +static void ddl_set_default_enc_vop_timing(struct ddl_encoder_data + *encoder); +static void ddl_set_default_enc_intra_period(struct ddl_encoder_data + *encoder); +static void ddl_set_default_enc_rc_params(struct ddl_encoder_data + *encoder); +static u32 ddl_valid_buffer_requirement(struct vcd_buffer_requirement + *original_buf_req, + struct vcd_buffer_requirement + *req_buf_req); +static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *decoder); +static u32 ddl_set_dec_buffers + (struct ddl_decoder_data *decoder, + struct ddl_property_dec_pic_buffers *dpb); + +u32 ddl_set_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + u32 vcd_status; + struct ddl_context *ddl_context; + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + + if (!property_hdr || !property_value) { + VIDC_LOGERR_STRING("ddl_set_prop:Bad_argument"); + return VCD_ERR_ILLEGAL_PARM; + } + ddl_context = ddl_get_context(); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_set_prop:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + + if (!ddl) { + VIDC_LOGERR_STRING("ddl_set_prop:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (ddl->decoding) { + vcd_status = + ddl_set_dec_property(ddl, property_hdr, + property_value); + } else { + vcd_status = + ddl_set_enc_property(ddl, property_hdr, + property_value); + } + if (vcd_status) + VIDC_LOGERR_STRING("ddl_set_prop:FAILED"); + + return vcd_status; +} + +u32 ddl_get_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + struct ddl_context *ddl_context; + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + + if (!property_hdr || !property_value) + return VCD_ERR_ILLEGAL_PARM; + + if (property_hdr->prop_id == DDL_I_CAPABILITY) { + if (sizeof(struct ddl_property_capability) == + property_hdr->sz) { + struct ddl_property_capability *ddl_capability = + (struct ddl_property_capability *) + property_value; + ddl_capability->max_num_client = VCD_MAX_NO_CLIENT; + ddl_capability->exclusive = + VCD_COMMAND_EXCLUSIVE; + ddl_capability->frame_command_depth = + VCD_FRAME_COMMAND_DEPTH; + ddl_capability->general_command_depth = + VCD_GENERAL_COMMAND_DEPTH; + ddl_capability->ddl_time_out_in_ms = + DDL_HW_TIMEOUT_IN_MS; + vcd_status = VCD_S_SUCCESS; + } + return vcd_status; + } + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) + return VCD_ERR_ILLEGAL_OP; + + if (!ddl) + return VCD_ERR_BAD_HANDLE; + + if (ddl->decoding) { + vcd_status = + ddl_get_dec_property(ddl, property_hdr, + property_value); + } else { + vcd_status = + ddl_get_enc_property(ddl, property_hdr, + property_value); + } + if (vcd_status) + VIDC_LOGERR_STRING("ddl_get_prop:FAILED"); + + return vcd_status; +} + +u32 ddl_decoder_ready_to_start(struct ddl_client_context *ddl, + struct vcd_sequence_hdr *header) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + if (!decoder->codec.codec) { + VIDC_LOGERR_STRING("ddl_dec_start_check:Codec_not_set"); + return false; + } + if ((!header) && + (!decoder->client_frame_size.height || + !decoder->client_frame_size.width) + ) { + VIDC_LOGERR_STRING + ("ddl_dec_start_check:Client_height_width_default"); + return false; + } + return true; +} + +u32 ddl_encoder_ready_to_start(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + + if (!encoder->codec.codec || + !encoder->frame_size.height || + !encoder->frame_size.width || + !encoder->frame_rate.fps_denominator || + !encoder->frame_rate.fps_numerator || + !encoder->target_bit_rate.target_bitrate) { + return false; + } + return true; +} + +static u32 ddl_set_dec_property + (struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) { + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + switch (property_hdr->prop_id) { + case DDL_I_DPB_RELEASE: + { + if (sizeof(struct ddl_frame_data_tag) == + property_hdr->sz + && decoder->dp_buf.no_of_dec_pic_buf) { + vcd_status = + ddl_decoder_dpb_transact(decoder, + (struct ddl_frame_data_tag *) + property_value, + DDL_DPB_OP_MARK_FREE); + } + break; + } + case DDL_I_DPB: + { + struct ddl_property_dec_pic_buffers *dpb = + (struct ddl_property_dec_pic_buffers *) + property_value; + + if (sizeof(struct ddl_property_dec_pic_buffers) == + property_hdr->sz && + (DDLCLIENT_STATE_IS + (ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) + || DDLCLIENT_STATE_IS(ddl, + DDL_CLIENT_WAIT_FOR_DPB) + ) && + dpb->no_of_dec_pic_buf >= + decoder->client_output_buf_req.actual_count) { + vcd_status = + ddl_set_dec_buffers(decoder, dpb); + } + break; + } + case DDL_I_REQ_OUTPUT_FLUSH: + { + if (sizeof(u32) == property_hdr->sz) { + decoder->dynamic_prop_change |= + DDL_DEC_REQ_OUTPUT_FLUSH; + decoder->dpb_mask.client_mask = 0; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_INPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *) + property_value; + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && + (ddl_valid_buffer_requirement( + &decoder->min_input_buf_req, + buffer_req))) { + decoder->client_input_buf_req = *buffer_req; + decoder->client_input_buf_req.min_count = + decoder->min_input_buf_req.min_count; + decoder->client_input_buf_req.max_count = + decoder->min_input_buf_req.max_count; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_OUTPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *) + property_value; + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && + (ddl_valid_buffer_requirement( + &decoder->min_output_buf_req, + buffer_req))) { + decoder->client_output_buf_req = + *buffer_req; + decoder->client_output_buf_req.min_count = + decoder->min_output_buf_req.min_count; + decoder->client_output_buf_req.max_count = + decoder->min_output_buf_req.max_count; + vcd_status = VCD_S_SUCCESS; + } + break; + } + + case VCD_I_CODEC: + { + struct vcd_property_codec *codec = + (struct vcd_property_codec *)property_value; + if (sizeof(struct vcd_property_codec) == + property_hdr->sz + && DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) + ) { + u32 status; + vcd_fw_transact(false, true, + decoder->codec.codec); + status = vcd_fw_transact(true, true, + codec->codec); + if (status) { + decoder->codec = *codec; + ddl_set_default_dec_property(ddl); + vcd_status = VCD_S_SUCCESS; + } else { + status = vcd_fw_transact(true, true, + decoder->codec.codec); + vcd_status = VCD_ERR_NOT_SUPPORTED; + } + } + break; + } + case VCD_I_POST_FILTER: + { + if (sizeof(struct vcd_property_post_filter) == + property_hdr->sz + && DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + (decoder->codec.codec == VCD_CODEC_MPEG4 || + decoder->codec.codec == VCD_CODEC_MPEG2) + ) { + decoder->post_filter = + *(struct vcd_property_post_filter *) + property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_FRAME_SIZE: + { + struct vcd_property_frame_size *frame_size = + (struct vcd_property_frame_size *) + property_value; + + if ((sizeof(struct vcd_property_frame_size) == + property_hdr->sz) && + (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN))) { + if (decoder->client_frame_size.height != + frame_size->height + || decoder->client_frame_size.width != + frame_size->width) { + decoder->client_frame_size = + *frame_size; + ddl_set_default_decoder_buffer_req + (decoder, true); + } + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_BUFFER_FORMAT: + { + struct vcd_property_buffer_format *tile = + (struct vcd_property_buffer_format *) + property_value; + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + (tile->buffer_format == VCD_BUFFER_FORMAT_NV12 + || tile->buffer_format == + VCD_BUFFER_FORMAT_TILE_4x2) + ) { + if (tile->buffer_format != + decoder->buf_format.buffer_format) { + decoder->buf_format = *tile; + ddl_set_default_decoder_buffer_req + (decoder, true); + } + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + { + vcd_status = ddl_set_metadata_params(ddl, + property_hdr, + property_value); + break; + } + case VCD_I_OUTPUT_ORDER: + { + if (sizeof(u32) == property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + decoder->output_order = + *(u32 *)property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_DEC_PICTYPE: + { + if ((sizeof(u32) == property_hdr->sz) && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + decoder->idr_only_decoding = + *(u32 *)property_value; + ddl_set_default_decoder_buffer_req( + decoder, true); + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_FRAME_RATE: + { + vcd_status = VCD_S_SUCCESS; + break; + } + default: + { + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + } + return vcd_status; +} + +static u32 ddl_set_enc_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) || + (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN))) + vcd_status = ddl_set_enc_dynamic_property(ddl, + property_hdr, property_value); + if (vcd_status == VCD_S_SUCCESS) + return vcd_status; + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) || + vcd_status != VCD_ERR_ILLEGAL_OP) { + VIDC_LOGERR_STRING + ("ddl_set_enc_property:Fails_as_not_in_open_state"); + return VCD_ERR_ILLEGAL_OP; + } + + switch (property_hdr->prop_id) { + case VCD_I_FRAME_SIZE: + { + struct vcd_property_frame_size *framesize = + (struct vcd_property_frame_size *) + property_value; + + if (sizeof(struct vcd_property_frame_size) + == property_hdr->sz && + DDL_ALLOW_ENC_FRAMESIZE(framesize->width, + framesize->height) && + (encoder->codec.codec == VCD_CODEC_H264 || + DDL_VALIDATE_ENC_FRAMESIZE(framesize->width, + framesize->height)) + ) { + encoder->frame_size = *framesize; + ddl_calculate_stride(&encoder->frame_size, + false, encoder->codec.codec); + ddl_set_default_encoder_buffer_req(encoder); + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_CODEC: + { + struct vcd_property_codec *codec = + (struct vcd_property_codec *) + property_value; + if (sizeof(struct vcd_property_codec) == + property_hdr->sz) { + u32 status; + + vcd_fw_transact(false, false, + encoder->codec.codec); + + status = vcd_fw_transact(true, false, + codec->codec); + if (status) { + encoder->codec = *codec; + ddl_set_default_enc_property(ddl); + vcd_status = VCD_S_SUCCESS; + } else { + status = vcd_fw_transact(true, false, + encoder->codec.codec); + vcd_status = VCD_ERR_NOT_SUPPORTED; + } + } + break; + } + case VCD_I_PROFILE: + { + struct vcd_property_profile *profile = + (struct vcd_property_profile *) + property_value; + if ((sizeof(struct vcd_property_profile) == + property_hdr->sz) && + ((encoder->codec.codec == + VCD_CODEC_MPEG4 && + (profile->profile == + VCD_PROFILE_MPEG4_SP || + profile->profile == + VCD_PROFILE_MPEG4_ASP)) || + (encoder->codec.codec == + VCD_CODEC_H264 && + (profile->profile >= + VCD_PROFILE_H264_BASELINE || + profile->profile <= + VCD_PROFILE_H264_HIGH)) || + (encoder->codec.codec == + VCD_CODEC_H263 && + profile->profile == + VCD_PROFILE_H263_BASELINE)) + ) { + encoder->profile = *profile; + vcd_status = VCD_S_SUCCESS; + + if (profile->profile == + VCD_PROFILE_H264_BASELINE) + encoder->entropy_control.entropy_sel + = VCD_ENTROPY_SEL_CAVLC; + else + encoder->entropy_control.entropy_sel + = VCD_ENTROPY_SEL_CABAC; + } + break; + } + case VCD_I_LEVEL: + { + struct vcd_property_level *level = + (struct vcd_property_level *) + property_value; + if ( + (sizeof(struct vcd_property_level) == + property_hdr->sz + ) && + ( + ( + (encoder->codec. + codec == VCD_CODEC_MPEG4) && + (level->level >= VCD_LEVEL_MPEG4_0) && + (level->level <= VCD_LEVEL_MPEG4_6) + ) || + ( + (encoder->codec. + codec == VCD_CODEC_H264) && + (level->level >= VCD_LEVEL_H264_1) && + (level->level <= VCD_LEVEL_H264_3p1) + ) || + ( + (encoder->codec. + codec == VCD_CODEC_H263) && + (level->level >= VCD_LEVEL_H263_10) && + (level->level <= VCD_LEVEL_H263_70) + ) + ) + ) { + encoder->level = *level; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_MULTI_SLICE: + { + struct vcd_property_multi_slice *multislice = + (struct vcd_property_multi_slice *) + property_value; + switch (multislice->m_slice_sel) { + case VCD_MSLICE_OFF: + { + vcd_status = VCD_S_SUCCESS; + break; + } + case VCD_MSLICE_BY_GOB: + { + if (encoder->codec.codec == + VCD_CODEC_H263) + vcd_status = VCD_S_SUCCESS; + break; + } + case VCD_MSLICE_BY_MB_COUNT: + { + if (multislice->m_slice_size + >= 1 && (multislice-> + m_slice_size <= + (encoder->frame_size.height + * encoder->frame_size.width + / 16 / 16)) + ) { + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_MSLICE_BY_BYTE_COUNT: + { + if (multislice->m_slice_size > 0) + vcd_status = VCD_S_SUCCESS; + break; + } + default: + { + break; + } + } + if (sizeof(struct vcd_property_multi_slice) == + property_hdr->sz && + !vcd_status) { + encoder->multi_slice = *multislice; + if (multislice->m_slice_sel == + VCD_MSLICE_OFF) + encoder->multi_slice.m_slice_size = 0; + } + break; + } + case VCD_I_RATE_CONTROL: + { + struct vcd_property_rate_control + *ratecontrol = + (struct vcd_property_rate_control *) + property_value; + if (sizeof(struct vcd_property_rate_control) == + property_hdr->sz && + ratecontrol-> + rate_control >= VCD_RATE_CONTROL_OFF && + ratecontrol-> + rate_control <= VCD_RATE_CONTROL_CBR_CFR + ) { + encoder->rc = *ratecontrol; + ddl_set_default_enc_rc_params(encoder); + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_SHORT_HEADER: + { + + if (sizeof(struct vcd_property_short_header) == + property_hdr->sz && + encoder->codec.codec == VCD_CODEC_MPEG4) { + encoder->short_header = + *(struct vcd_property_short_header *) + property_value; + vcd_status = VCD_S_SUCCESS; + } + + break; + } + case VCD_I_VOP_TIMING: + { + struct vcd_property_vop_timing *voptime = + (struct vcd_property_vop_timing *) + property_value; + if ( + (sizeof(struct vcd_property_vop_timing) == + property_hdr->sz + ) && + (encoder->frame_rate.fps_numerator <= + voptime->vop_time_resolution) + ) { + encoder->vop_timing = *voptime; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_HEADER_EXTENSION: + { + if (sizeof(u32) == property_hdr->sz && + encoder->codec.codec == VCD_CODEC_MPEG4 + ) { + encoder->hdr_ext_control = *(u32 *) + property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_ENTROPY_CTRL: + { + struct vcd_property_entropy_control + *entropy_control = + (struct vcd_property_entropy_control *) + property_value; + if (sizeof(struct vcd_property_entropy_control) == + property_hdr->sz && + encoder->codec.codec == VCD_CODEC_H264 + && entropy_control-> + entropy_sel >= VCD_ENTROPY_SEL_CAVLC && + entropy_control->entropy_sel <= + VCD_ENTROPY_SEL_CABAC) { + encoder->entropy_control = *entropy_control; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_DEBLOCKING: + { + struct vcd_property_db_config *dbconfig = + (struct vcd_property_db_config *) + property_value; + if (sizeof(struct vcd_property_db_config) == + property_hdr->sz && + encoder->codec.codec == VCD_CODEC_H264 + && dbconfig->db_config >= + VCD_DB_ALL_BLOCKING_BOUNDARY + && dbconfig->db_config <= + VCD_DB_SKIP_SLICE_BOUNDARY + ) { + encoder->db_control = *dbconfig; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_QP_RANGE: + { + struct vcd_property_qp_range *qp = + (struct vcd_property_qp_range *) + property_value; + if ((sizeof(struct vcd_property_qp_range) == + property_hdr->sz) && + (qp->min_qp <= qp->max_qp) && + ( + (encoder->codec.codec == VCD_CODEC_H264 + && qp->max_qp <= DDL_MAX_H264_QP) || + (qp->max_qp <= DDL_MAX_MPEG4_QP) + ) + ) { + encoder->qp_range = *qp; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_SESSION_QP: + { + struct vcd_property_session_qp *qp = + (struct vcd_property_session_qp *) + property_value; + + if ((sizeof(struct vcd_property_session_qp) == + property_hdr->sz) && + (qp->i_frame_qp >= encoder->qp_range.min_qp) && + (qp->i_frame_qp <= encoder->qp_range.max_qp) && + (qp->p_frame_qp >= encoder->qp_range.min_qp) && + (qp->p_frame_qp <= encoder->qp_range.max_qp) + ) { + encoder->session_qp = *qp; + vcd_status = VCD_S_SUCCESS; + } + + break; + } + case VCD_I_RC_LEVEL_CONFIG: + { + struct vcd_property_rc_level *rc_level = + (struct vcd_property_rc_level *) + property_value; + if (sizeof(struct vcd_property_rc_level) == + property_hdr->sz && + ( + encoder->rc. + rate_control >= VCD_RATE_CONTROL_VBR_VFR || + encoder->rc. + rate_control <= VCD_RATE_CONTROL_CBR_VFR + ) && + (!rc_level->mb_level_rc || + encoder->codec.codec == VCD_CODEC_H264 + ) + ) { + encoder->rc_level = *rc_level; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_FRAME_LEVEL_RC: + { + + struct vcd_property_frame_level_rc_params + *frame_levelrc = + (struct vcd_property_frame_level_rc_params *) + property_value; + + if ((sizeof(struct + vcd_property_frame_level_rc_params) + == property_hdr->sz) && + (frame_levelrc->reaction_coeff) && + (encoder->rc_level.frame_level_rc) + ) { + encoder->frame_level_rc = *frame_levelrc; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_ADAPTIVE_RC: + { + + if ((sizeof(struct + vcd_property_adaptive_rc_params) + == property_hdr->sz) && + (encoder->codec. + codec == VCD_CODEC_H264) && + (encoder->rc_level.mb_level_rc)) { + + encoder->adaptive_rc = + *(struct vcd_property_adaptive_rc_params *) + property_value; + + vcd_status = VCD_S_SUCCESS; + } + + break; + } + case VCD_I_BUFFER_FORMAT: + { + struct vcd_property_buffer_format *tile = + (struct vcd_property_buffer_format *) + property_value; + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz && + tile->buffer_format == + VCD_BUFFER_FORMAT_NV12) { + encoder->buf_format = *tile; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_INPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *) + property_value; + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && + (ddl_valid_buffer_requirement( + &encoder->input_buf_req, buffer_req)) + ) { + encoder->client_input_buf_req = *buffer_req; + encoder->client_input_buf_req.min_count = + encoder->input_buf_req.min_count; + encoder->client_input_buf_req.max_count = + encoder->input_buf_req.max_count; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_OUTPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *) + property_value; + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && + (ddl_valid_buffer_requirement( + &encoder->output_buf_req, buffer_req)) + ) { + encoder->client_output_buf_req = + *buffer_req; + encoder->client_output_buf_req.min_count = + encoder->output_buf_req.min_count; + encoder->client_output_buf_req.max_count = + encoder->output_buf_req.max_count; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + { + vcd_status = ddl_set_metadata_params( + ddl, property_hdr, property_value); + break; + } + case VCD_I_META_BUFFER_MODE: + { + vcd_status = VCD_S_SUCCESS; + break; + } + default: + { + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + } + return vcd_status; +} + +static u32 ddl_get_dec_property + (struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) { + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + + switch (property_hdr->prop_id) { + case VCD_I_FRAME_SIZE: + { + struct vcd_property_frame_size *fz_size; + if (sizeof(struct vcd_property_frame_size) == + property_hdr->sz) { + ddl_calculate_stride( + &decoder->client_frame_size, + !decoder->progressive_only, + decoder->codec.codec); + if (decoder->buf_format.buffer_format + == VCD_BUFFER_FORMAT_TILE_4x2) { + fz_size = + &decoder->client_frame_size; + fz_size->stride = + DDL_TILE_ALIGN(fz_size->width, + DDL_TILE_ALIGN_WIDTH); + fz_size->scan_lines = + DDL_TILE_ALIGN(fz_size->height, + DDL_TILE_ALIGN_HEIGHT); + } + *(struct vcd_property_frame_size *) + property_value = + decoder->client_frame_size; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_PROFILE: + { + if (sizeof(struct vcd_property_profile) == + property_hdr->sz) { + *(struct vcd_property_profile *) + property_value = decoder->profile; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_LEVEL: + { + if (sizeof(struct vcd_property_level) == + property_hdr->sz) { + *(struct vcd_property_level *) + property_value = decoder->level; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_PROGRESSIVE_ONLY: + { + if (sizeof(u32) == property_hdr->sz) { + *(u32 *) property_value = + decoder->progressive_only; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_INPUT_BUF_REQ: + { + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = + decoder->client_input_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_OUTPUT_BUF_REQ: + { + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = + decoder->client_output_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_CODEC: + { + if (sizeof(struct vcd_property_codec) == + property_hdr->sz) { + *(struct vcd_property_codec *) + property_value = decoder->codec; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_BUFFER_FORMAT: + { + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz) { + *(struct vcd_property_buffer_format *) + property_value = decoder->buf_format; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_POST_FILTER: + { + if (sizeof(struct vcd_property_post_filter) == + property_hdr->sz) { + *(struct vcd_property_post_filter *) + property_value = decoder->post_filter; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_SEQHDR_ALIGN_BYTES: + { + if (sizeof(u32) == property_hdr->sz) { + *(u32 *) property_value = + DDL_LINEAR_BUFFER_ALIGN_BYTES; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_FRAME_PROC_UNITS: + { + if (sizeof(u32) == property_hdr->sz) { + struct vcd_property_frame_size frame_sz = + decoder->client_frame_size; + ddl_calculate_stride(&frame_sz, + !decoder->progressive_only, + decoder->codec.codec); + *(u32 *) property_value = + ((frame_sz.stride >> 4) * + (frame_sz.scan_lines >> 4)); + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_DPB_RETRIEVE: + { + if (sizeof(struct ddl_frame_data_tag) == + property_hdr->sz) { + vcd_status = + ddl_decoder_dpb_transact(decoder, + (struct ddl_frame_data_tag *) + property_value, + DDL_DPB_OP_RETRIEVE); + } + break; + } + case VCD_I_OUTPUT_ORDER: + { + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = decoder->output_order; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + { + vcd_status = ddl_get_metadata_params( + ddl, + property_hdr, + property_value); + break; + } + default: + { + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + } + return vcd_status; +} + +static u32 ddl_get_enc_property + (struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) { + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + struct ddl_encoder_data *encoder = &ddl->codec_data.encoder; + + struct vcd_property_entropy_control *entropy_control; + struct vcd_property_intra_refresh_mb_number *intra_refresh; + + switch (property_hdr->prop_id) { + case VCD_I_CODEC: + { + if (sizeof(struct vcd_property_codec) == + property_hdr->sz) { + *(struct vcd_property_codec *) + property_value = + encoder->codec; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_FRAME_SIZE: + { + if (sizeof(struct vcd_property_frame_size) == + property_hdr->sz) { + *(struct vcd_property_frame_size *) + property_value = + encoder->frame_size; + + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_FRAME_RATE: + { + if (sizeof(struct vcd_property_frame_rate) == + property_hdr->sz) { + + *(struct vcd_property_frame_rate *) + property_value = + encoder->frame_rate; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_TARGET_BITRATE: + { + + if (sizeof(struct vcd_property_target_bitrate) == + property_hdr->sz) { + *(struct vcd_property_target_bitrate *) + property_value = + encoder->target_bit_rate; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_RATE_CONTROL: + { + if (sizeof(struct vcd_property_rate_control) == + property_hdr->sz) { + *(struct vcd_property_rate_control *) + property_value = encoder->rc; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_PROFILE: + { + if (sizeof(struct vcd_property_profile) == + property_hdr->sz) { + *(struct vcd_property_profile *) + property_value = encoder->profile; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_LEVEL: + { + if (sizeof(struct vcd_property_level) == + property_hdr->sz) { + *(struct vcd_property_level *) + property_value = encoder->level; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_MULTI_SLICE: + { + if (sizeof(struct vcd_property_multi_slice) == + property_hdr->sz) { + *(struct vcd_property_multi_slice *) + property_value = encoder->multi_slice; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_SEQ_HEADER: + { + struct vcd_sequence_hdr *seq_hdr = + (struct vcd_sequence_hdr *)property_value; + if (encoder->seq_header.buffer_size && + sizeof(struct vcd_sequence_hdr) == + property_hdr->sz + && encoder->seq_header.buffer_size <= + seq_hdr->sequence_header_len) { + DDL_MEMCPY(seq_hdr->sequence_header, + encoder->seq_header. + align_virtual_addr, + encoder->seq_header.buffer_size); + seq_hdr->sequence_header_len = + encoder->seq_header.buffer_size; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_SEQHDR_PRESENT: + { + if (sizeof(u32) == property_hdr->sz) { + if ((encoder->codec. + codec == VCD_CODEC_MPEG4 && + !encoder->short_header.short_header) + || encoder->codec.codec == + VCD_CODEC_H264) { + *(u32 *)property_value = 0x1; + } else { + *(u32 *)property_value = 0x0; + } + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_VOP_TIMING: + { + if (sizeof(struct vcd_property_vop_timing) == + property_hdr->sz) { + *(struct vcd_property_vop_timing *) + property_value = encoder->vop_timing; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_SHORT_HEADER: + { + if (sizeof(struct vcd_property_short_header) == + property_hdr->sz) { + if (encoder->codec.codec == + VCD_CODEC_MPEG4) { + *(struct vcd_property_short_header + *)property_value = + encoder->short_header; + vcd_status = VCD_S_SUCCESS; + } else { + vcd_status = VCD_ERR_ILLEGAL_OP; + } + } + break; + } + case VCD_I_ENTROPY_CTRL: + { + entropy_control = property_value; + if (sizeof(struct vcd_property_entropy_control) == + property_hdr->sz) { + if (encoder->codec.codec == + VCD_CODEC_H264) { + *entropy_control = + encoder->entropy_control; + vcd_status = VCD_S_SUCCESS; + } else { + vcd_status = VCD_ERR_ILLEGAL_OP; + } + } + break; + } + case VCD_I_DEBLOCKING: + { + if (sizeof(struct vcd_property_db_config) == + property_hdr->sz) { + if (encoder->codec.codec == + VCD_CODEC_H264) { + *(struct vcd_property_db_config *) + property_value = + encoder->db_control; + vcd_status = VCD_S_SUCCESS; + } else { + vcd_status = VCD_ERR_ILLEGAL_OP; + } + } + break; + } + case VCD_I_INTRA_PERIOD: + { + if (sizeof(struct vcd_property_i_period) == + property_hdr->sz) { + *(struct vcd_property_i_period *) + property_value = encoder->i_period; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_QP_RANGE: + { + if (sizeof(struct vcd_property_qp_range) == + property_hdr->sz) { + *(struct vcd_property_qp_range *) + property_value = encoder->qp_range; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_SESSION_QP: + { + if (sizeof(struct vcd_property_session_qp) == + property_hdr->sz) { + *(struct vcd_property_session_qp *) + property_value = encoder->session_qp; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_RC_LEVEL_CONFIG: + { + if (sizeof(struct vcd_property_rc_level) == + property_hdr->sz) { + *(struct vcd_property_rc_level *) + property_value = encoder->rc_level; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_FRAME_LEVEL_RC: + { + if (sizeof + (struct vcd_property_frame_level_rc_params) == + property_hdr->sz) { + *(struct vcd_property_frame_level_rc_params + *)property_value = + encoder->frame_level_rc; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_ADAPTIVE_RC: + { + if (sizeof(struct vcd_property_adaptive_rc_params) + == property_hdr->sz) { + *(struct vcd_property_adaptive_rc_params *) + property_value = encoder->adaptive_rc; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_INTRA_REFRESH: + { + intra_refresh = property_value; + if (sizeof + (struct vcd_property_intra_refresh_mb_number) + == property_hdr->sz) { + *intra_refresh = encoder->intra_refresh; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_INPUT_BUF_REQ: + { + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = + encoder->client_input_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_OUTPUT_BUF_REQ: + { + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = + encoder->client_output_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_BUFFER_FORMAT: + { + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz) { + *(struct vcd_property_buffer_format *) + property_value = encoder->buf_format; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_FRAME_PROC_UNITS: + { + if (sizeof(u32) == property_hdr->sz) { + *(u32 *) property_value = + ((encoder->frame_size.width >> 4) * + (encoder->frame_size.height >> 4) + ); + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_HEADER_EXTENSION: + { + if (sizeof(u32) == property_hdr->sz && + encoder->codec.codec == VCD_CODEC_MPEG4) { + *(u32 *) property_value = + encoder->hdr_ext_control; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + { + vcd_status = ddl_get_metadata_params( + ddl, + property_hdr, + property_value); + break; + } + default: + { + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + } + return vcd_status; +} + +static u32 ddl_set_enc_dynamic_property + (struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) { + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + u32 vcd_status = VCD_ERR_ILLEGAL_PARM, dynamic_prop_change = 0x0; + switch (property_hdr->prop_id) { + case VCD_I_REQ_IFRAME: + { + if (sizeof(struct vcd_property_req_i_frame) == + property_hdr->sz) { + dynamic_prop_change = DDL_ENC_REQ_IFRAME; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_TARGET_BITRATE: + { + struct vcd_property_target_bitrate *bitrate = + (struct vcd_property_target_bitrate *) + property_value; + if (sizeof(struct vcd_property_target_bitrate) == + property_hdr->sz && bitrate->target_bitrate > 0 + && bitrate->target_bitrate <= DDL_MAX_BIT_RATE) { + encoder->target_bit_rate = *bitrate; + dynamic_prop_change = DDL_ENC_CHANGE_BITRATE; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_INTRA_PERIOD: + { + struct vcd_property_i_period *iperiod = + (struct vcd_property_i_period *) + property_value; + if (sizeof(struct vcd_property_i_period) == + property_hdr->sz && + !iperiod->b_frames) { + encoder->i_period = *iperiod; + dynamic_prop_change = DDL_ENC_CHANGE_IPERIOD; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_FRAME_RATE: + { + struct vcd_property_frame_rate *frame_rate = + (struct vcd_property_frame_rate *) + property_value; + if (sizeof(struct vcd_property_frame_rate) + == property_hdr->sz && + frame_rate->fps_denominator && + frame_rate->fps_numerator && + frame_rate->fps_denominator <= + frame_rate->fps_numerator) { + encoder->frame_rate = *frame_rate; + dynamic_prop_change = DDL_ENC_CHANGE_FRAMERATE; + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + (encoder->codec.codec != VCD_CODEC_MPEG4 + || encoder->short_header.short_header)) + ddl_set_default_enc_vop_timing(encoder); + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_INTRA_REFRESH: + { + struct vcd_property_intra_refresh_mb_number + *intra_refresh_mbnum = ( + struct vcd_property_intra_refresh_mb_number *) + property_value; + u32 frame_mbnum = + (encoder->frame_size.width >> 4) * + (encoder->frame_size.height >> 4); + if (sizeof(struct + vcd_property_intra_refresh_mb_number) + == property_hdr->sz && + intra_refresh_mbnum->cir_mb_number <= + frame_mbnum) { + encoder->intra_refresh = + *intra_refresh_mbnum; + dynamic_prop_change = DDL_ENC_CHANGE_CIR; + vcd_status = VCD_S_SUCCESS; + } + + break; + } + default: + { + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + } + if (vcd_status == VCD_S_SUCCESS && + (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE))) + encoder->dynamic_prop_change |= dynamic_prop_change; + return vcd_status; +} + +void ddl_set_default_dec_property(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + + if (decoder->codec.codec >= VCD_CODEC_MPEG2 && + decoder->codec.codec <= VCD_CODEC_XVID) + decoder->post_filter.post_filter = true; + else + decoder->post_filter.post_filter = false; + decoder->buf_format.buffer_format = VCD_BUFFER_FORMAT_NV12; + decoder->client_frame_size.height = 144; + decoder->client_frame_size.width = 176; + decoder->client_frame_size.stride = 176; + decoder->client_frame_size.scan_lines = 144; + decoder->progressive_only = 1; + decoder->idr_only_decoding = 0; + decoder->profile.profile = VCD_PROFILE_UNKNOWN; + decoder->level.level = VCD_LEVEL_UNKNOWN; + decoder->output_order = VCD_DEC_ORDER_DISPLAY; + ddl_set_default_metadata_flag(ddl); + ddl_set_default_decoder_buffer_req(decoder, true); +} + +static void ddl_set_default_enc_property(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + + ddl_set_default_enc_profile(encoder); + ddl_set_default_enc_level(encoder); + + encoder->rc.rate_control = VCD_RATE_CONTROL_VBR_VFR; + ddl_set_default_enc_rc_params(encoder); + + ddl_set_default_enc_intra_period(encoder); + + encoder->intra_refresh.cir_mb_number = 0; + ddl_set_default_enc_vop_timing(encoder); + + encoder->multi_slice.m_slice_sel = VCD_MSLICE_OFF; + encoder->multi_slice.m_slice_size = 0; + encoder->short_header.short_header = false; + + encoder->entropy_control.entropy_sel = VCD_ENTROPY_SEL_CAVLC; + encoder->entropy_control.cabac_model = VCD_CABAC_MODEL_NUMBER_0; + encoder->db_control.db_config = VCD_DB_ALL_BLOCKING_BOUNDARY; + encoder->db_control.slice_alpha_offset = 0; + encoder->db_control.slice_beta_offset = 0; + + encoder->re_con_buf_format.buffer_format = + VCD_BUFFER_FORMAT_TILE_4x2; + + encoder->buf_format.buffer_format = VCD_BUFFER_FORMAT_NV12; + + encoder->hdr_ext_control = 0; + + ddl_set_default_metadata_flag(ddl); + + ddl_set_default_encoder_buffer_req(encoder); +} + +static void ddl_set_default_enc_profile(struct ddl_encoder_data *encoder) +{ + enum vcd_codec codec = encoder->codec.codec; + if (codec == VCD_CODEC_MPEG4) + encoder->profile.profile = VCD_PROFILE_MPEG4_SP; + else if (codec == VCD_CODEC_H264) + encoder->profile.profile = VCD_PROFILE_H264_BASELINE; + else + encoder->profile.profile = VCD_PROFILE_H263_BASELINE; +} + +static void ddl_set_default_enc_level(struct ddl_encoder_data *encoder) +{ + enum vcd_codec codec = encoder->codec.codec; + if (codec == VCD_CODEC_MPEG4) + encoder->level.level = VCD_LEVEL_MPEG4_1; + else if (codec == VCD_CODEC_H264) + encoder->level.level = VCD_LEVEL_H264_1; + else + encoder->level.level = VCD_LEVEL_H263_10; +} + +static void ddl_set_default_enc_vop_timing + (struct ddl_encoder_data *encoder) +{ + if (encoder->codec.codec == VCD_CODEC_MPEG4) + encoder->vop_timing.vop_time_resolution = + (2 * encoder->frame_rate.fps_numerator) / + encoder->frame_rate.fps_denominator; + else + encoder->vop_timing.vop_time_resolution = 0x7530; +} + +static void ddl_set_default_enc_intra_period( + struct ddl_encoder_data *encoder) +{ + switch (encoder->rc.rate_control) { + default: + case VCD_RATE_CONTROL_VBR_VFR: + case VCD_RATE_CONTROL_VBR_CFR: + case VCD_RATE_CONTROL_CBR_VFR: + case VCD_RATE_CONTROL_OFF: + { + encoder->i_period.p_frames = + ((encoder->frame_rate.fps_numerator << 1) / + encoder->frame_rate.fps_denominator) - 1; + break; + } + case VCD_RATE_CONTROL_CBR_CFR: + { + encoder->i_period.p_frames = + ((encoder->frame_rate.fps_numerator >> 1) / + encoder->frame_rate.fps_denominator) - 1; + break; + } + } + encoder->i_period.b_frames = 0; +} + +static void ddl_set_default_enc_rc_params( + struct ddl_encoder_data *encoder) +{ + enum vcd_codec codec = encoder->codec.codec; + + encoder->rc_level.frame_level_rc = true; + encoder->qp_range.min_qp = 0x1; + + if (codec == VCD_CODEC_H264) { + encoder->qp_range.max_qp = 0x33; + encoder->session_qp.i_frame_qp = 0x14; + encoder->session_qp.p_frame_qp = 0x14; + + encoder->rc_level.mb_level_rc = true; + encoder->adaptive_rc.activity_region_flag = true; + encoder->adaptive_rc.dark_region_as_flag = true; + encoder->adaptive_rc.smooth_region_as_flag = true; + encoder->adaptive_rc.static_region_as_flag = true; + } else { + encoder->qp_range.max_qp = 0x1f; + encoder->session_qp.i_frame_qp = 0xd; + encoder->session_qp.p_frame_qp = 0xd; + encoder->rc_level.mb_level_rc = false; + } + + switch (encoder->rc.rate_control) { + default: + case VCD_RATE_CONTROL_VBR_VFR: + { + encoder->r_cframe_skip = 1; + encoder->frame_level_rc.reaction_coeff = 0x1f4; + break; + } + case VCD_RATE_CONTROL_VBR_CFR: + { + encoder->r_cframe_skip = 0; + encoder->frame_level_rc.reaction_coeff = 0x1f4; + break; + } + case VCD_RATE_CONTROL_CBR_VFR: + { + encoder->r_cframe_skip = 1; + if (codec != VCD_CODEC_H264) { + encoder->session_qp.i_frame_qp = 0xf; + encoder->session_qp.p_frame_qp = 0xf; + } + + encoder->frame_level_rc.reaction_coeff = 0x14; + break; + } + case VCD_RATE_CONTROL_CBR_CFR: + { + encoder->r_cframe_skip = 0; + encoder->frame_level_rc.reaction_coeff = 0x6; + break; + } + case VCD_RATE_CONTROL_OFF: + { + encoder->r_cframe_skip = 0; + encoder->rc_level.frame_level_rc = false; + encoder->rc_level.mb_level_rc = false; + break; + } + } +} + +void ddl_set_default_encoder_buffer_req(struct ddl_encoder_data *encoder) +{ + u32 y_cb_cr_size; + + y_cb_cr_size = ddl_get_yuv_buffer_size(&encoder->frame_size, + &encoder->buf_format, false, encoder->codec.codec); + + memset(&encoder->input_buf_req, 0, + sizeof(struct vcd_buffer_requirement)); + + encoder->input_buf_req.min_count = 1; + encoder->input_buf_req.actual_count = + encoder->input_buf_req.min_count + 8; + encoder->input_buf_req.max_count = DDL_MAX_BUFFER_COUNT; + encoder->input_buf_req.sz = y_cb_cr_size; + encoder->input_buf_req.align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + + 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 = 2; + encoder->output_buf_req.actual_count = + encoder->output_buf_req.min_count + 3; + encoder->output_buf_req.max_count = DDL_MAX_BUFFER_COUNT; + encoder->output_buf_req.align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + encoder->output_buf_req.sz = y_cb_cr_size; + ddl_set_default_encoder_metadata_buffer_size(encoder); + encoder->client_output_buf_req = encoder->output_buf_req; +} + +void ddl_set_default_decoder_buffer_req(struct ddl_decoder_data *decoder, + u32 estimate) +{ + u32 y_cb_cr_size, min_dpb, num_mb; + struct vcd_property_frame_size *frame_size; + struct vcd_buffer_requirement *output_buf_req, *input_buf_req; + + if (!decoder->codec.codec) + return; + + if (estimate) { + frame_size = &decoder->client_frame_size; + output_buf_req = &decoder->client_output_buf_req; + input_buf_req = &decoder->client_input_buf_req; + min_dpb = ddl_decoder_min_num_dpb(decoder); + y_cb_cr_size = ddl_get_yuv_buffer_size(frame_size, + &decoder->buf_format, (!decoder->progressive_only), + decoder->codec.codec); + } else { + frame_size = &decoder->frame_size; + output_buf_req = &decoder->actual_output_buf_req; + input_buf_req = &decoder->actual_input_buf_req; + y_cb_cr_size = decoder->y_cb_cr_size; + min_dpb = decoder->min_dpb_num; + } + + if (decoder->idr_only_decoding) + min_dpb = 1; + + memset(output_buf_req, 0, sizeof(struct vcd_buffer_requirement)); + + output_buf_req->min_count = min_dpb; + + num_mb = DDL_NO_OF_MB(frame_size->width, frame_size->height); + if (decoder->idr_only_decoding) { + output_buf_req->actual_count = output_buf_req->min_count; + } else { + if (num_mb >= DDL_WVGA_MBS) { + output_buf_req->actual_count = min_dpb + 2; + if (output_buf_req->actual_count < 10) + output_buf_req->actual_count = 10; + } else + output_buf_req->actual_count = min_dpb + 5; + } + output_buf_req->max_count = DDL_MAX_BUFFER_COUNT; + output_buf_req->sz = y_cb_cr_size; + if (decoder->buf_format.buffer_format != VCD_BUFFER_FORMAT_NV12) + output_buf_req->align = DDL_TILE_BUFFER_ALIGN_BYTES; + else + output_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + + ddl_set_default_decoder_metadata_buffer_size(decoder, + frame_size, output_buf_req); + + decoder->min_output_buf_req = *output_buf_req; + + memset(input_buf_req, 0, sizeof(struct vcd_buffer_requirement)); + + input_buf_req->min_count = 1; + input_buf_req->actual_count = input_buf_req->min_count + 3; + input_buf_req->max_count = DDL_MAX_BUFFER_COUNT; + input_buf_req->sz = (1280*720*3*3) >> 3; + input_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + + decoder->min_input_buf_req = *input_buf_req; + +} + +u32 ddl_get_yuv_buffer_size(struct vcd_property_frame_size *frame_size, + struct vcd_property_buffer_format *buf_format, u32 inter_lace, + enum vcd_codec codec) +{ + struct vcd_property_frame_size frame_sz = *frame_size; + u32 total_memory_size; + ddl_calculate_stride(&frame_sz, inter_lace, codec); + + if (buf_format->buffer_format != VCD_BUFFER_FORMAT_NV12) { + u32 component_mem_size; + u32 width_round_up; + u32 height_round_up; + u32 height_chroma = (frame_sz.scan_lines >> 1); + + width_round_up = + DDL_TILE_ALIGN(frame_sz.stride, DDL_TILE_ALIGN_WIDTH); + height_round_up = + DDL_TILE_ALIGN(frame_sz.scan_lines, DDL_TILE_ALIGN_HEIGHT); + + component_mem_size = width_round_up * height_round_up; + component_mem_size = DDL_TILE_ALIGN(component_mem_size, + DDL_TILE_MULTIPLY_FACTOR); + + total_memory_size = ((component_mem_size + + DDL_TILE_BUF_ALIGN_GUARD_BYTES) & + DDL_TILE_BUF_ALIGN_MASK); + + height_round_up = + DDL_TILE_ALIGN(height_chroma, DDL_TILE_ALIGN_HEIGHT); + component_mem_size = width_round_up * height_round_up; + component_mem_size = DDL_TILE_ALIGN(component_mem_size, + DDL_TILE_MULTIPLY_FACTOR); + total_memory_size += component_mem_size; + } else { + total_memory_size = frame_sz.scan_lines * frame_sz.stride; + total_memory_size += (total_memory_size >> 1); + } + return total_memory_size; +} + +void ddl_calculate_stride(struct vcd_property_frame_size *frame_size, + u32 interlace, enum vcd_codec codec) +{ + frame_size->stride = ((frame_size->width + 15) >> 4) << 4; + if (!interlace || codec == VCD_CODEC_MPEG4 || + codec == VCD_CODEC_DIVX_4 || + codec == VCD_CODEC_DIVX_5 || + codec == VCD_CODEC_DIVX_6 || + codec == VCD_CODEC_XVID) { + frame_size->scan_lines = + ((frame_size->height + 15) >> 4) << 4; + } else { + frame_size->scan_lines = + ((frame_size->height + 31) >> 5) << 5; + } + +} + +static u32 ddl_valid_buffer_requirement + (struct vcd_buffer_requirement *original_buf_req, + struct vcd_buffer_requirement *req_buf_req) +{ + u32 status = false; + if (original_buf_req->max_count >= req_buf_req->actual_count && + original_buf_req->min_count <= req_buf_req->actual_count && + original_buf_req->align <= req_buf_req->align && + original_buf_req->sz <= req_buf_req->sz) { + status = true; + } else { + VIDC_LOGERR_STRING("ddl_valid_buf_req:Failed"); + } + return status; +} + +static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *decoder) +{ + u32 min_dpb = 0, yuv_size = 0; + struct vcd_property_frame_size frame_sz = decoder->client_frame_size; + switch (decoder->codec.codec) { + default: + case VCD_CODEC_MPEG4: + case VCD_CODEC_MPEG2: + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + { + min_dpb = 3; + break; + } + case VCD_CODEC_H263: + { + min_dpb = 2; + break; + } + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + { + min_dpb = 4; + break; + } + case VCD_CODEC_H264: + { + ddl_calculate_stride(&frame_sz, + !decoder->progressive_only, + decoder->codec.codec); + yuv_size = + ((frame_sz.scan_lines * + frame_sz.stride * 3) >> 1); + min_dpb = 6912000 / yuv_size; + if (min_dpb > 16) + min_dpb = 16; + + min_dpb += 2; + break; + } + } + return min_dpb; +} + +static u32 ddl_set_dec_buffers + (struct ddl_decoder_data *decoder, + struct ddl_property_dec_pic_buffers *dpb) { + u32 vcd_status = VCD_S_SUCCESS; + u32 loopc; + for (loopc = 0; !vcd_status && + loopc < dpb->no_of_dec_pic_buf; ++loopc) { + if ((!DDL_ADDR_IS_ALIGNED + (dpb->dec_pic_buffers[loopc].vcd_frm.physical, + decoder->client_output_buf_req.align) + ) + || (dpb->dec_pic_buffers[loopc].vcd_frm.alloc_len < + decoder->client_output_buf_req.sz) + ) { + vcd_status = VCD_ERR_ILLEGAL_PARM; + } + } + if (vcd_status) { + VIDC_LOGERR_STRING + ("ddl_set_prop:Dpb_align_fail_or_alloc_size_small"); + return vcd_status; + } + if (decoder->dp_buf.no_of_dec_pic_buf) { + DDL_FREE(decoder->dp_buf.dec_pic_buffers); + decoder->dp_buf.no_of_dec_pic_buf = 0; + } + decoder->dp_buf.dec_pic_buffers = + DDL_MALLOC(dpb->no_of_dec_pic_buf * + sizeof(struct ddl_frame_data_tag)); + + if (!decoder->dp_buf.dec_pic_buffers) { + VIDC_LOGERR_STRING + ("ddl_dec_set_prop:Dpb_container_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + decoder->dp_buf.no_of_dec_pic_buf = dpb->no_of_dec_pic_buf; + for (loopc = 0; loopc < dpb->no_of_dec_pic_buf; ++loopc) { + decoder->dp_buf.dec_pic_buffers[loopc] = + dpb->dec_pic_buffers[loopc]; + } + decoder->dpb_mask.client_mask = 0; + decoder->dpb_mask.hw_mask = 0; + decoder->dynamic_prop_change = 0; + return VCD_S_SUCCESS; +} + +void ddl_set_initial_default_values(struct ddl_client_context *ddl) +{ + if (ddl->decoding) { + ddl->codec_data.decoder.codec.codec = VCD_CODEC_MPEG4; + vcd_fw_transact(true, true, + ddl->codec_data.decoder.codec.codec); + ddl_set_default_dec_property(ddl); + } else { + struct ddl_encoder_data *encoder = + &(ddl->codec_data.encoder); + encoder->codec.codec = VCD_CODEC_MPEG4; + vcd_fw_transact(true, false, + encoder->codec.codec); + + encoder->target_bit_rate.target_bitrate = 64000; + encoder->frame_size.width = 176; + encoder->frame_size.height = 144; + encoder->frame_size.stride = 176; + encoder->frame_size.scan_lines = 144; + encoder->frame_rate.fps_numerator = 30; + encoder->frame_rate.fps_denominator = 1; + ddl_set_default_enc_property(ddl); + } + + return; +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..19d55f74b23bcf1c293bf7932613d003390a0cab --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c @@ -0,0 +1,242 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include "vcd_ddl_utils.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define DBG_TIME(x...) printk(KERN_DEBUG x) +#define ERR(x...) printk(KERN_ERR x) + +struct time_data { + unsigned int ddl_t1; + unsigned int ddl_ttotal; + unsigned int ddl_count; +}; + +static struct time_data proc_time[MAX_TIME_DATA]; + +#ifdef NO_IN_KERNEL_PMEM + +void ddl_pmem_alloc(struct ddl_buf_addr *buff_addr, size_t sz, u32 align) +{ + u32 guard_bytes, align_mask; + u32 physical_addr, align_offset; + dma_addr_t phy_addr; + + if (align == DDL_LINEAR_BUFFER_ALIGN_BYTES) { + + guard_bytes = 31; + align_mask = 0xFFFFFFE0U; + + } else { + + guard_bytes = DDL_TILE_BUF_ALIGN_GUARD_BYTES; + align_mask = DDL_TILE_BUF_ALIGN_MASK; + } + + buff_addr->virtual_base_addr = + kmalloc((sz + guard_bytes), GFP_KERNEL); + + if (!buff_addr->virtual_base_addr) { + ERR("\n ERROR %s:%u kamlloc fails to allocate" + " sz + guard_bytes = %u\n", __func__, __LINE__, + (sz + guard_bytes)); + return; + } + + phy_addr = dma_map_single(NULL, buff_addr->virtual_base_addr, + sz + guard_bytes, DMA_TO_DEVICE); + + buff_addr->buffer_size = sz; + physical_addr = (u32) phy_addr; + buff_addr->align_physical_addr = + (u32 *) ((physical_addr + guard_bytes) & align_mask); + align_offset = + (u32) (buff_addr->align_physical_addr) - physical_addr; + buff_addr->align_virtual_addr = + (u32 *) ((u32) (buff_addr->virtual_base_addr) + + align_offset); +} + +void ddl_pmem_free(struct ddl_buf_addr *buff_addr) +{ + kfree(buff_addr->virtual_base_addr); + buff_addr->buffer_size = 0; + buff_addr->virtual_base_addr = NULL; +} + +#else + +void ddl_pmem_alloc(struct ddl_buf_addr *buff_addr, size_t sz, u32 align) +{ + u32 guard_bytes, align_mask; + u32 physical_addr; + u32 align_offset; + u32 alloc_size, flags = 0; + struct ddl_context *ddl_context; + struct msm_mapped_buffer *mapped_buffer = NULL; + + if (!buff_addr) { + ERR("\n%s() Invalid Parameters", __func__); + return; + } + + DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz); + + if (align == DDL_LINEAR_BUFFER_ALIGN_BYTES) { + + guard_bytes = 31; + align_mask = 0xFFFFFFE0U; + + } else { + + guard_bytes = DDL_TILE_BUF_ALIGN_GUARD_BYTES; + align_mask = DDL_TILE_BUF_ALIGN_MASK; + } + ddl_context = ddl_get_context(); + alloc_size = sz + guard_bytes; + + physical_addr = (u32) + allocate_contiguous_memory_nomap(alloc_size, + ddl_context->memtype, SZ_4K); + + if (!physical_addr) { + pr_err("%s(): could not allocate kernel pmem buffers\n", + __func__); + goto bailout; + } + buff_addr->physical_base_addr = (u32 *) physical_addr; + flags = MSM_SUBSYSTEM_MAP_KADDR; + buff_addr->mapped_buffer = + msm_subsystem_map_buffer((unsigned long)physical_addr, + alloc_size, flags, NULL, 0); + if (IS_ERR(buff_addr->mapped_buffer)) { + pr_err(" %s() buffer map failed", __func__); + goto free_acm_alloc; + } + mapped_buffer = buff_addr->mapped_buffer; + if (!mapped_buffer->vaddr) { + pr_err("%s() mapped virtual address is NULL", __func__); + goto free_map_buffers; + } + buff_addr->virtual_base_addr = mapped_buffer->vaddr; + memset(buff_addr->virtual_base_addr, 0 , sz + guard_bytes); + buff_addr->buffer_size = sz; + + buff_addr->align_physical_addr = + (u32 *) ((physical_addr + guard_bytes) & align_mask); + + align_offset = + (u32) (buff_addr->align_physical_addr) - physical_addr; + + buff_addr->align_virtual_addr = + (u32 *) ((u32) (buff_addr->virtual_base_addr) + + align_offset); + + DBG_PMEM("\n%s() OUT: phy_addr(%p) ker_addr(%p) size(%u)", __func__, + buff_addr->physical_base_addr, buff_addr->virtual_base_addr, + buff_addr->buffer_size); + + return; +free_map_buffers: + msm_subsystem_unmap_buffer(buff_addr->mapped_buffer); +free_acm_alloc: + free_contiguous_memory_by_paddr( + (unsigned long) physical_addr); +bailout: + buff_addr->physical_base_addr = NULL; + buff_addr->virtual_base_addr = NULL; + buff_addr->buffer_size = 0; + buff_addr->mapped_buffer = NULL; +} + +void ddl_pmem_free(struct ddl_buf_addr *buff_addr) +{ + if (!buff_addr) { + ERR("\n %s() invalid arguments %p", __func__, buff_addr); + return; + } + DBG_PMEM("\n%s() IN: phy_addr(%p) ker_addr(%p) size(%u)", __func__, + buff_addr->physical_base_addr, buff_addr->virtual_base_addr, + buff_addr->buffer_size); + + if (buff_addr->mapped_buffer) + msm_subsystem_unmap_buffer(buff_addr->mapped_buffer); + if (buff_addr->physical_base_addr) + free_contiguous_memory_by_paddr( + (unsigned long) buff_addr->physical_base_addr); + DBG_PMEM("\n%s() OUT: phy_addr(%p) ker_addr(%p) size(%u)", __func__, + buff_addr->physical_base_addr, buff_addr->virtual_base_addr, + buff_addr->buffer_size); + buff_addr->buffer_size = 0; + buff_addr->physical_base_addr = NULL; + buff_addr->virtual_base_addr = NULL; + buff_addr->mapped_buffer = NULL; +} +#endif + +void ddl_set_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); + if (!time_data->ddl_t1) { + time_data->ddl_t1 = act_time; + DBG("\n%s(): Start Time (%u)", func_name, act_time); + } else { + DBG_TIME("\n%s(): Timer already started! St(%u) Act(%u)", + func_name, time_data->ddl_t1, act_time); + } +} + +void ddl_calc_core_proc_time(const char *func_name, u32 index) +{ + 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++; + DBG_TIME("\n%s(): cnt(%u) Diff(%u) Avg(%u)", + func_name, time_data->ddl_count, + ddl_t2 - time_data->ddl_t1, + time_data->ddl_ttotal/time_data->ddl_count); + time_data->ddl_t1 = 0; + } +} + +void ddl_reset_core_time_variables(u32 index) +{ + proc_time[index].ddl_t1 = 0; + proc_time[index].ddl_ttotal = 0; + proc_time[index].ddl_count = 0; +} +int ddl_get_core_decode_proc_time(u32 *ddl_handle) +{ + return 0; +} + +void ddl_reset_avg_dec_time(u32 *ddl_handle) +{ + return; +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..633292b23e9e59d04d3fea34269026a130c4dd14 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h @@ -0,0 +1,60 @@ +/* Copyright (c) 2010-2011, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_DDL_UTILS_H_ +#define _VCD_DDL_UTILS_H_ + +#include "vcd_ddl_core.h" +#include "vcd_ddl.h" + +extern u32 vidc_msg_pmem; +extern u32 vidc_msg_timing; + +enum timing_data { + DEC_OP_TIME, + DEC_IP_TIME, + ENC_OP_TIME, + MAX_TIME_DATA +}; + +#define DDL_INLINE + +#define DDL_ALIGN_SIZE(sz, guard_bytes, align_mask) \ + (((u32)(sz) + guard_bytes) & align_mask) + +#define DDL_MALLOC(x) kmalloc(x, GFP_KERNEL) +#define DDL_FREE(x) { if ((x)) kfree((x)); (x) = NULL; } + +#define DBG_PMEM(x...) \ +do { \ + if (vidc_msg_pmem) \ + printk(KERN_DEBUG x); \ +} while (0) + +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); + +int ddl_get_core_decode_proc_time(u32 *ddl_handle); + +void ddl_reset_avg_dec_time(u32 *ddl_handle); + +#define DDL_ASSERT(x) +#define DDL_MEMSET(src, value, len) memset((src), (value), (len)) +#define DDL_MEMCPY(dest, src, len) memcpy((dest), (src), (len)) + +#define DDL_ADDR_IS_ALIGNED(addr, align_bytes) \ +(!((u32)(addr) & ((align_bytes) - 1))) + +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vidc.c b/drivers/video/msm/vidc/720p/ddl/vidc.c new file mode 100644 index 0000000000000000000000000000000000000000..da969ef64233e411b37ee61c28d26ee0f5e340ce --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vidc.c @@ -0,0 +1,804 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include "vidc.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define VIDC_720P_VERSION_STRING "VIDC_V1.0" +u8 *vidc_base_addr; + +#ifdef VIDC_REGISTER_LOG_INTO_BUFFER +char vidclog[VIDC_REGLOG_BUFSIZE]; +unsigned int vidclog_index; +#endif + +void vidc_720p_set_device_virtual_base(u8 *core_virtual_base_addr) +{ + vidc_base_addr = core_virtual_base_addr; +} + +void vidc_720p_init(char **ppsz_version, u32 i_firmware_size, + u32 *pi_firmware_address, + enum vidc_720p_endian dma_endian, + u32 interrupt_off, + enum vidc_720p_interrupt_level_selection + interrupt_sel, u32 interrupt_mask) +{ + if (ppsz_version) + *ppsz_version = VIDC_720P_VERSION_STRING; + + if (interrupt_sel == VIDC_720P_INTERRUPT_LEVEL_SEL) + VIDC_IO_OUT(REG_491082, 0); + else + VIDC_IO_OUT(REG_491082, 1); + + if (interrupt_off) + VIDC_IO_OUT(REG_609676, 1); + else + VIDC_IO_OUT(REG_609676, 0); + + VIDC_IO_OUT(REG_614776, 1); + + VIDC_IO_OUT(REG_418173, 0); + + VIDC_IO_OUT(REG_418173, interrupt_mask); + + VIDC_IO_OUT(REG_736316, dma_endian); + + VIDC_IO_OUT(REG_215724, 0); + + VIDC_IO_OUT(REG_361582, 1); + + VIDC_IO_OUT(REG_591577, i_firmware_size); + + VIDC_IO_OUT(REG_203921, pi_firmware_address); + + VIDC_IO_OUT(REG_531515_ADDR, 0); + + VIDC_IO_OUT(REG_614413, 1); +} + +u32 vidc_720p_do_sw_reset(void) +{ + + u32 fw_start = 0; + VIDC_BUSY_WAIT(5); + VIDC_IO_OUT(REG_224135, 0); + VIDC_BUSY_WAIT(5); + VIDC_IO_OUT(REG_193553, 0); + VIDC_BUSY_WAIT(5); + VIDC_IO_OUT(REG_141269, 1); + VIDC_BUSY_WAIT(15); + VIDC_IO_OUT(REG_141269, 0); + VIDC_BUSY_WAIT(5); + VIDC_IO_IN(REG_193553, &fw_start); + + if (!fw_start) { + DBG("\n VIDC-SW-RESET-FAILS!"); + return false; + } + return true; +} + +u32 vidc_720p_reset_is_success() +{ + u32 stagecounter = 0; + VIDC_IO_IN(REG_352831, &stagecounter); + stagecounter &= 0xff; + if (stagecounter != 0xe5) { + DBG("\n VIDC-CPU_RESET-FAILS!"); + VIDC_IO_OUT(REG_224135, 0); + msleep(10); + return false; + } + return true; +} + +void vidc_720p_start_cpu(enum vidc_720p_endian dma_endian, + u32 *icontext_bufferstart, + u32 *debug_core_dump_addr, + u32 debug_buffer_size) +{ + u32 dbg_info_input0_reg = 0x1; + VIDC_IO_OUT(REG_361582, 0); + VIDC_IO_OUT(REG_958768, icontext_bufferstart); + VIDC_IO_OUT(REG_736316, dma_endian); + if (debug_buffer_size) { + dbg_info_input0_reg = (debug_buffer_size << 0x10) + | (0x2 << 1) | 0x1; + VIDC_IO_OUT(REG_166247, debug_core_dump_addr); + } + VIDC_IO_OUT(REG_699747, dbg_info_input0_reg); + VIDC_IO_OUT(REG_224135, 1); +} + +u32 vidc_720p_cpu_start() +{ + u32 fw_status = 0x0; + VIDC_IO_IN(REG_381535, &fw_status); + if (fw_status != 0x02) + return false; + return true; +} + + +void vidc_720p_stop_fw(void) +{ + VIDC_IO_OUT(REG_193553, 0); + VIDC_IO_OUT(REG_224135, 0); +} + +void vidc_720p_get_interrupt_status(u32 *interrupt_status, + u32 *cmd_err_status, u32 *disp_pic_err_status, u32 *op_failed) +{ + u32 err_status; + VIDC_IO_IN(REG_512143, interrupt_status); + VIDC_IO_IN(REG_300310, &err_status); + *cmd_err_status = err_status & 0xffff; + *disp_pic_err_status = (err_status & 0xffff0000) >> 16; + VIDC_IO_INF(REG_724381, OPERATION_FAILED, \ + op_failed); +} + +void vidc_720p_interrupt_done_clear(void) +{ + VIDC_IO_OUT(REG_614776, 1); + VIDC_IO_OUT(REG_97293, 4); +} + +void vidc_720p_submit_command(u32 ch_id, u32 cmd_id) +{ + u32 fw_status; + VIDC_IO_OUT(REG_97293, ch_id); + VIDC_IO_OUT(REG_62325, cmd_id); + VIDC_DEBUG_REGISTER_LOG; + VIDC_IO_IN(REG_381535, &fw_status); + VIDC_IO_OUT(REG_926519, fw_status); +} + +u32 vidc_720p_engine_reset(u32 ch_id, + enum vidc_720p_endian dma_endian, + enum vidc_720p_interrupt_level_selection interrupt_sel, + u32 interrupt_mask +) +{ + u32 op_done = 0; + u32 counter = 0; + + VIDC_LOGERR_STRING("ENG-RESET!!"); + /* issue the engine reset command */ + vidc_720p_submit_command(ch_id, VIDC_720P_CMD_MFC_ENGINE_RESET); + + do { + VIDC_BUSY_WAIT(20); + VIDC_IO_IN(REG_982553, &op_done); + counter++; + } while (!op_done && counter < 10); + + if (!op_done) { + /* Reset fails */ + return false ; + } + + /* write invalid channel id */ + VIDC_IO_OUT(REG_97293, 4); + + /* Set INT_PULSE_SEL */ + if (interrupt_sel == VIDC_720P_INTERRUPT_LEVEL_SEL) + VIDC_IO_OUT(REG_491082, 0); + else + VIDC_IO_OUT(REG_491082, 1); + + if (!interrupt_mask) { + /* Disable interrupt */ + VIDC_IO_OUT(REG_609676, 1); + } else { + /* Enable interrupt */ + VIDC_IO_OUT(REG_609676, 0); + } + + /* Clear any pending interrupt */ + VIDC_IO_OUT(REG_614776, 1); + + /* Set INT_ENABLE_REG */ + VIDC_IO_OUT(REG_418173, interrupt_mask); + + /*Sets the DMA endianness */ + VIDC_IO_OUT(REG_736316, dma_endian); + + /*Restore ARM endianness */ + VIDC_IO_OUT(REG_215724, 0); + + /* retun engine reset success */ + return true ; +} + +void vidc_720p_set_channel(u32 i_ch_id, + enum vidc_720p_enc_dec_selection + enc_dec_sel, enum vidc_720p_codec codec, + u32 *pi_fw, u32 i_firmware_size) +{ + u32 std_sel = 0; + VIDC_IO_OUT(REG_661565, 0); + + if (enc_dec_sel) + std_sel = VIDC_REG_713080_ENC_ON_BMSK; + + std_sel |= (u32) codec; + + VIDC_IO_OUT(REG_713080, std_sel); + + switch (codec) { + default: + case VIDC_720P_DIVX: + case VIDC_720P_XVID: + case VIDC_720P_MPEG4: + { + if (enc_dec_sel == VIDC_720P_ENCODER) + VIDC_IO_OUT(REG_765787, pi_fw); + else + VIDC_IO_OUT(REG_225040, pi_fw); + break; + } + case VIDC_720P_H264: + { + if (enc_dec_sel == VIDC_720P_ENCODER) + VIDC_IO_OUT(REG_942456, pi_fw); + else + VIDC_IO_OUT(REG_942170_ADDR_3, pi_fw); + break; + } + case VIDC_720P_H263: + { + if (enc_dec_sel == VIDC_720P_ENCODER) + VIDC_IO_OUT(REG_765787, pi_fw); + else + VIDC_IO_OUT(REG_942170_ADDR_6, pi_fw); + break; + } + case VIDC_720P_VC1: + { + VIDC_IO_OUT(REG_880188, pi_fw); + break; + } + case VIDC_720P_MPEG2: + { + VIDC_IO_OUT(REG_40293, pi_fw); + break; + } + } + VIDC_IO_OUT(REG_591577, i_firmware_size); + + vidc_720p_submit_command(i_ch_id, VIDC_720P_CMD_CHSET); +} + +void vidc_720p_encode_set_profile(u32 i_profile, u32 i_level) +{ + u32 profile_level = i_profile|(i_level << 0x8); + VIDC_IO_OUT(REG_839021, profile_level); +} + +void vidc_720p_set_frame_size(u32 i_size_x, u32 i_size_y) +{ + VIDC_IO_OUT(REG_999267, i_size_x); + + VIDC_IO_OUT(REG_345712, i_size_y); +} + +void vidc_720p_encode_set_fps(u32 i_rc_frame_rate) +{ + VIDC_IO_OUT(REG_625444, i_rc_frame_rate); +} + +void vidc_720p_encode_set_short_header(u32 i_short_header) +{ + VIDC_IO_OUT(REG_314290, i_short_header); +} + +void vidc_720p_encode_set_vop_time(u32 vop_time_resolution, + u32 vop_time_increment) +{ + u32 enable_vop, vop_timing_reg; + if (!vop_time_resolution) + VIDC_IO_OUT(REG_64895, 0x0); + else { + enable_vop = 0x1; + vop_timing_reg = (enable_vop << 0x1f) | + (vop_time_resolution << 0x10) | vop_time_increment; + VIDC_IO_OUT(REG_64895, vop_timing_reg); + } +} + +void vidc_720p_encode_set_hec_period(u32 hec_period) +{ + VIDC_IO_OUT(REG_407718, hec_period); +} + +void vidc_720p_encode_set_qp_params(u32 i_max_qp, u32 i_min_qp) +{ + u32 qp = i_min_qp | (i_max_qp << 0x8); + VIDC_IO_OUT(REG_734318, qp); +} + +void vidc_720p_encode_set_rc_config(u32 enable_frame_level_rc, + u32 enable_mb_level_rc_flag, + u32 i_frame_qp, u32 pframe_qp) +{ + u32 rc_config = i_frame_qp; + + if (enable_frame_level_rc) + rc_config |= (0x1 << 0x9); + + if (enable_mb_level_rc_flag) + rc_config |= (0x1 << 0x8); + + VIDC_IO_OUT(REG_58211, rc_config); + VIDC_IO_OUT(REG_548359, pframe_qp); +} + +void vidc_720p_encode_set_bit_rate(u32 i_target_bitrate) +{ + VIDC_IO_OUT(REG_174150, i_target_bitrate); +} + +void vidc_720p_encoder_set_param_change(u32 enc_param_change) +{ + VIDC_IO_OUT(REG_804959, enc_param_change); +} + +void vidc_720p_encode_set_control_param(u32 param_val) +{ + VIDC_IO_OUT(REG_128234, param_val); +} + +void vidc_720p_encode_set_frame_level_rc_params(u32 i_reaction_coeff) +{ + VIDC_IO_OUT(REG_677784, i_reaction_coeff); +} + +void vidc_720p_encode_set_mb_level_rc_params(u32 dark_region_as_flag, + u32 smooth_region_as_flag, + u32 static_region_as_flag, + u32 activity_region_flag) +{ + u32 mb_level_rc = 0x0; + if (activity_region_flag) + mb_level_rc |= 0x1; + if (static_region_as_flag) + mb_level_rc |= (0x1 << 0x1); + if (smooth_region_as_flag) + mb_level_rc |= (0x1 << 0x2); + if (dark_region_as_flag) + mb_level_rc |= (0x1 << 0x3); + /* Write MB level rate control */ + VIDC_IO_OUT(REG_995041, mb_level_rc); +} + +void vidc_720p_encode_set_entropy_control(enum vidc_720p_entropy_sel + entropy_sel, + enum vidc_720p_cabac_model + cabac_model_number) +{ + u32 num; + u32 entropy_params = (u32)entropy_sel; + /* Set Model Number */ + if (entropy_sel == VIDC_720P_ENTROPY_SEL_CABAC) { + num = (u32)cabac_model_number; + entropy_params |= (num << 0x2); + } + /* Set Entropy parameters */ + VIDC_IO_OUT(REG_504878, entropy_params); +} + +void vidc_720p_encode_set_db_filter_control(enum vidc_720p_DBConfig + db_config, + u32 i_slice_alpha_offset, + u32 i_slice_beta_offset) +{ + u32 deblock_params; + deblock_params = (u32)db_config; + deblock_params |= + ((i_slice_beta_offset << 0x2) | (i_slice_alpha_offset << 0x7)); + + /* Write deblocking control settings */ + VIDC_IO_OUT(REG_458130, deblock_params); +} + +void vidc_720p_encode_set_intra_refresh_mb_number(u32 i_cir_mb_number) +{ + VIDC_IO_OUT(REG_857491, i_cir_mb_number); +} + +void vidc_720p_encode_set_multi_slice_info(enum + vidc_720p_MSlice_selection + m_slice_sel, + u32 multi_slice_size) +{ + switch (m_slice_sel) { + case VIDC_720P_MSLICE_BY_MB_COUNT: + { + VIDC_IO_OUT(REG_588301, 0x1); + VIDC_IO_OUT(REG_1517, m_slice_sel); + VIDC_IO_OUT(REG_105335, multi_slice_size); + break; + } + case VIDC_720P_MSLICE_BY_BYTE_COUNT: + { + VIDC_IO_OUT(REG_588301, 0x1); + VIDC_IO_OUT(REG_1517, m_slice_sel); + VIDC_IO_OUT(REG_561679, multi_slice_size); + break; + } + case VIDC_720P_MSLICE_BY_GOB: + { + VIDC_IO_OUT(REG_588301, 0x1); + break; + } + default: + case VIDC_720P_MSLICE_OFF: + { + VIDC_IO_OUT(REG_588301, 0x0); + break; + } + } +} + +void vidc_720p_encode_set_dpb_buffer(u32 *pi_enc_dpb_addr, u32 alloc_len) +{ + VIDC_IO_OUT(REG_341928_ADDR, pi_enc_dpb_addr); + VIDC_IO_OUT(REG_319934, alloc_len); +} + +void vidc_720p_encode_set_i_period(u32 i_i_period) +{ + VIDC_IO_OUT(REG_950374, i_i_period); +} + +void vidc_720p_encode_init_codec(u32 i_ch_id, + enum vidc_720p_memory_access_method + memory_access_model) +{ + + VIDC_IO_OUT(REG_841539, memory_access_model); + vidc_720p_submit_command(i_ch_id, VIDC_720P_CMD_INITCODEC); +} + +void vidc_720p_encode_unalign_bitstream(u32 upper_unalign_word, + u32 lower_unalign_word) +{ + VIDC_IO_OUT(REG_792026, upper_unalign_word); + VIDC_IO_OUT(REG_844152, lower_unalign_word); +} + +void vidc_720p_encode_set_seq_header_buffer(u32 ext_buffer_start, + u32 ext_buffer_end, + u32 start_byte_num) +{ + VIDC_IO_OUT(REG_275113_ADDR, ext_buffer_start); + + VIDC_IO_OUT(REG_87912, ext_buffer_start); + + VIDC_IO_OUT(REG_988007_ADDR, ext_buffer_end); + + VIDC_IO_OUT(REG_66693, start_byte_num); +} + +void vidc_720p_encode_frame(u32 ch_id, + u32 ext_buffer_start, + u32 ext_buffer_end, + u32 start_byte_number, u32 y_addr, + u32 c_addr) +{ + VIDC_IO_OUT(REG_275113_ADDR, ext_buffer_start); + + VIDC_IO_OUT(REG_988007_ADDR, ext_buffer_end); + + VIDC_IO_OUT(REG_87912, ext_buffer_start); + + VIDC_IO_OUT(REG_66693, start_byte_number); + + VIDC_IO_OUT(REG_99105, y_addr); + + VIDC_IO_OUT(REG_777113_ADDR, c_addr); + + vidc_720p_submit_command(ch_id, VIDC_720P_CMD_FRAMERUN); +} + +void vidc_720p_encode_get_header(u32 *pi_enc_header_size) +{ + VIDC_IO_IN(REG_114286, pi_enc_header_size); +} + +void vidc_720p_enc_frame_info(struct vidc_720p_enc_frame_info + *enc_frame_info) +{ + VIDC_IO_IN(REG_782249, &enc_frame_info->enc_size); + + VIDC_IO_IN(REG_441270, &enc_frame_info->frame); + + enc_frame_info->frame &= 0x03; + + VIDC_IO_IN(REG_613254, + &enc_frame_info->metadata_exists); +} + +void vidc_720p_decode_bitstream_header(u32 ch_id, + u32 dec_unit_size, + u32 start_byte_num, + u32 ext_buffer_start, + u32 ext_buffer_end, + enum + vidc_720p_memory_access_method + memory_access_model, + u32 decode_order) +{ + VIDC_IO_OUT(REG_965480, decode_order); + + VIDC_IO_OUT(REG_639999, 0x8080); + + VIDC_IO_OUT(REG_275113_ADDR, ext_buffer_start); + + VIDC_IO_OUT(REG_988007_ADDR, ext_buffer_end); + + VIDC_IO_OUT(REG_87912, ext_buffer_end); + + VIDC_IO_OUT(REG_761892, dec_unit_size); + + VIDC_IO_OUT(REG_66693, start_byte_num); + + VIDC_IO_OUT(REG_841539, memory_access_model); + + vidc_720p_submit_command(ch_id, VIDC_720P_CMD_INITCODEC); +} + +void vidc_720p_decode_get_seq_hdr_info(struct vidc_720p_seq_hdr_info + *seq_hdr_info) +{ + u32 display_status; + VIDC_IO_IN(REG_999267, &seq_hdr_info->img_size_x); + + VIDC_IO_IN(REG_345712, &seq_hdr_info->img_size_y); + + VIDC_IO_IN(REG_257463, &seq_hdr_info->min_num_dpb); + + VIDC_IO_IN(REG_854281, &seq_hdr_info->min_dpb_size); + + VIDC_IO_IN(REG_580603, &seq_hdr_info->dec_frm_size); + + VIDC_IO_INF(REG_606447, DISP_PIC_PROFILE, + &seq_hdr_info->profile); + + VIDC_IO_INF(REG_606447, DIS_PIC_LEVEL, + &seq_hdr_info->level); + + VIDC_IO_INF(REG_612715, DISPLAY_STATUS, + &display_status); + seq_hdr_info->progressive = + ((display_status & 0x4) >> 2); + /* bit 3 is for crop existence */ + seq_hdr_info->crop_exists = ((display_status & 0x8) >> 3); + + if (seq_hdr_info->crop_exists) { + /* read the cropping information */ + VIDC_IO_INF(REG_881638, CROP_RIGHT_OFFSET, \ + &seq_hdr_info->crop_right_offset); + VIDC_IO_INF(REG_881638, CROP_LEFT_OFFSET, \ + &seq_hdr_info->crop_left_offset); + VIDC_IO_INF(REG_161486, CROP_BOTTOM_OFFSET, \ + &seq_hdr_info->crop_bottom_offset); + VIDC_IO_INF(REG_161486, CROP_TOP_OFFSET, \ + &seq_hdr_info->crop_top_offset); + } + /* Read the MPEG4 data partitioning indication */ + VIDC_IO_INF(REG_441270, DATA_PARTITIONED, \ + &seq_hdr_info->data_partitioned); + +} + +void vidc_720p_decode_set_dpb_release_buffer_mask(u32 + i_dpb_release_buffer_mask) +{ + VIDC_IO_OUT(REG_603032, i_dpb_release_buffer_mask); +} + +void vidc_720p_decode_set_dpb_buffers(u32 i_buf_index, u32 *pi_dpb_buffer) +{ + VIDC_IO_OUTI(REG_615716, i_buf_index, pi_dpb_buffer); +} + +void vidc_720p_decode_set_comv_buffer(u32 *pi_dpb_comv_buffer, + u32 alloc_len) +{ + VIDC_IO_OUT(REG_456376_ADDR, pi_dpb_comv_buffer); + + VIDC_IO_OUT(REG_490443, alloc_len); +} + +void vidc_720p_decode_set_dpb_details(u32 num_dpb, u32 alloc_len, + u32 *ref_buffer) +{ + VIDC_IO_OUT(REG_518133, ref_buffer); + + VIDC_IO_OUT(REG_267567, 0); + + VIDC_IO_OUT(REG_883500, num_dpb); + + VIDC_IO_OUT(REG_319934, alloc_len); +} + +void vidc_720p_decode_set_mpeg4Post_filter(u32 enable_post_filter) +{ + if (enable_post_filter) + VIDC_IO_OUT(REG_443811, 0x1); + else + VIDC_IO_OUT(REG_443811, 0x0); +} + +void vidc_720p_decode_set_error_control(u32 enable_error_control) +{ + if (enable_error_control) + VIDC_IO_OUT(REG_846346, 0); + else + VIDC_IO_OUT(REG_846346, 1); +} + +void vidc_720p_set_deblock_line_buffer(u32 *pi_deblock_line_buffer_start, + u32 alloc_len) +{ + VIDC_IO_OUT(REG_979942, pi_deblock_line_buffer_start); + + VIDC_IO_OUT(REG_101184, alloc_len); +} + +void vidc_720p_decode_set_mpeg4_data_partitionbuffer(u32 *vsp_buf_start) +{ + VIDC_IO_OUT(REG_958768, vsp_buf_start); +} + +void vidc_720p_decode_setH264VSPBuffer(u32 *pi_vsp_temp_buffer_start) +{ + VIDC_IO_OUT(REG_958768, pi_vsp_temp_buffer_start); +} + +void vidc_720p_decode_frame(u32 ch_id, u32 ext_buffer_start, + u32 ext_buffer_end, u32 dec_unit_size, + u32 start_byte_num, u32 input_frame_tag) +{ + VIDC_IO_OUT(REG_275113_ADDR, ext_buffer_start); + + VIDC_IO_OUT(REG_988007_ADDR, ext_buffer_end); + + VIDC_IO_OUT(REG_87912, ext_buffer_end); + + VIDC_IO_OUT(REG_66693, start_byte_num); + + VIDC_IO_OUT(REG_94750, input_frame_tag); + + VIDC_IO_OUT(REG_761892, dec_unit_size); + + vidc_720p_submit_command(ch_id, VIDC_720P_CMD_FRAMERUN); +} + +void vidc_720p_issue_eos(u32 i_ch_id) +{ + VIDC_IO_OUT(REG_896825, 0x1); + + VIDC_IO_OUT(REG_761892, 0); + + vidc_720p_submit_command(i_ch_id, VIDC_720P_CMD_FRAMERUN); +} + +void vidc_720p_eos_info(u32 *disp_status, u32 *resl_change) +{ + VIDC_IO_INF(REG_612715, DISPLAY_STATUS, disp_status); + (*disp_status) = (*disp_status) & 0x3; + VIDC_IO_INF(REG_724381, RESOLUTION_CHANGE, resl_change); +} + +void vidc_720p_decode_display_info(struct vidc_720p_dec_disp_info + *disp_info) +{ + u32 display_status = 0; + VIDC_IO_INF(REG_612715, DISPLAY_STATUS, &display_status); + + disp_info->disp_status = + (enum vidc_720p_display_status)((display_status & 0x3)); + + disp_info->disp_is_interlace = ((display_status & 0x4) >> 2); + disp_info->crop_exists = ((display_status & 0x8) >> 3); + + disp_info->resl_change = ((display_status & 0x30) >> 4); + + VIDC_IO_INF(REG_724381, RESOLUTION_CHANGE, + &disp_info->reconfig_flush_done); + + VIDC_IO_IN(REG_999267, &disp_info->img_size_x); + + VIDC_IO_IN(REG_345712, &disp_info->img_size_y); + VIDC_IO_IN(REG_151345, &disp_info->y_addr); + VIDC_IO_IN(REG_293983, &disp_info->c_addr); + VIDC_IO_IN(REG_370409, &disp_info->tag_top); + VIDC_IO_IN(REG_438677, &disp_info->tag_bottom); + VIDC_IO_IN(REG_679165, &disp_info->pic_time_top); + VIDC_IO_IN(REG_374150, &disp_info->pic_time_bottom); + + if (disp_info->crop_exists) { + VIDC_IO_INF(REG_881638, CROP_RIGHT_OFFSET, + &disp_info->crop_right_offset); + VIDC_IO_INF(REG_881638, CROP_LEFT_OFFSET, + &disp_info->crop_left_offset); + VIDC_IO_INF(REG_161486, CROP_BOTTOM_OFFSET, + &disp_info->crop_bottom_offset); + VIDC_IO_INF(REG_161486, CROP_TOP_OFFSET, + &disp_info->crop_top_offset); + } + VIDC_IO_IN(REG_613254, &disp_info->metadata_exists); + + VIDC_IO_IN(REG_580603, + &disp_info->input_bytes_consumed); + + VIDC_IO_IN(REG_757835, &disp_info->input_frame_num); + + VIDC_IO_INF(REG_441270, FRAME_TYPE, + &disp_info->input_frame); + + disp_info->input_is_interlace = + ((disp_info->input_frame & 0x4) >> 2); + + if (disp_info->input_frame & 0x10) + disp_info->input_frame = VIDC_720P_IDRFRAME; + else + disp_info->input_frame &= 0x3; +} + +void vidc_720p_decode_skip_frm_details(u32 *free_luma_dpb) +{ + u32 disp_frm; + VIDC_IO_IN(REG_697961, &disp_frm); + + if (disp_frm == VIDC_720P_NOTCODED) + VIDC_IO_IN(REG_347105, free_luma_dpb); +} + +void vidc_720p_metadata_enable(u32 flag, u32 *input_buffer) +{ + VIDC_IO_OUT(REG_854681, flag); + VIDC_IO_OUT(REG_988552, input_buffer); +} + +void vidc_720p_decode_dynamic_req_reset(void) +{ + VIDC_IO_OUT(REG_76706, 0x0); + VIDC_IO_OUT(REG_147682, 0x0); + VIDC_IO_OUT(REG_896825, 0x0); +} + +void vidc_720p_decode_dynamic_req_set(u32 property) +{ + if (property == VIDC_720P_FLUSH_REQ) + VIDC_IO_OUT(REG_76706, 0x1); + else if (property == VIDC_720P_EXTRADATA) + VIDC_IO_OUT(REG_147682, 0x1); +} + +void vidc_720p_decode_setpassthrough_start(u32 pass_startaddr) +{ + VIDC_IO_OUT(REG_486169, pass_startaddr); +} diff --git a/drivers/video/msm/vidc/720p/ddl/vidc.h b/drivers/video/msm/vidc/720p/ddl/vidc.h new file mode 100644 index 0000000000000000000000000000000000000000..a09034f204d1435c26b7534ec07ec8ed4214262f --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vidc.h @@ -0,0 +1,2705 @@ +/* Copyright (c) 2010-2011, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef VIDC_H +#define VIDC_H +#include +#include +#include + +#define VIDC_720P_IN(reg) VIDC_##reg##_IN +#define VIDC_720P_INM(reg, mask) VIDC_##reg##_INM(mask) +#define VIDC_720P_OUT(reg, val) VIDC_##reg##_OUT(val) +#define VIDC_720P_OUTI(reg, index, val) VIDC_##reg##_OUTI(index, val) +#define VIDC_720P_OUTM(reg, mask, val) VIDC_##reg##_OUTM(mask, val) +#define VIDC_720P_SHFT(reg, field) VIDC_##reg##_##field##_SHFT +#define VIDC_720P_FMSK(reg, field) VIDC_##reg##_##field##_BMSK + +#define VIDC_720P_INF(io, field) (VIDC_720P_INM(io, VIDC_720P_FMSK(io, field)) \ + >> VIDC_720P_SHFT(io, field)) +#define VIDC_720P_OUTF(io, field, val) \ + VIDC_720P_OUTM(io, VIDC_720P_FMSK(io, field), \ + val << VIDC_720P_SHFT(io, field)) + +#define __inpdw(port) ioread32(port) +#define __outpdw(port, val) iowrite32(val, port) + +#define in_dword_masked(addr, mask) (__inpdw(addr) & (mask)) + +#define out_dword(addr, val) __outpdw(addr, val) + +#define out_dword_masked(io, mask, val, shadow) \ +do { \ + shadow = (shadow & (u32)(~(mask))) | ((u32)((val) & (mask))); \ + (void) out_dword(io, shadow); \ +} while (0) + +#define out_dword_masked_ns(io, mask, val, current_reg_content) \ + (void) out_dword(io, ((current_reg_content & (u32)(~(mask))) | \ + ((u32)((val) & (mask))))) + +extern u8 *vidc_base_addr; + +#define VIDC720P_BASE vidc_base_addr +#define VIDC_720P_WRAPPER_REG_BASE (VIDC720P_BASE + \ + 0x00000000) +#define VIDC_720P_WRAPPER_REG_BASE_PHYS VIDC_720P_BASE_PHYS + +#define VIDC_REG_614413_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 00000000) +#define VIDC_REG_614413_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 00000000) +#define VIDC_REG_614413_RMSK 0x1 +#define VIDC_REG_614413_SHFT 0 +#define VIDC_REG_614413_IN \ + in_dword_masked(VIDC_REG_614413_ADDR, \ + VIDC_REG_614413_RMSK) +#define VIDC_REG_614413_INM(m) \ + in_dword_masked(VIDC_REG_614413_ADDR, m) +#define VIDC_REG_614413_OUT(v) \ + out_dword(VIDC_REG_614413_ADDR, v) +#define VIDC_REG_614413_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_614413_ADDR, m, v, \ + VIDC_REG_614413_IN); \ +} while (0) +#define VIDC_REG_614413_DMA_START_BMSK 0x1 +#define VIDC_REG_614413_DMA_START_SHFT 0 + +#define VIDC_REG_591577_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000000c) +#define VIDC_REG_591577_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000000c) +#define VIDC_REG_591577_RMSK 0xffffffff +#define VIDC_REG_591577_SHFT 0 +#define VIDC_REG_591577_IN \ + in_dword_masked(VIDC_REG_591577_ADDR, \ + VIDC_REG_591577_RMSK) +#define VIDC_REG_591577_INM(m) \ + in_dword_masked(VIDC_REG_591577_ADDR, m) +#define VIDC_REG_591577_OUT(v) \ + out_dword(VIDC_REG_591577_ADDR, v) +#define VIDC_REG_591577_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_591577_ADDR, m, v, \ + VIDC_REG_591577_IN); \ +} while (0) +#define VIDC_REG_591577_BOOTCODE_SIZE_BMSK 0xffffffff +#define VIDC_REG_591577_BOOTCODE_SIZE_SHFT 0 + +#define VIDC_REG_203921_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000014) +#define VIDC_REG_203921_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000014) +#define VIDC_REG_203921_RMSK 0xffffffff +#define VIDC_REG_203921_SHFT 0 +#define VIDC_REG_203921_IN \ + in_dword_masked(VIDC_REG_203921_ADDR, \ + VIDC_REG_203921_RMSK) +#define VIDC_REG_203921_INM(m) \ + in_dword_masked(VIDC_REG_203921_ADDR, m) +#define VIDC_REG_203921_OUT(v) \ + out_dword(VIDC_REG_203921_ADDR, v) +#define VIDC_REG_203921_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_203921_ADDR, m, v, \ + VIDC_REG_203921_IN); \ +} while (0) +#define VIDC_REG_203921_DMA_EXTADDR_BMSK 0xffffffff +#define VIDC_REG_203921_DMA_EXTADDR_SHFT 0 + +#define VIDC_REG_275113_ADDR_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000018) +#define VIDC_REG_275113_ADDR_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000018) +#define VIDC_REG_275113_ADDR_RMSK 0xffffffff +#define VIDC_REG_275113_ADDR_SHFT 0 +#define VIDC_REG_275113_ADDR_IN \ + in_dword_masked(VIDC_REG_275113_ADDR_ADDR, \ + VIDC_REG_275113_ADDR_RMSK) +#define VIDC_REG_275113_ADDR_INM(m) \ + in_dword_masked(VIDC_REG_275113_ADDR_ADDR, m) +#define VIDC_REG_275113_ADDR_OUT(v) \ + out_dword(VIDC_REG_275113_ADDR_ADDR, v) +#define VIDC_REG_275113_ADDR_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_275113_ADDR_ADDR, m, v, \ + VIDC_REG_275113_ADDR_IN); \ +} while (0) +#define VIDC_REG_742076_ADDR_BMSK 0xffffffff +#define VIDC_REG_742076_ADDR_SHFT 0 + +#define VIDC_REG_988007_ADDR_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000001c) +#define VIDC_REG_988007_ADDR_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000001c) +#define VIDC_REG_988007_ADDR_RMSK 0xffffffff +#define VIDC_REG_988007_ADDR_SHFT 0 +#define VIDC_REG_988007_ADDR_IN \ + in_dword_masked(VIDC_REG_988007_ADDR_ADDR, \ + VIDC_REG_988007_ADDR_RMSK) +#define VIDC_REG_988007_ADDR_INM(m) \ + in_dword_masked(VIDC_REG_988007_ADDR_ADDR, m) +#define VIDC_REG_988007_ADDR_OUT(v) \ + out_dword(VIDC_REG_988007_ADDR_ADDR, v) +#define VIDC_REG_988007_ADDR_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_988007_ADDR_ADDR, m, v, \ + VIDC_REG_988007_ADDR_IN); \ +} while (0) +#define VIDC_REG_988007_ADDR_EXT_BUF_END_ADDR_BMSK 0xffffffff +#define VIDC_REG_988007_ADDR_EXT_BUF_END_ADDR_SHFT 0 + +#define VIDC_REG_531515_ADDR_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000020) +#define VIDC_REG_531515_ADDR_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000020) +#define VIDC_REG_531515_ADDR_RMSK 0xffffffff +#define VIDC_REG_531515_ADDR_SHFT 0 +#define VIDC_REG_531515_ADDR_IN \ + in_dword_masked(VIDC_REG_531515_ADDR_ADDR, \ + VIDC_REG_531515_ADDR_RMSK) +#define VIDC_REG_531515_ADDR_INM(m) \ + in_dword_masked(VIDC_REG_531515_ADDR_ADDR, m) +#define VIDC_REG_531515_ADDR_OUT(v) \ + out_dword(VIDC_REG_531515_ADDR_ADDR, v) +#define VIDC_REG_531515_ADDR_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_531515_ADDR_ADDR, m, v, \ + VIDC_REG_531515_ADDR_IN); \ +} while (0) +#define VIDC_REG_531515_ADDR_DMA_INT_ADDR_BMSK 0xffffffff +#define VIDC_REG_531515_ADDR_DMA_INT_ADDR_SHFT 0 + +#define VIDC_REG_87912_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000024) +#define VIDC_REG_87912_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000024) +#define VIDC_REG_87912_RMSK 0xffffffff +#define VIDC_REG_87912_SHFT 0 +#define VIDC_REG_87912_IN \ + in_dword_masked(VIDC_REG_87912_ADDR, \ + VIDC_REG_87912_RMSK) +#define VIDC_REG_87912_INM(m) \ + in_dword_masked(VIDC_REG_87912_ADDR, m) +#define VIDC_REG_87912_OUT(v) \ + out_dword(VIDC_REG_87912_ADDR, v) +#define VIDC_REG_87912_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_87912_ADDR, m, v, \ + VIDC_REG_87912_IN); \ +} while (0) +#define VIDC_REG_87912_HOST_PTR_ADDR_BMSK 0xffffffff +#define VIDC_REG_87912_HOST_PTR_ADDR_SHFT 0 + +#define VIDC_REG_896825_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000028) +#define VIDC_REG_896825_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000028) +#define VIDC_REG_896825_RMSK 0x1 +#define VIDC_REG_896825_SHFT 0 +#define VIDC_REG_896825_IN \ + in_dword_masked(VIDC_REG_896825_ADDR, \ + VIDC_REG_896825_RMSK) +#define VIDC_REG_896825_INM(m) \ + in_dword_masked(VIDC_REG_896825_ADDR, m) +#define VIDC_REG_896825_OUT(v) \ + out_dword(VIDC_REG_896825_ADDR, v) +#define VIDC_REG_896825_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_896825_ADDR, m, v, \ + VIDC_REG_896825_IN); \ +} while (0) +#define VIDC_REG_896825_LAST_DEC_BMSK 0x1 +#define VIDC_REG_896825_LAST_DEC_SHFT 0 + +#define VIDC_REG_174526_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000002c) +#define VIDC_REG_174526_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000002c) +#define VIDC_REG_174526_RMSK 0x1 +#define VIDC_REG_174526_SHFT 0 +#define VIDC_REG_174526_IN \ + in_dword_masked(VIDC_REG_174526_ADDR, VIDC_REG_174526_RMSK) +#define VIDC_REG_174526_INM(m) \ + in_dword_masked(VIDC_REG_174526_ADDR, m) +#define VIDC_REG_174526_DONE_M_BMSK 0x1 +#define VIDC_REG_174526_DONE_M_SHFT 0 + +#define VIDC_REG_736316_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000044) +#define VIDC_REG_736316_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000044) +#define VIDC_REG_736316_RMSK 0x1 +#define VIDC_REG_736316_SHFT 0 +#define VIDC_REG_736316_IN \ + in_dword_masked(VIDC_REG_736316_ADDR, \ + VIDC_REG_736316_RMSK) +#define VIDC_REG_736316_INM(m) \ + in_dword_masked(VIDC_REG_736316_ADDR, m) +#define VIDC_REG_736316_OUT(v) \ + out_dword(VIDC_REG_736316_ADDR, v) +#define VIDC_REG_736316_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_736316_ADDR, m, v, \ + VIDC_REG_736316_IN); \ +} while (0) +#define VIDC_REG_736316_BITS_ENDIAN_BMSK 0x1 +#define VIDC_REG_736316_BITS_ENDIAN_SHFT 0 + +#define VIDC_REG_761892_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000054) +#define VIDC_REG_761892_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000054) +#define VIDC_REG_761892_RMSK 0xffffffff +#define VIDC_REG_761892_SHFT 0 +#define VIDC_REG_761892_IN \ + in_dword_masked(VIDC_REG_761892_ADDR, \ + VIDC_REG_761892_RMSK) +#define VIDC_REG_761892_INM(m) \ + in_dword_masked(VIDC_REG_761892_ADDR, m) +#define VIDC_REG_761892_OUT(v) \ + out_dword(VIDC_REG_761892_ADDR, v) +#define VIDC_REG_761892_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_761892_ADDR, m, v, \ + VIDC_REG_761892_IN); \ +} while (0) +#define VIDC_REG_761892_DEC_UNIT_SIZE_BMSK 0xffffffff +#define VIDC_REG_761892_DEC_UNIT_SIZE_SHFT 0 + +#define VIDC_REG_782249_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000058) +#define VIDC_REG_782249_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000058) +#define VIDC_REG_782249_RMSK 0xffffffff +#define VIDC_REG_782249_SHFT 0 +#define VIDC_REG_782249_IN \ + in_dword_masked(VIDC_REG_782249_ADDR, \ + VIDC_REG_782249_RMSK) +#define VIDC_REG_782249_INM(m) \ + in_dword_masked(VIDC_REG_782249_ADDR, m) +#define VIDC_REG_782249_ENC_UNIT_SIZE_BMSK 0xffffffff +#define VIDC_REG_782249_ENC_UNIT_SIZE_SHFT 0 + +#define VIDC_REG_66693_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000005c) +#define VIDC_REG_66693_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000005c) +#define VIDC_REG_66693_RMSK 0xf +#define VIDC_REG_66693_SHFT 0 +#define VIDC_REG_66693_IN \ + in_dword_masked(VIDC_REG_66693_ADDR, \ + VIDC_REG_66693_RMSK) +#define VIDC_REG_66693_INM(m) \ + in_dword_masked(VIDC_REG_66693_ADDR, m) +#define VIDC_REG_66693_OUT(v) \ + out_dword(VIDC_REG_66693_ADDR, v) +#define VIDC_REG_66693_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_66693_ADDR, m, v, \ + VIDC_REG_66693_IN); \ +} while (0) +#define VIDC_REG_66693_START_BYTE_NUM_BMSK 0xf +#define VIDC_REG_66693_START_BYTE_NUM_SHFT 0 + +#define VIDC_REG_114286_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000060) +#define VIDC_REG_114286_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000060) +#define VIDC_REG_114286_RMSK 0xffffffff +#define VIDC_REG_114286_SHFT 0 +#define VIDC_REG_114286_IN \ + in_dword_masked(VIDC_REG_114286_ADDR, \ + VIDC_REG_114286_RMSK) +#define VIDC_REG_114286_INM(m) \ + in_dword_masked(VIDC_REG_114286_ADDR, m) +#define VIDC_REG_114286_ENC_HEADER_SIZE_BMSK 0xffffffff +#define VIDC_REG_114286_ENC_HEADER_SIZE_SHFT 0 + +#define VIDC_REG_713080_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000100) +#define VIDC_REG_713080_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000100) +#define VIDC_REG_713080_RMSK 0x1f +#define VIDC_REG_713080_SHFT 0 +#define VIDC_REG_713080_IN \ + in_dword_masked(VIDC_REG_713080_ADDR, \ + VIDC_REG_713080_RMSK) +#define VIDC_REG_713080_INM(m) \ + in_dword_masked(VIDC_REG_713080_ADDR, m) +#define VIDC_REG_713080_OUT(v) \ + out_dword(VIDC_REG_713080_ADDR, v) +#define VIDC_REG_713080_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_713080_ADDR, m, v, \ + VIDC_REG_713080_IN); \ +} while (0) +#define VIDC_REG_713080_ENC_ON_BMSK 0x10 +#define VIDC_REG_713080_ENC_ON_SHFT 0x4 +#define VIDC_REG_713080_STANDARD_SEL_BMSK 0xf +#define VIDC_REG_713080_STANDARD_SEL_SHFT 0 + +#define VIDC_REG_97293_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000104) +#define VIDC_REG_97293_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000104) +#define VIDC_REG_97293_RMSK 0x1f +#define VIDC_REG_97293_SHFT 0 +#define VIDC_REG_97293_IN \ + in_dword_masked(VIDC_REG_97293_ADDR, VIDC_REG_97293_RMSK) +#define VIDC_REG_97293_INM(m) \ + in_dword_masked(VIDC_REG_97293_ADDR, m) +#define VIDC_REG_97293_OUT(v) \ + out_dword(VIDC_REG_97293_ADDR, v) +#define VIDC_REG_97293_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_97293_ADDR, m, v, \ + VIDC_REG_97293_IN); \ +} while (0) +#define VIDC_REG_97293_CH_ID_BMSK 0x1f +#define VIDC_REG_97293_CH_ID_SHFT 0 + +#define VIDC_REG_224135_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000108) +#define VIDC_REG_224135_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000108) +#define VIDC_REG_224135_RMSK 0x1 +#define VIDC_REG_224135_SHFT 0 +#define VIDC_REG_224135_IN \ + in_dword_masked(VIDC_REG_224135_ADDR, \ + VIDC_REG_224135_RMSK) +#define VIDC_REG_224135_INM(m) \ + in_dword_masked(VIDC_REG_224135_ADDR, m) +#define VIDC_REG_224135_OUT(v) \ + out_dword(VIDC_REG_224135_ADDR, v) +#define VIDC_REG_224135_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_224135_ADDR, m, v, \ + VIDC_REG_224135_IN); \ +} while (0) +#define VIDC_REG_224135_CPU_RESET_BMSK 0x1 +#define VIDC_REG_224135_CPU_RESET_SHFT 0 + +#define VIDC_REG_832522_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000010c) +#define VIDC_REG_832522_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000010c) +#define VIDC_REG_832522_RMSK 0x1 +#define VIDC_REG_832522_SHFT 0 +#define VIDC_REG_832522_IN \ + in_dword_masked(VIDC_REG_832522_ADDR, VIDC_REG_832522_RMSK) +#define VIDC_REG_832522_INM(m) \ + in_dword_masked(VIDC_REG_832522_ADDR, m) +#define VIDC_REG_832522_OUT(v) \ + out_dword(VIDC_REG_832522_ADDR, v) +#define VIDC_REG_832522_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_832522_ADDR, m, v, \ + VIDC_REG_832522_IN); \ +} while (0) +#define VIDC_REG_832522_FW_END_BMSK 0x1 +#define VIDC_REG_832522_FW_END_SHFT 0 + +#define VIDC_REG_361582_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000110) +#define VIDC_REG_361582_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000110) +#define VIDC_REG_361582_RMSK 0x1 +#define VIDC_REG_361582_SHFT 0 +#define VIDC_REG_361582_IN \ + in_dword_masked(VIDC_REG_361582_ADDR, \ + VIDC_REG_361582_RMSK) +#define VIDC_REG_361582_INM(m) \ + in_dword_masked(VIDC_REG_361582_ADDR, m) +#define VIDC_REG_361582_OUT(v) \ + out_dword(VIDC_REG_361582_ADDR, v) +#define VIDC_REG_361582_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_361582_ADDR, m, v, \ + VIDC_REG_361582_IN); \ +} while (0) +#define VIDC_REG_361582_BUS_MASTER_BMSK 0x1 +#define VIDC_REG_361582_BUS_MASTER_SHFT 0 + +#define VIDC_REG_314435_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000114) +#define VIDC_REG_314435_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000114) +#define VIDC_REG_314435_RMSK 0x1 +#define VIDC_REG_314435_SHFT 0 +#define VIDC_REG_314435_IN \ + in_dword_masked(VIDC_REG_314435_ADDR, \ + VIDC_REG_314435_RMSK) +#define VIDC_REG_314435_INM(m) \ + in_dword_masked(VIDC_REG_314435_ADDR, m) +#define VIDC_REG_314435_OUT(v) \ + out_dword(VIDC_REG_314435_ADDR, v) +#define VIDC_REG_314435_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_314435_ADDR, m, v, \ + VIDC_REG_314435_IN); \ +} while (0) +#define VIDC_REG_314435_FRAME_START_BMSK 0x1 +#define VIDC_REG_314435_FRAME_START_SHFT 0 + +#define VIDC_REG_999267_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000118) +#define VIDC_REG_999267_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000118) +#define VIDC_REG_999267_RMSK 0xffff +#define VIDC_REG_999267_SHFT 0 +#define VIDC_REG_999267_IN \ + in_dword_masked(VIDC_REG_999267_ADDR, \ + VIDC_REG_999267_RMSK) +#define VIDC_REG_999267_INM(m) \ + in_dword_masked(VIDC_REG_999267_ADDR, m) +#define VIDC_REG_999267_OUT(v) \ + out_dword(VIDC_REG_999267_ADDR, v) +#define VIDC_REG_999267_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_999267_ADDR, m, v, \ + VIDC_REG_999267_IN); \ +} while (0) +#define VIDC_REG_999267_IMG_SIZE_X_BMSK 0xffff +#define VIDC_REG_999267_IMG_SIZE_X_SHFT 0 + +#define VIDC_REG_345712_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000011c) +#define VIDC_REG_345712_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000011c) +#define VIDC_REG_345712_RMSK 0xffff +#define VIDC_REG_345712_SHFT 0 +#define VIDC_REG_345712_IN \ + in_dword_masked(VIDC_REG_345712_ADDR, \ + VIDC_REG_345712_RMSK) +#define VIDC_REG_345712_INM(m) \ + in_dword_masked(VIDC_REG_345712_ADDR, m) +#define VIDC_REG_345712_OUT(v) \ + out_dword(VIDC_REG_345712_ADDR, v) +#define VIDC_REG_345712_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_345712_ADDR, m, v, \ + VIDC_REG_345712_IN); \ +} while (0) +#define VIDC_REG_345712_IMG_SIZE_Y_BMSK 0xffff +#define VIDC_REG_345712_IMG_SIZE_Y_SHFT 0 + +#define VIDC_REG_443811_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000124) +#define VIDC_REG_443811_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000124) +#define VIDC_REG_443811_RMSK 0x1 +#define VIDC_REG_443811_SHFT 0 +#define VIDC_REG_443811_IN \ + in_dword_masked(VIDC_REG_443811_ADDR, VIDC_REG_443811_RMSK) +#define VIDC_REG_443811_INM(m) \ + in_dword_masked(VIDC_REG_443811_ADDR, m) +#define VIDC_REG_443811_OUT(v) \ + out_dword(VIDC_REG_443811_ADDR, v) +#define VIDC_REG_443811_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_443811_ADDR, m, v, \ + VIDC_REG_443811_IN); \ +} while (0) +#define VIDC_REG_443811_POST_ON_BMSK 0x1 +#define VIDC_REG_443811_POST_ON_SHFT 0 + +#define VIDC_REG_538267_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000128) +#define VIDC_REG_538267_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000128) +#define VIDC_REG_538267_RMSK 0xffffffff +#define VIDC_REG_538267_SHFT 0 +#define VIDC_REG_538267_IN \ + in_dword_masked(VIDC_REG_538267_ADDR, \ + VIDC_REG_538267_RMSK) +#define VIDC_REG_538267_INM(m) \ + in_dword_masked(VIDC_REG_538267_ADDR, m) +#define VIDC_REG_538267_OUT(v) \ + out_dword(VIDC_REG_538267_ADDR, v) +#define VIDC_REG_538267_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_538267_ADDR, m, v, \ + VIDC_REG_538267_IN); \ +} while (0) +#define VIDC_REG_538267_QUOTIENT_VAL_BMSK 0xffff0000 +#define VIDC_REG_538267_QUOTIENT_VAL_SHFT 0x10 +#define VIDC_REG_538267_REMAINDER_VAL_BMSK 0xffff +#define VIDC_REG_538267_REMAINDER_VAL_SHFT 0 + +#define VIDC_REG_661565_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000012c) +#define VIDC_REG_661565_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000012c) +#define VIDC_REG_661565_RMSK 0x1 +#define VIDC_REG_661565_SHFT 0 +#define VIDC_REG_661565_IN \ + in_dword_masked(VIDC_REG_661565_ADDR, \ + VIDC_REG_661565_RMSK) +#define VIDC_REG_661565_INM(m) \ + in_dword_masked(VIDC_REG_661565_ADDR, m) +#define VIDC_REG_661565_OUT(v) \ + out_dword(VIDC_REG_661565_ADDR, v) +#define VIDC_REG_661565_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_661565_ADDR, m, v, \ + VIDC_REG_661565_IN); \ +} while (0) +#define VIDC_REG_661565_SEQUENCE_START_BMSK 0x1 +#define VIDC_REG_661565_SEQUENCE_START_SHFT 0 + +#define VIDC_REG_141269_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000130) +#define VIDC_REG_141269_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000130) +#define VIDC_REG_141269_RMSK 0x1 +#define VIDC_REG_141269_SHFT 0 +#define VIDC_REG_141269_IN \ + in_dword_masked(VIDC_REG_141269_ADDR, \ + VIDC_REG_141269_RMSK) +#define VIDC_REG_141269_INM(m) \ + in_dword_masked(VIDC_REG_141269_ADDR, m) +#define VIDC_REG_141269_OUT(v) \ + out_dword(VIDC_REG_141269_ADDR, v) +#define VIDC_REG_141269_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_141269_ADDR, m, v, \ + VIDC_REG_141269_IN); \ +} while (0) +#define VIDC_REG_141269_SW_RESET_BMSK 0x1 +#define VIDC_REG_141269_SW_RESET_SHFT 0 + +#define VIDC_REG_193553_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000134) +#define VIDC_REG_193553_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000134) +#define VIDC_REG_193553_RMSK 0x1 +#define VIDC_REG_193553_SHFT 0 +#define VIDC_REG_193553_IN \ + in_dword_masked(VIDC_REG_193553_ADDR, \ + VIDC_REG_193553_RMSK) +#define VIDC_REG_193553_INM(m) \ + in_dword_masked(VIDC_REG_193553_ADDR, m) +#define VIDC_REG_193553_OUT(v) \ + out_dword(VIDC_REG_193553_ADDR, v) +#define VIDC_REG_193553_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_193553_ADDR, m, v, \ + VIDC_REG_193553_IN); \ +} while (0) +#define VIDC_REG_193553_FW_START_BMSK 0x1 +#define VIDC_REG_193553_FW_START_SHFT 0 + +#define VIDC_REG_215724_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000138) +#define VIDC_REG_215724_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000138) +#define VIDC_REG_215724_RMSK 0x1 +#define VIDC_REG_215724_SHFT 0 +#define VIDC_REG_215724_IN \ + in_dword_masked(VIDC_REG_215724_ADDR, \ + VIDC_REG_215724_RMSK) +#define VIDC_REG_215724_INM(m) \ + in_dword_masked(VIDC_REG_215724_ADDR, m) +#define VIDC_REG_215724_OUT(v) \ + out_dword(VIDC_REG_215724_ADDR, v) +#define VIDC_REG_215724_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_215724_ADDR, m, v, \ + VIDC_REG_215724_IN); \ +} while (0) +#define VIDC_REG_215724_ARM_ENDIAN_BMSK 0x1 +#define VIDC_REG_215724_ARM_ENDIAN_SHFT 0 + +#define VIDC_REG_846346_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000013c) +#define VIDC_REG_846346_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000013c) +#define VIDC_REG_846346_RMSK 0x1 +#define VIDC_REG_846346_SHFT 0 +#define VIDC_REG_846346_IN \ + in_dword_masked(VIDC_REG_846346_ADDR, \ + VIDC_REG_846346_RMSK) +#define VIDC_REG_846346_INM(m) \ + in_dword_masked(VIDC_REG_846346_ADDR, m) +#define VIDC_REG_846346_OUT(v) \ + out_dword(VIDC_REG_846346_ADDR, v) +#define VIDC_REG_846346_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_846346_ADDR, m, v, \ + VIDC_REG_846346_IN); \ +} while (0) +#define VIDC_REG_846346_ERR_CTRL_BMSK 0x1 +#define VIDC_REG_846346_ERR_CTRL_SHFT 0 + +#define VIDC_REG_765787_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000200) +#define VIDC_REG_765787_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000200) +#define VIDC_REG_765787_RMSK 0xffffffff +#define VIDC_REG_765787_SHFT 0 +#define VIDC_REG_765787_IN \ + in_dword_masked(VIDC_REG_765787_ADDR, \ + VIDC_REG_765787_RMSK) +#define VIDC_REG_765787_INM(m) \ + in_dword_masked(VIDC_REG_765787_ADDR, m) +#define VIDC_REG_765787_OUT(v) \ + out_dword(VIDC_REG_765787_ADDR, v) +#define VIDC_REG_765787_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_765787_ADDR, m, v, \ + VIDC_REG_765787_IN); \ +} while (0) +#define VIDC_REG_765787_FW_STT_ADDR_0_BMSK 0xffffffff +#define VIDC_REG_765787_FW_STT_ADDR_0_SHFT 0 + +#define VIDC_REG_225040_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000204) +#define VIDC_REG_225040_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000204) +#define VIDC_REG_225040_RMSK 0xffffffff +#define VIDC_REG_225040_SHFT 0 +#define VIDC_REG_225040_IN \ + in_dword_masked(VIDC_REG_225040_ADDR, \ + VIDC_REG_225040_RMSK) +#define VIDC_REG_225040_INM(m) \ + in_dword_masked(VIDC_REG_225040_ADDR, m) +#define VIDC_REG_225040_OUT(v) \ + out_dword(VIDC_REG_225040_ADDR, v) +#define VIDC_REG_225040_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_225040_ADDR, m, v, \ + VIDC_REG_225040_IN); \ +} while (0) +#define VIDC_REG_225040_FW_STT_ADDR_1_BMSK 0xffffffff +#define VIDC_REG_225040_FW_STT_ADDR_1_SHFT 0 + +#define VIDC_REG_942456_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000208) +#define VIDC_REG_942456_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000208) +#define VIDC_REG_942456_RMSK 0xffffffff +#define VIDC_REG_942456_SHFT 0 +#define VIDC_REG_942456_IN \ + in_dword_masked(VIDC_REG_942456_ADDR, \ + VIDC_REG_942456_RMSK) +#define VIDC_REG_942456_INM(m) \ + in_dword_masked(VIDC_REG_942456_ADDR, m) +#define VIDC_REG_942456_OUT(v) \ + out_dword(VIDC_REG_942456_ADDR, v) +#define VIDC_REG_942456_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_942456_ADDR, m, v, \ + VIDC_REG_942456_IN); \ +} while (0) +#define VIDC_REG_942456_FW_STT_ADDR_2_BMSK 0xffffffff +#define VIDC_REG_942456_FW_STT_ADDR_2_SHFT 0 + +#define VIDC_REG_942170_ADDR_3_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000020c) +#define VIDC_REG_942170_ADDR_3_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000020c) +#define VIDC_REG_942170_ADDR_3_RMSK 0xffffffff +#define VIDC_REG_942170_ADDR_3_SHFT 0 +#define VIDC_REG_942170_ADDR_3_IN \ + in_dword_masked(VIDC_REG_942170_ADDR_3_ADDR, \ + VIDC_REG_942170_ADDR_3_RMSK) +#define VIDC_REG_942170_ADDR_3_INM(m) \ + in_dword_masked(VIDC_REG_942170_ADDR_3_ADDR, m) +#define VIDC_REG_942170_ADDR_3_OUT(v) \ + out_dword(VIDC_REG_942170_ADDR_3_ADDR, v) +#define VIDC_REG_942170_ADDR_3_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_942170_ADDR_3_ADDR, m, v, \ + VIDC_REG_942170_ADDR_3_IN); \ +} while (0) +#define VIDC_REG_942170_ADDR_3_FW_STT_ADDR_3_BMSK 0xffffffff +#define VIDC_REG_942170_ADDR_3_FW_STT_ADDR_3_SHFT 0 + +#define VIDC_REG_880188_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000210) +#define VIDC_REG_880188_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000210) +#define VIDC_REG_880188_RMSK 0xffffffff +#define VIDC_REG_880188_SHFT 0 +#define VIDC_REG_880188_IN \ + in_dword_masked(VIDC_REG_880188_ADDR, \ + VIDC_REG_880188_RMSK) +#define VIDC_REG_880188_INM(m) \ + in_dword_masked(VIDC_REG_880188_ADDR, m) +#define VIDC_REG_880188_OUT(v) \ + out_dword(VIDC_REG_880188_ADDR, v) +#define VIDC_REG_880188_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_880188_ADDR, m, v, \ + VIDC_REG_880188_IN); \ +} while (0) +#define VIDC_REG_880188_FW_STT_ADDR_4_BMSK 0xffffffff +#define VIDC_REG_880188_FW_STT_ADDR_4_SHFT 0 + +#define VIDC_REG_40293_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000214) +#define VIDC_REG_40293_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000214) +#define VIDC_REG_40293_RMSK 0xffffffff +#define VIDC_REG_40293_SHFT 0 +#define VIDC_REG_40293_IN \ + in_dword_masked(VIDC_REG_40293_ADDR, \ + VIDC_REG_40293_RMSK) +#define VIDC_REG_40293_INM(m) \ + in_dword_masked(VIDC_REG_40293_ADDR, m) +#define VIDC_REG_40293_OUT(v) \ + out_dword(VIDC_REG_40293_ADDR, v) +#define VIDC_REG_40293_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_40293_ADDR, m, v, \ + VIDC_REG_40293_IN); \ +} while (0) +#define VIDC_REG_40293_FW_STT_ADDR_5_BMSK 0xffffffff +#define VIDC_REG_40293_FW_STT_ADDR_5_SHFT 0 + +#define VIDC_REG_942170_ADDR_6_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000218) +#define VIDC_REG_942170_ADDR_6_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000218) +#define VIDC_REG_942170_ADDR_6_RMSK 0xffffffff +#define VIDC_REG_942170_ADDR_6_SHFT 0 +#define VIDC_REG_942170_ADDR_6_IN \ + in_dword_masked(VIDC_REG_942170_ADDR_6_ADDR, \ + VIDC_REG_942170_ADDR_6_RMSK) +#define VIDC_REG_942170_ADDR_6_INM(m) \ + in_dword_masked(VIDC_REG_942170_ADDR_6_ADDR, m) +#define VIDC_REG_942170_ADDR_6_OUT(v) \ + out_dword(VIDC_REG_942170_ADDR_6_ADDR, v) +#define VIDC_REG_942170_ADDR_6_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_942170_ADDR_6_ADDR, m, v, \ + VIDC_REG_942170_ADDR_6_IN); \ +} while (0) +#define VIDC_REG_942170_ADDR_6_FW_STT_ADDR_6_BMSK 0xffffffff +#define VIDC_REG_942170_ADDR_6_FW_STT_ADDR_6_SHFT 0 + +#define VIDC_REG_958768_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000230) +#define VIDC_REG_958768_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000230) +#define VIDC_REG_958768_RMSK 0xffffffff +#define VIDC_REG_958768_SHFT 0 +#define VIDC_REG_958768_IN \ + in_dword_masked(VIDC_REG_958768_ADDR, \ + VIDC_REG_958768_RMSK) +#define VIDC_REG_958768_INM(m) \ + in_dword_masked(VIDC_REG_958768_ADDR, m) +#define VIDC_REG_958768_OUT(v) \ + out_dword(VIDC_REG_958768_ADDR, v) +#define VIDC_REG_958768_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_958768_ADDR, m, v, \ + VIDC_REG_958768_IN); \ +} while (0) +#define VIDC_REG_699384_ADDR_BMSK 0xffffffff +#define VIDC_REG_699384_ADDR_SHFT 0 + +#define VIDC_REG_979942_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000234) +#define VIDC_REG_979942_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000234) +#define VIDC_REG_979942_RMSK 0xffffffff +#define VIDC_REG_979942_SHFT 0 +#define VIDC_REG_979942_IN \ + in_dword_masked(VIDC_REG_979942_ADDR, \ + VIDC_REG_979942_RMSK) +#define VIDC_REG_979942_INM(m) \ + in_dword_masked(VIDC_REG_979942_ADDR, m) +#define VIDC_REG_979942_OUT(v) \ + out_dword(VIDC_REG_979942_ADDR, v) +#define VIDC_REG_979942_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_979942_ADDR, m, v, \ + VIDC_REG_979942_IN); \ +} while (0) +#define VIDC_REG_979942_DB_STT_ADDR_BMSK 0xffffffff +#define VIDC_REG_979942_DB_STT_ADDR_SHFT 0 + +#define VIDC_REG_839021_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000300) +#define VIDC_REG_839021_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000300) +#define VIDC_REG_839021_RMSK 0xff1f +#define VIDC_REG_839021_SHFT 0 +#define VIDC_REG_839021_IN \ + in_dword_masked(VIDC_REG_839021_ADDR, VIDC_REG_839021_RMSK) +#define VIDC_REG_839021_INM(m) \ + in_dword_masked(VIDC_REG_839021_ADDR, m) +#define VIDC_REG_839021_OUT(v) \ + out_dword(VIDC_REG_839021_ADDR, v) +#define VIDC_REG_839021_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_839021_ADDR, m, v, \ + VIDC_REG_839021_IN); \ +} while (0) +#define VIDC_REG_839021_LEVEL_BMSK 0xff00 +#define VIDC_REG_839021_LEVEL_SHFT 0x8 +#define VIDC_REG_839021_PROFILE_BMSK 0x1f +#define VIDC_REG_839021_PROFILE_SHFT 0 + +#define VIDC_REG_950374_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000308) +#define VIDC_REG_950374_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000308) +#define VIDC_REG_950374_RMSK 0xffff +#define VIDC_REG_950374_SHFT 0 +#define VIDC_REG_950374_IN \ + in_dword_masked(VIDC_REG_950374_ADDR, \ + VIDC_REG_950374_RMSK) +#define VIDC_REG_950374_INM(m) \ + in_dword_masked(VIDC_REG_950374_ADDR, m) +#define VIDC_REG_950374_OUT(v) \ + out_dword(VIDC_REG_950374_ADDR, v) +#define VIDC_REG_950374_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_950374_ADDR, m, v, \ + VIDC_REG_950374_IN); \ +} while (0) +#define VIDC_REG_950374_I_PERIOD_BMSK 0xffff +#define VIDC_REG_950374_I_PERIOD_SHFT 0 + +#define VIDC_REG_504878_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000310) +#define VIDC_REG_504878_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000310) +#define VIDC_REG_504878_RMSK 0xd +#define VIDC_REG_504878_SHFT 0 +#define VIDC_REG_504878_IN \ + in_dword_masked(VIDC_REG_504878_ADDR, \ + VIDC_REG_504878_RMSK) +#define VIDC_REG_504878_INM(m) \ + in_dword_masked(VIDC_REG_504878_ADDR, m) +#define VIDC_REG_504878_OUT(v) \ + out_dword(VIDC_REG_504878_ADDR, v) +#define VIDC_REG_504878_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_504878_ADDR, m, v, \ + VIDC_REG_504878_IN); \ +} while (0) +#define VIDC_REG_504878_FIXED_NUMBER_BMSK 0xc +#define VIDC_REG_504878_FIXED_NUMBER_SHFT 0x2 +#define VIDC_REG_504878_ENTROPY_SEL_BMSK 0x1 +#define VIDC_REG_504878_ENTROPY_SEL_SHFT 0 + +#define VIDC_REG_458130_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000314) +#define VIDC_REG_458130_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000314) +#define VIDC_REG_458130_RMSK 0xfff +#define VIDC_REG_458130_SHFT 0 +#define VIDC_REG_458130_IN \ + in_dword_masked(VIDC_REG_458130_ADDR, \ + VIDC_REG_458130_RMSK) +#define VIDC_REG_458130_INM(m) \ + in_dword_masked(VIDC_REG_458130_ADDR, m) +#define VIDC_REG_458130_OUT(v) \ + out_dword(VIDC_REG_458130_ADDR, v) +#define VIDC_REG_458130_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_458130_ADDR, m, v, \ + VIDC_REG_458130_IN); \ +} while (0) +#define VIDC_REG_458130_SLICE_ALPHA_C0_OFFSET_DIV2_BMSK \ + 0xf80 +#define VIDC_REG_458130_SLICE_ALPHA_C0_OFFSET_DIV2_SHFT \ + 0x7 +#define VIDC_REG_458130_SLICE_BETA_OFFSET_DIV2_BMSK 0x7c +#define VIDC_REG_458130_SLICE_BETA_OFFSET_DIV2_SHFT 0x2 +#define \ + \ +VIDC_REG_458130_DISABLE_DEBLOCKING_FILTER_IDC_BMSK 0x3 +#define \ + \ +VIDC_REG_458130_DISABLE_DEBLOCKING_FILTER_IDC_SHFT 0 + +#define VIDC_REG_314290_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000318) +#define VIDC_REG_314290_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000318) +#define VIDC_REG_314290_RMSK 0x1 +#define VIDC_REG_314290_SHFT 0 +#define VIDC_REG_314290_IN \ + in_dword_masked(VIDC_REG_314290_ADDR, \ + VIDC_REG_314290_RMSK) +#define VIDC_REG_314290_INM(m) \ + in_dword_masked(VIDC_REG_314290_ADDR, m) +#define VIDC_REG_314290_OUT(v) \ + out_dword(VIDC_REG_314290_ADDR, v) +#define VIDC_REG_314290_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_314290_ADDR, m, v, \ + VIDC_REG_314290_IN); \ +} while (0) +#define VIDC_REG_314290_SHORT_HD_ON_BMSK 0x1 +#define VIDC_REG_314290_SHORT_HD_ON_SHFT 0 + +#define VIDC_REG_588301_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000031c) +#define VIDC_REG_588301_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000031c) +#define VIDC_REG_588301_RMSK 0x1 +#define VIDC_REG_588301_SHFT 0 +#define VIDC_REG_588301_IN \ + in_dword_masked(VIDC_REG_588301_ADDR, \ + VIDC_REG_588301_RMSK) +#define VIDC_REG_588301_INM(m) \ + in_dword_masked(VIDC_REG_588301_ADDR, m) +#define VIDC_REG_588301_OUT(v) \ + out_dword(VIDC_REG_588301_ADDR, v) +#define VIDC_REG_588301_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_588301_ADDR, m, v, \ + VIDC_REG_588301_IN); \ +} while (0) +#define VIDC_REG_588301_MSLICE_ENA_BMSK 0x1 +#define VIDC_REG_588301_MSLICE_ENA_SHFT 0 + +#define VIDC_REG_1517_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000320) +#define VIDC_REG_1517_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000320) +#define VIDC_REG_1517_RMSK 0x3 +#define VIDC_REG_1517_SHFT 0 +#define VIDC_REG_1517_IN \ + in_dword_masked(VIDC_REG_1517_ADDR, \ + VIDC_REG_1517_RMSK) +#define VIDC_REG_1517_INM(m) \ + in_dword_masked(VIDC_REG_1517_ADDR, m) +#define VIDC_REG_1517_OUT(v) \ + out_dword(VIDC_REG_1517_ADDR, v) +#define VIDC_REG_1517_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_1517_ADDR, m, v, \ + VIDC_REG_1517_IN); \ +} while (0) +#define VIDC_REG_1517_MSLICE_SEL_BMSK 0x3 +#define VIDC_REG_1517_MSLICE_SEL_SHFT 0 + +#define VIDC_REG_105335_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000324) +#define VIDC_REG_105335_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000324) +#define VIDC_REG_105335_RMSK 0xffffffff +#define VIDC_REG_105335_SHFT 0 +#define VIDC_REG_105335_IN \ + in_dword_masked(VIDC_REG_105335_ADDR, \ + VIDC_REG_105335_RMSK) +#define VIDC_REG_105335_INM(m) \ + in_dword_masked(VIDC_REG_105335_ADDR, m) +#define VIDC_REG_105335_OUT(v) \ + out_dword(VIDC_REG_105335_ADDR, v) +#define VIDC_REG_105335_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_105335_ADDR, m, v, \ + VIDC_REG_105335_IN); \ +} while (0) +#define VIDC_REG_105335_MSLICE_MB_BMSK 0xffffffff +#define VIDC_REG_105335_MSLICE_MB_SHFT 0 + +#define VIDC_REG_561679_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000328) +#define VIDC_REG_561679_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000328) +#define VIDC_REG_561679_RMSK 0xffffffff +#define VIDC_REG_561679_SHFT 0 +#define VIDC_REG_561679_IN \ + in_dword_masked(VIDC_REG_561679_ADDR, \ + VIDC_REG_561679_RMSK) +#define VIDC_REG_561679_INM(m) \ + in_dword_masked(VIDC_REG_561679_ADDR, m) +#define VIDC_REG_561679_OUT(v) \ + out_dword(VIDC_REG_561679_ADDR, v) +#define VIDC_REG_561679_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_561679_ADDR, m, v, \ + VIDC_REG_561679_IN); \ +} while (0) +#define VIDC_REG_561679_MSLICE_BYTE_BMSK 0xffffffff +#define VIDC_REG_561679_MSLICE_BYTE_SHFT 0 + +#define VIDC_REG_151345_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000400) +#define VIDC_REG_151345_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000400) +#define VIDC_REG_151345_RMSK 0xffffffff +#define VIDC_REG_151345_SHFT 0 +#define VIDC_REG_151345_IN \ + in_dword_masked(VIDC_REG_151345_ADDR, \ + VIDC_REG_151345_RMSK) +#define VIDC_REG_151345_INM(m) \ + in_dword_masked(VIDC_REG_151345_ADDR, m) +#define VIDC_REG_151345_DISPLAY_Y_ADR_BMSK 0xffffffff +#define VIDC_REG_151345_DISPLAY_Y_ADR_SHFT 0 + +#define VIDC_REG_293983_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000404) +#define VIDC_REG_293983_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000404) +#define VIDC_REG_293983_RMSK 0xffffffff +#define VIDC_REG_293983_SHFT 0 +#define VIDC_REG_293983_IN \ + in_dword_masked(VIDC_REG_293983_ADDR, \ + VIDC_REG_293983_RMSK) +#define VIDC_REG_293983_INM(m) \ + in_dword_masked(VIDC_REG_293983_ADDR, m) +#define VIDC_REG_293983_DISPLAY_C_ADR_BMSK 0xffffffff +#define VIDC_REG_293983_DISPLAY_C_ADR_SHFT 0 + +#define VIDC_REG_612715_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000408) +#define VIDC_REG_612715_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000408) +#define VIDC_REG_612715_RMSK 0x3f +#define VIDC_REG_612715_SHFT 0 +#define VIDC_REG_612715_IN \ + in_dword_masked(VIDC_REG_612715_ADDR, \ + VIDC_REG_612715_RMSK) +#define VIDC_REG_612715_INM(m) \ + in_dword_masked(VIDC_REG_612715_ADDR, m) +#define VIDC_REG_612715_DISPLAY_STATUS_BMSK 0x3f +#define VIDC_REG_612715_DISPLAY_STATUS_SHFT 0 + +#define VIDC_REG_209364_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000040c) +#define VIDC_REG_209364_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000040c) +#define VIDC_REG_209364_RMSK 0x1 +#define VIDC_REG_209364_SHFT 0 +#define VIDC_REG_209364_IN \ + in_dword_masked(VIDC_REG_209364_ADDR, \ + VIDC_REG_209364_RMSK) +#define VIDC_REG_209364_INM(m) \ + in_dword_masked(VIDC_REG_209364_ADDR, m) +#define VIDC_REG_209364_HEADER_DONE_BMSK 0x1 +#define VIDC_REG_209364_HEADER_DONE_SHFT 0 + +#define VIDC_REG_757835_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000410) +#define VIDC_REG_757835_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000410) +#define VIDC_REG_757835_RMSK 0xffffffff +#define VIDC_REG_757835_SHFT 0 +#define VIDC_REG_757835_IN \ + in_dword_masked(VIDC_REG_757835_ADDR, \ + VIDC_REG_757835_RMSK) +#define VIDC_REG_757835_INM(m) \ + in_dword_masked(VIDC_REG_757835_ADDR, m) +#define VIDC_REG_757835_FRAME_NUM_BMSK 0xffffffff +#define VIDC_REG_757835_FRAME_NUM_SHFT 0 + +#define VIDC_REG_352831_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000414) +#define VIDC_REG_352831_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000414) +#define VIDC_REG_352831_RMSK 0xffffffff +#define VIDC_REG_352831_SHFT 0 +#define VIDC_REG_352831_IN \ + in_dword_masked(VIDC_REG_352831_ADDR, \ + VIDC_REG_352831_RMSK) +#define VIDC_REG_352831_INM(m) \ + in_dword_masked(VIDC_REG_352831_ADDR, m) +#define VIDC_REG_352831_DBG_INFO_OUTPUT0_BMSK 0xffffffff +#define VIDC_REG_352831_DBG_INFO_OUTPUT0_SHFT 0 + +#define VIDC_REG_668634_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000418) +#define VIDC_REG_668634_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000418) +#define VIDC_REG_668634_RMSK 0xffffffff +#define VIDC_REG_668634_SHFT 0 +#define VIDC_REG_668634_IN \ + in_dword_masked(VIDC_REG_668634_ADDR, \ + VIDC_REG_668634_RMSK) +#define VIDC_REG_668634_INM(m) \ + in_dword_masked(VIDC_REG_668634_ADDR, m) +#define VIDC_REG_668634_DBG_INFO_OUTPUT1_BMSK 0xffffffff +#define VIDC_REG_668634_DBG_INFO_OUTPUT1_SHFT 0 + +#define VIDC_REG_609676_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000500) +#define VIDC_REG_609676_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000500) +#define VIDC_REG_609676_RMSK 0x1 +#define VIDC_REG_609676_SHFT 0 +#define VIDC_REG_609676_IN \ + in_dword_masked(VIDC_REG_609676_ADDR, VIDC_REG_609676_RMSK) +#define VIDC_REG_609676_INM(m) \ + in_dword_masked(VIDC_REG_609676_ADDR, m) +#define VIDC_REG_609676_OUT(v) \ + out_dword(VIDC_REG_609676_ADDR, v) +#define VIDC_REG_609676_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_609676_ADDR, m, v, \ + VIDC_REG_609676_IN); \ +} while (0) +#define VIDC_REG_609676_INT_OFF_BMSK 0x1 +#define VIDC_REG_609676_INT_OFF_SHFT 0 + +#define VIDC_REG_491082_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000504) +#define VIDC_REG_491082_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000504) +#define VIDC_REG_491082_RMSK 0x1 +#define VIDC_REG_491082_SHFT 0 +#define VIDC_REG_491082_IN \ + in_dword_masked(VIDC_REG_491082_ADDR, \ + VIDC_REG_491082_RMSK) +#define VIDC_REG_491082_INM(m) \ + in_dword_masked(VIDC_REG_491082_ADDR, m) +#define VIDC_REG_491082_OUT(v) \ + out_dword(VIDC_REG_491082_ADDR, v) +#define VIDC_REG_491082_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_491082_ADDR, m, v, \ + VIDC_REG_491082_IN); \ +} while (0) +#define VIDC_REG_491082_INT_PULSE_SEL_BMSK 0x1 +#define VIDC_REG_491082_INT_PULSE_SEL_SHFT 0 + +#define VIDC_REG_614776_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000508) +#define VIDC_REG_614776_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000508) +#define VIDC_REG_614776_RMSK 0x1 +#define VIDC_REG_614776_SHFT 0 +#define VIDC_REG_614776_IN \ + in_dword_masked(VIDC_REG_614776_ADDR, \ + VIDC_REG_614776_RMSK) +#define VIDC_REG_614776_INM(m) \ + in_dword_masked(VIDC_REG_614776_ADDR, m) +#define VIDC_REG_614776_OUT(v) \ + out_dword(VIDC_REG_614776_ADDR, v) +#define VIDC_REG_614776_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_614776_ADDR, m, v, \ + VIDC_REG_614776_IN); \ +} while (0) +#define VIDC_REG_614776_INT_DONE_CLEAR_BMSK 0x1 +#define VIDC_REG_614776_INT_DONE_CLEAR_SHFT 0 + +#define VIDC_REG_982553_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000050c) +#define VIDC_REG_982553_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000050c) +#define VIDC_REG_982553_RMSK 0x1 +#define VIDC_REG_982553_SHFT 0 +#define VIDC_REG_982553_IN \ + in_dword_masked(VIDC_REG_982553_ADDR, \ + VIDC_REG_982553_RMSK) +#define VIDC_REG_982553_INM(m) \ + in_dword_masked(VIDC_REG_982553_ADDR, m) +#define VIDC_REG_982553_OPERATION_DONE_BMSK 0x1 +#define VIDC_REG_982553_OPERATION_DONE_SHFT 0 + +#define VIDC_REG_259967_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000510) +#define VIDC_REG_259967_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000510) +#define VIDC_REG_259967_RMSK 0x1 +#define VIDC_REG_259967_SHFT 0 +#define VIDC_REG_259967_IN \ + in_dword_masked(VIDC_REG_259967_ADDR, VIDC_REG_259967_RMSK) +#define VIDC_REG_259967_INM(m) \ + in_dword_masked(VIDC_REG_259967_ADDR, m) +#define VIDC_REG_259967_FW_DONE_BMSK 0x1 +#define VIDC_REG_259967_FW_DONE_SHFT 0 + +#define VIDC_REG_512143_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000514) +#define VIDC_REG_512143_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000514) +#define VIDC_REG_512143_RMSK 0x1f8 +#define VIDC_REG_512143_SHFT 0 +#define VIDC_REG_512143_IN \ + in_dword_masked(VIDC_REG_512143_ADDR, \ + VIDC_REG_512143_RMSK) +#define VIDC_REG_512143_INM(m) \ + in_dword_masked(VIDC_REG_512143_ADDR, m) +#define VIDC_REG_512143_FRAME_DONE_STAT_BMSK 0x100 +#define VIDC_REG_512143_FRAME_DONE_STAT_SHFT 0x8 +#define VIDC_REG_512143_DMA_DONE_STAT_BMSK 0x80 +#define VIDC_REG_512143_DMA_DONE_STAT_SHFT 0x7 +#define VIDC_REG_512143_HEADER_DONE_STAT_BMSK 0x40 +#define VIDC_REG_512143_HEADER_DONE_STAT_SHFT 0x6 +#define VIDC_REG_512143_FW_DONE_STAT_BMSK 0x20 +#define VIDC_REG_512143_FW_DONE_STAT_SHFT 0x5 +#define VIDC_REG_512143_OPERATION_FAILED_BMSK 0x10 +#define VIDC_REG_512143_OPERATION_FAILED_SHFT 0x4 +#define VIDC_REG_512143_STREAM_HDR_CHANGED_BMSK 0x8 +#define VIDC_REG_512143_STREAM_HDR_CHANGED_SHFT 0x3 + +#define VIDC_REG_418173_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000518) +#define VIDC_REG_418173_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000518) +#define VIDC_REG_418173_RMSK 0x1fa +#define VIDC_REG_418173_SHFT 0 +#define VIDC_REG_418173_IN \ + in_dword_masked(VIDC_REG_418173_ADDR, \ + VIDC_REG_418173_RMSK) +#define VIDC_REG_418173_INM(m) \ + in_dword_masked(VIDC_REG_418173_ADDR, m) +#define VIDC_REG_418173_OUT(v) \ + out_dword(VIDC_REG_418173_ADDR, v) +#define VIDC_REG_418173_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_418173_ADDR, m, v, \ + VIDC_REG_418173_IN); \ +} while (0) +#define VIDC_REG_418173_FRAME_DONE_ENABLE_BMSK 0x100 +#define VIDC_REG_418173_FRAME_DONE_ENABLE_SHFT 0x8 +#define VIDC_REG_418173_DMA_DONE_ENABLE_BMSK 0x80 +#define VIDC_REG_418173_DMA_DONE_ENABLE_SHFT 0x7 +#define VIDC_REG_418173_HEADER_DONE_ENABLE_BMSK 0x40 +#define VIDC_REG_418173_HEADER_DONE_ENABLE_SHFT 0x6 +#define VIDC_REG_418173_FW_DONE_ENABLE_BMSK 0x20 +#define VIDC_REG_418173_FW_DONE_ENABLE_SHFT 0x5 +#define VIDC_REG_418173_OPERATION_FAILED_ENABLE_BMSK 0x10 +#define VIDC_REG_418173_OPERATION_FAILED_ENABLE_SHFT 0x4 +#define VIDC_REG_418173_STREAM_HDR_CHANGED_ENABLE_BMSK 0x8 +#define VIDC_REG_418173_STREAM_HDR_CHANGED_ENABLE_SHFT 0x3 +#define VIDC_REG_418173_BUFFER_FULL_ENABLE_BMSK 0x2 +#define VIDC_REG_418173_BUFFER_FULL_ENABLE_SHFT 0x1 + +#define VIDC_REG_841539_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000600) +#define VIDC_REG_841539_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000600) +#define VIDC_REG_841539_RMSK 0x3 +#define VIDC_REG_841539_SHFT 0 +#define VIDC_REG_841539_IN \ + in_dword_masked(VIDC_REG_841539_ADDR, \ + VIDC_REG_841539_RMSK) +#define VIDC_REG_841539_INM(m) \ + in_dword_masked(VIDC_REG_841539_ADDR, m) +#define VIDC_REG_841539_OUT(v) \ + out_dword(VIDC_REG_841539_ADDR, v) +#define VIDC_REG_841539_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_841539_ADDR, m, v, \ + VIDC_REG_841539_IN); \ +} while (0) +#define VIDC_REG_841539_TILE_MODE_BMSK 0x3 +#define VIDC_REG_841539_TILE_MODE_SHFT 0 + +#define VIDC_REG_99105_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000800) +#define VIDC_REG_99105_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000800) +#define VIDC_REG_99105_RMSK 0xffffffff +#define VIDC_REG_99105_SHFT 0 +#define VIDC_REG_99105_IN \ + in_dword_masked(VIDC_REG_99105_ADDR, \ + VIDC_REG_99105_RMSK) +#define VIDC_REG_99105_INM(m) \ + in_dword_masked(VIDC_REG_99105_ADDR, m) +#define VIDC_REG_99105_OUT(v) \ + out_dword(VIDC_REG_99105_ADDR, v) +#define VIDC_REG_99105_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_99105_ADDR, m, v, \ + VIDC_REG_99105_IN); \ +} while (0) +#define VIDC_REG_99105_ENC_CUR_Y_ADDR_BMSK 0xffffffff +#define VIDC_REG_99105_ENC_CUR_Y_ADDR_SHFT 0 + +#define VIDC_REG_777113_ADDR_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000804) +#define VIDC_REG_777113_ADDR_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000804) +#define VIDC_REG_777113_ADDR_RMSK 0xffffffff +#define VIDC_REG_777113_ADDR_SHFT 0 +#define VIDC_REG_777113_ADDR_IN \ + in_dword_masked(VIDC_REG_777113_ADDR_ADDR, \ + VIDC_REG_777113_ADDR_RMSK) +#define VIDC_REG_777113_ADDR_INM(m) \ + in_dword_masked(VIDC_REG_777113_ADDR_ADDR, m) +#define VIDC_REG_777113_ADDR_OUT(v) \ + out_dword(VIDC_REG_777113_ADDR_ADDR, v) +#define VIDC_REG_777113_ADDR_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_777113_ADDR_ADDR, m, v, \ + VIDC_REG_777113_ADDR_IN); \ +} while (0) +#define VIDC_REG_777113_ADDR_ENC_CUR_C_ADDR_BMSK 0xffffffff +#define VIDC_REG_777113_ADDR_ENC_CUR_C_ADDR_SHFT 0 + +#define VIDC_REG_341928_ADDR_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000080c) +#define VIDC_REG_341928_ADDR_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000080c) +#define VIDC_REG_341928_ADDR_RMSK 0xffffffff +#define VIDC_REG_341928_ADDR_SHFT 0 +#define VIDC_REG_341928_ADDR_IN \ + in_dword_masked(VIDC_REG_341928_ADDR_ADDR, \ + VIDC_REG_341928_ADDR_RMSK) +#define VIDC_REG_341928_ADDR_INM(m) \ + in_dword_masked(VIDC_REG_341928_ADDR_ADDR, m) +#define VIDC_REG_341928_ADDR_OUT(v) \ + out_dword(VIDC_REG_341928_ADDR_ADDR, v) +#define VIDC_REG_341928_ADDR_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_341928_ADDR_ADDR, m, v, \ + VIDC_REG_341928_ADDR_IN); \ +} while (0) +#define VIDC_REG_341928_ADDR_ENC_DPB_ADR_BMSK 0xffffffff +#define VIDC_REG_341928_ADDR_ENC_DPB_ADR_SHFT 0 + +#define VIDC_REG_857491_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000810) +#define VIDC_REG_857491_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000810) +#define VIDC_REG_857491_RMSK 0xfff +#define VIDC_REG_857491_SHFT 0 +#define VIDC_REG_857491_IN \ + in_dword_masked(VIDC_REG_857491_ADDR, \ + VIDC_REG_857491_RMSK) +#define VIDC_REG_857491_INM(m) \ + in_dword_masked(VIDC_REG_857491_ADDR, m) +#define VIDC_REG_857491_OUT(v) \ + out_dword(VIDC_REG_857491_ADDR, v) +#define VIDC_REG_857491_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_857491_ADDR, m, v, \ + VIDC_REG_857491_IN); \ +} while (0) +#define VIDC_REG_857491_CIR_MB_NUM_BMSK 0xfff +#define VIDC_REG_857491_CIR_MB_NUM_SHFT 0 + +#define VIDC_REG_518133_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000900) +#define VIDC_REG_518133_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000900) +#define VIDC_REG_518133_RMSK 0xffffffff +#define VIDC_REG_518133_SHFT 0 +#define VIDC_REG_518133_IN \ + in_dword_masked(VIDC_REG_518133_ADDR, \ + VIDC_REG_518133_RMSK) +#define VIDC_REG_518133_INM(m) \ + in_dword_masked(VIDC_REG_518133_ADDR, m) +#define VIDC_REG_518133_OUT(v) \ + out_dword(VIDC_REG_518133_ADDR, v) +#define VIDC_REG_518133_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_518133_ADDR, m, v, \ + VIDC_REG_518133_IN); \ +} while (0) +#define VIDC_REG_518133_DEC_DPB_ADDR_BMSK 0xffffffff +#define VIDC_REG_518133_DEC_DPB_ADDR_SHFT 0 + +#define VIDC_REG_456376_ADDR_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000904) +#define VIDC_REG_456376_ADDR_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000904) +#define VIDC_REG_456376_ADDR_RMSK 0xffffffff +#define VIDC_REG_456376_ADDR_SHFT 0 +#define VIDC_REG_456376_ADDR_IN \ + in_dword_masked(VIDC_REG_456376_ADDR_ADDR, \ + VIDC_REG_456376_ADDR_RMSK) +#define VIDC_REG_456376_ADDR_INM(m) \ + in_dword_masked(VIDC_REG_456376_ADDR_ADDR, m) +#define VIDC_REG_456376_ADDR_OUT(v) \ + out_dword(VIDC_REG_456376_ADDR_ADDR, v) +#define VIDC_REG_456376_ADDR_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_456376_ADDR_ADDR, m, v, \ + VIDC_REG_456376_ADDR_IN); \ +} while (0) +#define VIDC_REG_456376_ADDR_DPB_COMV_ADDR_BMSK 0xffffffff +#define VIDC_REG_456376_ADDR_DPB_COMV_ADDR_SHFT 0 + +#define VIDC_REG_267567_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000908) +#define VIDC_REG_267567_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000908) +#define VIDC_REG_267567_RMSK 0xffffffff +#define VIDC_REG_267567_SHFT 0 +#define VIDC_REG_267567_IN \ + in_dword_masked(VIDC_REG_267567_ADDR, \ + VIDC_REG_267567_RMSK) +#define VIDC_REG_267567_INM(m) \ + in_dword_masked(VIDC_REG_267567_ADDR, m) +#define VIDC_REG_267567_OUT(v) \ + out_dword(VIDC_REG_267567_ADDR, v) +#define VIDC_REG_267567_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_267567_ADDR, m, v, \ + VIDC_REG_267567_IN); \ +} while (0) +#define VIDC_REG_798486_ADDR_BMSK 0xffffffff +#define VIDC_REG_798486_ADDR_SHFT 0 + +#define VIDC_REG_105770_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000090c) +#define VIDC_REG_105770_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000090c) +#define VIDC_REG_105770_RMSK 0xff +#define VIDC_REG_105770_SHFT 0 +#define VIDC_REG_105770_IN \ + in_dword_masked(VIDC_REG_105770_ADDR, \ + VIDC_REG_105770_RMSK) +#define VIDC_REG_105770_INM(m) \ + in_dword_masked(VIDC_REG_105770_ADDR, m) +#define VIDC_REG_105770_DPB_SIZE_BMSK 0xff +#define VIDC_REG_105770_DPB_SIZE_SHFT 0 + +#define VIDC_REG_58211_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a00) +#define VIDC_REG_58211_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a00) +#define VIDC_REG_58211_RMSK 0x33f +#define VIDC_REG_58211_SHFT 0 +#define VIDC_REG_58211_IN \ + in_dword_masked(VIDC_REG_58211_ADDR, \ + VIDC_REG_58211_RMSK) +#define VIDC_REG_58211_INM(m) \ + in_dword_masked(VIDC_REG_58211_ADDR, m) +#define VIDC_REG_58211_OUT(v) \ + out_dword(VIDC_REG_58211_ADDR, v) +#define VIDC_REG_58211_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_58211_ADDR, m, v, \ + VIDC_REG_58211_IN); \ +} while (0) +#define VIDC_REG_58211_FR_RC_EN_BMSK 0x200 +#define VIDC_REG_58211_FR_RC_EN_SHFT 0x9 +#define VIDC_REG_58211_MB_RC_EN_BMSK 0x100 +#define VIDC_REG_58211_MB_RC_EN_SHFT 0x8 +#define VIDC_REG_58211_FRAME_QP_BMSK 0x3f +#define VIDC_REG_58211_FRAME_QP_SHFT 0 + +#define VIDC_REG_548359_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a04) +#define VIDC_REG_548359_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a04) +#define VIDC_REG_548359_RMSK 0x3f +#define VIDC_REG_548359_SHFT 0 +#define VIDC_REG_548359_IN \ + in_dword_masked(VIDC_REG_548359_ADDR, \ + VIDC_REG_548359_RMSK) +#define VIDC_REG_548359_INM(m) \ + in_dword_masked(VIDC_REG_548359_ADDR, m) +#define VIDC_REG_548359_OUT(v) \ + out_dword(VIDC_REG_548359_ADDR, v) +#define VIDC_REG_548359_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_548359_ADDR, m, v, \ + VIDC_REG_548359_IN); \ +} while (0) +#define VIDC_REG_548359_P_FRAME_QP_BMSK 0x3f +#define VIDC_REG_548359_P_FRAME_QP_SHFT 0 + +#define VIDC_REG_174150_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a08) +#define VIDC_REG_174150_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a08) +#define VIDC_REG_174150_RMSK 0xffffffff +#define VIDC_REG_174150_SHFT 0 +#define VIDC_REG_174150_IN \ + in_dword_masked(VIDC_REG_174150_ADDR, \ + VIDC_REG_174150_RMSK) +#define VIDC_REG_174150_INM(m) \ + in_dword_masked(VIDC_REG_174150_ADDR, m) +#define VIDC_REG_174150_OUT(v) \ + out_dword(VIDC_REG_174150_ADDR, v) +#define VIDC_REG_174150_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_174150_ADDR, m, v, \ + VIDC_REG_174150_IN); \ +} while (0) +#define VIDC_REG_174150_BIT_RATE_BMSK 0xffffffff +#define VIDC_REG_174150_BIT_RATE_SHFT 0 + +#define VIDC_REG_734318_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a0c) +#define VIDC_REG_734318_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a0c) +#define VIDC_REG_734318_RMSK 0x3f3f +#define VIDC_REG_734318_SHFT 0 +#define VIDC_REG_734318_IN \ + in_dword_masked(VIDC_REG_734318_ADDR, \ + VIDC_REG_734318_RMSK) +#define VIDC_REG_734318_INM(m) \ + in_dword_masked(VIDC_REG_734318_ADDR, m) +#define VIDC_REG_734318_OUT(v) \ + out_dword(VIDC_REG_734318_ADDR, v) +#define VIDC_REG_734318_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_734318_ADDR, m, v, \ + VIDC_REG_734318_IN); \ +} while (0) +#define VIDC_REG_734318_MAX_QP_BMSK 0x3f00 +#define VIDC_REG_734318_MAX_QP_SHFT 0x8 +#define VIDC_REG_734318_MIN_QP_BMSK 0x3f +#define VIDC_REG_734318_MIN_QP_SHFT 0 + +#define VIDC_REG_677784_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a10) +#define VIDC_REG_677784_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a10) +#define VIDC_REG_677784_RMSK 0xffff +#define VIDC_REG_677784_SHFT 0 +#define VIDC_REG_677784_IN \ + in_dword_masked(VIDC_REG_677784_ADDR, \ + VIDC_REG_677784_RMSK) +#define VIDC_REG_677784_INM(m) \ + in_dword_masked(VIDC_REG_677784_ADDR, m) +#define VIDC_REG_677784_OUT(v) \ + out_dword(VIDC_REG_677784_ADDR, v) +#define VIDC_REG_677784_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_677784_ADDR, m, v, \ + VIDC_REG_677784_IN); \ +} while (0) +#define VIDC_REG_677784_REACT_PARA_BMSK 0xffff +#define VIDC_REG_677784_REACT_PARA_SHFT 0 + +#define VIDC_REG_995041_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a14) +#define VIDC_REG_995041_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a14) +#define VIDC_REG_995041_RMSK 0xf +#define VIDC_REG_995041_SHFT 0 +#define VIDC_REG_995041_IN \ + in_dword_masked(VIDC_REG_995041_ADDR, \ + VIDC_REG_995041_RMSK) +#define VIDC_REG_995041_INM(m) \ + in_dword_masked(VIDC_REG_995041_ADDR, m) +#define VIDC_REG_995041_OUT(v) \ + out_dword(VIDC_REG_995041_ADDR, v) +#define VIDC_REG_995041_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_995041_ADDR, m, v, \ + VIDC_REG_995041_IN); \ +} while (0) +#define VIDC_REG_995041_DARK_DISABLE_BMSK 0x8 +#define VIDC_REG_995041_DARK_DISABLE_SHFT 0x3 +#define VIDC_REG_995041_SMOOTH_DISABLE_BMSK 0x4 +#define VIDC_REG_995041_SMOOTH_DISABLE_SHFT 0x2 +#define VIDC_REG_995041_STATIC_DISABLE_BMSK 0x2 +#define VIDC_REG_995041_STATIC_DISABLE_SHFT 0x1 +#define VIDC_REG_995041_ACT_DISABLE_BMSK 0x1 +#define VIDC_REG_995041_ACT_DISABLE_SHFT 0 + +#define VIDC_REG_273649_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a18) +#define VIDC_REG_273649_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a18) +#define VIDC_REG_273649_RMSK 0x3f +#define VIDC_REG_273649_SHFT 0 +#define VIDC_REG_273649_IN \ + in_dword_masked(VIDC_REG_273649_ADDR, VIDC_REG_273649_RMSK) +#define VIDC_REG_273649_INM(m) \ + in_dword_masked(VIDC_REG_273649_ADDR, m) +#define VIDC_REG_273649_QP_OUT_BMSK 0x3f +#define VIDC_REG_273649_QP_OUT_SHFT 0 + +#define VIDC_REG_548823_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000b00) +#define VIDC_REG_548823_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000b00) +#define VIDC_REG_548823_RMSK 0xffffffff +#define VIDC_REG_548823_SHFT 0 +#define VIDC_REG_548823_IN \ + in_dword_masked(VIDC_REG_548823_ADDR, \ + VIDC_REG_548823_RMSK) +#define VIDC_REG_548823_INM(m) \ + in_dword_masked(VIDC_REG_548823_ADDR, m) +#define VIDC_REG_548823_720P_VERSION_BMSK 0xffffffff +#define VIDC_REG_548823_720P_VERSION_SHFT 0 + +#define VIDC_REG_881638_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c00) +#define VIDC_REG_881638_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c00) +#define VIDC_REG_881638_RMSK 0xffffffff +#define VIDC_REG_881638_SHFT 0 +#define VIDC_REG_881638_IN \ + in_dword_masked(VIDC_REG_881638_ADDR, \ + VIDC_REG_881638_RMSK) +#define VIDC_REG_881638_INM(m) \ + in_dword_masked(VIDC_REG_881638_ADDR, m) +#define VIDC_REG_881638_CROP_RIGHT_OFFSET_BMSK 0xffff0000 +#define VIDC_REG_881638_CROP_RIGHT_OFFSET_SHFT 0x10 +#define VIDC_REG_881638_CROP_LEFT_OFFSET_BMSK 0xffff +#define VIDC_REG_881638_CROP_LEFT_OFFSET_SHFT 0 + +#define VIDC_REG_161486_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c04) +#define VIDC_REG_161486_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c04) +#define VIDC_REG_161486_RMSK 0xffffffff +#define VIDC_REG_161486_SHFT 0 +#define VIDC_REG_161486_IN \ + in_dword_masked(VIDC_REG_161486_ADDR, \ + VIDC_REG_161486_RMSK) +#define VIDC_REG_161486_INM(m) \ + in_dword_masked(VIDC_REG_161486_ADDR, m) +#define VIDC_REG_161486_CROP_BOTTOM_OFFSET_BMSK 0xffff0000 +#define VIDC_REG_161486_CROP_BOTTOM_OFFSET_SHFT 0x10 +#define VIDC_REG_161486_CROP_TOP_OFFSET_BMSK 0xffff +#define VIDC_REG_161486_CROP_TOP_OFFSET_SHFT 0 + +#define VIDC_REG_580603_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c08) +#define VIDC_REG_580603_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c08) +#define VIDC_REG_580603_RMSK 0xffffffff +#define VIDC_REG_580603_SHFT 0 +#define VIDC_REG_580603_IN \ + in_dword_masked(VIDC_REG_580603_ADDR, \ + VIDC_REG_580603_RMSK) +#define VIDC_REG_580603_INM(m) \ + in_dword_masked(VIDC_REG_580603_ADDR, m) +#define VIDC_REG_580603_720P_DEC_FRM_SIZE_BMSK 0xffffffff +#define VIDC_REG_580603_720P_DEC_FRM_SIZE_SHFT 0 + + +#define VIDC_REG_606447_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c0c) +#define VIDC_REG_606447_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c0c) +#define VIDC_REG_606447_RMSK 0xff1f +#define VIDC_REG_606447_SHFT 0 +#define VIDC_REG_606447_IN \ + in_dword_masked(VIDC_REG_606447_ADDR, \ + VIDC_REG_606447_RMSK) +#define VIDC_REG_606447_INM(m) \ + in_dword_masked(VIDC_REG_606447_ADDR, m) +#define VIDC_REG_606447_OUT(v) \ + out_dword(VIDC_REG_606447_ADDR, v) +#define VIDC_REG_606447_OUTM(m, v) \ + out_dword_masked_ns(VIDC_REG_606447_ADDR, \ + m, v, VIDC_REG_606447_IN); \ + +#define VIDC_REG_606447_DIS_PIC_LEVEL_BMSK 0xff00 +#define VIDC_REG_606447_DIS_PIC_LEVEL_SHFT 0x8 +#define VIDC_REG_606447_DISP_PIC_PROFILE_BMSK 0x1f +#define VIDC_REG_606447_DISP_PIC_PROFILE_SHFT 0 + +#define VIDC_REG_854281_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c10) +#define VIDC_REG_854281_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c10) +#define VIDC_REG_854281_RMSK 0xffffffff +#define VIDC_REG_854281_SHFT 0 +#define VIDC_REG_854281_IN \ + in_dword_masked(VIDC_REG_854281_ADDR, \ + VIDC_REG_854281_RMSK) +#define VIDC_REG_854281_INM(m) \ + in_dword_masked(VIDC_REG_854281_ADDR, m) +#define VIDC_REG_854281_MIN_DPB_SIZE_BMSK 0xffffffff +#define VIDC_REG_854281_MIN_DPB_SIZE_SHFT 0 + + +#define VIDC_REG_381535_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c14) +#define VIDC_REG_381535_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c14) +#define VIDC_REG_381535_RMSK 0xffffffff +#define VIDC_REG_381535_SHFT 0 +#define VIDC_REG_381535_IN \ + in_dword_masked(VIDC_REG_381535_ADDR, \ + VIDC_REG_381535_RMSK) +#define VIDC_REG_381535_INM(m) \ + in_dword_masked(VIDC_REG_381535_ADDR, m) +#define VIDC_REG_381535_720P_FW_STATUS_BMSK 0xffffffff +#define VIDC_REG_381535_720P_FW_STATUS_SHFT 0 + + +#define VIDC_REG_347105_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c18) +#define VIDC_REG_347105_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c18) +#define VIDC_REG_347105_RMSK 0xffffffff +#define VIDC_REG_347105_SHFT 0 +#define VIDC_REG_347105_IN \ + in_dword_masked(VIDC_REG_347105_ADDR, \ + VIDC_REG_347105_RMSK) +#define VIDC_REG_347105_INM(m) \ + in_dword_masked(VIDC_REG_347105_ADDR, m) +#define VIDC_REG_347105_FREE_LUMA_DPB_BMSK 0xffffffff +#define VIDC_REG_347105_FREE_LUMA_DPB_SHFT 0 + + +#define VIDC_REG_62325_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d00) +#define VIDC_REG_62325_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d00) +#define VIDC_REG_62325_RMSK 0xf +#define VIDC_REG_62325_SHFT 0 +#define VIDC_REG_62325_IN \ + in_dword_masked(VIDC_REG_62325_ADDR, \ + VIDC_REG_62325_RMSK) +#define VIDC_REG_62325_INM(m) \ + in_dword_masked(VIDC_REG_62325_ADDR, m) +#define VIDC_REG_62325_OUT(v) \ + out_dword(VIDC_REG_62325_ADDR, v) +#define VIDC_REG_62325_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_62325_ADDR, m, v, \ + VIDC_REG_62325_IN); \ +} while (0) +#define VIDC_REG_62325_COMMAND_TYPE_BMSK 0xf +#define VIDC_REG_62325_COMMAND_TYPE_SHFT 0 + +#define VIDC_REG_101184_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d04) +#define VIDC_REG_101184_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d04) +#define VIDC_REG_101184_RMSK 0xffffffff +#define VIDC_REG_101184_SHFT 0 +#define VIDC_REG_101184_OUT(v) \ + out_dword(VIDC_REG_101184_ADDR, v) + +#define VIDC_REG_490443_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d08) +#define VIDC_REG_490443_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d08) +#define VIDC_REG_490443_RMSK \ + 0xffffffff +#define \ + \ +VIDC_REG_490443_SHFT 0 +#define VIDC_REG_490443_OUT(v) \ + out_dword(VIDC_REG_490443_ADDR, v) + +#define VIDC_REG_625444_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d14) +#define VIDC_REG_625444_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d14) +#define VIDC_REG_625444_RMSK 0xffffffff +#define VIDC_REG_625444_SHFT 0 +#define VIDC_REG_625444_IN \ + in_dword_masked(VIDC_REG_625444_ADDR, \ + VIDC_REG_625444_RMSK) +#define VIDC_REG_625444_INM(m) \ + in_dword_masked(VIDC_REG_625444_ADDR, m) +#define VIDC_REG_625444_OUT(v) \ + out_dword(VIDC_REG_625444_ADDR, v) +#define VIDC_REG_625444_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_625444_ADDR, m, v, \ + VIDC_REG_625444_IN); \ +} while (0) +#define VIDC_REG_625444_FRAME_RATE_BMSK 0xffffffff +#define VIDC_REG_625444_FRAME_RATE_SHFT 0 + +#define VIDC_REG_639999_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d20) +#define VIDC_REG_639999_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d20) +#define VIDC_REG_639999_RMSK 0xffff +#define VIDC_REG_639999_SHFT 0 +#define VIDC_REG_639999_OUT(v) \ + out_dword(VIDC_REG_639999_ADDR, v) + +#define VIDC_REG_64895_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e00) +#define VIDC_REG_64895_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e00) +#define VIDC_REG_64895_RMSK 0xffffffff +#define VIDC_REG_64895_SHFT 0 +#define VIDC_REG_64895_OUT(v) \ + out_dword(VIDC_REG_64895_ADDR, v) + +#define VIDC_REG_965480_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e04) +#define VIDC_REG_965480_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e04) +#define VIDC_REG_965480_RMSK 0x1 +#define VIDC_REG_965480_SHFT 0 +#define VIDC_REG_965480_OUT(v) \ + out_dword(VIDC_REG_965480_ADDR, v) + +#define VIDC_REG_804959_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e08) +#define VIDC_REG_804959_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e08) +#define VIDC_REG_804959_RMSK 0x7 +#define VIDC_REG_804959_SHFT 0 +#define VIDC_REG_804959_OUT(v) \ + out_dword(VIDC_REG_804959_ADDR, v) + +#define VIDC_REG_257463_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e10) +#define VIDC_REG_257463_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e10) +#define VIDC_REG_257463_RMSK 0xffffffff +#define VIDC_REG_257463_SHFT 0 +#define VIDC_REG_257463_IN \ + in_dword_masked(VIDC_REG_257463_ADDR, \ + VIDC_REG_257463_RMSK) +#define VIDC_REG_257463_INM(m) \ + in_dword_masked(VIDC_REG_257463_ADDR, m) +#define VIDC_REG_257463_MIN_NUM_DPB_BMSK 0xffffffff +#define VIDC_REG_257463_MIN_NUM_DPB_SHFT 0 + +#define VIDC_REG_883500_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e14) +#define VIDC_REG_883500_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e14) +#define VIDC_REG_883500_RMSK 0xffffffff +#define VIDC_REG_883500_SHFT 0 +#define VIDC_REG_883500_OUT(v) \ + out_dword(VIDC_REG_883500_ADDR, v) + +#define VIDC_REG_615716_ADDR(n) \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e18 + 4 * (n)) +#define VIDC_REG_615716_PHYS(n) \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e18 + 4 * (n)) +#define VIDC_REG_615716_RMSK 0xffffffff +#define VIDC_REG_615716_SHFT 0 +#define VIDC_REG_615716_OUTI(n, v) \ + out_dword(VIDC_REG_615716_ADDR(n), v) + +#define VIDC_REG_603032_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e98) +#define VIDC_REG_603032_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e98) +#define VIDC_REG_603032_RMSK 0xffffffff +#define VIDC_REG_603032_SHFT 0 +#define VIDC_REG_603032_OUT(v) \ + out_dword(VIDC_REG_603032_ADDR, v) + +#define VIDC_REG_300310_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e9c) +#define VIDC_REG_300310_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e9c) +#define VIDC_REG_300310_RMSK 0xffffffff +#define VIDC_REG_300310_SHFT 0 +#define VIDC_REG_300310_IN \ + in_dword_masked(VIDC_REG_300310_ADDR, \ + VIDC_REG_300310_RMSK) +#define VIDC_REG_300310_INM(m) \ + in_dword_masked(VIDC_REG_300310_ADDR, m) +#define VIDC_REG_300310_ERROR_STATUS_BMSK 0xffffffff +#define VIDC_REG_300310_ERROR_STATUS_SHFT 0 + +#define VIDC_REG_792026_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ea0) +#define VIDC_REG_792026_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ea0) +#define VIDC_REG_792026_RMSK 0xffffffff +#define VIDC_REG_792026_SHFT 0 +#define VIDC_REG_792026_OUT(v) \ + out_dword(VIDC_REG_792026_ADDR, v) + +#define VIDC_REG_844152_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ea4) +#define VIDC_REG_844152_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ea4) +#define VIDC_REG_844152_RMSK 0xffffffff +#define VIDC_REG_844152_SHFT 0 +#define VIDC_REG_844152_OUT(v) \ + out_dword(VIDC_REG_844152_ADDR, v) + +#define VIDC_REG_370409_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ea8) +#define VIDC_REG_370409_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ea8) +#define VIDC_REG_370409_RMSK 0xffffffff +#define VIDC_REG_370409_SHFT 0 +#define VIDC_REG_370409_IN \ + in_dword_masked(VIDC_REG_370409_ADDR, \ + VIDC_REG_370409_RMSK) +#define VIDC_REG_370409_INM(m) \ + in_dword_masked(VIDC_REG_370409_ADDR, m) +#define VIDC_REG_370409_GET_FRAME_TAG_TOP_BMSK 0xffffffff +#define VIDC_REG_370409_GET_FRAME_TAG_TOP_SHFT 0 + +#define VIDC_REG_147682_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000eac) +#define VIDC_REG_147682_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000eac) +#define VIDC_REG_147682_RMSK 0x1 +#define VIDC_REG_147682_SHFT 0 +#define VIDC_REG_147682_OUT(v) \ + out_dword(VIDC_REG_147682_ADDR, v) + +#define VIDC_REG_407718_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000eb0) +#define VIDC_REG_407718_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000eb0) +#define VIDC_REG_407718_RMSK 0xffffffff +#define VIDC_REG_407718_SHFT 0 +#define VIDC_REG_407718_OUT(v) \ + out_dword(VIDC_REG_407718_ADDR, v) + +#define VIDC_REG_697961_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000eb4) +#define VIDC_REG_697961_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000eb4) +#define VIDC_REG_697961_RMSK 0x3 +#define VIDC_REG_697961_SHFT 0 +#define VIDC_REG_697961_IN \ + in_dword_masked(VIDC_REG_697961_ADDR, \ + VIDC_REG_697961_RMSK) +#define VIDC_REG_697961_INM(m) \ + in_dword_masked(VIDC_REG_697961_ADDR, m) +#define VIDC_REG_697961_FRAME_TYPE_BMSK 0x3 +#define VIDC_REG_697961_FRAME_TYPE_SHFT 0 + + +#define VIDC_REG_613254_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000eb8) +#define VIDC_REG_613254_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000eb8) +#define VIDC_REG_613254_RMSK 0x1 +#define VIDC_REG_613254_SHFT 0 +#define VIDC_REG_613254_IN \ + in_dword_masked(VIDC_REG_613254_ADDR, \ + VIDC_REG_613254_RMSK) +#define VIDC_REG_613254_INM(m) \ + in_dword_masked(VIDC_REG_613254_ADDR, m) +#define VIDC_REG_613254_METADATA_STATUS_BMSK 0x1 +#define VIDC_REG_613254_METADATA_STATUS_SHFT 0 +#define VIDC_REG_441270_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ebc) +#define VIDC_REG_441270_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ebc) +#define VIDC_REG_441270_RMSK 0x1f +#define VIDC_REG_441270_SHFT 0 +#define VIDC_REG_441270_IN \ + in_dword_masked(VIDC_REG_441270_ADDR, \ + VIDC_REG_441270_RMSK) +#define VIDC_REG_441270_INM(m) \ + in_dword_masked(VIDC_REG_441270_ADDR, m) +#define VIDC_REG_441270_DATA_PARTITIONED_BMSK 0x8 +#define VIDC_REG_441270_DATA_PARTITIONED_SHFT 0x3 + +#define VIDC_REG_441270_FRAME_TYPE_BMSK 0x17 +#define VIDC_REG_441270_FRAME_TYPE_SHFT 0 + +#define VIDC_REG_724381_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ec0) +#define VIDC_REG_724381_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ec0) +#define VIDC_REG_724381_RMSK 0x3 +#define VIDC_REG_724381_SHFT 0 +#define VIDC_REG_724381_IN \ + in_dword_masked(VIDC_REG_724381_ADDR, \ + VIDC_REG_724381_RMSK) +#define VIDC_REG_724381_INM(m) \ + in_dword_masked(VIDC_REG_724381_ADDR, m) +#define VIDC_REG_724381_MORE_FIELD_NEEDED_BMSK 0x4 +#define VIDC_REG_724381_MORE_FIELD_NEEDED_SHFT 0x2 +#define VIDC_REG_724381_OPERATION_FAILED_BMSK 0x2 +#define VIDC_REG_724381_OPERATION_FAILED_SHFT 0x1 +#define VIDC_REG_724381_RESOLUTION_CHANGE_BMSK 0x1 +#define VIDC_REG_724381_RESOLUTION_CHANGE_SHFT 0 + +#define VIDC_REG_854681_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ec4) +#define VIDC_REG_854681_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ec4) +#define VIDC_REG_854681_RMSK 0x7f +#define VIDC_REG_854681_SHFT 0 +#define VIDC_REG_854681_OUT(v) \ + out_dword(VIDC_REG_854681_ADDR, v) + +#define VIDC_REG_128234_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ec8) +#define VIDC_REG_128234_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ec8) +#define VIDC_REG_128234_RMSK 0xffff000f +#define VIDC_REG_128234_SHFT 0 +#define VIDC_REG_128234_OUT(v) \ + out_dword(VIDC_REG_128234_ADDR, v) + +#define VIDC_REG_1137_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ecc) +#define VIDC_REG_1137_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ecc) +#define VIDC_REG_1137_RMSK 0xffffffff +#define VIDC_REG_1137_SHFT 0 +#define VIDC_REG_1137_IN \ + in_dword_masked(VIDC_REG_1137_ADDR, \ + VIDC_REG_1137_RMSK) +#define VIDC_REG_1137_INM(m) \ + in_dword_masked(VIDC_REG_1137_ADDR, m) +#define VIDC_REG_1137_METADATA_DISPLAY_INDEX_BMSK \ + 0xffffffff +#define \ + \ +VIDC_REG_1137_METADATA_DISPLAY_INDEX_SHFT 0 + +#define VIDC_REG_988552_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ed0) +#define VIDC_REG_988552_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ed0) +#define VIDC_REG_988552_RMSK 0xffffffff +#define VIDC_REG_988552_SHFT 0 +#define VIDC_REG_988552_OUT(v) \ + out_dword(VIDC_REG_988552_ADDR, v) + +#define VIDC_REG_319934_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ed4) +#define VIDC_REG_319934_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ed4) +#define VIDC_REG_319934_RMSK 0xffffffff +#define VIDC_REG_319934_SHFT 0 +#define VIDC_REG_319934_OUT(v) \ + out_dword(VIDC_REG_319934_ADDR, v) + +#define VIDC_REG_679165_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ed8) +#define VIDC_REG_679165_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ed8) +#define VIDC_REG_679165_RMSK 0xffffffff +#define VIDC_REG_679165_SHFT 0 +#define VIDC_REG_679165_IN \ + in_dword_masked(VIDC_REG_679165_ADDR, \ + VIDC_REG_679165_RMSK) +#define VIDC_REG_679165_INM(m) \ + in_dword_masked(VIDC_REG_679165_ADDR, m) +#define VIDC_REG_679165_PIC_TIME_TOP_BMSK 0xffffffff +#define VIDC_REG_679165_PIC_TIME_TOP_SHFT 0 + +#define VIDC_REG_374150_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000edc) +#define VIDC_REG_374150_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000edc) +#define VIDC_REG_374150_RMSK 0xffffffff +#define VIDC_REG_374150_SHFT 0 +#define VIDC_REG_374150_IN \ + in_dword_masked(VIDC_REG_374150_ADDR, \ + VIDC_REG_374150_RMSK) +#define VIDC_REG_374150_INM(m) \ + in_dword_masked(VIDC_REG_374150_ADDR, m) +#define VIDC_REG_374150_PIC_TIME_BOTTOM_BMSK 0xffffffff +#define VIDC_REG_374150_PIC_TIME_BOTTOM_SHFT 0 + +#define VIDC_REG_94750_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ee0) +#define VIDC_REG_94750_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ee0) +#define VIDC_REG_94750_RMSK 0xffffffff +#define VIDC_REG_94750_SHFT 0 +#define VIDC_REG_94750_OUT(v) \ + out_dword(VIDC_REG_94750_ADDR, v) + +#define VIDC_REG_438677_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ee4) +#define VIDC_REG_438677_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ee4) +#define VIDC_REG_438677_RMSK 0xffffffff +#define VIDC_REG_438677_SHFT 0 +#define VIDC_REG_438677_IN \ + in_dword_masked(VIDC_REG_438677_ADDR, \ + VIDC_REG_438677_RMSK) +#define VIDC_REG_438677_INM(m) \ + in_dword_masked(VIDC_REG_438677_ADDR, m) +#define VIDC_REG_438677_GET_FRAME_TAG_BOTTOM_BMSK 0xffffffff +#define VIDC_REG_438677_GET_FRAME_TAG_BOTTOM_SHFT 0 + +#define VIDC_REG_76706_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ee8) +#define VIDC_REG_76706_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ee8) +#define VIDC_REG_76706_RMSK 0x1 +#define VIDC_REG_76706_SHFT 0 +#define VIDC_REG_76706_OUT(v) \ + out_dword(VIDC_REG_76706_ADDR, v) + +#define VIDC_REG_809984_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00001000) +#define VIDC_REG_809984_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00001000) +#define VIDC_REG_809984_RMSK 0xffff0007 +#define VIDC_REG_809984_SHFT 0 +#define VIDC_REG_809984_IN \ + in_dword_masked(VIDC_REG_809984_ADDR, VIDC_REG_809984_RMSK) +#define VIDC_REG_809984_INM(m) \ + in_dword_masked(VIDC_REG_809984_ADDR, m) +#define VIDC_REG_809984_720PV_720P_WRAPPER_VERSION_BMSK 0xffff0000 +#define VIDC_REG_809984_720PV_720P_WRAPPER_VERSION_SHFT 0x10 +#define VIDC_REG_809984_TEST_MUX_SEL_BMSK 0x7 +#define VIDC_REG_809984_TEST_MUX_SEL_SHFT 0 + + +#define VIDC_REG_699747_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d0c) +#define VIDC_REG_699747_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d0c) +#define VIDC_REG_699747_RMSK 0xffffffff +#define VIDC_REG_699747_SHFT 0 +#define VIDC_REG_699747_OUT(v) \ + out_dword(VIDC_REG_699747_ADDR, v) + +#define VIDC_REG_166247_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d10) +#define VIDC_REG_166247_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d10) +#define VIDC_REG_166247_RMSK 0xffffffff +#define VIDC_REG_166247_SHFT 0 +#define VIDC_REG_166247_OUT(v) \ + out_dword(VIDC_REG_166247_ADDR, v) + +#define VIDC_REG_486169_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d18) +#define VIDC_REG_486169_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d18) +#define VIDC_REG_486169_RMSK 0xffffffff +#define VIDC_REG_486169_SHFT 0 +#define VIDC_REG_486169_OUT(v) \ + out_dword(VIDC_REG_486169_ADDR, v) + +#define VIDC_REG_926519_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d1c) +#define VIDC_REG_926519_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d1c) +#define VIDC_REG_926519_RMSK 0xffffffff +#define VIDC_REG_926519_SHFT 0 +#define VIDC_REG_926519_OUT(v) \ + out_dword(VIDC_REG_926519_ADDR, v) + +/** List all the levels and their register valus */ + +#define VIDC_720P_PROFILE_MPEG4_SP 0 +#define VIDC_720P_PROFILE_MPEG4_ASP 1 +#define VIDC_720P_PROFILE_H264_BASELINE 0 +#define VIDC_720P_PROFILE_H264_MAIN 1 +#define VIDC_720P_PROFILE_H264_HIGH 2 +#define VIDC_720P_PROFILE_H264_CPB 3 +#define VIDC_720P_PROFILE_H263_BASELINE 0 + +#define VIDC_720P_PROFILE_VC1_SP 0 +#define VIDC_720P_PROFILE_VC1_MAIN 1 +#define VIDC_720P_PROFILE_VC1_ADV 2 +#define VIDC_720P_PROFILE_MPEG2_MAIN 4 +#define VIDC_720P_PROFILE_MPEG2_SP 5 + +#define VIDC_720P_MPEG4_LEVEL0 0 +#define VIDC_720P_MPEG4_LEVEL0b 9 +#define VIDC_720P_MPEG4_LEVEL1 1 +#define VIDC_720P_MPEG4_LEVEL2 2 +#define VIDC_720P_MPEG4_LEVEL3 3 +#define VIDC_720P_MPEG4_LEVEL3b 7 +#define VIDC_720P_MPEG4_LEVEL4a 4 +#define VIDC_720P_MPEG4_LEVEL5 5 +#define VIDC_720P_MPEG4_LEVEL6 6 + +#define VIDC_720P_H264_LEVEL1 10 +#define VIDC_720P_H264_LEVEL1b 9 +#define VIDC_720P_H264_LEVEL1p1 11 +#define VIDC_720P_H264_LEVEL1p2 12 +#define VIDC_720P_H264_LEVEL1p3 13 +#define VIDC_720P_H264_LEVEL2 20 +#define VIDC_720P_H264_LEVEL2p1 21 +#define VIDC_720P_H264_LEVEL2p2 22 +#define VIDC_720P_H264_LEVEL3 30 +#define VIDC_720P_H264_LEVEL3p1 31 +#define VIDC_720P_H264_LEVEL3p2 32 + +#define VIDC_720P_H263_LEVEL10 10 +#define VIDC_720P_H263_LEVEL20 20 +#define VIDC_720P_H263_LEVEL30 30 +#define VIDC_720P_H263_LEVEL40 40 +#define VIDC_720P_H263_LEVEL45 45 +#define VIDC_720P_H263_LEVEL50 50 +#define VIDC_720P_H263_LEVEL60 60 +#define VIDC_720P_H263_LEVEL70 70 + +#define VIDC_720P_VC1_LEVEL_LOW 0 +#define VIDC_720P_VC1_LEVEL_MED 2 +#define VIDC_720P_VC1_LEVEL_HIGH 4 +#define VIDC_720P_VC1_LEVEL0 0 +#define VIDC_720P_VC1_LEVEL1 1 +#define VIDC_720P_VC1_LEVEL2 2 +#define VIDC_720P_VC1_LEVEL3 3 +#define VIDC_720P_VC1_LEVEL4 4 + +#define VIDCL_720P_MPEG2_LEVEL_LOW 10 +#define VIDCL_720P_MPEG2_LEVEL_MAIN 8 +#define VIDCL_720P_MPEG2_LEVEL_HIGH14 6 + +#define VIDC_720P_CMD_CHSET 0x0 +#define VIDC_720P_CMD_CHEND 0x2 +#define VIDC_720P_CMD_INITCODEC 0x3 +#define VIDC_720P_CMD_FRAMERUN 0x4 +#define VIDC_720P_CMD_INITBUFFERS 0x5 +#define VIDC_720P_CMD_FRAMERUN_REALLOCATE 0x6 +#define VIDC_720P_CMD_MFC_ENGINE_RESET 0x7 + +enum vidc_720p_endian { + VIDC_720P_BIG_ENDIAN = 0x0, + VIDC_720P_LITTLE_ENDIAN = 0x1 +}; + +enum vidc_720p_memory_access_method { + VIDC_720P_TILE_LINEAR = 0, + VIDC_720P_TILE_16x16 = 2, + VIDC_720P_TILE_64x32 = 3 +}; + +enum vidc_720p_interrupt_control_mode { + VIDC_720P_INTERRUPT_MODE = 0, + VIDC_720P_POLL_MODE = 1 +}; + +enum vidc_720p_interrupt_level_selection { + VIDC_720P_INTERRUPT_LEVEL_SEL = 0, + VIDC_720P_INTERRUPT_PULSE_SEL = 1 +}; + +#define VIDC_720P_INTR_BUFFER_FULL 0x002 +#define VIDC_720P_INTR_FW_DONE 0x020 +#define VIDC_720P_INTR_HEADER_DONE 0x040 +#define VIDC_720P_INTR_DMA_DONE 0x080 +#define VIDC_720P_INTR_FRAME_DONE 0x100 + +enum vidc_720p_enc_dec_selection { + VIDC_720P_DECODER = 0, + VIDC_720P_ENCODER = 1 +}; + +enum vidc_720p_codec { + VIDC_720P_MPEG4 = 0, + VIDC_720P_H264 = 1, + VIDC_720P_DIVX = 2, + VIDC_720P_XVID = 3, + VIDC_720P_H263 = 4, + VIDC_720P_MPEG2 = 5, + VIDC_720P_VC1 = 6 +}; + +enum vidc_720p_frame { + VIDC_720P_NOTCODED = 0, + VIDC_720P_IFRAME = 1, + VIDC_720P_PFRAME = 2, + VIDC_720P_BFRAME = 3, + VIDC_720P_IDRFRAME = 4 +}; + +enum vidc_720p_entropy_sel { + VIDC_720P_ENTROPY_SEL_CAVLC = 0, + VIDC_720P_ENTROPY_SEL_CABAC = 1 +}; + +enum vidc_720p_cabac_model { + VIDC_720P_CABAC_MODEL_NUMBER_0 = 0, + VIDC_720P_CABAC_MODEL_NUMBER_1 = 1, + VIDC_720P_CABAC_MODEL_NUMBER_2 = 2 +}; + +enum vidc_720p_DBConfig { + VIDC_720P_DB_ALL_BLOCKING_BOUNDARY = 0, + VIDC_720P_DB_DISABLE = 1, + VIDC_720P_DB_SKIP_SLICE_BOUNDARY = 2 +}; + +enum vidc_720p_MSlice_selection { + VIDC_720P_MSLICE_BY_MB_COUNT = 0, + VIDC_720P_MSLICE_BY_BYTE_COUNT = 1, + VIDC_720P_MSLICE_BY_GOB = 2, + VIDC_720P_MSLICE_OFF = 3 +}; + +enum vidc_720p_display_status { + VIDC_720P_DECODE_ONLY = 0, + VIDC_720P_DECODE_AND_DISPLAY = 1, + VIDC_720P_DISPLAY_ONLY = 2, + VIDC_720P_EMPTY_BUFFER = 3 +}; + +#define VIDC_720P_ENC_IFRAME_REQ 0x1 +#define VIDC_720P_ENC_IPERIOD_CHANGE 0x1 +#define VIDC_720P_ENC_FRAMERATE_CHANGE 0x2 +#define VIDC_720P_ENC_BITRATE_CHANGE 0x4 + +#define VIDC_720P_FLUSH_REQ 0x1 +#define VIDC_720P_EXTRADATA 0x2 + +#define VIDC_720P_METADATA_ENABLE_QP 0x01 +#define VIDC_720P_METADATA_ENABLE_CONCEALMB 0x02 +#define VIDC_720P_METADATA_ENABLE_VC1 0x04 +#define VIDC_720P_METADATA_ENABLE_SEI 0x08 +#define VIDC_720P_METADATA_ENABLE_VUI 0x10 +#define VIDC_720P_METADATA_ENABLE_ENCSLICE 0x20 +#define VIDC_720P_METADATA_ENABLE_PASSTHROUGH 0x40 + +struct vidc_720p_dec_disp_info { + enum vidc_720p_display_status disp_status; + u32 resl_change; + u32 reconfig_flush_done; + u32 img_size_x; + u32 img_size_y; + u32 y_addr; + u32 c_addr; + u32 tag_top; + u32 pic_time_top; + u32 disp_is_interlace; + u32 tag_bottom; + u32 pic_time_bottom; + u32 metadata_exists; + u32 crop_exists; + u32 crop_right_offset; + u32 crop_left_offset; + u32 crop_bottom_offset; + u32 crop_top_offset; + u32 input_frame; + u32 input_bytes_consumed; + u32 input_is_interlace; + u32 input_frame_num; +}; + +struct vidc_720p_seq_hdr_info { + u32 img_size_x; + u32 img_size_y; + u32 dec_frm_size; + u32 min_num_dpb; + u32 min_dpb_size; + u32 profile; + u32 level; + u32 progressive; + u32 data_partitioned; + u32 crop_exists; + u32 crop_right_offset; + u32 crop_left_offset; + u32 crop_bottom_offset; + u32 crop_top_offset; +}; + +struct vidc_720p_enc_frame_info { + u32 enc_size; + u32 frame; + u32 metadata_exists; +}; + +void vidc_720p_set_device_virtual_base(u8 *core_virtual_base_addr); + +void vidc_720p_init(char **ppsz_version, u32 i_firmware_size, + u32 *pi_firmware_address, enum vidc_720p_endian dma_endian, + u32 interrupt_off, + enum vidc_720p_interrupt_level_selection interrupt_sel, + u32 interrupt_mask); + +u32 vidc_720p_do_sw_reset(void); + +u32 vidc_720p_reset_is_success(void); + +void vidc_720p_start_cpu(enum vidc_720p_endian dma_endian, + u32 *icontext_bufferstart, u32 *debug_core_dump_addr, + u32 debug_buffer_size); + +u32 vidc_720p_cpu_start(void); + +void vidc_720p_stop_fw(void); + +void vidc_720p_get_interrupt_status(u32 *interrupt_status, + u32 *cmd_err_status, u32 *disp_pic_err_status, + u32 *op_failed); + +void vidc_720p_interrupt_done_clear(void); + +void vidc_720p_submit_command(u32 ch_id, u32 cmd_id); + + +void vidc_720p_set_channel(u32 i_ch_id, + enum vidc_720p_enc_dec_selection enc_dec_sel, + enum vidc_720p_codec codec, u32 *pi_fw, u32 i_firmware_size); + +u32 vidc_720p_engine_reset(u32 ch_id, + enum vidc_720p_endian dma_endian, + enum vidc_720p_interrupt_level_selection interrupt_sel, + u32 interrupt_mask +); + +void vidc_720p_encode_set_profile(u32 i_profile, u32 i_level); + +void vidc_720p_set_frame_size(u32 i_size_x, u32 i_size_y); + +void vidc_720p_encode_set_fps(u32 i_rc_frame_rate); + +void vidc_720p_encode_set_vop_time(u32 vop_time_resolution, + u32 vop_time_increment); + +void vidc_720p_encode_set_hec_period(u32 hec_period); + +void vidc_720p_encode_set_short_header(u32 i_short_header); + +void vidc_720p_encode_set_qp_params(u32 i_max_qp, u32 i_min_qp); + +void vidc_720p_encode_set_rc_config(u32 enable_frame_level_rc, + u32 enable_mb_level_rc_flag, u32 i_frame_qp, u32 pframe_qp); + +void vidc_720p_encode_set_bit_rate(u32 i_target_bitrate); + +void vidc_720p_encoder_set_param_change(u32 enc_param_change); + +void vidc_720p_encode_set_control_param(u32 param_val); + +void vidc_720p_encode_set_frame_level_rc_params(u32 i_reaction_coeff); + +void vidc_720p_encode_set_mb_level_rc_params(u32 dark_region_as_flag, + u32 smooth_region_as_flag, u32 static_region_as_flag, + u32 activity_region_flag); + +void vidc_720p_encode_set_entropy_control(enum vidc_720p_entropy_sel \ + entropy_sel, + enum vidc_720p_cabac_model cabac_model_number); + +void vidc_720p_encode_set_db_filter_control(enum vidc_720p_DBConfig + db_config, u32 i_slice_alpha_offset, u32 i_slice_beta_offset); + +void vidc_720p_encode_set_intra_refresh_mb_number(u32 i_cir_mb_number); + +void vidc_720p_encode_set_multi_slice_info( + enum vidc_720p_MSlice_selection m_slice_sel, + u32 multi_slice_size); + +void vidc_720p_encode_set_dpb_buffer(u32 *pi_enc_dpb_addr, u32 alloc_len); + +void vidc_720p_set_deblock_line_buffer(u32 *pi_deblock_line_buffer_start, + u32 alloc_len); + +void vidc_720p_encode_set_i_period(u32 i_i_period); + +void vidc_720p_encode_init_codec(u32 i_ch_id, + enum vidc_720p_memory_access_method memory_access_model); + +void vidc_720p_encode_unalign_bitstream(u32 upper_unalign_word, + u32 lower_unalign_word); + +void vidc_720p_encode_set_seq_header_buffer(u32 ext_buffer_start, + u32 ext_buffer_end, u32 start_byte_num); + +void vidc_720p_encode_frame(u32 ch_id, u32 ext_buffer_start, + u32 ext_buffer_end, u32 start_byte_number, + u32 y_addr, u32 c_addr); + +void vidc_720p_encode_get_header(u32 *pi_enc_header_size); + +void vidc_720p_enc_frame_info + (struct vidc_720p_enc_frame_info *enc_frame_info); + +void vidc_720p_decode_bitstream_header(u32 ch_id, u32 dec_unit_size, + u32 start_byte_num, u32 ext_buffer_start, u32 ext_buffer_end, + enum vidc_720p_memory_access_method memory_access_model, + u32 decode_order); + +void vidc_720p_decode_get_seq_hdr_info + (struct vidc_720p_seq_hdr_info *seq_hdr_info); + +void vidc_720p_decode_set_dpb_release_buffer_mask + (u32 i_dpb_release_buffer_mask); + +void vidc_720p_decode_set_dpb_buffers(u32 i_buf_index, u32 *pi_dpb_buffer); + +void vidc_720p_decode_set_comv_buffer + (u32 *pi_dpb_comv_buffer, u32 alloc_len); + +void vidc_720p_decode_set_dpb_details + (u32 num_dpb, u32 alloc_len, u32 *ref_buffer); + +void vidc_720p_decode_set_mpeg4Post_filter(u32 enable_post_filter); + +void vidc_720p_decode_set_error_control(u32 enable_error_control); + +void vidc_720p_decode_set_mpeg4_data_partitionbuffer(u32 *vsp_buf_start); + +void vidc_720p_decode_setH264VSPBuffer(u32 *pi_vsp_temp_buffer_start); + +void vidc_720p_decode_frame(u32 ch_id, u32 ext_buffer_start, + u32 ext_buffer_end, u32 dec_unit_size, + u32 start_byte_num, u32 input_frame_tag); + +void vidc_720p_issue_eos(u32 i_ch_id); +void vidc_720p_eos_info(u32 *disp_status, u32 *resl_change); + +void vidc_720p_decode_display_info + (struct vidc_720p_dec_disp_info *disp_info); + +void vidc_720p_decode_skip_frm_details(u32 *free_luma_dpb); + +void vidc_720p_metadata_enable(u32 flag, u32 *input_buffer); + +void vidc_720p_decode_dynamic_req_reset(void); + +void vidc_720p_decode_dynamic_req_set(u32 property); + +void vidc_720p_decode_setpassthrough_start(u32 pass_startaddr); + + + +#define DDL_720P_REG_BASE VIDC_720P_WRAPPER_REG_BASE +#define VIDC_BUSY_WAIT(n) udelay(n) + +#undef VIDC_REGISTER_LOG_MSG +#undef VIDC_REGISTER_LOG_INTO_BUFFER + +#ifdef VIDC_REGISTER_LOG_MSG +#define VIDC_MSG1(msg_format, a) printk(KERN_INFO msg_format, a) +#define VIDC_MSG2(msg_format, a, b) printk(KERN_INFO msg_format, a, b) +#define VIDC_MSG3(msg_format, a, b, c) printk(KERN_INFO msg_format, a, b, c) +#else +#define VIDC_MSG1(msg_format, a) +#define VIDC_MSG2(msg_format, a, b) +#define VIDC_MSG3(msg_format, a, b, c) +#endif + +#ifdef VIDC_REGISTER_LOG_INTO_BUFFER + +#define VIDC_REGLOG_BUFSIZE 200000 +#define VIDC_REGLOG_MAX_PRINT_SIZE 100 +extern char vidclog[VIDC_REGLOG_BUFSIZE]; +extern unsigned int vidclog_index; + +#define VIDC_LOG_BUFFER_INIT \ +{if (vidclog_index) \ + memset(vidclog, 0, vidclog_index+1); \ + vidclog_index = 0; } + +#define VIDC_REGLOG_CHECK_BUFINDEX(req_size) \ + vidclog_index = \ + (vidclog_index+(req_size) < VIDC_REGLOG_BUFSIZE) ? vidclog_index : 0; + +#define VIDC_LOG_WRITE(reg, val) \ +{unsigned int len; \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \ + "(0x%x:"#reg"=0x%x)" , VIDC_##reg##_ADDR - DDL_720P_REG_BASE, val);\ + vidclog_index += len; } + +#define VIDC_LOG_WRITEI(reg, index, val) \ +{unsigned int len; \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \ + "(0x%x:"#reg"=0x%x)" , VIDC_##reg##_ADDR(index)-DDL_720P_REG_BASE, \ + val); vidclog_index += len; } + +#define VIDC_LOG_WRITEF(reg, field, val) \ +{unsigned int len; \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \ + "(0x%x:"#reg":0x%x:=0x%x)" , VIDC_##reg##_ADDR - DDL_720P_REG_BASE, \ + VIDC_##reg##_##field##_BMSK, val);\ + vidclog_index += len; } + +#define VIDC_LOG_READ(reg, pval) \ +{ unsigned int len; \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \ + "(0x%x:"#reg"==0x%x)" , VIDC_##reg##_ADDR - DDL_720P_REG_BASE, \ + (u32)*pval); \ + vidclog_index += len; } + +#define VIDC_STR_LOGBUFFER(str) \ +{ unsigned int len; \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \ + "<%s>" , str); vidclog_index += len; } + +#define VIDC_LONG_LOGBUFFER(str, arg1) \ +{ unsigned int len; \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \ + "<%s=0x%x>" , str, arg1); vidclog_index += len; } + +#define VIDC_DEBUG_REGISTER_LOG \ +{ u32 val; unsigned int len; \ + val = VIDC_720P_IN(REG_881638); \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], 50, "[dbg1=%x]" , val); \ + vidclog_index += len; \ + val = VIDC_720P_IN(REG_161486); \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], 50, "[dbg2=%x]" , val); \ + vidclog_index += len; } + +#else +#define VIDC_LOG_WRITE(reg, val) +#define VIDC_LOG_WRITEI(reg, index, val) +#define VIDC_LOG_WRITEF(reg, field, val) +#define VIDC_LOG_READ(reg, pval) +#define VIDC_LOG_BUFFER_INIT +#define VIDC_STR_LOGBUFFER(str) +#define VIDC_LONG_LOGBUFFER(str, arg1) +#define VIDC_DEBUG_REGISTER_LOG +#endif + +void vidcputlog(char *str); +void vidcput_debug_reglog(void); + +#define VIDC_LOGERR_STRING(str) \ +do { \ + VIDC_STR_LOGBUFFER(str); \ + VIDC_MSG1("\n<%s>", str); \ +} while (0) + +#define VIDC_LOG_STRING(str) \ +do { \ + VIDC_STR_LOGBUFFER(str); \ + VIDC_MSG1("\n<%s>", str); \ +} while (0) + +#define VIDC_LOG1(str, arg1) \ +do { \ + VIDC_LONG_LOGBUFFER(str, arg1); \ + VIDC_MSG2("\n<%s=0x%08x>", str, arg1); \ +} while (0) + +#define VIDC_IO_OUT(reg, val) \ +do { \ + VIDC_LOG_WRITE(reg, (u32)val); \ + VIDC_MSG2("\n(0x%08x:"#reg"=0x%08x)", \ + (u32)(VIDC_##reg##_ADDR - DDL_720P_REG_BASE), (u32)val); \ + mb(); \ + VIDC_720P_OUT(reg, val); \ +} while (0) + +#define VIDC_IO_OUTI(reg, index, val) \ +do { \ + VIDC_LOG_WRITEI(reg, index, (u32)val); \ + VIDC_MSG2("\n(0x%08x:"#reg"=0x%08x)", \ + (u32)(VIDC_##reg##_ADDR(index)-DDL_720P_REG_BASE), (u32)val); \ + mb(); \ + VIDC_720P_OUTI(reg, index, val); \ +} while (0) + +#define VIDC_IO_OUTF(reg, field, val) \ +do { \ + VIDC_LOG_WRITEF(reg, field, val); \ + VIDC_MSG3("\n(0x%08x:"#reg":0x%x:=0x%08x)", \ + (u32)(VIDC_##reg##_ADDR - DDL_720P_REG_BASE), \ + VIDC_##reg##_##field##_BMSK, (u32)val); \ + mb(); \ + VIDC_720P_OUTF(reg, field, val); \ +} while (0) + +#define VIDC_IO_IN(reg, pval) \ +do { \ + mb(); \ + *pval = (u32) VIDC_720P_IN(reg); \ + VIDC_LOG_READ(reg, pval); \ + VIDC_MSG2("\n(0x%08x:"#reg"==0x%08x)", \ + (u32)(VIDC_##reg##_ADDR - DDL_720P_REG_BASE), (u32) *pval); \ +} while (0) + +#define VIDC_IO_INF(reg, mask, pval) \ +do { \ + mb(); \ + *pval = VIDC_720P_INF(reg, mask); \ + VIDC_LOG_READ(reg, pval); \ + VIDC_MSG2("\n(0x%08x:"#reg"==0x%08x)", \ + (u32)(VIDC_##reg##_ADDR - DDL_720P_REG_BASE), *pval); \ +} while (0) + +#endif diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c new file mode 100644 index 0000000000000000000000000000000000000000..79b2e673a43a5399712564adc0edc15f46940bdc --- /dev/null +++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c @@ -0,0 +1,771 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "vcd_res_tracker.h" + +#define MSM_AXI_QOS_NAME "msm_vidc_reg" +#define AXI_CLK_SCALING + +#define QVGA_PERF_LEVEL (300 * 30) +#define VGA_PERF_LEVEL (1200 * 30) +#define WVGA_PERF_LEVEL (1500 * 30) + +static unsigned int mfc_clk_freq_table[3] = { + 61440000, 122880000, 170667000 +}; + +static unsigned int axi_clk_freq_table_enc[2] = { + 122880, 192000 +}; +static unsigned int axi_clk_freq_table_dec[2] = { + 122880, 192000 +}; + +static struct res_trk_context resource_context; + +#define VIDC_BOOT_FW "vidc_720p_command_control.fw" +#define VIDC_MPG4_DEC_FW "vidc_720p_mp4_dec_mc.fw" +#define VIDC_H263_DEC_FW "vidc_720p_h263_dec_mc.fw" +#define VIDC_H264_DEC_FW "vidc_720p_h264_dec_mc.fw" +#define VIDC_MPG4_ENC_FW "vidc_720p_mp4_enc_mc.fw" +#define VIDC_H264_ENC_FW "vidc_720p_h264_enc_mc.fw" +#define VIDC_VC1_DEC_FW "vidc_720p_vc1_dec_mc.fw" + +unsigned char *vidc_command_control_fw; +u32 vidc_command_control_fw_size; + +unsigned char *vidc_mpg4_dec_fw; +u32 vidc_mpg4_dec_fw_size; + +unsigned char *vidc_h263_dec_fw; +u32 vidc_h263_dec_fw_size; + +unsigned char *vidc_h264_dec_fw; +u32 vidc_h264_dec_fw_size; + +unsigned char *vidc_mpg4_enc_fw; +u32 vidc_mpg4_enc_fw_size; + +unsigned char *vidc_h264_enc_fw; +u32 vidc_h264_enc_fw_size; + +unsigned char *vidc_vc1_dec_fw; +u32 vidc_vc1_dec_fw_size; + +static u32 res_trk_disable_videocore(void) +{ + int rc = -1; + mutex_lock(&resource_context.lock); + + if (!resource_context.rail_enabled) { + mutex_unlock(&resource_context.lock); + return false; + } + + if (!resource_context.clock_enabled && + resource_context.pclk && + resource_context.hclk && + resource_context.hclk_div2) { + + VCDRES_MSG_LOW("\nEnabling clk before disabling pwr rail\n"); + if (clk_set_rate(resource_context.hclk, + mfc_clk_freq_table[0])) { + VCDRES_MSG_ERROR("\n pwr_rail_disable:" + " set clk rate failed\n"); + goto bail_out; + } + + if (clk_prepare_enable(resource_context.pclk)) { + VCDRES_MSG_ERROR("vidc pclk Enable failed\n"); + goto bail_out; + } + + if (clk_prepare_enable(resource_context.hclk)) { + VCDRES_MSG_ERROR("vidc hclk Enable failed\n"); + goto disable_pclk; + } + + if (clk_prepare_enable(resource_context.hclk_div2)) { + VCDRES_MSG_ERROR("vidc hclk_div2 Enable failed\n"); + goto disable_hclk; + } + } else { + VCDRES_MSG_ERROR("\ndisabling pwr rail: Enabling clk failed\n"); + goto bail_out; + } + + resource_context.rail_enabled = 0; + rc = clk_reset(resource_context.pclk, CLK_RESET_ASSERT); + if (rc) { + VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc); + mutex_unlock(&resource_context.lock); + return false; + } + msleep(20); + + clk_disable_unprepare(resource_context.pclk); + clk_disable_unprepare(resource_context.hclk); + clk_disable_unprepare(resource_context.hclk_div2); + + clk_put(resource_context.hclk_div2); + clk_put(resource_context.hclk); + clk_put(resource_context.pclk); + + rc = regulator_disable(resource_context.regulator); + if (rc) { + VCDRES_MSG_ERROR("\n regulator disable failed %d\n", rc); + mutex_unlock(&resource_context.lock); + return false; + } + + resource_context.hclk_div2 = NULL; + resource_context.hclk = NULL; + resource_context.pclk = NULL; + + mutex_unlock(&resource_context.lock); + + return true; + +disable_hclk: + clk_disable_unprepare(resource_context.hclk); +disable_pclk: + clk_disable_unprepare(resource_context.pclk); +bail_out: + if (resource_context.pclk) { + clk_put(resource_context.pclk); + resource_context.pclk = NULL; + } + if (resource_context.hclk) { + clk_put(resource_context.hclk); + resource_context.hclk = NULL; + } + if (resource_context.hclk_div2) { + clk_put(resource_context.hclk_div2); + resource_context.hclk_div2 = NULL; + } + mutex_unlock(&resource_context.lock); + return false; +} + +u32 res_trk_enable_clocks(void) +{ + VCDRES_MSG_LOW("\n in res_trk_enable_clocks()"); + + mutex_lock(&resource_context.lock); + if (!resource_context.clock_enabled) { + VCDRES_MSG_LOW("Enabling IRQ in %s()\n", __func__); + enable_irq(resource_context.irq_num); + + VCDRES_MSG_LOW("%s(): Enabling the clocks ...\n", __func__); + + if (clk_prepare_enable(resource_context.pclk)) { + VCDRES_MSG_ERROR("vidc pclk Enable failed\n"); + + clk_put(resource_context.hclk); + clk_put(resource_context.hclk_div2); + mutex_unlock(&resource_context.lock); + return false; + } + + if (clk_prepare_enable(resource_context.hclk)) { + VCDRES_MSG_ERROR("vidc hclk Enable failed\n"); + clk_put(resource_context.pclk); + clk_put(resource_context.hclk_div2); + mutex_unlock(&resource_context.lock); + return false; + } + + if (clk_prepare_enable(resource_context.hclk_div2)) { + VCDRES_MSG_ERROR("vidc hclk Enable failed\n"); + clk_put(resource_context.hclk); + clk_put(resource_context.pclk); + mutex_unlock(&resource_context.lock); + return false; + } + } + + resource_context.clock_enabled = 1; + mutex_unlock(&resource_context.lock); + return true; +} + +static u32 res_trk_sel_clk_rate(unsigned long hclk_rate) +{ + mutex_lock(&resource_context.lock); + if (clk_set_rate(resource_context.hclk, + hclk_rate)) { + VCDRES_MSG_ERROR("vidc hclk set rate failed\n"); + mutex_unlock(&resource_context.lock); + return false; + } + resource_context.hclk_rate = hclk_rate; + mutex_unlock(&resource_context.lock); + return true; +} + +static u32 res_trk_get_clk_rate(unsigned long *phclk_rate) +{ + if (!phclk_rate) { + VCDRES_MSG_ERROR("%s(): phclk_rate is NULL\n", __func__); + return false; + } + mutex_lock(&resource_context.lock); + *phclk_rate = clk_get_rate(resource_context.hclk); + if (!(*phclk_rate)) { + VCDRES_MSG_ERROR("vidc hclk get rate failed\n"); + mutex_unlock(&resource_context.lock); + return false; + } + mutex_unlock(&resource_context.lock); + return true; +} + +u32 res_trk_disable_clocks(void) +{ + VCDRES_MSG_LOW("in res_trk_disable_clocks()\n"); + + mutex_lock(&resource_context.lock); + + if (!resource_context.clock_enabled) { + mutex_unlock(&resource_context.lock); + return false; + } + + VCDRES_MSG_LOW("Disabling IRQ in %s()\n", __func__); + disable_irq_nosync(resource_context.irq_num); + VCDRES_MSG_LOW("%s(): Disabling the clocks ...\n", __func__); + + resource_context.clock_enabled = 0; + clk_disable_unprepare(resource_context.hclk); + clk_disable_unprepare(resource_context.hclk_div2); + clk_disable_unprepare(resource_context.pclk); + mutex_unlock(&resource_context.lock); + + return true; +} + +static u32 res_trk_enable_videocore(void) +{ + mutex_lock(&resource_context.lock); + if (!resource_context.rail_enabled) { + int rc = -1; + + rc = regulator_enable(resource_context.regulator); + if (rc) { + VCDRES_MSG_ERROR("%s(): regulator_enable failed %d\n", + __func__, rc); + goto bail_out; + } + VCDRES_MSG_LOW("%s(): regulator enable Success %d\n", + __func__, rc); + + resource_context.pclk = clk_get(resource_context.device, + "iface_clk"); + + if (IS_ERR(resource_context.pclk)) { + VCDRES_MSG_ERROR("%s(): iface_clk get failed\n" + , __func__); + goto disable_regulator; + } + + resource_context.hclk = clk_get(resource_context.device, + "core_clk"); + + if (IS_ERR(resource_context.hclk)) { + VCDRES_MSG_ERROR("%s(): core_clk get failed\n" + , __func__); + + goto release_pclk; + } + + resource_context.hclk_div2 = + clk_get(resource_context.device, "core_div2_clk"); + + if (IS_ERR(resource_context.hclk_div2)) { + VCDRES_MSG_ERROR("%s(): core_div2_clk get failed\n" + , __func__); + goto release_hclk_pclk; + } + + if (clk_set_rate(resource_context.hclk, + mfc_clk_freq_table[0])) { + VCDRES_MSG_ERROR("\n pwr_rail_enable:" + " set clk rate failed\n"); + goto release_all_clks; + } + + if (clk_prepare_enable(resource_context.pclk)) { + VCDRES_MSG_ERROR("vidc pclk Enable failed\n"); + goto release_all_clks; + } + + if (clk_prepare_enable(resource_context.hclk)) { + VCDRES_MSG_ERROR("vidc hclk Enable failed\n"); + goto disable_pclk; + } + + if (clk_prepare_enable(resource_context.hclk_div2)) { + VCDRES_MSG_ERROR("vidc hclk_div2 Enable failed\n"); + goto disable_hclk_pclk; + } + + rc = clk_reset(resource_context.pclk, CLK_RESET_DEASSERT); + if (rc) { + VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc); + goto disable_and_release_all_clks; + } + msleep(20); + + clk_disable_unprepare(resource_context.pclk); + clk_disable_unprepare(resource_context.hclk); + clk_disable_unprepare(resource_context.hclk_div2); + + } + resource_context.rail_enabled = 1; + mutex_unlock(&resource_context.lock); + return true; + +disable_and_release_all_clks: + clk_disable_unprepare(resource_context.hclk_div2); +disable_hclk_pclk: + clk_disable_unprepare(resource_context.hclk); +disable_pclk: + clk_disable_unprepare(resource_context.pclk); +release_all_clks: + clk_put(resource_context.hclk_div2); + resource_context.hclk_div2 = NULL; +release_hclk_pclk: + clk_put(resource_context.hclk); + resource_context.hclk = NULL; +release_pclk: + clk_put(resource_context.pclk); + resource_context.pclk = NULL; +disable_regulator: + regulator_disable(resource_context.regulator); +bail_out: + mutex_unlock(&resource_context.lock); + return false; +} + +static u32 res_trk_convert_freq_to_perf_lvl(u64 freq) +{ + u64 perf_lvl; + u64 temp; + + VCDRES_MSG_MED("\n %s():: freq = %u\n", __func__, (u32)freq); + + if (!freq) + return 0; + + temp = freq * 1000; + do_div(temp, VCD_RESTRK_HZ_PER_1000_PERFLVL); + perf_lvl = (u32)temp; + VCDRES_MSG_MED("\n %s(): perf_lvl = %u\n", __func__, + (u32)perf_lvl); + + return (u32)perf_lvl; +} + +static u32 res_trk_convert_perf_lvl_to_freq(u64 perf_lvl) +{ + u64 freq, temp; + + VCDRES_MSG_MED("\n %s():: perf_lvl = %u\n", __func__, + (u32)perf_lvl); + temp = (perf_lvl * VCD_RESTRK_HZ_PER_1000_PERFLVL) + 999; + do_div(temp, 1000); + freq = (u32)temp; + VCDRES_MSG_MED("\n %s(): freq = %u\n", __func__, (u32)freq); + + return (u32)freq; +} + +static struct clk *ebi1_clk; + +u32 res_trk_power_up(void) +{ + VCDRES_MSG_LOW("clk_regime_rail_enable"); + VCDRES_MSG_LOW("clk_regime_sel_rail_control"); +#ifdef AXI_CLK_SCALING +{ + VCDRES_MSG_MED("\n res_trk_power_up():: " + "Calling AXI add requirement\n"); + ebi1_clk = clk_get(resource_context.device, "mem_clk"); + if (IS_ERR(ebi1_clk)) { + VCDRES_MSG_ERROR("Request AXI bus QOS fails."); + return false; + } + clk_prepare_enable(ebi1_clk); +} +#endif + + VCDRES_MSG_MED("\n res_trk_power_up():: Calling " + "vidc_enable_pwr_rail()\n"); + return res_trk_enable_videocore(); +} + +u32 res_trk_power_down(void) +{ + VCDRES_MSG_LOW("clk_regime_rail_disable"); +#ifdef AXI_CLK_SCALING + VCDRES_MSG_MED("\n res_trk_power_down()::" + "Calling AXI remove requirement\n"); + clk_disable_unprepare(ebi1_clk); + clk_put(ebi1_clk); +#endif + VCDRES_MSG_MED("\n res_trk_power_down():: Calling " + "res_trk_disable_videocore()\n"); + return res_trk_disable_videocore(); +} + +u32 res_trk_get_max_perf_level(u32 *pn_max_perf_lvl) +{ + if (!pn_max_perf_lvl) { + VCDRES_MSG_ERROR("%s(): pn_max_perf_lvl is NULL\n", + __func__); + return false; + } + + *pn_max_perf_lvl = VCD_RESTRK_MAX_PERF_LEVEL; + return true; +} + +u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl, + struct vcd_dev_ctxt *dev_ctxt) +{ + struct vcd_clnt_ctxt *cctxt_itr = NULL; + u32 axi_freq = 0, mfc_freq = 0, calc_mfc_freq = 0; + u8 enc_clnt_present = false; + + if (!pn_set_perf_lvl || !dev_ctxt) { + VCDRES_MSG_ERROR("%s(): NULL pointer! dev_ctxt(%p)\n", + __func__, dev_ctxt); + return false; + } + + VCDRES_MSG_LOW("%s(), req_perf_lvl = %d", __func__, req_perf_lvl); + calc_mfc_freq = res_trk_convert_perf_lvl_to_freq( + (u64)req_perf_lvl); + + if (calc_mfc_freq < VCD_RESTRK_MIN_FREQ_POINT) + calc_mfc_freq = VCD_RESTRK_MIN_FREQ_POINT; + else if (calc_mfc_freq > VCD_RESTRK_MAX_FREQ_POINT) + calc_mfc_freq = VCD_RESTRK_MAX_FREQ_POINT; + + cctxt_itr = dev_ctxt->cctxt_list_head; + while (cctxt_itr) { + VCDRES_MSG_LOW("\n cctxt_itr = %p", cctxt_itr); + if (!cctxt_itr->decoding) { + VCDRES_MSG_LOW("\n Encoder client"); + enc_clnt_present = true; + break; + } else { + VCDRES_MSG_LOW("\n Decoder client"); + } + cctxt_itr = cctxt_itr->next; + } + + if (enc_clnt_present) { + if (req_perf_lvl >= VGA_PERF_LEVEL) { + mfc_freq = mfc_clk_freq_table[2]; + axi_freq = axi_clk_freq_table_enc[1]; + } else { + mfc_freq = mfc_clk_freq_table[0]; + axi_freq = axi_clk_freq_table_enc[0]; + } + VCDRES_MSG_MED("\n ENCODER: axi_freq = %u" + ", mfc_freq = %u, calc_mfc_freq = %u," + " req_perf_lvl = %u", axi_freq, + mfc_freq, calc_mfc_freq, + req_perf_lvl); + } else { + if (req_perf_lvl <= QVGA_PERF_LEVEL) { + mfc_freq = mfc_clk_freq_table[0]; + axi_freq = axi_clk_freq_table_dec[0]; + } else { + axi_freq = axi_clk_freq_table_dec[0]; + if (req_perf_lvl <= VGA_PERF_LEVEL) + mfc_freq = mfc_clk_freq_table[0]; + else if (req_perf_lvl <= WVGA_PERF_LEVEL) + mfc_freq = mfc_clk_freq_table[1]; + else { + mfc_freq = mfc_clk_freq_table[2]; + axi_freq = axi_clk_freq_table_dec[1]; + } + } + VCDRES_MSG_MED("\n DECODER: axi_freq = %u" + ", mfc_freq = %u, calc_mfc_freq = %u," + " req_perf_lvl = %u", axi_freq, + mfc_freq, calc_mfc_freq, + req_perf_lvl); + } + +#ifdef AXI_CLK_SCALING + if (req_perf_lvl != VCD_RESTRK_MIN_PERF_LEVEL) { + VCDRES_MSG_MED("\n %s(): Setting AXI freq to %u", + __func__, axi_freq); + clk_set_rate(ebi1_clk, axi_freq * 1000); + } +#endif + +#ifdef USE_RES_TRACKER + if (req_perf_lvl != VCD_RESTRK_MIN_PERF_LEVEL) { + VCDRES_MSG_MED("\n %s(): Setting MFC freq to %u", + __func__, mfc_freq); + if (!res_trk_sel_clk_rate(mfc_freq)) { + VCDRES_MSG_ERROR("%s(): res_trk_sel_clk_rate FAILED\n", + __func__); + *pn_set_perf_lvl = 0; + return false; + } + } +#endif + + *pn_set_perf_lvl = + res_trk_convert_freq_to_perf_lvl((u64) mfc_freq); + return true; +} + +u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl) +{ + unsigned long freq; + + if (!pn_perf_lvl) { + VCDRES_MSG_ERROR("%s(): pn_perf_lvl is NULL\n", + __func__); + return false; + } + VCDRES_MSG_LOW("clk_regime_msm_get_clk_freq_hz"); + if (!res_trk_get_clk_rate(&freq)) { + VCDRES_MSG_ERROR("%s(): res_trk_get_clk_rate FAILED\n", + __func__); + *pn_perf_lvl = 0; + return false; + } + + *pn_perf_lvl = res_trk_convert_freq_to_perf_lvl((u64) freq); + VCDRES_MSG_MED("%s(): freq = %lu, *pn_perf_lvl = %u", __func__, + freq, *pn_perf_lvl); + return true; +} + +u32 res_trk_download_firmware(void) +{ + const struct firmware *fw_boot = NULL; + const struct firmware *fw_mpg4_dec = NULL; + const struct firmware *fw_h263_dec = NULL; + const struct firmware *fw_h264_dec = NULL; + const struct firmware *fw_mpg4_enc = NULL; + const struct firmware *fw_h264_enc = NULL; + const struct firmware *fw_vc1_dec = NULL; + int rc = 0; + u32 status = true; + + VCDRES_MSG_HIGH("%s(): Request firmware download\n", + __func__); + mutex_lock(&resource_context.lock); + rc = request_firmware(&fw_boot, VIDC_BOOT_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_BOOT_FW, rc); + mutex_unlock(&resource_context.lock); + return false; + } + vidc_command_control_fw = (unsigned char *)fw_boot->data; + vidc_command_control_fw_size = (u32) fw_boot->size; + + rc = request_firmware(&fw_mpg4_dec, VIDC_MPG4_DEC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_MPG4_DEC_FW, rc); + status = false; + goto boot_fw_free; + } + vidc_mpg4_dec_fw = (unsigned char *)fw_mpg4_dec->data; + vidc_mpg4_dec_fw_size = (u32) fw_mpg4_dec->size; + + + rc = request_firmware(&fw_h263_dec, VIDC_H263_DEC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_H263_DEC_FW, rc); + status = false; + goto mp4dec_fw_free; + } + vidc_h263_dec_fw = (unsigned char *)fw_h263_dec->data; + vidc_h263_dec_fw_size = (u32) fw_h263_dec->size; + + rc = request_firmware(&fw_h264_dec, VIDC_H264_DEC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_H264_DEC_FW, rc); + status = false; + goto h263dec_fw_free; + } + vidc_h264_dec_fw = (unsigned char *)fw_h264_dec->data; + vidc_h264_dec_fw_size = (u32) fw_h264_dec->size; + + rc = request_firmware(&fw_mpg4_enc, VIDC_MPG4_ENC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_MPG4_ENC_FW, rc); + status = false; + goto h264dec_fw_free; + } + vidc_mpg4_enc_fw = (unsigned char *)fw_mpg4_enc->data; + vidc_mpg4_enc_fw_size = (u32) fw_mpg4_enc->size; + + rc = request_firmware(&fw_h264_enc, VIDC_H264_ENC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_H264_ENC_FW, rc); + status = false; + goto mp4enc_fw_free; + } + vidc_h264_enc_fw = (unsigned char *)fw_h264_enc->data; + vidc_h264_enc_fw_size = (u32) fw_h264_enc->size; + + rc = request_firmware(&fw_vc1_dec, VIDC_VC1_DEC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_VC1_DEC_FW, rc); + status = false; + goto h264enc_fw_free; + } + vidc_vc1_dec_fw = (unsigned char *)fw_vc1_dec->data; + vidc_vc1_dec_fw_size = (u32) fw_vc1_dec->size; + mutex_unlock(&resource_context.lock); + return status; + +h264enc_fw_free: + release_firmware(fw_h264_enc); +mp4enc_fw_free: + release_firmware(fw_mpg4_enc); +h264dec_fw_free: + release_firmware(fw_h264_dec); +h263dec_fw_free: + release_firmware(fw_h263_dec); +mp4dec_fw_free: + release_firmware(fw_mpg4_dec); +boot_fw_free: + release_firmware(fw_boot); + mutex_unlock(&resource_context.lock); + return false; +} + +void res_trk_init(struct device *device, u32 irq) +{ + if (resource_context.device || resource_context.irq_num || + !device) { + VCDRES_MSG_ERROR("%s() Resource Tracker Init error\n", + __func__); + return; + } + memset(&resource_context, 0, sizeof(resource_context)); + mutex_init(&resource_context.lock); + resource_context.device = device; + resource_context.irq_num = irq; + resource_context.core_type = VCD_CORE_720P; + resource_context.regulator = regulator_get(NULL, "fs_mfc"); + resource_context.vidc_platform_data = + (struct msm_vidc_platform_data *) device->platform_data; + if (resource_context.vidc_platform_data) { + resource_context.memtype = + resource_context.vidc_platform_data->memtype; + } else { + resource_context.memtype = -1; + } +} + +u32 res_trk_get_core_type(void){ + return resource_context.core_type; +} + +u32 res_trk_get_mem_type(void){ + return resource_context.memtype; +} + +u32 res_trk_get_enable_ion(void) +{ + return 0; +} + +struct ion_client *res_trk_get_ion_client(void) +{ + return NULL; +} + +void res_trk_set_mem_type(enum ddl_mem_area mem_type) +{ + return; +} + +u32 res_trk_get_disable_fullhd(void) +{ + return 0; +} + +int res_trk_check_for_sec_session() +{ + return 0; +} + +void res_trk_secure_unset(void) +{ + return; +} + +void res_trk_secure_set(void) +{ + return; +} + +int res_trk_open_secure_session() +{ + return -EINVAL; +} + +int res_trk_close_secure_session() +{ + return 0; +} +u32 get_res_trk_perf_level(enum vcd_perf_level perf_level) +{ + return -ENOTSUPP; +} +u32 res_trk_is_cp_enabled(void) +{ + if (resource_context.vidc_platform_data->cp_enabled) + return 1; + else + return 0; +} +u32 res_trk_estimate_perf_level(u32 pn_perf_lvl) +{ + return 0; +} + diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h new file mode 100644 index 0000000000000000000000000000000000000000..d255772a2a0fe4704dc5884dcc59f26d8fa941f6 --- /dev/null +++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VIDEO_720P_RESOURCE_TRACKER_H_ +#define _VIDEO_720P_RESOURCE_TRACKER_H_ +#include +#include "vcd_res_tracker_api.h" + +#define VCD_RESTRK_MIN_PERF_LEVEL 37900 +#define VCD_RESTRK_MAX_PERF_LEVEL 108000 +#define VCD_RESTRK_MIN_FREQ_POINT 61440000 +#define VCD_RESTRK_MAX_FREQ_POINT 170667000 +#define VCD_RESTRK_HZ_PER_1000_PERFLVL 1580250 + +struct res_trk_context { + struct device *device; + u32 irq_num; + struct mutex lock; + struct clk *hclk; + struct clk *hclk_div2; + struct clk *pclk; + unsigned long hclk_rate; + unsigned int clock_enabled; + unsigned int rail_enabled; + struct regulator *regulator; + struct msm_vidc_platform_data *vidc_platform_data; + u32 core_type; + int memtype; + u32 secure_session; +}; + +#if DEBUG + +#define VCDRES_MSG_LOW(xx_fmt...) printk(KERN_INFO "\n\t* " xx_fmt) +#define VCDRES_MSG_MED(xx_fmt...) printk(KERN_INFO "\n * " xx_fmt) + +#else + +#define VCDRES_MSG_LOW(xx_fmt...) +#define VCDRES_MSG_MED(xx_fmt...) + +#endif + +#define VCDRES_MSG_HIGH(xx_fmt...) printk(KERN_WARNING "\n" xx_fmt) +#define VCDRES_MSG_ERROR(xx_fmt...) printk(KERN_ERR "\n err: " xx_fmt) +#define VCDRES_MSG_FATAL(xx_fmt...) printk(KERN_ERR "\n " xx_fmt) + +#endif diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h new file mode 100644 index 0000000000000000000000000000000000000000..1b2b4fa1cbb62738115e9671f3c5c5aa1da81648 --- /dev/null +++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h @@ -0,0 +1,43 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VIDEO_720P_RESOURCE_TRACKER_API_H_ +#define _VIDEO_720P_RESOURCE_TRACKER_API_H_ + +#include "vcd_core.h" +#include "vcd_ddl.h" + +void res_trk_init(struct device *device, u32 irq); +u32 res_trk_power_up(void); +u32 res_trk_power_down(void); +u32 res_trk_enable_clocks(void); +u32 res_trk_disable_clocks(void); +u32 res_trk_get_max_perf_level(u32 *pn_max_perf_lvl); +u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl, + struct vcd_dev_ctxt *dev_ctxt); +u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl); +u32 res_trk_download_firmware(void); +u32 res_trk_get_core_type(void); +u32 res_trk_get_mem_type(void); +u32 res_trk_get_disable_fullhd(void); +u32 res_trk_get_enable_ion(void); +u32 res_trk_is_cp_enabled(void); +struct ion_client *res_trk_get_ion_client(void); +void res_trk_set_mem_type(enum ddl_mem_area mem_type); +int res_trk_check_for_sec_session(void); +int res_trk_open_secure_session(void); +int res_trk_close_secure_session(void); +void res_trk_secure_set(void); +void res_trk_secure_unset(void); +u32 get_res_trk_perf_level(enum vcd_perf_level perf_level); +u32 res_trk_estimate_perf_level(u32 pn_perf_lvl); +#endif diff --git a/drivers/video/msm/vidc/Kconfig b/drivers/video/msm/vidc/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..9ffcb154af1d5046754d6e21933cdfe858b69ab5 --- /dev/null +++ b/drivers/video/msm/vidc/Kconfig @@ -0,0 +1,39 @@ +# +# VIDEO CORE +# +menuconfig MSM_VIDC + bool "Video Core Driver" + depends on ARCH_MSM8X60 || ARCH_MSM7X30 || ARCH_MSM8960 + default y + ---help--- + Say Y here to see options for video device drivers. + If you say N, all options in this submenu will be skipped and disabled. + +config MSM_VIDC_720P + bool "720P Video Core" + depends on MSM_VIDC && ARCH_MSM7X30 + default y + help + This option enables support for Video core. + +config MSM_VIDC_1080P + bool "1080P Video Core" + depends on MSM_VIDC && (ARCH_MSM8X60 || ARCH_MSM8960) + default y + help + This option enables support for Video core. + +config MSM_VIDC_VENC + tristate "Video encoder" + depends on MSM_VIDC + default y + help + This option enables support for Video encoder. + +config MSM_VIDC_VDEC + tristate "Video decoder" + depends on MSM_VIDC + default y + help + This option enables support for Video decoder. + diff --git a/drivers/video/msm/vidc/Makefile b/drivers/video/msm/vidc/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..af41f181878e489bc091287131842ba24f92cca5 --- /dev/null +++ b/drivers/video/msm/vidc/Makefile @@ -0,0 +1,62 @@ +ifdef CONFIG_MSM_VIDC_720P +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/720p/ddl +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/720p/resource_tracker +endif + +ifdef CONFIG_MSM_VIDC_1080P +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/1080p/ddl +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/1080p/resource_tracker +endif + +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/common/dec +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/common/enc +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/common/vcd +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/common/init + +obj-$(CONFIG_MSM_VIDC) += vidc.o + +vidc-objs := common/init/vidc_init.o \ + common/vcd/vcd_api.o \ + common/vcd/vcd_power_sm.o \ + common/vcd/vcd_client_sm.o \ + common/vcd/vcd_device_sm.o \ + common/vcd/vcd_scheduler.o \ + common/vcd/vcd_sub.o \ + +ifdef CONFIG_MSM_VIDC_720P +vidc-objs += 720p/ddl/vcd_ddl_firmware.o \ + 720p/ddl/vcd_ddl_metadata.o \ + 720p/ddl/vidc.o \ + 720p/ddl/vcd_ddl_utils.o \ + 720p/ddl/vcd_ddl.o \ + 720p/ddl/vcd_ddl_helper.o \ + 720p/ddl/vcd_ddl_interrupt_handler.o \ + 720p/ddl/vcd_ddl_hal.o \ + 720p/ddl/vcd_ddl_properties.o \ + 720p/resource_tracker/vcd_res_tracker.o \ + 720p/ddl/vcd_ddl_errors.o +endif + +ifdef CONFIG_MSM_VIDC_1080P +vidc-objs += 1080p/ddl/vcd_ddl_helper.o \ + 1080p/ddl/vcd_ddl_utils.o \ + 1080p/ddl/vcd_ddl_interrupt_handler.o \ + 1080p/ddl/vcd_ddl_properties.o \ + 1080p/ddl/vcd_ddl_errors.o \ + 1080p/ddl/vcd_ddl_shared_mem.o \ + 1080p/ddl/vidc.o \ + 1080p/ddl/vidc_pix_cache.o \ + 1080p/ddl/vcd_ddl_vidc.o \ + 1080p/ddl/vcd_ddl.o \ + 1080p/ddl/vcd_ddl_metadata.o \ + 1080p/resource_tracker/vcd_res_tracker.o +endif + +obj-$(CONFIG_MSM_VIDC_VDEC) += vidc_vdec.o + +vidc_vdec-objs := common/dec/vdec.o + +obj-$(CONFIG_MSM_VIDC_VENC) += vidc_venc.o + +vidc_venc-objs := common/enc/venc.o \ + common/enc/venc_internal.o diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c new file mode 100644 index 0000000000000000000000000000000000000000..716b04952e244193817022c3b76097fdee18f975 --- /dev/null +++ b/drivers/video/msm/vidc/common/dec/vdec.c @@ -0,0 +1,2380 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vcd_res_tracker_api.h" +#include "vdec_internal.h" + + + +#define DBG(x...) pr_debug(x) +#define INFO(x...) pr_info(x) +#define ERR(x...) pr_err(x) + +#define VID_DEC_NAME "msm_vidc_dec" + +static char *node_name[2] = {"", "_sec"}; +static struct vid_dec_dev *vid_dec_device_p; +static dev_t vid_dec_dev_num; +static struct class *vid_dec_class; + +static unsigned int vidc_mmu_subsystem[] = { + MSM_SUBSYSTEM_VIDEO}; +static s32 vid_dec_get_empty_client_index(void) +{ + u32 i, found = false; + + for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) { + if (!vid_dec_device_p->vdec_clients[i].vcd_handle) { + found = true; + break; + } + } + if (!found) { + ERR("%s():ERROR No space for new client\n", __func__); + return -ENOMEM; + } else { + DBG("%s(): available client index = %u\n", __func__, i); + return i; + } +} + +u32 vid_dec_get_status(u32 status) +{ + u32 vdec_status; + + switch (status) { + case VCD_ERR_SEQHDR_PARSE_FAIL: + case VCD_ERR_BITSTREAM_ERR: + vdec_status = VDEC_S_INPUT_BITSTREAM_ERR; + break; + case VCD_S_SUCCESS: + vdec_status = VDEC_S_SUCCESS; + break; + case VCD_ERR_FAIL: + vdec_status = VDEC_S_EFAIL; + break; + case VCD_ERR_ALLOC_FAIL: + vdec_status = VDEC_S_ENOSWRES; + break; + case VCD_ERR_ILLEGAL_OP: + vdec_status = VDEC_S_EINVALCMD; + break; + case VCD_ERR_ILLEGAL_PARM: + vdec_status = VDEC_S_EBADPARAM; + break; + case VCD_ERR_BAD_POINTER: + case VCD_ERR_BAD_HANDLE: + vdec_status = VDEC_S_EFATAL; + break; + case VCD_ERR_NOT_SUPPORTED: + vdec_status = VDEC_S_ENOTSUPP; + break; + case VCD_ERR_BAD_STATE: + vdec_status = VDEC_S_EINVALSTATE; + break; + case VCD_ERR_BUSY: + vdec_status = VDEC_S_BUSY; + break; + case VCD_ERR_MAX_CLIENT: + vdec_status = VDEC_S_ENOHWRES; + break; + default: + vdec_status = VDEC_S_EFAIL; + break; + } + + return vdec_status; +} + +static void vid_dec_notify_client(struct video_client_ctx *client_ctx) +{ + if (client_ctx) + complete(&client_ctx->event); +} + +void vid_dec_vcd_open_done(struct video_client_ctx *client_ctx, + struct vcd_handle_container *handle_container) +{ + DBG("vid_dec_vcd_open_done\n"); + + if (client_ctx) { + if (handle_container) + client_ctx->vcd_handle = handle_container->handle; + else + ERR("%s(): ERROR. handle_container is NULL\n", + __func__); + + vid_dec_notify_client(client_ctx); + } else + ERR("%s(): ERROR. client_ctx is NULL\n", __func__); +} + +static void vid_dec_handle_field_drop(struct video_client_ctx *client_ctx, + u32 event, u32 status, int64_t time_stamp) +{ + struct vid_dec_msg *vdec_msg; + + if (!client_ctx) { + ERR("%s() NULL pointer\n", __func__); + return; + } + + vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL); + if (!vdec_msg) { + ERR("%s(): cannot allocate vid_dec_msg " + " buffer\n", __func__); + return; + } + vdec_msg->vdec_msg_info.status_code = vid_dec_get_status(status); + if (event == VCD_EVT_IND_INFO_FIELD_DROPPED) { + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_EVT_INFO_FIELD_DROPPED; + vdec_msg->vdec_msg_info.msgdata.output_frame.time_stamp + = time_stamp; + DBG("Send FIELD_DROPPED message to client = %p\n", client_ctx); + } else { + ERR("vid_dec_input_frame_done(): invalid event type: " + "%d\n", event); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID; + } + vdec_msg->vdec_msg_info.msgdatasize = + sizeof(struct vdec_output_frameinfo); + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&vdec_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + +static void vid_dec_input_frame_done(struct video_client_ctx *client_ctx, + u32 event, u32 status, + struct vcd_frame_data *vcd_frame_data) +{ + struct vid_dec_msg *vdec_msg; + + if (!client_ctx || !vcd_frame_data) { + ERR("vid_dec_input_frame_done() NULL pointer\n"); + return; + } + + kfree(vcd_frame_data->desc_buf); + vcd_frame_data->desc_buf = NULL; + vcd_frame_data->desc_size = 0; + + vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL); + if (!vdec_msg) { + ERR("vid_dec_input_frame_done(): cannot allocate vid_dec_msg " + " buffer\n"); + return; + } + + vdec_msg->vdec_msg_info.status_code = vid_dec_get_status(status); + + if (event == VCD_EVT_RESP_INPUT_DONE) { + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_RESP_INPUT_BUFFER_DONE; + DBG("Send INPUT_DON message to client = %p\n", client_ctx); + + } else if (event == VCD_EVT_RESP_INPUT_FLUSHED) { + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_INPUT_FLUSHED; + DBG("Send INPUT_FLUSHED message to client = %p\n", client_ctx); + } else { + ERR("vid_dec_input_frame_done(): invalid event type: " + "%d\n", event); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID; + } + + vdec_msg->vdec_msg_info.msgdata.input_frame_clientdata = + (void *)vcd_frame_data->frm_clnt_data; + vdec_msg->vdec_msg_info.msgdatasize = sizeof(void *); + + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&vdec_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + +static void vid_dec_output_frame_done(struct video_client_ctx *client_ctx, + u32 event, u32 status, + struct vcd_frame_data *vcd_frame_data) +{ + struct vid_dec_msg *vdec_msg; + + unsigned long kernel_vaddr = 0, phy_addr = 0, user_vaddr = 0; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + enum vdec_picture pic_type; + u32 ion_flag = 0; + struct ion_handle *buff_handle = NULL; + struct vdec_output_frameinfo *output_frame; + + if (!client_ctx || !vcd_frame_data) { + ERR("vid_dec_input_frame_done() NULL pointer\n"); + return; + } + + vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL); + if (!vdec_msg) { + ERR("vid_dec_input_frame_done(): cannot allocate vid_dec_msg " + " buffer\n"); + return; + } + + vdec_msg->vdec_msg_info.status_code = vid_dec_get_status(status); + + if (event == VCD_EVT_RESP_OUTPUT_DONE) + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; + else if (event == VCD_EVT_RESP_OUTPUT_FLUSHED) + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_OUTPUT_FLUSHED; + else { + ERR("QVD: vid_dec_output_frame_done invalid cmd type: " + "%d\n", event); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID; + } + + kernel_vaddr = (unsigned long)vcd_frame_data->virtual; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, + false, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index) || + (vcd_frame_data->flags & VCD_FRAME_FLAG_EOS)) { + /* Buffer address in user space */ + vdec_msg->vdec_msg_info.msgdata.output_frame.bufferaddr = + (u8 *) user_vaddr; + /* Data length */ + vdec_msg->vdec_msg_info.msgdata.output_frame.len = + vcd_frame_data->data_len; + vdec_msg->vdec_msg_info.msgdata.output_frame.flags = + vcd_frame_data->flags; + /* Timestamp pass-through from input frame */ + vdec_msg->vdec_msg_info.msgdata.output_frame.time_stamp = + vcd_frame_data->time_stamp; + /* Output frame client data */ + vdec_msg->vdec_msg_info.msgdata.output_frame.client_data = + (void *)vcd_frame_data->frm_clnt_data; + /* Associated input frame client data */ + vdec_msg->vdec_msg_info.msgdata.output_frame. + input_frame_clientdata = + (void *)vcd_frame_data->ip_frm_tag; + /* Decoded picture width and height */ + vdec_msg->vdec_msg_info.msgdata.output_frame.framesize. + bottom = + vcd_frame_data->dec_op_prop.disp_frm.bottom; + vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.left = + vcd_frame_data->dec_op_prop.disp_frm.left; + vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.right = + vcd_frame_data->dec_op_prop.disp_frm.right; + vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.top = + vcd_frame_data->dec_op_prop.disp_frm.top; + if (vcd_frame_data->interlaced) { + vdec_msg->vdec_msg_info.msgdata. + output_frame.interlaced_format = + VDEC_InterlaceInterleaveFrameTopFieldFirst; + } else { + vdec_msg->vdec_msg_info.msgdata. + output_frame.interlaced_format = + VDEC_InterlaceFrameProgressive; + } + /* Decoded picture type */ + switch (vcd_frame_data->frame) { + case VCD_FRAME_I: + pic_type = PICTURE_TYPE_I; + break; + case VCD_FRAME_P: + pic_type = PICTURE_TYPE_P; + break; + case VCD_FRAME_B: + pic_type = PICTURE_TYPE_B; + break; + case VCD_FRAME_NOTCODED: + pic_type = PICTURE_TYPE_SKIP; + break; + case VCD_FRAME_IDR: + pic_type = PICTURE_TYPE_IDR; + break; + default: + pic_type = PICTURE_TYPE_UNKNOWN; + } + vdec_msg->vdec_msg_info.msgdata.output_frame.pic_type = + pic_type; + output_frame = &vdec_msg->vdec_msg_info.msgdata.output_frame; + output_frame->aspect_ratio_info.aspect_ratio = + vcd_frame_data->aspect_ratio_info.aspect_ratio; + output_frame->aspect_ratio_info.par_width = + vcd_frame_data->aspect_ratio_info.extended_par_width; + output_frame->aspect_ratio_info.par_height = + vcd_frame_data->aspect_ratio_info.extended_par_height; + vdec_msg->vdec_msg_info.msgdatasize = + sizeof(struct vdec_output_frameinfo); + } else { + ERR("vid_dec_output_frame_done UVA can not be found\n"); + vdec_msg->vdec_msg_info.status_code = VDEC_S_EFATAL; + } + if (vcd_frame_data->data_len > 0) { + ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT, + pmem_fd, kernel_vaddr, buffer_index, + &buff_handle); + if (ion_flag == CACHED && buff_handle) { + msm_ion_do_cache_op(client_ctx->user_ion_client, + buff_handle, + (unsigned long *) kernel_vaddr, + (unsigned long)vcd_frame_data->data_len, + ION_IOC_INV_CACHES); + } + } + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&vdec_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + +static void vid_dec_lean_event(struct video_client_ctx *client_ctx, + u32 event, u32 status) +{ + struct vid_dec_msg *vdec_msg; + + if (!client_ctx) { + ERR("%s(): !client_ctx pointer\n", __func__); + return; + } + + vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL); + if (!vdec_msg) { + ERR("%s(): cannot allocate vid_dec_msg buffer\n", __func__); + return; + } + + vdec_msg->vdec_msg_info.status_code = vid_dec_get_status(status); + + switch (event) { + case VCD_EVT_IND_OUTPUT_RECONFIG: + DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_CONFIG_CHANGED" + " to client"); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_EVT_CONFIG_CHANGED; + break; + case VCD_EVT_IND_RESOURCES_LOST: + DBG("msm_vidc_dec: Sending VDEC_EVT_RESOURCES_LOST" + " to client"); + vdec_msg->vdec_msg_info.msgcode = VDEC_EVT_RESOURCES_LOST; + break; + case VCD_EVT_RESP_FLUSH_INPUT_DONE: + DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_INPUT_DONE" + " to client"); + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_RESP_FLUSH_INPUT_DONE; + break; + case VCD_EVT_RESP_FLUSH_OUTPUT_DONE: + DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_OUTPUT_DONE" + " to client"); + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_RESP_FLUSH_OUTPUT_DONE; + break; + case VCD_EVT_IND_HWERRFATAL: + DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_HW_ERROR" + " to client"); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_EVT_HW_ERROR; + break; + case VCD_EVT_RESP_START: + DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_START_DONE" + " to client"); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_START_DONE; + break; + case VCD_EVT_RESP_STOP: + DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_STOP_DONE" + " to client"); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_STOP_DONE; + break; + case VCD_EVT_RESP_PAUSE: + DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_PAUSE_DONE" + " to client"); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_PAUSE_DONE; + break; + case VCD_EVT_IND_INFO_OUTPUT_RECONFIG: + DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_INFO_CONFIG_CHANGED" + " to client"); + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_EVT_INFO_CONFIG_CHANGED; + break; + default: + ERR("%s() : unknown event type\n", __func__); + break; + } + + vdec_msg->vdec_msg_info.msgdatasize = 0; + if (client_ctx->stop_sync_cb && + (event == VCD_EVT_RESP_STOP || event == VCD_EVT_IND_HWERRFATAL)) { + client_ctx->stop_sync_cb = false; + complete(&client_ctx->event); + kfree(vdec_msg); + return; + } + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&vdec_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + + +void vid_dec_vcd_cb(u32 event, u32 status, + void *info, size_t sz, void *handle, void *const client_data) +{ + struct video_client_ctx *client_ctx = + (struct video_client_ctx *)client_data; + + DBG("Entering %s()\n", __func__); + + if (!client_ctx) { + ERR("%s(): client_ctx is NULL\n", __func__); + return; + } + + client_ctx->event_status = status; + + switch (event) { + case VCD_EVT_RESP_OPEN: + vid_dec_vcd_open_done(client_ctx, + (struct vcd_handle_container *) + info); + break; + case VCD_EVT_RESP_INPUT_DONE: + case VCD_EVT_RESP_INPUT_FLUSHED: + vid_dec_input_frame_done(client_ctx, event, status, + (struct vcd_frame_data *)info); + break; + case VCD_EVT_IND_INFO_FIELD_DROPPED: + if (info) + vid_dec_handle_field_drop(client_ctx, event, + status, *((int64_t *)info)); + else + pr_err("Wrong Payload for Field dropped\n"); + break; + case VCD_EVT_RESP_OUTPUT_DONE: + case VCD_EVT_RESP_OUTPUT_FLUSHED: + vid_dec_output_frame_done(client_ctx, event, status, + (struct vcd_frame_data *)info); + break; + case VCD_EVT_RESP_PAUSE: + case VCD_EVT_RESP_STOP: + case VCD_EVT_RESP_FLUSH_INPUT_DONE: + case VCD_EVT_RESP_FLUSH_OUTPUT_DONE: + case VCD_EVT_IND_OUTPUT_RECONFIG: + case VCD_EVT_IND_HWERRFATAL: + case VCD_EVT_IND_RESOURCES_LOST: + case VCD_EVT_IND_INFO_OUTPUT_RECONFIG: + vid_dec_lean_event(client_ctx, event, status); + break; + case VCD_EVT_RESP_START: + if (!client_ctx->seq_header_set) + vid_dec_lean_event(client_ctx, event, status); + else + vid_dec_notify_client(client_ctx); + break; + default: + ERR("%s() : Error - Invalid event type =%u\n", __func__, + event); + break; + } +} + +static u32 vid_dec_set_codec(struct video_client_ctx *client_ctx, + enum vdec_codec *vdec_codec) +{ + u32 result = true; + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_codec codec; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !vdec_codec) + return false; + + vcd_property_hdr.prop_id = VCD_I_CODEC; + vcd_property_hdr.sz = sizeof(struct vcd_property_codec); + + switch (*vdec_codec) { + case VDEC_CODECTYPE_MPEG4: + codec.codec = VCD_CODEC_MPEG4; + break; + case VDEC_CODECTYPE_H264: + codec.codec = VCD_CODEC_H264; + break; + case VDEC_CODECTYPE_DIVX_3: + codec.codec = VCD_CODEC_DIVX_3; + break; + case VDEC_CODECTYPE_DIVX_4: + codec.codec = VCD_CODEC_DIVX_4; + break; + case VDEC_CODECTYPE_DIVX_5: + codec.codec = VCD_CODEC_DIVX_5; + break; + case VDEC_CODECTYPE_DIVX_6: + codec.codec = VCD_CODEC_DIVX_6; + break; + case VDEC_CODECTYPE_XVID: + codec.codec = VCD_CODEC_XVID; + break; + case VDEC_CODECTYPE_H263: + codec.codec = VCD_CODEC_H263; + break; + case VDEC_CODECTYPE_MPEG2: + codec.codec = VCD_CODEC_MPEG2; + break; + case VDEC_CODECTYPE_VC1: + codec.codec = VCD_CODEC_VC1; + break; + case VDEC_CODECTYPE_VC1_RCV: + codec.codec = VCD_CODEC_VC1_RCV; + break; + default: + result = false; + break; + } + + if (result) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &codec); + if (vcd_status) + result = false; + } + return result; +} + +static u32 vid_dec_set_output_format(struct video_client_ctx *client_ctx, + enum vdec_output_fromat *output_format) +{ + u32 result = true; + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_buffer_format vcd_prop_buffer_format; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !output_format) + return false; + + vcd_property_hdr.prop_id = VCD_I_BUFFER_FORMAT;; + vcd_property_hdr.sz = + sizeof(struct vcd_property_buffer_format); + + switch (*output_format) { + case VDEC_YUV_FORMAT_NV12: + vcd_prop_buffer_format.buffer_format = VCD_BUFFER_FORMAT_NV12; + break; + case VDEC_YUV_FORMAT_TILE_4x2: + vcd_prop_buffer_format.buffer_format = + VCD_BUFFER_FORMAT_TILE_4x2; + break; + default: + result = false; + break; + } + + if (result) + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, + &vcd_prop_buffer_format); + + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_set_frame_resolution(struct video_client_ctx *client_ctx, + struct vdec_picsize *video_resoultion) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_frame_size frame_resolution; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !video_resoultion) + return false; + + vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE; + vcd_property_hdr.sz = sizeof(struct vcd_property_frame_size); + frame_resolution.width = video_resoultion->frame_width; + frame_resolution.height = video_resoultion->frame_height; + frame_resolution.stride = video_resoultion->stride; + frame_resolution.scan_lines = video_resoultion->scan_lines; + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &frame_resolution); + + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_get_frame_resolution(struct video_client_ctx *client_ctx, + struct vdec_picsize *video_resoultion) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_frame_size frame_resolution; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !video_resoultion) + return false; + + vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE; + vcd_property_hdr.sz = sizeof(struct vcd_property_frame_size); + + vcd_status = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr, + &frame_resolution); + + video_resoultion->frame_width = frame_resolution.width; + video_resoultion->frame_height = frame_resolution.height; + video_resoultion->scan_lines = frame_resolution.scan_lines; + video_resoultion->stride = frame_resolution.stride; + + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_get_progressive_only(struct video_client_ctx *client_ctx, + u32 *progressive_only) +{ + struct vcd_property_hdr vcd_property_hdr; + if (!client_ctx || !progressive_only) + return false; + vcd_property_hdr.prop_id = VCD_I_PROGRESSIVE_ONLY; + vcd_property_hdr.sz = sizeof(u32); + if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr, + progressive_only)) + return false; + else + return true; +} + +static u32 vid_dec_get_disable_dmx_support(struct video_client_ctx *client_ctx, + u32 *disable_dmx) +{ + + struct vcd_property_hdr vcd_property_hdr; + if (!client_ctx || !disable_dmx) + return false; + vcd_property_hdr.prop_id = VCD_I_DISABLE_DMX_SUPPORT; + vcd_property_hdr.sz = sizeof(u32); + if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr, + disable_dmx)) + return false; + else + return true; +} +static u32 vid_dec_get_disable_dmx(struct video_client_ctx *client_ctx, + u32 *disable_dmx) +{ + + struct vcd_property_hdr vcd_property_hdr; + if (!client_ctx || !disable_dmx) + return false; + vcd_property_hdr.prop_id = VCD_I_DISABLE_DMX; + vcd_property_hdr.sz = sizeof(u32); + if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr, + disable_dmx)) + return false; + else + return true; +} + +static u32 vid_dec_set_disable_dmx(struct video_client_ctx *client_ctx) +{ + + struct vcd_property_hdr vcd_property_hdr; + u32 vcd_disable_dmx; + if (!client_ctx) + return false; + vcd_property_hdr.prop_id = VCD_I_DISABLE_DMX; + vcd_property_hdr.sz = sizeof(u32); + vcd_disable_dmx = true; + DBG("%s() : Setting Disable DMX: %d\n", + __func__, vcd_disable_dmx); + + if (vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr, + &vcd_disable_dmx)) + return false; + else + return true; +} + +static u32 vid_dec_set_picture_order(struct video_client_ctx *client_ctx, + u32 *picture_order) +{ + struct vcd_property_hdr vcd_property_hdr; + u32 vcd_status = VCD_ERR_FAIL, vcd_picture_order, ret = true; + if (!client_ctx || !picture_order) + return false; + vcd_property_hdr.prop_id = VCD_I_OUTPUT_ORDER; + vcd_property_hdr.sz = sizeof(u32); + if (*picture_order == VDEC_ORDER_DISPLAY) + vcd_picture_order = VCD_DEC_ORDER_DISPLAY; + else if (*picture_order == VDEC_ORDER_DECODE) + vcd_picture_order = VCD_DEC_ORDER_DECODE; + else + ret = false; + if (ret) { + DBG("%s() : Setting output picture order: %d\n", + __func__, vcd_picture_order); + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_picture_order); + if (vcd_status != VCD_S_SUCCESS) + ret = false; + } + return ret; +} + +static u32 vid_dec_set_frame_rate(struct video_client_ctx *client_ctx, + struct vdec_framerate *frame_rate) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_frame_rate vcd_frame_rate; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !frame_rate) + return false; + + vcd_property_hdr.prop_id = VCD_I_FRAME_RATE; + vcd_property_hdr.sz = sizeof(struct vcd_property_frame_rate); + vcd_frame_rate.fps_numerator = frame_rate->fps_numerator; + vcd_frame_rate.fps_denominator = frame_rate->fps_denominator; + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_frame_rate); + + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_set_extradata(struct video_client_ctx *client_ctx, + u32 *extradata_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_meta_data_enable vcd_meta_data; + u32 vcd_status = VCD_ERR_FAIL; + if (!client_ctx || !extradata_flag) + return false; + vcd_property_hdr.prop_id = VCD_I_METADATA_ENABLE; + vcd_property_hdr.sz = sizeof(struct vcd_property_meta_data_enable); + vcd_meta_data.meta_data_enable_flag = *extradata_flag; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_meta_data); + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_set_idr_only_decoding(struct video_client_ctx *client_ctx) +{ + struct vcd_property_hdr vcd_property_hdr; + u32 vcd_status = VCD_ERR_FAIL; + u32 enable = true; + if (!client_ctx) + return false; + vcd_property_hdr.prop_id = VCD_I_DEC_PICTYPE; + vcd_property_hdr.sz = sizeof(u32); + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &enable); + if (vcd_status) + return false; + return true; +} + +static u32 vid_dec_set_h264_mv_buffers(struct video_client_ctx *client_ctx, + struct vdec_h264_mv *mv_data) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_h264_mv_buffer *vcd_h264_mv_buffer = NULL; + struct msm_mapped_buffer *mapped_buffer = NULL; + u32 vcd_status = VCD_ERR_FAIL; + u32 len = 0, flags = 0; + struct file *file; + int rc = 0; + unsigned long ionflag = 0; + unsigned long buffer_size = 0; + unsigned long iova = 0; + + if (!client_ctx || !mv_data) + return false; + + vcd_property_hdr.prop_id = VCD_I_H264_MV_BUFFER; + vcd_property_hdr.sz = sizeof(struct vcd_property_h264_mv_buffer); + vcd_h264_mv_buffer = &client_ctx->vcd_h264_mv_buffer; + + memset(&client_ctx->vcd_h264_mv_buffer, 0, + sizeof(struct vcd_property_h264_mv_buffer)); + vcd_h264_mv_buffer->size = mv_data->size; + vcd_h264_mv_buffer->count = mv_data->count; + vcd_h264_mv_buffer->pmem_fd = mv_data->pmem_fd; + vcd_h264_mv_buffer->offset = mv_data->offset; + + if (!vcd_get_ion_status()) { + if (get_pmem_file(vcd_h264_mv_buffer->pmem_fd, + (unsigned long *) (&(vcd_h264_mv_buffer-> + physical_addr)), + (unsigned long *) (&vcd_h264_mv_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_h264_mv_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_h264_mv_buffer->client_data = (void *) mapped_buffer; + vcd_h264_mv_buffer->dev_addr = (u8 *)mapped_buffer->iova[0]; + } else { + client_ctx->h264_mv_ion_handle = ion_import_fd( + client_ctx->user_ion_client, + vcd_h264_mv_buffer->pmem_fd); + if (IS_ERR_OR_NULL(client_ctx->h264_mv_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->h264_mv_ion_handle, + &ionflag); + if (rc) { + ERR("%s():get_ION_flags fail\n", + __func__); + goto import_ion_error; + } + vcd_h264_mv_buffer->kernel_virtual_addr = (u8 *) ion_map_kernel( + client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle, + ionflag); + if (!vcd_h264_mv_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()) { + rc = ion_phys(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle, + (unsigned long *) (&(vcd_h264_mv_buffer-> + physical_addr)), &len); + if (rc) { + ERR("%s():get_ION_kernel physical addr fail\n", + __func__); + goto ion_map_error; + } + vcd_h264_mv_buffer->client_data = NULL; + vcd_h264_mv_buffer->dev_addr = (u8 *) + vcd_h264_mv_buffer->physical_addr; + } else { + rc = ion_map_iommu(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle, + VIDEO_DOMAIN, VIDEO_MAIN_POOL, + SZ_4K, 0, (unsigned long *)&iova, + (unsigned long *)&buffer_size, + UNCACHED, 0); + if (rc) { + ERR("%s():get_ION_kernel physical addr fail\n", + __func__); + goto ion_map_error; + } + vcd_h264_mv_buffer->physical_addr = (u8 *) iova; + vcd_h264_mv_buffer->client_data = NULL; + vcd_h264_mv_buffer->dev_addr = (u8 *) iova; + } + } + DBG("Virt: %p, Phys %p, fd: %d", vcd_h264_mv_buffer-> + kernel_virtual_addr, vcd_h264_mv_buffer->physical_addr, + vcd_h264_mv_buffer->pmem_fd); + DBG("Dev addr %p", vcd_h264_mv_buffer->dev_addr); + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, vcd_h264_mv_buffer); + + if (vcd_status) + return false; + else + return true; +ion_map_error: + if (vcd_h264_mv_buffer->kernel_virtual_addr) { + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle); + vcd_h264_mv_buffer->kernel_virtual_addr = NULL; + } + if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) { + ion_free(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle); + client_ctx->h264_mv_ion_handle = NULL; + } +import_ion_error: + return false; +} + +static u32 vid_dec_set_cont_on_reconfig(struct video_client_ctx *client_ctx) +{ + struct vcd_property_hdr vcd_property_hdr; + u32 vcd_status = VCD_ERR_FAIL; + u32 enable = true; + if (!client_ctx) + return false; + vcd_property_hdr.prop_id = VCD_I_CONT_ON_RECONFIG; + vcd_property_hdr.sz = sizeof(u32); + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &enable); + if (vcd_status) + return false; + return true; +} + +static u32 vid_dec_get_h264_mv_buffer_size(struct video_client_ctx *client_ctx, + struct vdec_mv_buff_size *mv_buff) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_buffer_size h264_mv_buffer_size; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !mv_buff) + return false; + + vcd_property_hdr.prop_id = VCD_I_GET_H264_MV_SIZE; + vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size); + + h264_mv_buffer_size.width = mv_buff->width; + h264_mv_buffer_size.height = mv_buff->height; + + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &h264_mv_buffer_size); + + mv_buff->width = h264_mv_buffer_size.width; + mv_buff->height = h264_mv_buffer_size.height; + mv_buff->size = h264_mv_buffer_size.size; + mv_buff->alignment = h264_mv_buffer_size.alignment; + + 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; + struct vcd_property_buffer_size h264_mv_buffer_size; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx) + return false; + if (client_ctx->vcd_h264_mv_buffer.client_data) + msm_subsystem_unmap_buffer((struct msm_mapped_buffer *) + client_ctx->vcd_h264_mv_buffer.client_data); + + vcd_property_hdr.prop_id = VCD_I_FREE_H264_MV_BUFFER; + vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size); + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &h264_mv_buffer_size); + + if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) { + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + } + ion_free(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle); + client_ctx->h264_mv_ion_handle = NULL; + } + + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_get_buffer_req(struct video_client_ctx *client_ctx, + struct vdec_allocatorproperty *vdec_buf_req) +{ + u32 vcd_status = VCD_ERR_FAIL; + struct vcd_buffer_requirement vcd_buf_req; + + if (!client_ctx || !vdec_buf_req) + return false; + + if (vdec_buf_req->buffer_type == VDEC_BUFFER_TYPE_INPUT) { + vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle, + VCD_BUFFER_INPUT, + &vcd_buf_req); + } else { + vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle, + VCD_BUFFER_OUTPUT, + &vcd_buf_req); + } + + if (vcd_status) { + return false; + } else { + vdec_buf_req->mincount = vcd_buf_req.min_count; + vdec_buf_req->maxcount = vcd_buf_req.max_count; + vdec_buf_req->actualcount = vcd_buf_req.actual_count; + 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; + + return true; + } +} + +static u32 vid_dec_set_buffer(struct video_client_ctx *client_ctx, + struct vdec_setbuffer_cmd *buffer_info) +{ + enum vcd_buffer_type buffer = VCD_BUFFER_INPUT; + enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT; + u32 vcd_status = VCD_ERR_FAIL; + unsigned long kernel_vaddr, buf_adr_offset = 0, length; + + if (!client_ctx || !buffer_info) + return false; + + if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { + dir_buffer = BUFFER_TYPE_OUTPUT; + buffer = VCD_BUFFER_OUTPUT; + buf_adr_offset = (unsigned long)buffer_info->buffer.offset; + } + length = buffer_info->buffer.buffer_len; + /*If buffer cannot be set, ignore */ + if (!vidc_insert_addr_table(client_ctx, dir_buffer, + (unsigned long)buffer_info->buffer.bufferaddr, + &kernel_vaddr, buffer_info->buffer.pmem_fd, + buf_adr_offset, MAX_VIDEO_NUM_OF_BUFF, length)) { + DBG("%s() : user_virt_addr = %p cannot be set.", + __func__, buffer_info->buffer.bufferaddr); + return false; + } + vcd_status = vcd_set_buffer(client_ctx->vcd_handle, + buffer, (u8 *) kernel_vaddr, + buffer_info->buffer.buffer_len); + + if (!vcd_status) + return true; + else + return false; +} + + +static u32 vid_dec_free_buffer(struct video_client_ctx *client_ctx, + struct vdec_setbuffer_cmd *buffer_info) +{ + enum vcd_buffer_type buffer = VCD_BUFFER_INPUT; + enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT; + u32 vcd_status = VCD_ERR_FAIL; + unsigned long kernel_vaddr; + + if (!client_ctx || !buffer_info) + return false; + + if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { + dir_buffer = BUFFER_TYPE_OUTPUT; + buffer = VCD_BUFFER_OUTPUT; + } + + /*If buffer NOT set, ignore */ + if (!vidc_delete_addr_table(client_ctx, dir_buffer, + (unsigned long)buffer_info->buffer.bufferaddr, + &kernel_vaddr)) { + DBG("%s() : user_virt_addr = %p has not been set.", + __func__, buffer_info->buffer.bufferaddr); + return true; + } + vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer, + (u8 *)kernel_vaddr); + + if (!vcd_status) + return true; + else + return false; +} + +static u32 vid_dec_pause_resume(struct video_client_ctx *client_ctx, u32 pause) +{ + u32 vcd_status; + + if (!client_ctx) { + ERR("\n %s(): Invalid client_ctx", __func__); + return false; + } + + if (pause) { + DBG("msm_vidc_dec: PAUSE command from client = %p\n", + client_ctx); + vcd_status = vcd_pause(client_ctx->vcd_handle); + } else{ + DBG("msm_vidc_dec: RESUME command from client = %p\n", + client_ctx); + vcd_status = vcd_resume(client_ctx->vcd_handle); + } + + if (vcd_status) + return false; + + return true; + +} + +static u32 vid_dec_start_stop(struct video_client_ctx *client_ctx, u32 start) +{ + struct vid_dec_msg *vdec_msg = NULL; + u32 vcd_status; + + DBG("msm_vidc_dec: Inside %s()", __func__); + if (!client_ctx) { + ERR("\n Invalid client_ctx"); + return false; + } + + if (start) { + if (client_ctx->seq_header_set) { + DBG("%s(): Seq Hdr set: Send START_DONE to client", + __func__); + vdec_msg = kzalloc(sizeof(*vdec_msg), GFP_KERNEL); + if (!vdec_msg) { + ERR("vid_dec_start_stop: cannot allocate" + "buffer\n"); + return false; + } + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_RESP_START_DONE; + vdec_msg->vdec_msg_info.status_code = VDEC_S_SUCCESS; + vdec_msg->vdec_msg_info.msgdatasize = 0; + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&vdec_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + + wake_up(&client_ctx->msg_wait); + + DBG("Send START_DONE message to client = %p\n", + client_ctx); + + } else { + DBG("%s(): Calling decode_start()", __func__); + vcd_status = + vcd_decode_start(client_ctx->vcd_handle, NULL); + + if (vcd_status) { + ERR("%s(): vcd_decode_start failed." + " vcd_status = %u\n", __func__, vcd_status); + return false; + } + } + } else { + DBG("%s(): Calling vcd_stop()", __func__); + mutex_lock(&vid_dec_device_p->lock); + vcd_status = VCD_ERR_FAIL; + if (!client_ctx->stop_called) { + client_ctx->stop_called = true; + vcd_status = vcd_stop(client_ctx->vcd_handle); + } + if (vcd_status) { + ERR("%s(): vcd_stop failed. vcd_status = %u\n", + __func__, vcd_status); + mutex_unlock(&vid_dec_device_p->lock); + return false; + } + DBG("Send STOP_DONE message to client = %p\n", client_ctx); + mutex_unlock(&vid_dec_device_p->lock); + } + return true; +} + +static u32 vid_dec_decode_frame(struct video_client_ctx *client_ctx, + struct vdec_input_frameinfo *input_frame_info, + u8 *desc_buf, u32 desc_size) +{ + struct vcd_frame_data vcd_input_buffer; + unsigned long kernel_vaddr, phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + u32 vcd_status = VCD_ERR_FAIL; + u32 ion_flag = 0; + struct ion_handle *buff_handle = NULL; + + if (!client_ctx || !input_frame_info) + return false; + + user_vaddr = (unsigned long)input_frame_info->bufferaddr; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT, + true, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + /* kernel_vaddr is found. send the frame to VCD */ + memset((void *)&vcd_input_buffer, 0, + sizeof(struct vcd_frame_data)); + vcd_input_buffer.virtual = + (u8 *) (kernel_vaddr + input_frame_info->pmem_offset); + vcd_input_buffer.offset = input_frame_info->offset; + vcd_input_buffer.frm_clnt_data = + (u32) input_frame_info->client_data; + vcd_input_buffer.ip_frm_tag = + (u32) input_frame_info->client_data; + vcd_input_buffer.data_len = input_frame_info->datalen; + vcd_input_buffer.time_stamp = input_frame_info->timestamp; + /* Rely on VCD using the same flags as OMX */ + vcd_input_buffer.flags = input_frame_info->flags; + vcd_input_buffer.desc_buf = desc_buf; + vcd_input_buffer.desc_size = desc_size; + if (vcd_input_buffer.data_len > 0) { + ion_flag = vidc_get_fd_info(client_ctx, + BUFFER_TYPE_INPUT, + pmem_fd, + kernel_vaddr, + buffer_index, + &buff_handle); + if (ion_flag == CACHED && buff_handle) { + msm_ion_do_cache_op(client_ctx->user_ion_client, + buff_handle, + (unsigned long *)kernel_vaddr, + (unsigned long) vcd_input_buffer.data_len, + ION_IOC_CLEAN_CACHES); + } + } + vcd_status = vcd_decode_frame(client_ctx->vcd_handle, + &vcd_input_buffer); + if (!vcd_status) + return true; + else { + ERR("%s(): vcd_decode_frame failed = %u\n", __func__, + vcd_status); + return false; + } + + } else { + ERR("%s(): kernel_vaddr not found\n", __func__); + return false; + } +} + +static u32 vid_dec_fill_output_buffer(struct video_client_ctx *client_ctx, + struct vdec_fillbuffer_cmd *fill_buffer_cmd) +{ + unsigned long kernel_vaddr, phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + u32 vcd_status = VCD_ERR_FAIL; + struct ion_handle *buff_handle = NULL; + + struct vcd_frame_data vcd_frame; + + if (!client_ctx || !fill_buffer_cmd) + return false; + + user_vaddr = (unsigned long)fill_buffer_cmd->buffer.bufferaddr; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, + true, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + memset((void *)&vcd_frame, 0, + sizeof(struct vcd_frame_data)); + vcd_frame.virtual = (u8 *) kernel_vaddr; + vcd_frame.frm_clnt_data = (u32) fill_buffer_cmd->client_data; + vcd_frame.alloc_len = fill_buffer_cmd->buffer.buffer_len; + vcd_frame.ion_flag = vidc_get_fd_info(client_ctx, + BUFFER_TYPE_OUTPUT, + pmem_fd, kernel_vaddr, + buffer_index, + &buff_handle); + vcd_frame.buff_ion_handle = buff_handle; + vcd_status = vcd_fill_output_buffer(client_ctx->vcd_handle, + &vcd_frame); + if (!vcd_status) + return true; + else { + ERR("%s(): vcd_fill_output_buffer failed = %u\n", + __func__, vcd_status); + return false; + } + } else { + ERR("%s(): kernel_vaddr not found\n", __func__); + return false; + } +} + + +static u32 vid_dec_flush(struct video_client_ctx *client_ctx, + enum vdec_bufferflush flush_dir) +{ + u32 vcd_status = VCD_ERR_FAIL; + + DBG("msm_vidc_dec: %s() called with dir = %u", __func__, + flush_dir); + if (!client_ctx) { + ERR("\n Invalid client_ctx"); + return false; + } + + switch (flush_dir) { + case VDEC_FLUSH_TYPE_INPUT: + vcd_status = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_INPUT); + break; + case VDEC_FLUSH_TYPE_OUTPUT: + vcd_status = vcd_flush(client_ctx->vcd_handle, + VCD_FLUSH_OUTPUT); + break; + case VDEC_FLUSH_TYPE_ALL: + vcd_status = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_ALL); + break; + default: + ERR("%s(): Inavlid flush cmd. flush_dir = %u\n", __func__, + flush_dir); + return false; + break; + } + + if (!vcd_status) + return true; + else { + ERR("%s(): vcd_flush failed. vcd_status = %u " + " flush_dir = %u\n", __func__, vcd_status, flush_dir); + return false; + } +} + +static u32 vid_dec_msg_pending(struct video_client_ctx *client_ctx) +{ + u32 islist_empty = 0; + mutex_lock(&client_ctx->msg_queue_lock); + islist_empty = list_empty(&client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + + if (islist_empty) { + DBG("%s(): vid_dec msg queue empty\n", __func__); + if (client_ctx->stop_msg) { + DBG("%s(): List empty and Stop Msg set\n", + __func__); + return client_ctx->stop_msg; + } + } else + DBG("%s(): vid_dec msg queue Not empty\n", __func__); + + return !islist_empty; +} + +static int vid_dec_get_next_msg(struct video_client_ctx *client_ctx, + struct vdec_msginfo *vdec_msg_info) +{ + int rc; + struct vid_dec_msg *vid_dec_msg = NULL; + + if (!client_ctx) + return false; + + rc = wait_event_interruptible(client_ctx->msg_wait, + vid_dec_msg_pending(client_ctx)); + if (rc < 0) { + DBG("rc = %d, stop_msg = %u\n", rc, client_ctx->stop_msg); + return rc; + } else if (client_ctx->stop_msg) { + DBG("rc = %d, stop_msg = %u\n", rc, client_ctx->stop_msg); + return -EIO; + } + + mutex_lock(&client_ctx->msg_queue_lock); + if (!list_empty(&client_ctx->msg_queue)) { + DBG("%s(): After Wait\n", __func__); + vid_dec_msg = list_first_entry(&client_ctx->msg_queue, + struct vid_dec_msg, list); + list_del(&vid_dec_msg->list); + memcpy(vdec_msg_info, &vid_dec_msg->vdec_msg_info, + sizeof(struct vdec_msginfo)); + kfree(vid_dec_msg); + } + mutex_unlock(&client_ctx->msg_queue_lock); + return 0; +} + +static long vid_dec_ioctl(struct file *file, + unsigned cmd, unsigned long u_arg) +{ + struct video_client_ctx *client_ctx = NULL; + struct vdec_ioctl_msg vdec_msg; + u32 vcd_status; + unsigned long kernel_vaddr, phy_addr, len; + unsigned long ker_vaddr; + struct file *pmem_file; + u32 result = true; + void __user *arg = (void __user *)u_arg; + int rc = 0; + size_t ion_len; + + DBG("%s\n", __func__); + if (_IOC_TYPE(cmd) != VDEC_IOCTL_MAGIC) + return -ENOTTY; + + client_ctx = (struct video_client_ctx *)file->private_data; + if (!client_ctx) { + ERR("!client_ctx. Cannot attach to device handle\n"); + return -ENODEV; + } + + switch (cmd) { + case VDEC_IOCTL_SET_CODEC: + { + enum vdec_codec vdec_codec; + DBG("VDEC_IOCTL_SET_CODEC\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&vdec_codec, vdec_msg.in, + sizeof(vdec_codec))) + return -EFAULT; + DBG("setting code type = %u\n", vdec_codec); + result = vid_dec_set_codec(client_ctx, &vdec_codec); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_SET_OUTPUT_FORMAT: + { + enum vdec_output_fromat output_format; + DBG("VDEC_IOCTL_SET_OUTPUT_FORMAT\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&output_format, vdec_msg.in, + sizeof(output_format))) + return -EFAULT; + + result = vid_dec_set_output_format(client_ctx, &output_format); + + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_SET_PICRES: + { + struct vdec_picsize video_resoultion; + DBG("VDEC_IOCTL_SET_PICRES\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&video_resoultion, vdec_msg.in, + sizeof(video_resoultion))) + return -EFAULT; + result = + vid_dec_set_frame_resolution(client_ctx, &video_resoultion); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_GET_PICRES: + { + struct vdec_picsize video_resoultion; + DBG("VDEC_IOCTL_GET_PICRES\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&video_resoultion, vdec_msg.out, + sizeof(video_resoultion))) + return -EFAULT; + + result = vid_dec_get_frame_resolution(client_ctx, + &video_resoultion); + + if (result) { + if (copy_to_user(vdec_msg.out, &video_resoultion, + sizeof(video_resoultion))) + return -EFAULT; + } else + return -EIO; + break; + } + case VDEC_IOCTL_SET_BUFFER_REQ: + { + struct vdec_allocatorproperty vdec_buf_req; + struct vcd_buffer_requirement buffer_req; + DBG("VDEC_IOCTL_SET_BUFFER_REQ\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + + if (copy_from_user(&vdec_buf_req, vdec_msg.in, + sizeof(vdec_buf_req))) + return -EFAULT; + + buffer_req.actual_count = vdec_buf_req.actualcount; + buffer_req.align = vdec_buf_req.alignment; + buffer_req.max_count = vdec_buf_req.maxcount; + buffer_req.min_count = vdec_buf_req.mincount; + buffer_req.sz = vdec_buf_req.buffer_size; + + switch (vdec_buf_req.buffer_type) { + case VDEC_BUFFER_TYPE_INPUT: + vcd_status = + vcd_set_buffer_requirements(client_ctx->vcd_handle, + VCD_BUFFER_INPUT, &buffer_req); + break; + case VDEC_BUFFER_TYPE_OUTPUT: + vcd_status = + vcd_set_buffer_requirements(client_ctx->vcd_handle, + VCD_BUFFER_OUTPUT, &buffer_req); + break; + default: + vcd_status = VCD_ERR_BAD_POINTER; + break; + } + + if (vcd_status) + return -EFAULT; + break; + } + case VDEC_IOCTL_GET_BUFFER_REQ: + { + struct vdec_allocatorproperty vdec_buf_req; + DBG("VDEC_IOCTL_GET_BUFFER_REQ\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&vdec_buf_req, vdec_msg.out, + sizeof(vdec_buf_req))) + return -EFAULT; + + result = vid_dec_get_buffer_req(client_ctx, &vdec_buf_req); + + if (result) { + if (copy_to_user(vdec_msg.out, &vdec_buf_req, + sizeof(vdec_buf_req))) + return -EFAULT; + } else + return -EIO; + break; + } + case VDEC_IOCTL_SET_BUFFER: + { + struct vdec_setbuffer_cmd setbuffer; + DBG("VDEC_IOCTL_SET_BUFFER\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&setbuffer, vdec_msg.in, + sizeof(setbuffer))) + return -EFAULT; + result = vid_dec_set_buffer(client_ctx, &setbuffer); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_FREE_BUFFER: + { + struct vdec_setbuffer_cmd setbuffer; + DBG("VDEC_IOCTL_FREE_BUFFER\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&setbuffer, vdec_msg.in, + sizeof(setbuffer))) + return -EFAULT; + result = vid_dec_free_buffer(client_ctx, &setbuffer); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_CMD_START: + { + DBG(" VDEC_IOCTL_CMD_START\n"); + result = vid_dec_start_stop(client_ctx, true); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_CMD_STOP: + { + DBG("VDEC_IOCTL_CMD_STOP\n"); + result = vid_dec_start_stop(client_ctx, false); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_CMD_PAUSE: + { + result = vid_dec_pause_resume(client_ctx, true); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_CMD_RESUME: + { + DBG("VDEC_IOCTL_CMD_PAUSE\n"); + result = vid_dec_pause_resume(client_ctx, false); + + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_DECODE_FRAME: + { + struct vdec_input_frameinfo input_frame_info; + u8 *desc_buf = NULL; + u32 desc_size = 0; + DBG("VDEC_IOCTL_DECODE_FRAME\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&input_frame_info, vdec_msg.in, + sizeof(input_frame_info))) + return -EFAULT; + if (client_ctx->dmx_disable) { + if (input_frame_info.desc_addr) { + desc_size = input_frame_info.desc_size; + desc_buf = kzalloc(desc_size, GFP_KERNEL); + if (desc_buf) { + if (copy_from_user(desc_buf, + input_frame_info.desc_addr, + desc_size)) { + kfree(desc_buf); + desc_buf = NULL; + return -EFAULT; + } + } + } else + return -EINVAL; + } + result = vid_dec_decode_frame(client_ctx, &input_frame_info, + desc_buf, desc_size); + + if (!result) { + kfree(desc_buf); + desc_buf = NULL; + return -EIO; + } + break; + } + case VDEC_IOCTL_FILL_OUTPUT_BUFFER: + { + struct vdec_fillbuffer_cmd fill_buffer_cmd; + DBG("VDEC_IOCTL_FILL_OUTPUT_BUFFER\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&fill_buffer_cmd, vdec_msg.in, + sizeof(fill_buffer_cmd))) + return -EFAULT; + result = vid_dec_fill_output_buffer(client_ctx, + &fill_buffer_cmd); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_CMD_FLUSH: + { + enum vdec_bufferflush flush_dir; + DBG("VDEC_IOCTL_CMD_FLUSH\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&flush_dir, vdec_msg.in, + sizeof(flush_dir))) + return -EFAULT; + result = vid_dec_flush(client_ctx, flush_dir); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_GET_NEXT_MSG: + { + struct vdec_msginfo vdec_msg_info; + DBG("VDEC_IOCTL_GET_NEXT_MSG\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + result = vid_dec_get_next_msg(client_ctx, &vdec_msg_info); + if (result) + return result; + if (copy_to_user(vdec_msg.out, &vdec_msg_info, + sizeof(vdec_msg_info))) + return -EFAULT; + break; + } + case VDEC_IOCTL_STOP_NEXT_MSG: + { + DBG("VDEC_IOCTL_STOP_NEXT_MSG\n"); + client_ctx->stop_msg = 1; + wake_up(&client_ctx->msg_wait); + break; + } + case VDEC_IOCTL_SET_SEQUENCE_HEADER: + { + struct vdec_seqheader seq_header; + struct vcd_sequence_hdr vcd_seq_hdr; + unsigned long ionflag; + DBG("VDEC_IOCTL_SET_SEQUENCE_HEADER\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) { + ERR("Copy from user vdec_msg failed\n"); + return -EFAULT; + } + if (copy_from_user(&seq_header, vdec_msg.in, + sizeof(seq_header))) { + ERR("Copy from user seq_header failed\n"); + return -EFAULT; + } + if (!seq_header.seq_header_len) { + ERR("Seq Len is Zero\n"); + return -EFAULT; + } + + if (!vcd_get_ion_status()) { + if (get_pmem_file(seq_header.pmem_fd, + &phy_addr, &kernel_vaddr, &len, &pmem_file)) { + ERR("%s(): get_pmem_file failed\n", __func__); + return false; + } + put_pmem_file(pmem_file); + } else { + client_ctx->seq_hdr_ion_handle = ion_import_fd( + client_ctx->user_ion_client, + seq_header.pmem_fd); + if (!client_ctx->seq_hdr_ion_handle) { + ERR("%s(): get_ION_handle failed\n", __func__); + return false; + } + rc = ion_handle_get_flags(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle, + &ionflag); + if (rc) { + ERR("%s():get_ION_flags fail\n", + __func__); + ion_free(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle); + return false; + } + ker_vaddr = (unsigned long) ion_map_kernel( + client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle, ionflag); + if (!ker_vaddr) { + ERR("%s():get_ION_kernel virtual addr fail\n", + __func__); + ion_free(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle); + return false; + } + kernel_vaddr = ker_vaddr; + rc = ion_phys(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle, + &phy_addr, &ion_len); + if (rc) { + ERR("%s():get_ION_kernel physical addr fail\n", + __func__); + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle); + ion_free(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle); + return false; + } + len = ion_len; + } + vcd_seq_hdr.sequence_header_len = seq_header.seq_header_len; + kernel_vaddr += (unsigned long)seq_header.pmem_offset; + vcd_seq_hdr.sequence_header = (u8 *)kernel_vaddr; + if (!vcd_seq_hdr.sequence_header) { + ERR("Sequence Header pointer failed\n"); + return -EFAULT; + } + client_ctx->seq_header_set = true; + if (vcd_decode_start(client_ctx->vcd_handle, &vcd_seq_hdr)) { + ERR("Decode start Failed\n"); + client_ctx->seq_header_set = false; + return -EFAULT; + } + DBG("Wait Client completion Sequence Header\n"); + wait_for_completion(&client_ctx->event); + vcd_seq_hdr.sequence_header = NULL; + if (client_ctx->event_status) { + ERR("Set Seq Header status is failed"); + return -EFAULT; + } + if (vcd_get_ion_status()) { + if (client_ctx->seq_hdr_ion_handle) { + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle); + ion_free(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle); + } + } + break; + } + case VDEC_IOCTL_GET_NUMBER_INSTANCES: + { + DBG("VDEC_IOCTL_GET_NUMBER_INSTANCES\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_to_user(vdec_msg.out, + &vid_dec_device_p->num_clients, sizeof(u32))) + return -EFAULT; + break; + } + case VDEC_IOCTL_GET_INTERLACE_FORMAT: + { + u32 progressive_only, interlace_format; + DBG("VDEC_IOCTL_GET_INTERLACE_FORMAT\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + result = vid_dec_get_progressive_only(client_ctx, + &progressive_only); + if (result) { + interlace_format = progressive_only ? + VDEC_InterlaceFrameProgressive : + VDEC_InterlaceInterleaveFrameTopFieldFirst; + if (copy_to_user(vdec_msg.out, &interlace_format, + sizeof(u32))) + return -EFAULT; + } else + return -EIO; + break; + } + + case VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT: + { + u32 disable_dmx; + DBG("VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + result = vid_dec_get_disable_dmx_support(client_ctx, + &disable_dmx); + if (result) { + if (copy_to_user(vdec_msg.out, &disable_dmx, + sizeof(u32))) + return -EFAULT; + } else + return -EIO; + break; + } + case VDEC_IOCTL_GET_DISABLE_DMX: + { + u32 disable_dmx; + DBG("VDEC_IOCTL_GET_DISABLE_DMX\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + result = vid_dec_get_disable_dmx(client_ctx, + &disable_dmx); + if (result) { + if (copy_to_user(vdec_msg.out, &disable_dmx, + sizeof(u32))) + return -EFAULT; + } else + return -EIO; + break; + } + case VDEC_IOCTL_SET_DISABLE_DMX: + { + DBG("VDEC_IOCTL_SET_DISABLE_DMX\n"); + result = vid_dec_set_disable_dmx(client_ctx); + if (!result) + return -EIO; + client_ctx->dmx_disable = 1; + break; + } + case VDEC_IOCTL_SET_PICTURE_ORDER: + { + u32 picture_order; + DBG("VDEC_IOCTL_SET_PICTURE_ORDER\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&picture_order, vdec_msg.in, + sizeof(u32))) + return -EFAULT; + result = vid_dec_set_picture_order(client_ctx, &picture_order); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_SET_FRAME_RATE: + { + struct vdec_framerate frame_rate; + DBG("VDEC_IOCTL_SET_FRAME_RATE\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&frame_rate, vdec_msg.in, + sizeof(frame_rate))) + return -EFAULT; + result = vid_dec_set_frame_rate(client_ctx, &frame_rate); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_SET_EXTRADATA: + { + u32 extradata_flag; + DBG("VDEC_IOCTL_SET_EXTRADATA\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&extradata_flag, vdec_msg.in, + sizeof(u32))) + return -EFAULT; + result = vid_dec_set_extradata(client_ctx, &extradata_flag); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_SET_H264_MV_BUFFER: + { + struct vdec_h264_mv mv_data; + DBG("VDEC_IOCTL_SET_H264_MV_BUFFER\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&mv_data, vdec_msg.in, + sizeof(mv_data))) + return -EFAULT; + result = vid_dec_set_h264_mv_buffers(client_ctx, &mv_data); + + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_FREE_H264_MV_BUFFER: + { + DBG("VDEC_IOCTL_FREE_H264_MV_BUFFER\n"); + result = vid_dec_free_h264_mv_buffers(client_ctx); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_GET_MV_BUFFER_SIZE: + { + struct vdec_mv_buff_size mv_buff; + DBG("VDEC_IOCTL_GET_MV_BUFFER_SIZE\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&mv_buff, vdec_msg.out, + sizeof(mv_buff))) + return -EFAULT; + result = vid_dec_get_h264_mv_buffer_size(client_ctx, &mv_buff); + if (result) { + DBG(" Returning W: %d, H: %d, S: %d, A: %d", + mv_buff.width, mv_buff.height, + mv_buff.size, mv_buff.alignment); + if (copy_to_user(vdec_msg.out, &mv_buff, + sizeof(mv_buff))) + return -EFAULT; + } else + return -EIO; + break; + } + case VDEC_IOCTL_SET_IDR_ONLY_DECODING: + { + result = vid_dec_set_idr_only_decoding(client_ctx); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_SET_CONT_ON_RECONFIG: + { + result = vid_dec_set_cont_on_reconfig(client_ctx); + if (!result) + return -EIO; + break; + } + default: + ERR("%s(): Unsupported ioctl\n", __func__); + return -ENOTTY; + break; + } + + return 0; +} + +static u32 vid_dec_close_client(struct video_client_ctx *client_ctx) +{ + struct vid_dec_msg *vdec_msg; + u32 vcd_status; + + DBG("msm_vidc_dec: Inside %s()", __func__); + if (!client_ctx || (!client_ctx->vcd_handle)) { + ERR("\n Invalid client_ctx"); + return false; + } + + mutex_lock(&vid_dec_device_p->lock); + if (!client_ctx->stop_called) { + client_ctx->stop_called = true; + client_ctx->stop_sync_cb = true; + vcd_status = vcd_stop(client_ctx->vcd_handle); + DBG("\n Stuck at the stop call"); + if (!vcd_status) + wait_for_completion(&client_ctx->event); + DBG("\n Came out of wait event"); + } + mutex_lock(&client_ctx->msg_queue_lock); + while (!list_empty(&client_ctx->msg_queue)) { + DBG("%s(): Delete remaining entries\n", __func__); + vdec_msg = list_first_entry(&client_ctx->msg_queue, + struct vid_dec_msg, list); + if (vdec_msg) { + list_del(&vdec_msg->list); + kfree(vdec_msg); + } + } + mutex_unlock(&client_ctx->msg_queue_lock); + vcd_status = vcd_close(client_ctx->vcd_handle); + + if (vcd_status) { + mutex_unlock(&vid_dec_device_p->lock); + return false; + } + client_ctx->user_ion_client = NULL; + memset((void *)client_ctx, 0, sizeof(struct video_client_ctx)); + vid_dec_device_p->num_clients--; + mutex_unlock(&vid_dec_device_p->lock); + return true; +} + +int vid_dec_open_client(struct video_client_ctx **vid_clnt_ctx, int flags) +{ + int rc = 0; + s32 client_index; + struct video_client_ctx *client_ctx = NULL; + u8 client_count; + + if (!vid_clnt_ctx) { + ERR("Invalid input\n"); + return -EINVAL; + } + *vid_clnt_ctx = NULL; + client_count = vcd_get_num_of_clients(); + if (client_count == VIDC_MAX_NUM_CLIENTS) { + ERR("ERROR : vid_dec_open() max number of clients" + "limit reached\n"); + rc = -ENOMEM; + goto client_failure; + } + + DBG(" Virtual Address of ioremap is %p\n", vid_dec_device_p->virt_base); + if (!vid_dec_device_p->num_clients) { + if (!vidc_load_firmware()) { + rc = -ENOMEM; + goto client_failure; + } + } + + client_index = vid_dec_get_empty_client_index(); + if (client_index == -1) { + ERR("%s() : No free clients client_index == -1\n", __func__); + rc = -ENOMEM; + goto client_failure; + } + client_ctx = &vid_dec_device_p->vdec_clients[client_index]; + vid_dec_device_p->num_clients++; + init_completion(&client_ctx->event); + mutex_init(&client_ctx->msg_queue_lock); + mutex_init(&client_ctx->enrty_queue_lock); + INIT_LIST_HEAD(&client_ctx->msg_queue); + init_waitqueue_head(&client_ctx->msg_wait); + client_ctx->stop_msg = 0; + client_ctx->stop_called = false; + client_ctx->stop_sync_cb = false; + client_ctx->dmx_disable = 0; + if (vcd_get_ion_status()) { + client_ctx->user_ion_client = vcd_get_ion_client(); + if (!client_ctx->user_ion_client) { + ERR("vcd_open ion client get failed"); + rc = -ENOMEM; + goto client_failure; + } + } + rc = vcd_open(vid_dec_device_p->device_handle, true, + vid_dec_vcd_cb, client_ctx, flags); + if (!rc) { + wait_for_completion(&client_ctx->event); + if (client_ctx->event_status) { + ERR("callback for vcd_open returned error: %u", + client_ctx->event_status); + rc = -ENODEV; + goto client_failure; + } + } else { + ERR("vcd_open returned error: %u", rc); + goto client_failure; + } + client_ctx->seq_header_set = false; + *vid_clnt_ctx = client_ctx; +client_failure: + return rc; +} + +static int vid_dec_open_secure(struct inode *inode, struct file *file) +{ + int rc = 0; + struct video_client_ctx *client_ctx; + mutex_lock(&vid_dec_device_p->lock); + rc = vid_dec_open_client(&client_ctx, VCD_CP_SESSION); + if (rc) + goto error; + if (!client_ctx) { + rc = -ENOMEM; + goto error; + } + + file->private_data = client_ctx; + if (res_trk_open_secure_session()) { + ERR("Secure session operation failure\n"); + rc = -EACCES; + goto error; + } + mutex_unlock(&vid_dec_device_p->lock); + return 0; +error: + mutex_unlock(&vid_dec_device_p->lock); + return rc; +} + +static int vid_dec_open(struct inode *inode, struct file *file) +{ + int rc = 0; + struct video_client_ctx *client_ctx; + INFO("msm_vidc_dec: Inside %s()", __func__); + mutex_lock(&vid_dec_device_p->lock); + rc = vid_dec_open_client(&client_ctx, 0); + if (rc) { + mutex_unlock(&vid_dec_device_p->lock); + return rc; + } + if (!client_ctx) { + mutex_unlock(&vid_dec_device_p->lock); + return -ENOMEM; + } + + file->private_data = client_ctx; + mutex_unlock(&vid_dec_device_p->lock); + return rc; +} + +static int vid_dec_release_secure(struct inode *inode, struct file *file) +{ + struct video_client_ctx *client_ctx = file->private_data; + + INFO("msm_vidc_dec: Inside %s()", __func__); + vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT); + vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_INPUT); + vid_dec_close_client(client_ctx); + vidc_release_firmware(); +#ifndef USE_RES_TRACKER + vidc_disable_clk(); +#endif + INFO("msm_vidc_dec: Return from %s()", __func__); + return 0; +} + +static int vid_dec_release(struct inode *inode, struct file *file) +{ + struct video_client_ctx *client_ctx = file->private_data; + + INFO("msm_vidc_dec: Inside %s()", __func__); + vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT); + vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_INPUT); + vid_dec_close_client(client_ctx); + vidc_release_firmware(); +#ifndef USE_RES_TRACKER + vidc_disable_clk(); +#endif + INFO("msm_vidc_dec: Return from %s()", __func__); + return 0; +} + +static const struct file_operations vid_dec_fops[2] = { + { + .owner = THIS_MODULE, + .open = vid_dec_open, + .release = vid_dec_release, + .unlocked_ioctl = vid_dec_ioctl, + }, + { + .owner = THIS_MODULE, + .open = vid_dec_open_secure, + .release = vid_dec_release_secure, + .unlocked_ioctl = vid_dec_ioctl, + }, + +}; + +void vid_dec_interrupt_deregister(void) +{ +} + +void vid_dec_interrupt_register(void *device_name) +{ +} + +void vid_dec_interrupt_clear(void) +{ +} + +void *vid_dec_map_dev_base_addr(void *device_name) +{ + return vid_dec_device_p->virt_base; +} + +static int vid_dec_vcd_init(void) +{ + int rc; + struct vcd_init_config vcd_init_config; + u32 i; + + /* init_timer(&hw_timer); */ + DBG("msm_vidc_dec: Inside %s()", __func__); + vid_dec_device_p->num_clients = 0; + + for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) { + memset((void *)&vid_dec_device_p->vdec_clients[i], 0, + sizeof(vid_dec_device_p->vdec_clients[i])); + } + + mutex_init(&vid_dec_device_p->lock); + vid_dec_device_p->virt_base = vidc_get_ioaddr(); + DBG("%s() : base address for VIDC core %u\n", __func__, \ + (int)vid_dec_device_p->virt_base); + + if (!vid_dec_device_p->virt_base) { + ERR("%s() : ioremap failed\n", __func__); + return -ENOMEM; + } + + vcd_init_config.device_name = "VIDC"; + vcd_init_config.map_dev_base_addr = vid_dec_map_dev_base_addr; + vcd_init_config.interrupt_clr = vid_dec_interrupt_clear; + vcd_init_config.register_isr = vid_dec_interrupt_register; + vcd_init_config.deregister_isr = vid_dec_interrupt_deregister; + vcd_init_config.timer_create = vidc_timer_create; + vcd_init_config.timer_release = vidc_timer_release; + vcd_init_config.timer_start = vidc_timer_start; + vcd_init_config.timer_stop = vidc_timer_stop; + + rc = vcd_init(&vcd_init_config, &vid_dec_device_p->device_handle); + + if (rc) { + ERR("%s() : vcd_init failed\n", __func__); + return -ENODEV; + } + return 0; +} + +static int __init vid_dec_init(void) +{ + int rc = 0, i = 0, j = 0; + struct device *class_devp; + + DBG("msm_vidc_dec: Inside %s()", __func__); + vid_dec_device_p = kzalloc(sizeof(struct vid_dec_dev), GFP_KERNEL); + if (!vid_dec_device_p) { + ERR("%s Unable to allocate memory for vid_dec_dev\n", + __func__); + return -ENOMEM; + } + + rc = alloc_chrdev_region(&vid_dec_dev_num, 0, NUM_OF_DRIVER_NODES, + VID_DEC_NAME); + if (rc < 0) { + ERR("%s: alloc_chrdev_region Failed rc = %d\n", + __func__, rc); + goto error_vid_dec_alloc_chrdev_region; + } + + vid_dec_class = class_create(THIS_MODULE, VID_DEC_NAME); + if (IS_ERR(vid_dec_class)) { + rc = PTR_ERR(vid_dec_class); + ERR("%s: couldn't create vid_dec_class rc = %d\n", + __func__, rc); + + goto error_vid_dec_class_create; + } + for (i = 0; i < NUM_OF_DRIVER_NODES; i++) { + class_devp = device_create(vid_dec_class, NULL, + (vid_dec_dev_num + i), + NULL, VID_DEC_NAME "%s", + node_name[i]); + + if (IS_ERR(class_devp)) { + rc = PTR_ERR(class_devp); + ERR("%s: class device_create failed %d\n", + __func__, rc); + if (!i) + goto error_vid_dec_class_device_create; + else + goto error_vid_dec_cdev_add; + } + + vid_dec_device_p->device[i] = class_devp; + + cdev_init(&vid_dec_device_p->cdev[i], &vid_dec_fops[i]); + vid_dec_device_p->cdev[i].owner = THIS_MODULE; + rc = cdev_add(&(vid_dec_device_p->cdev[i]), + (vid_dec_dev_num+i), 1); + + if (rc < 0) { + ERR("%s: cdev_add failed %d\n", __func__, rc); + goto error_vid_dec_cdev_add; + } + } + vid_dec_vcd_init(); + return 0; + +error_vid_dec_cdev_add: + for (j = i-1; j >= 0; j--) + cdev_del(&(vid_dec_device_p->cdev[j])); + device_destroy(vid_dec_class, vid_dec_dev_num); +error_vid_dec_class_device_create: + class_destroy(vid_dec_class); +error_vid_dec_class_create: + unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES); +error_vid_dec_alloc_chrdev_region: + kfree(vid_dec_device_p); + return rc; +} + +static void __exit vid_dec_exit(void) +{ + int i = 0; + INFO("msm_vidc_dec: Inside %s()", __func__); + for (i = 0; i < NUM_OF_DRIVER_NODES; i++) + cdev_del(&(vid_dec_device_p->cdev[i])); + device_destroy(vid_dec_class, vid_dec_dev_num); + class_destroy(vid_dec_class); + unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES); + kfree(vid_dec_device_p); + DBG("msm_vidc_dec: Return from %s()", __func__); +} + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Video decoder driver"); +MODULE_VERSION("1.0"); + +module_init(vid_dec_init); +module_exit(vid_dec_exit); diff --git a/drivers/video/msm/vidc/common/dec/vdec_internal.h b/drivers/video/msm/vidc/common/dec/vdec_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..a7a32a58e062e4568f39327765243f1ed224bad6 --- /dev/null +++ b/drivers/video/msm/vidc/common/dec/vdec_internal.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2010, 2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef VDEC_INTERNAL_H +#define VDEC_INTERNAL_H + +#include +#include +#include + +#define NUM_OF_DRIVER_NODES 2 + +struct vid_dec_msg { + struct list_head list; + struct vdec_msginfo vdec_msg_info; +}; + +struct vid_dec_dev { + struct cdev cdev[NUM_OF_DRIVER_NODES]; + struct device *device[NUM_OF_DRIVER_NODES]; + resource_size_t phys_base; + void __iomem *virt_base; + unsigned int irq; + struct clk *hclk; + struct clk *hclk_div2; + struct clk *pclk; + unsigned long hclk_rate; + struct mutex lock; + s32 device_handle; + struct video_client_ctx vdec_clients[VIDC_MAX_NUM_CLIENTS]; + u32 num_clients; + void(*timer_handler)(void *); +}; + +#endif diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c new file mode 100644 index 0000000000000000000000000000000000000000..29b74d176e36b9d1db941c47a5510dcbac7b64cb --- /dev/null +++ b/drivers/video/msm/vidc/common/enc/venc.c @@ -0,0 +1,1650 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "venc_internal.h" +#include "vcd_res_tracker_api.h" + +#define VID_ENC_NAME "msm_vidc_enc" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define INFO(x...) printk(KERN_INFO x) +#define ERR(x...) printk(KERN_ERR x) + +static struct vid_enc_dev *vid_enc_device_p; +static dev_t vid_enc_dev_num; +static struct class *vid_enc_class; +static long vid_enc_ioctl(struct file *file, + unsigned cmd, unsigned long arg); +static int stop_cmd; + +static s32 vid_enc_get_empty_client_index(void) +{ + u32 i; + u32 found = false; + + for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) { + if (!vid_enc_device_p->venc_clients[i].vcd_handle) { + found = true; + break; + } + } + if (!found) { + ERR("%s():ERROR No space for new client\n", + __func__); + return -ENOMEM; + } else { + DBG("%s(): available client index = %u\n", + __func__, i); + return i; + } +} + + +u32 vid_enc_get_status(u32 status) +{ + u32 venc_status; + + switch (status) { + case VCD_S_SUCCESS: + venc_status = VEN_S_SUCCESS; + break; + case VCD_ERR_FAIL: + venc_status = VEN_S_EFAIL; + break; + case VCD_ERR_ALLOC_FAIL: + venc_status = VEN_S_ENOSWRES; + break; + case VCD_ERR_ILLEGAL_OP: + venc_status = VEN_S_EINVALCMD; + break; + case VCD_ERR_ILLEGAL_PARM: + venc_status = VEN_S_EBADPARAM; + break; + case VCD_ERR_BAD_POINTER: + case VCD_ERR_BAD_HANDLE: + venc_status = VEN_S_EFATAL; + break; + case VCD_ERR_NOT_SUPPORTED: + venc_status = VEN_S_ENOTSUPP; + break; + case VCD_ERR_BAD_STATE: + venc_status = VEN_S_EINVALSTATE; + break; + case VCD_ERR_MAX_CLIENT: + venc_status = VEN_S_ENOHWRES; + break; + default: + venc_status = VEN_S_EFAIL; + break; + } + return venc_status; +} + +static void vid_enc_notify_client(struct video_client_ctx *client_ctx) +{ + if (client_ctx) + complete(&client_ctx->event); +} + +void vid_enc_vcd_open_done(struct video_client_ctx *client_ctx, + struct vcd_handle_container *handle_container) +{ + DBG("vid_enc_vcd_open_done\n"); + + if (client_ctx) { + if (handle_container) + client_ctx->vcd_handle = handle_container->handle; + else + ERR("%s(): ERROR. handle_container is NULL\n", + __func__); + vid_enc_notify_client(client_ctx); + } else + ERR("%s(): ERROR. client_ctx is NULL\n", + __func__); +} + +static void vid_enc_input_frame_done(struct video_client_ctx *client_ctx, + u32 event, u32 status, + struct vcd_frame_data *vcd_frame_data) +{ + struct vid_enc_msg *venc_msg; + + if (!client_ctx || !vcd_frame_data) { + ERR("vid_enc_input_frame_done() NULL pointer\n"); + return; + } + + venc_msg = kzalloc(sizeof(struct vid_enc_msg), + GFP_KERNEL); + if (!venc_msg) { + ERR("vid_enc_input_frame_done(): cannot allocate vid_enc_msg " + " buffer\n"); + return; + } + + venc_msg->venc_msg_info.statuscode = vid_enc_get_status(status); + + venc_msg->venc_msg_info.msgcode = VEN_MSG_INPUT_BUFFER_DONE; + + switch (event) { + case VCD_EVT_RESP_INPUT_DONE: + DBG("Send INPUT_DON message to client = %p\n", + client_ctx); + break; + case VCD_EVT_RESP_INPUT_FLUSHED: + DBG("Send INPUT_FLUSHED message to client = %p\n", + client_ctx); + break; + default: + ERR("vid_enc_input_frame_done(): invalid event type: " + "%d\n", event); + venc_msg->venc_msg_info.statuscode = VEN_S_EFATAL; + break; + } + + venc_msg->venc_msg_info.buf.clientdata = + (void *)vcd_frame_data->frm_clnt_data; + venc_msg->venc_msg_info.msgdata_size = + sizeof(struct vid_enc_msg); + + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&venc_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + +static void vid_enc_output_frame_done(struct video_client_ctx *client_ctx, + u32 event, u32 status, + struct vcd_frame_data *vcd_frame_data) +{ + struct vid_enc_msg *venc_msg; + unsigned long kernel_vaddr, phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + u32 ion_flag = 0; + struct ion_handle *buff_handle = NULL; + + if (!client_ctx || !vcd_frame_data) { + ERR("vid_enc_input_frame_done() NULL pointer\n"); + return; + } + + venc_msg = kzalloc(sizeof(struct vid_enc_msg), + GFP_KERNEL); + if (!venc_msg) { + ERR("vid_enc_input_frame_done(): cannot allocate vid_enc_msg " + " buffer\n"); + return; + } + + venc_msg->venc_msg_info.statuscode = vid_enc_get_status(status); + venc_msg->venc_msg_info.msgcode = VEN_MSG_OUTPUT_BUFFER_DONE; + + switch (event) { + case VCD_EVT_RESP_OUTPUT_DONE: + DBG("Send INPUT_DON message to client = %p\n", + client_ctx); + break; + case VCD_EVT_RESP_OUTPUT_FLUSHED: + DBG("Send INPUT_FLUSHED message to client = %p\n", + client_ctx); + break; + default: + ERR("QVD: vid_enc_output_frame_done invalid cmd type: %d\n", event); + venc_msg->venc_msg_info.statuscode = VEN_S_EFATAL; + break; + } + + kernel_vaddr = + (unsigned long)vcd_frame_data->virtual; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, + false, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + /* Buffer address in user space */ + venc_msg->venc_msg_info.buf.ptrbuffer = (u8 *) user_vaddr; + /* Buffer address in user space */ + venc_msg->venc_msg_info.buf.clientdata = (void *) + vcd_frame_data->frm_clnt_data; + /* Data length */ + venc_msg->venc_msg_info.buf.len = + vcd_frame_data->data_len; + venc_msg->venc_msg_info.buf.flags = + vcd_frame_data->flags; + /* Timestamp pass-through from input frame */ + venc_msg->venc_msg_info.buf.timestamp = + vcd_frame_data->time_stamp; + venc_msg->venc_msg_info.buf.sz = + vcd_frame_data->alloc_len; + + /* Decoded picture width and height */ + venc_msg->venc_msg_info.msgdata_size = + sizeof(struct venc_buffer); + } else { + ERR("vid_enc_output_frame_done UVA can not be found\n"); + venc_msg->venc_msg_info.statuscode = + VEN_S_EFATAL; + } + if (venc_msg->venc_msg_info.buf.len > 0) { + ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT, + pmem_fd, kernel_vaddr, buffer_index, + &buff_handle); + if (ion_flag == CACHED && buff_handle) { + msm_ion_do_cache_op(client_ctx->user_ion_client, + buff_handle, + (unsigned long *) kernel_vaddr, + (unsigned long)venc_msg->venc_msg_info.buf.sz, + ION_IOC_CLEAN_INV_CACHES); + } + } + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&venc_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + +static void vid_enc_lean_event(struct video_client_ctx *client_ctx, + u32 event, u32 status) +{ + struct vid_enc_msg *venc_msg; + if (!client_ctx) { + ERR("%s(): !client_ctx pointer\n", + __func__); + return; + } + + venc_msg = kzalloc(sizeof(struct vid_enc_msg), + GFP_KERNEL); + if (!venc_msg) { + ERR("%s(): cannot allocate vid_enc_msg buffer\n", + __func__); + return; + } + + venc_msg->venc_msg_info.statuscode = + vid_enc_get_status(status); + + switch (event) { + case VCD_EVT_RESP_FLUSH_INPUT_DONE: + INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_FLUSH_INPUT_DONE" + " to client"); + venc_msg->venc_msg_info.msgcode = + VEN_MSG_FLUSH_INPUT_DONE; + break; + case VCD_EVT_RESP_FLUSH_OUTPUT_DONE: + INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_FLUSH_OUTPUT_DONE" + " to client"); + venc_msg->venc_msg_info.msgcode = + VEN_MSG_FLUSH_OUPUT_DONE; + break; + + case VCD_EVT_RESP_START: + INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_START" + " to client"); + venc_msg->venc_msg_info.msgcode = + VEN_MSG_START; + break; + + case VCD_EVT_RESP_STOP: + INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_STOP" + " to client"); + venc_msg->venc_msg_info.msgcode = + VEN_MSG_STOP; + break; + + case VCD_EVT_RESP_PAUSE: + INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_PAUSE" + " to client"); + venc_msg->venc_msg_info.msgcode = + VEN_MSG_PAUSE; + break; + + default: + ERR("%s() : unknown event type %u\n", + __func__, event); + break; + } + + venc_msg->venc_msg_info.msgdata_size = 0; + + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&venc_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + + +void vid_enc_vcd_cb(u32 event, u32 status, + void *info, size_t sz, void *handle, + void *const client_data) +{ + struct video_client_ctx *client_ctx = + (struct video_client_ctx *)client_data; + + DBG("Entering %s()\n", __func__); + + if (!client_ctx) { + ERR("%s(): client_ctx is NULL\n", __func__); + return; + } + + client_ctx->event_status = status; + + switch (event) { + case VCD_EVT_RESP_OPEN: + vid_enc_vcd_open_done(client_ctx, + (struct vcd_handle_container *)info); + break; + + case VCD_EVT_RESP_INPUT_DONE: + case VCD_EVT_RESP_INPUT_FLUSHED: + vid_enc_input_frame_done(client_ctx, event, + status, (struct vcd_frame_data *)info); + break; + + case VCD_EVT_RESP_OUTPUT_DONE: + case VCD_EVT_RESP_OUTPUT_FLUSHED: + vid_enc_output_frame_done(client_ctx, event, status, + (struct vcd_frame_data *)info); + break; + + case VCD_EVT_RESP_PAUSE: + case VCD_EVT_RESP_START: + case VCD_EVT_RESP_STOP: + case VCD_EVT_RESP_FLUSH_INPUT_DONE: + case VCD_EVT_RESP_FLUSH_OUTPUT_DONE: + case VCD_EVT_IND_OUTPUT_RECONFIG: + case VCD_EVT_IND_HWERRFATAL: + case VCD_EVT_IND_RESOURCES_LOST: + vid_enc_lean_event(client_ctx, event, status); + break; + + default: + ERR("%s() : Error - Invalid event type =%u\n", + __func__, event); + break; + } +} + +static u32 vid_enc_msg_pending(struct video_client_ctx *client_ctx) +{ + u32 islist_empty = 0; + + mutex_lock(&client_ctx->msg_queue_lock); + islist_empty = list_empty(&client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + + if (islist_empty) { + DBG("%s(): vid_enc msg queue empty\n", + __func__); + if (client_ctx->stop_msg) { + DBG("%s(): List empty and Stop Msg set\n", + __func__); + return client_ctx->stop_msg; + } + } else + DBG("%s(): vid_enc msg queue Not empty\n", + __func__); + + return !islist_empty; +} + +static int vid_enc_get_next_msg(struct video_client_ctx *client_ctx, + struct venc_msg *venc_msg_info) +{ + int rc; + struct vid_enc_msg *vid_enc_msg = NULL; + + if (!client_ctx) + return -EIO; + + rc = wait_event_interruptible(client_ctx->msg_wait, + vid_enc_msg_pending(client_ctx)); + + if (rc < 0) { + DBG("rc = %d,stop_msg= %u\n", rc, client_ctx->stop_msg); + return rc; + } else if (client_ctx->stop_msg) { + DBG("stopped stop_msg = %u\n", client_ctx->stop_msg); + return -EIO; + } + + mutex_lock(&client_ctx->msg_queue_lock); + + if (!list_empty(&client_ctx->msg_queue)) { + DBG("%s(): After Wait\n", __func__); + vid_enc_msg = list_first_entry(&client_ctx->msg_queue, + struct vid_enc_msg, list); + list_del(&vid_enc_msg->list); + memcpy(venc_msg_info, &vid_enc_msg->venc_msg_info, + sizeof(struct venc_msg)); + kfree(vid_enc_msg); + } + mutex_unlock(&client_ctx->msg_queue_lock); + return 0; +} + +static u32 vid_enc_close_client(struct video_client_ctx *client_ctx) +{ + struct vid_enc_msg *vid_enc_msg = NULL; + u32 vcd_status; + int rc; + + INFO("\n msm_vidc_enc: Inside %s()", __func__); + if (!client_ctx || (!client_ctx->vcd_handle)) { + ERR("\n %s(): Invalid client_ctx", __func__); + return false; + } + + mutex_lock(&vid_enc_device_p->lock); + + if (!stop_cmd) { + vcd_status = vcd_stop(client_ctx->vcd_handle); + DBG("Waiting for VCD_STOP: Before Timeout\n"); + if (!vcd_status) { + rc = wait_for_completion_timeout(&client_ctx->event, + 5 * HZ); + if (!rc) { + ERR("%s:ERROR vcd_stop time out" + "rc = %d\n", __func__, rc); + } + + if (client_ctx->event_status) { + ERR("%s:ERROR " + "vcd_stop Not successs\n", __func__); + } + } + } + DBG("VCD_STOPPED: After Timeout, calling VCD_CLOSE\n"); + mutex_lock(&client_ctx->msg_queue_lock); + while (!list_empty(&client_ctx->msg_queue)) { + DBG("%s(): Delete remaining entries\n", __func__); + vid_enc_msg = list_first_entry(&client_ctx->msg_queue, + struct vid_enc_msg, list); + list_del(&vid_enc_msg->list); + kfree(vid_enc_msg); + } + mutex_unlock(&client_ctx->msg_queue_lock); + vcd_status = vcd_close(client_ctx->vcd_handle); + + if (vcd_status) { + mutex_unlock(&vid_enc_device_p->lock); + return false; + } + memset((void *)client_ctx, 0, + sizeof(struct video_client_ctx)); + + vid_enc_device_p->num_clients--; + stop_cmd = 0; + mutex_unlock(&vid_enc_device_p->lock); + return true; +} + + +static int vid_enc_open(struct inode *inode, struct file *file) +{ + s32 client_index; + struct video_client_ctx *client_ctx; + int rc = 0; + u8 client_count = 0; + + INFO("\n msm_vidc_enc: Inside %s()", __func__); + + mutex_lock(&vid_enc_device_p->lock); + + stop_cmd = 0; + client_count = vcd_get_num_of_clients(); + if (client_count == VIDC_MAX_NUM_CLIENTS) { + ERR("ERROR : vid_enc_open() max number of clients" + "limit reached\n"); + mutex_unlock(&vid_enc_device_p->lock); + return -ENODEV; + } + + DBG(" Virtual Address of ioremap is %p\n", vid_enc_device_p->virt_base); + if (!vid_enc_device_p->num_clients) { + if (!vidc_load_firmware()) + return -ENODEV; + } + + client_index = vid_enc_get_empty_client_index(); + + if (client_index == -1) { + ERR("%s() : No free clients client_index == -1\n", + __func__); + return -ENODEV; + } + + client_ctx = + &vid_enc_device_p->venc_clients[client_index]; + vid_enc_device_p->num_clients++; + + init_completion(&client_ctx->event); + mutex_init(&client_ctx->msg_queue_lock); + mutex_init(&client_ctx->enrty_queue_lock); + INIT_LIST_HEAD(&client_ctx->msg_queue); + init_waitqueue_head(&client_ctx->msg_wait); + if (vcd_get_ion_status()) { + client_ctx->user_ion_client = vcd_get_ion_client(); + if (!client_ctx->user_ion_client) { + ERR("vcd_open ion get client failed"); + return -EFAULT; + } + } + rc = vcd_open(vid_enc_device_p->device_handle, false, + vid_enc_vcd_cb, client_ctx, 0); + client_ctx->stop_msg = 0; + + if (!rc) { + wait_for_completion(&client_ctx->event); + if (client_ctx->event_status) { + ERR("callback for vcd_open returned error: %u", + client_ctx->event_status); + mutex_unlock(&vid_enc_device_p->lock); + return -EFAULT; + } + } else { + ERR("vcd_open returned error: %u", rc); + mutex_unlock(&vid_enc_device_p->lock); + return rc; + } + file->private_data = client_ctx; + mutex_unlock(&vid_enc_device_p->lock); + return rc; +} + +static int vid_enc_release(struct inode *inode, struct file *file) +{ + struct video_client_ctx *client_ctx = file->private_data; + INFO("\n msm_vidc_enc: Inside %s()", __func__); + vid_enc_close_client(client_ctx); + vidc_release_firmware(); +#ifndef USE_RES_TRACKER + vidc_disable_clk(); +#endif + INFO("\n msm_vidc_enc: Return from %s()", __func__); + return 0; +} + +static const struct file_operations vid_enc_fops = { + .owner = THIS_MODULE, + .open = vid_enc_open, + .release = vid_enc_release, + .unlocked_ioctl = vid_enc_ioctl, +}; + +void vid_enc_interrupt_deregister(void) +{ +} + +void vid_enc_interrupt_register(void *device_name) +{ +} + +void vid_enc_interrupt_clear(void) +{ +} + +void *vid_enc_map_dev_base_addr(void *device_name) +{ + return vid_enc_device_p->virt_base; +} + +static int vid_enc_vcd_init(void) +{ + int rc; + struct vcd_init_config vcd_init_config; + u32 i; + + INFO("\n msm_vidc_enc: Inside %s()", __func__); + vid_enc_device_p->num_clients = 0; + + for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) { + memset((void *)&vid_enc_device_p->venc_clients[i], 0, + sizeof(vid_enc_device_p->venc_clients[i])); + } + + mutex_init(&vid_enc_device_p->lock); + vid_enc_device_p->virt_base = vidc_get_ioaddr(); + + if (!vid_enc_device_p->virt_base) { + ERR("%s() : ioremap failed\n", __func__); + return -ENOMEM; + } + + vcd_init_config.device_name = "VIDC"; + vcd_init_config.map_dev_base_addr = + vid_enc_map_dev_base_addr; + vcd_init_config.interrupt_clr = + vid_enc_interrupt_clear; + vcd_init_config.register_isr = + vid_enc_interrupt_register; + vcd_init_config.deregister_isr = + vid_enc_interrupt_deregister; + + rc = vcd_init(&vcd_init_config, + &vid_enc_device_p->device_handle); + + if (rc) { + ERR("%s() : vcd_init failed\n", + __func__); + return -ENODEV; + } + return 0; +} + +static int __init vid_enc_init(void) +{ + int rc = 0; + struct device *class_devp; + + INFO("\n msm_vidc_enc: Inside %s()", __func__); + vid_enc_device_p = kzalloc(sizeof(struct vid_enc_dev), + GFP_KERNEL); + if (!vid_enc_device_p) { + ERR("%s Unable to allocate memory for vid_enc_dev\n", + __func__); + return -ENOMEM; + } + + rc = alloc_chrdev_region(&vid_enc_dev_num, 0, 1, VID_ENC_NAME); + if (rc < 0) { + ERR("%s: alloc_chrdev_region Failed rc = %d\n", + __func__, rc); + goto error_vid_enc_alloc_chrdev_region; + } + + vid_enc_class = class_create(THIS_MODULE, VID_ENC_NAME); + if (IS_ERR(vid_enc_class)) { + rc = PTR_ERR(vid_enc_class); + ERR("%s: couldn't create vid_enc_class rc = %d\n", + __func__, rc); + goto error_vid_enc_class_create; + } + + class_devp = device_create(vid_enc_class, NULL, + vid_enc_dev_num, NULL, VID_ENC_NAME); + + if (IS_ERR(class_devp)) { + rc = PTR_ERR(class_devp); + ERR("%s: class device_create failed %d\n", + __func__, rc); + goto error_vid_enc_class_device_create; + } + + vid_enc_device_p->device = class_devp; + + cdev_init(&vid_enc_device_p->cdev, &vid_enc_fops); + vid_enc_device_p->cdev.owner = THIS_MODULE; + rc = cdev_add(&(vid_enc_device_p->cdev), vid_enc_dev_num, 1); + + if (rc < 0) { + ERR("%s: cdev_add failed %d\n", + __func__, rc); + goto error_vid_enc_cdev_add; + } + vid_enc_vcd_init(); + return 0; + +error_vid_enc_cdev_add: + device_destroy(vid_enc_class, vid_enc_dev_num); +error_vid_enc_class_device_create: + class_destroy(vid_enc_class); +error_vid_enc_class_create: + unregister_chrdev_region(vid_enc_dev_num, 1); +error_vid_enc_alloc_chrdev_region: + kfree(vid_enc_device_p); + + return rc; +} + +static void __exit vid_enc_exit(void) +{ + INFO("\n msm_vidc_enc: Inside %s()", __func__); + cdev_del(&(vid_enc_device_p->cdev)); + device_destroy(vid_enc_class, vid_enc_dev_num); + class_destroy(vid_enc_class); + unregister_chrdev_region(vid_enc_dev_num, 1); + kfree(vid_enc_device_p); + INFO("\n msm_vidc_enc: Return from %s()", __func__); +} +static long vid_enc_ioctl(struct file *file, + unsigned cmd, unsigned long u_arg) +{ + struct video_client_ctx *client_ctx = NULL; + struct venc_ioctl_msg venc_msg; + void __user *arg = (void __user *)u_arg; + u32 result = true; + int result_read = -1; + + DBG("%s\n", __func__); + + client_ctx = (struct video_client_ctx *)file->private_data; + if (!client_ctx) { + ERR("!client_ctx. Cannot attach to device handle\n"); + return -ENODEV; + } + + switch (cmd) { + case VEN_IOCTL_CMD_READ_NEXT_MSG: + { + struct venc_msg cb_msg; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_CMD_READ_NEXT_MSG\n"); + result_read = vid_enc_get_next_msg(client_ctx, &cb_msg); + if (result_read < 0) + return result_read; + if (copy_to_user(venc_msg.out, &cb_msg, sizeof(cb_msg))) + return -EFAULT; + break; + } + case VEN_IOCTL_CMD_STOP_READ_MSG: + { + DBG("VEN_IOCTL_CMD_STOP_READ_MSG\n"); + client_ctx->stop_msg = 1; + wake_up(&client_ctx->msg_wait); + break; + } + case VEN_IOCTL_CMD_ENCODE_FRAME: + case VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER: + { + struct venc_buffer enc_buffer; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_CMD_ENCODE_FRAME" + "/VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER\n"); + if (copy_from_user(&enc_buffer, venc_msg.in, + sizeof(enc_buffer))) + return -EFAULT; + if (cmd == VEN_IOCTL_CMD_ENCODE_FRAME) + result = vid_enc_encode_frame(client_ctx, + &enc_buffer); + else + result = vid_enc_fill_output_buffer(client_ctx, + &enc_buffer); + if (!result) { + DBG("\n VEN_IOCTL_CMD_ENCODE_FRAME/" + "VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_INPUT_BUFFER: + case VEN_IOCTL_SET_OUTPUT_BUFFER: + { + enum venc_buffer_dir buffer_dir; + struct venc_bufferpayload buffer_info; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_SET_INPUT_BUFFER/VEN_IOCTL_SET_OUTPUT_BUFFER\n"); + if (copy_from_user(&buffer_info, venc_msg.in, + sizeof(buffer_info))) + return -EFAULT; + buffer_dir = VEN_BUFFER_TYPE_INPUT; + if (cmd == VEN_IOCTL_SET_OUTPUT_BUFFER) + buffer_dir = VEN_BUFFER_TYPE_OUTPUT; + result = vid_enc_set_buffer(client_ctx, &buffer_info, + buffer_dir); + if (!result) { + DBG("\n VEN_IOCTL_SET_INPUT_BUFFER" + "/VEN_IOCTL_SET_OUTPUT_BUFFER failed"); + return -EIO; + } + break; + } + case VEN_IOCTL_CMD_FREE_INPUT_BUFFER: + case VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER: + { + enum venc_buffer_dir buffer_dir; + struct venc_bufferpayload buffer_info; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_CMD_FREE_INPUT_BUFFER/" + "VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER\n"); + + if (copy_from_user(&buffer_info, venc_msg.in, + sizeof(buffer_info))) + return -EFAULT; + + buffer_dir = VEN_BUFFER_TYPE_INPUT; + if (cmd == VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER) + buffer_dir = VEN_BUFFER_TYPE_OUTPUT; + + result = vid_enc_free_buffer(client_ctx, &buffer_info, + buffer_dir); + if (!result) { + DBG("\n VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER" + "/VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER failed"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_INPUT_BUFFER_REQ: + case VEN_IOCTL_SET_OUTPUT_BUFFER_REQ: + { + struct venc_allocatorproperty allocatorproperty; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_SET_INPUT_BUFFER_REQ" + "/VEN_IOCTL_SET_OUTPUT_BUFFER_REQ\n"); + + if (copy_from_user(&allocatorproperty, venc_msg.in, + sizeof(allocatorproperty))) + return -EFAULT; + + if (cmd == VEN_IOCTL_SET_OUTPUT_BUFFER_REQ) + result = vid_enc_set_buffer_req(client_ctx, + &allocatorproperty, false); + else + result = vid_enc_set_buffer_req(client_ctx, + &allocatorproperty, true); + if (!result) { + DBG("setting VEN_IOCTL_SET_OUTPUT_BUFFER_REQ/" + "VEN_IOCTL_SET_INPUT_BUFFER_REQ failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_GET_INPUT_BUFFER_REQ: + case VEN_IOCTL_GET_OUTPUT_BUFFER_REQ: + { + struct venc_allocatorproperty allocatorproperty; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_GET_INPUT_BUFFER_REQ/" + "VEN_IOCTL_GET_OUTPUT_BUFFER_REQ\n"); + + if (cmd == VEN_IOCTL_GET_OUTPUT_BUFFER_REQ) + result = vid_enc_get_buffer_req(client_ctx, + &allocatorproperty, false); + else + result = vid_enc_get_buffer_req(client_ctx, + &allocatorproperty, true); + if (!result) + return -EIO; + if (copy_to_user(venc_msg.out, &allocatorproperty, + sizeof(allocatorproperty))) + return -EFAULT; + break; + } + case VEN_IOCTL_CMD_FLUSH: + { + struct venc_bufferflush bufferflush; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_CMD_FLUSH\n"); + if (copy_from_user(&bufferflush, venc_msg.in, + sizeof(bufferflush))) + return -EFAULT; + INFO("\n %s(): Calling vid_enc_flush with mode = %lu", + __func__, bufferflush.flush_mode); + result = vid_enc_flush(client_ctx, &bufferflush); + + if (!result) { + ERR("setting VEN_IOCTL_CMD_FLUSH failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_CMD_START: + { + INFO("\n %s(): Executing VEN_IOCTL_CMD_START", __func__); + result = vid_enc_start_stop(client_ctx, true); + if (!result) { + ERR("setting VEN_IOCTL_CMD_START failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_CMD_STOP: + { + INFO("\n %s(): Executing VEN_IOCTL_CMD_STOP", __func__); + result = vid_enc_start_stop(client_ctx, false); + if (!result) { + ERR("setting VEN_IOCTL_CMD_STOP failed\n"); + return -EIO; + } + stop_cmd = 1; + break; + } + case VEN_IOCTL_CMD_PAUSE: + { + INFO("\n %s(): Executing VEN_IOCTL_CMD_PAUSE", __func__); + result = vid_enc_pause_resume(client_ctx, true); + if (!result) { + ERR("setting VEN_IOCTL_CMD_PAUSE failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_CMD_RESUME: + { + INFO("\n %s(): Executing VEN_IOCTL_CMD_RESUME", __func__); + result = vid_enc_pause_resume(client_ctx, false); + if (!result) { + ERR("setting VEN_IOCTL_CMD_RESUME failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_RECON_BUFFER: + { + struct venc_recon_addr venc_recon; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_SET_RECON_BUFFER\n"); + if (copy_from_user(&venc_recon, venc_msg.in, + sizeof(venc_recon))) + return -EFAULT; + result = vid_enc_set_recon_buffers(client_ctx, + &venc_recon); + if (!result) { + ERR("setting VEN_IOCTL_SET_RECON_BUFFER failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_FREE_RECON_BUFFER: + { + struct venc_recon_addr venc_recon; + DBG("VEN_IOCTL_FREE_RECON_BUFFER\n"); + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + if (copy_from_user(&venc_recon, venc_msg.in, + sizeof(venc_recon))) + return -EFAULT; + result = vid_enc_free_recon_buffers(client_ctx, + &venc_recon); + if (!result) { + ERR("VEN_IOCTL_FREE_RECON_BUFFER failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_GET_RECON_BUFFER_SIZE: + { + struct venc_recon_buff_size venc_recon_size; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_GET_RECON_BUFFER_SIZE\n"); + if (copy_from_user(&venc_recon_size, venc_msg.out, + sizeof(venc_recon_size))) + return -EFAULT; + result = vid_enc_get_recon_buffer_size(client_ctx, + &venc_recon_size); + if (result) { + if (copy_to_user(venc_msg.out, &venc_recon_size, + sizeof(venc_recon_size))) + return -EFAULT; + } else { + ERR("setting VEN_IOCTL_GET_RECON_BUFFER_SIZE" + "failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_QP_RANGE: + case VEN_IOCTL_GET_QP_RANGE: + { + struct venc_qprange qprange; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_G(S)ET_QP_RANGE\n"); + if (cmd == VEN_IOCTL_SET_QP_RANGE) { + if (copy_from_user(&qprange, venc_msg.in, + sizeof(qprange))) + return -EFAULT; + result = vid_enc_set_get_qprange(client_ctx, + &qprange, true); + } else { + result = vid_enc_set_get_qprange(client_ctx, + &qprange, false); + if (result) { + if (copy_to_user(venc_msg.out, &qprange, + sizeof(qprange))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_G(S)ET_QP_RANGE failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_HEC: + case VEN_IOCTL_GET_HEC: + { + struct venc_headerextension headerextension; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_HEC\n"); + if (cmd == VEN_IOCTL_SET_HEC) { + if (copy_from_user(&headerextension, venc_msg.in, + sizeof(headerextension))) + return -EFAULT; + + result = vid_enc_set_get_headerextension(client_ctx, + &headerextension, true); + } else { + result = vid_enc_set_get_headerextension(client_ctx, + &headerextension, false); + if (result) { + if (copy_to_user(venc_msg.out, &headerextension, + sizeof(headerextension))) + return -EFAULT; + } + } + + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_HEC failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_TARGET_BITRATE: + case VEN_IOCTL_GET_TARGET_BITRATE: + { + struct venc_targetbitrate targetbitrate; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_TARGET_BITRATE\n"); + if (cmd == VEN_IOCTL_SET_TARGET_BITRATE) { + if (copy_from_user(&targetbitrate, venc_msg.in, + sizeof(targetbitrate))) + return -EFAULT; + + result = vid_enc_set_get_bitrate(client_ctx, + &targetbitrate, true); + } else { + result = vid_enc_set_get_bitrate(client_ctx, + &targetbitrate, false); + if (result) { + if (copy_to_user(venc_msg.out, &targetbitrate, + sizeof(targetbitrate))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_TARGET_BITRATE failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_FRAME_RATE: + case VEN_IOCTL_GET_FRAME_RATE: + { + struct venc_framerate framerate; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_FRAME_RATE\n"); + if (cmd == VEN_IOCTL_SET_FRAME_RATE) { + if (copy_from_user(&framerate, venc_msg.in, + sizeof(framerate))) + return -EFAULT; + result = vid_enc_set_get_framerate(client_ctx, + &framerate, true); + } else { + result = vid_enc_set_get_framerate(client_ctx, + &framerate, false); + if (result) { + if (copy_to_user(venc_msg.out, &framerate, + sizeof(framerate))) + return -EFAULT; + } + } + + if (!result) { + ERR("VEN_IOCTL_(G)SET_FRAME_RATE failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_VOP_TIMING_CFG: + case VEN_IOCTL_GET_VOP_TIMING_CFG: + { + struct venc_voptimingcfg voptimingcfg; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_(G)SET_VOP_TIMING_CFG\n"); + if (cmd == VEN_IOCTL_SET_VOP_TIMING_CFG) { + if (copy_from_user(&voptimingcfg, venc_msg.in, + sizeof(voptimingcfg))) + return -EFAULT; + result = vid_enc_set_get_voptimingcfg(client_ctx, + &voptimingcfg, true); + } else { + result = vid_enc_set_get_voptimingcfg(client_ctx, + &voptimingcfg, false); + if (result) { + if (copy_to_user(venc_msg.out, &voptimingcfg, + sizeof(voptimingcfg))) + return -EFAULT; + } + } + if (!result) { + ERR("VEN_IOCTL_(G)SET_VOP_TIMING_CFG failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_RATE_CTRL_CFG: + case VEN_IOCTL_GET_RATE_CTRL_CFG: + { + struct venc_ratectrlcfg ratectrlcfg; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_RATE_CTRL_CFG\n"); + if (cmd == VEN_IOCTL_SET_RATE_CTRL_CFG) { + if (copy_from_user(&ratectrlcfg, venc_msg.in, + sizeof(ratectrlcfg))) + return -EFAULT; + + result = vid_enc_set_get_ratectrlcfg(client_ctx, + &ratectrlcfg, true); + } else { + result = vid_enc_set_get_ratectrlcfg(client_ctx, + &ratectrlcfg, false); + if (result) { + if (copy_to_user(venc_msg.out, &ratectrlcfg, + sizeof(ratectrlcfg))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_RATE_CTRL_CFG failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_MULTI_SLICE_CFG: + case VEN_IOCTL_GET_MULTI_SLICE_CFG: + { + struct venc_multiclicecfg multiclicecfg; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_MULTI_SLICE_CFG\n"); + if (cmd == VEN_IOCTL_SET_MULTI_SLICE_CFG) { + if (copy_from_user(&multiclicecfg, venc_msg.in, + sizeof(multiclicecfg))) + return -EFAULT; + + result = vid_enc_set_get_multiclicecfg(client_ctx, + &multiclicecfg, true); + } else { + result = vid_enc_set_get_multiclicecfg(client_ctx, + &multiclicecfg, false); + if (result) { + if (copy_to_user(venc_msg.out, &multiclicecfg, + sizeof(multiclicecfg))) + return -EFAULT; + } + } + if (!result) { + ERR("VEN_IOCTL_(G)SET_MULTI_SLICE_CFG failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_INTRA_REFRESH: + case VEN_IOCTL_GET_INTRA_REFRESH: + { + struct venc_intrarefresh intrarefresh; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_INTRA_REFRESH\n"); + if (cmd == VEN_IOCTL_SET_INTRA_REFRESH) { + if (copy_from_user(&intrarefresh, venc_msg.in, + sizeof(intrarefresh))) + return -EFAULT; + result = vid_enc_set_get_intrarefresh(client_ctx, + &intrarefresh, true); + } else { + result = vid_enc_set_get_intrarefresh(client_ctx, + &intrarefresh, false); + if (result) { + if (copy_to_user(venc_msg.out, &intrarefresh, + sizeof(intrarefresh))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_SET_INTRA_REFRESH failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_DEBLOCKING_CFG: + case VEN_IOCTL_GET_DEBLOCKING_CFG: + { + struct venc_dbcfg dbcfg; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_(G)SET_DEBLOCKING_CFG\n"); + if (cmd == VEN_IOCTL_SET_DEBLOCKING_CFG) { + if (copy_from_user(&dbcfg, venc_msg.in, + sizeof(dbcfg))) + return -EFAULT; + result = vid_enc_set_get_dbcfg(client_ctx, + &dbcfg, true); + } else { + result = vid_enc_set_get_dbcfg(client_ctx, + &dbcfg, false); + if (result) { + if (copy_to_user(venc_msg.out, &dbcfg, + sizeof(dbcfg))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_SET_DEBLOCKING_CFG failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_ENTROPY_CFG: + case VEN_IOCTL_GET_ENTROPY_CFG: + { + struct venc_entropycfg entropy_cfg; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_ENTROPY_CFG\n"); + if (cmd == VEN_IOCTL_SET_ENTROPY_CFG) { + if (copy_from_user(&entropy_cfg, venc_msg.in, + sizeof(entropy_cfg))) + return -EFAULT; + result = vid_enc_set_get_entropy_cfg(client_ctx, + &entropy_cfg, true); + } else { + result = vid_enc_set_get_entropy_cfg(client_ctx, + &entropy_cfg, false); + if (result) { + if (copy_to_user(venc_msg.out, &entropy_cfg, + sizeof(entropy_cfg))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_ENTROPY_CFG failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_GET_SEQUENCE_HDR: + { + struct venc_seqheader seq_header; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + if (copy_from_user(&seq_header, venc_msg.in, + sizeof(seq_header))) + return -EFAULT; + + DBG("VEN_IOCTL_GET_SEQUENCE_HDR\n"); + result = vid_enc_get_sequence_header(client_ctx, + &seq_header); + if (!result) { + ERR("get sequence header failed\n"); + return -EIO; + } + DBG("seq_header: buf=%x, sz=%d, hdrlen=%d\n", + (int)seq_header.hdrbufptr, + (int)seq_header.bufsize, + (int)seq_header.hdrlen); + if (copy_to_user(venc_msg.out, &seq_header, + sizeof(seq_header))) + return -EFAULT; + break; + } + case VEN_IOCTL_CMD_REQUEST_IFRAME: + { + result = vid_enc_request_iframe(client_ctx); + if (!result) { + ERR("setting VEN_IOCTL_CMD_REQUEST_IFRAME failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_INTRA_PERIOD: + case VEN_IOCTL_GET_INTRA_PERIOD: + { + struct venc_intraperiod intraperiod; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_INTRA_PERIOD\n"); + if (cmd == VEN_IOCTL_SET_INTRA_PERIOD) { + if (copy_from_user(&intraperiod, venc_msg.in, + sizeof(intraperiod))) + return -EFAULT; + result = vid_enc_set_get_intraperiod(client_ctx, + &intraperiod, true); + } else { + result = vid_enc_set_get_intraperiod(client_ctx, + &intraperiod, false); + if (result) { + if (copy_to_user(venc_msg.out, &intraperiod, + sizeof(intraperiod))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_INTRA_PERIOD failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_SESSION_QP: + case VEN_IOCTL_GET_SESSION_QP: + { + struct venc_sessionqp session_qp; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_SESSION_QP\n"); + if (cmd == VEN_IOCTL_SET_SESSION_QP) { + if (copy_from_user(&session_qp, venc_msg.in, + sizeof(session_qp))) + return -EFAULT; + result = vid_enc_set_get_session_qp(client_ctx, + &session_qp, true); + } else { + result = vid_enc_set_get_session_qp(client_ctx, + &session_qp, false); + if (result) { + if (copy_to_user(venc_msg.out, &session_qp, + sizeof(session_qp))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_SESSION_QP failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_PROFILE_LEVEL: + case VEN_IOCTL_GET_PROFILE_LEVEL: + { + struct ven_profilelevel profile_level; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_(G)SET_PROFILE_LEVEL\n"); + if (cmd == VEN_IOCTL_SET_PROFILE_LEVEL) { + if (copy_from_user(&profile_level, venc_msg.in, + sizeof(profile_level))) + return -EFAULT; + result = vid_enc_set_get_profile_level(client_ctx, + &profile_level, true); + } else { + result = vid_enc_set_get_profile_level(client_ctx, + &profile_level, false); + if (result) { + if (copy_to_user(venc_msg.out, + &profile_level, sizeof(profile_level))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_SET_PROFILE_LEVEL failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_CODEC_PROFILE: + case VEN_IOCTL_GET_CODEC_PROFILE: + { + struct venc_profile profile; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_(G)SET_CODEC_PROFILE\n"); + if (cmd == VEN_IOCTL_SET_CODEC_PROFILE) { + if (copy_from_user(&profile, venc_msg.in, + sizeof(profile))) + return -EFAULT; + result = vid_enc_set_get_profile(client_ctx, + &profile, true); + } else { + result = vid_enc_set_get_profile(client_ctx, + &profile, false); + if (result) { + if (copy_to_user(venc_msg.out, &profile, + sizeof(profile))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_SET_CODEC_PROFILE failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_SHORT_HDR: + case VEN_IOCTL_GET_SHORT_HDR: + { + struct venc_switch encoder_switch; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("Getting VEN_IOCTL_(G)SET_SHORT_HDR\n"); + if (cmd == VEN_IOCTL_SET_SHORT_HDR) { + if (copy_from_user(&encoder_switch, venc_msg.in, + sizeof(encoder_switch))) + return -EFAULT; + + result = vid_enc_set_get_short_header(client_ctx, + &encoder_switch, true); + } else { + result = vid_enc_set_get_short_header(client_ctx, + &encoder_switch, false); + if (result) { + if (copy_to_user(venc_msg.out, &encoder_switch, + sizeof(encoder_switch))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_SHORT_HDR failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_BASE_CFG: + case VEN_IOCTL_GET_BASE_CFG: + { + struct venc_basecfg base_config; + DBG("VEN_IOCTL_SET_BASE_CFG\n"); + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + if (cmd == VEN_IOCTL_SET_BASE_CFG) { + if (copy_from_user(&base_config, venc_msg.in, + sizeof(base_config))) + return -EFAULT; + result = vid_enc_set_get_base_cfg(client_ctx, + &base_config, true); + } else { + result = vid_enc_set_get_base_cfg(client_ctx, + &base_config, false); + if (result) { + if (copy_to_user(venc_msg.out, &base_config, + sizeof(base_config))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_SET_BASE_CFG failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_LIVE_MODE: + case VEN_IOCTL_GET_LIVE_MODE: + { + struct venc_switch encoder_switch; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("Getting VEN_IOCTL_(G)SET_LIVE_MODE\n"); + if (cmd == VEN_IOCTL_SET_LIVE_MODE) { + if (copy_from_user(&encoder_switch, venc_msg.in, + sizeof(encoder_switch))) + return -EFAULT; + result = vid_enc_set_get_live_mode(client_ctx, + &encoder_switch, true); + } else { + result = vid_enc_set_get_live_mode(client_ctx, + &encoder_switch, false); + if (result) { + if (copy_to_user(venc_msg.out, &encoder_switch, + sizeof(encoder_switch))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_LIVE_MODE failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_GET_NUMBER_INSTANCES: + { + DBG("VEN_IOCTL_GET_NUMBER_INSTANCES\n"); + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + if (copy_to_user(venc_msg.out, + &vid_enc_device_p->num_clients, sizeof(u32))) + return -EFAULT; + break; + } + case VEN_IOCTL_SET_METABUFFER_MODE: + { + u32 metabuffer_mode, vcd_status; + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_live live_mode; + + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + if (copy_from_user(&metabuffer_mode, venc_msg.in, + sizeof(metabuffer_mode))) + return -EFAULT; + vcd_property_hdr.prop_id = VCD_I_META_BUFFER_MODE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_live); + live_mode.live = metabuffer_mode; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &live_mode); + if (vcd_status) { + pr_err(" Setting metabuffer mode failed"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_EXTRADATA: + case VEN_IOCTL_GET_EXTRADATA: + { + u32 extradata_flag; + DBG("VEN_IOCTL_(G)SET_EXTRADATA\n"); + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + if (cmd == VEN_IOCTL_SET_EXTRADATA) { + if (copy_from_user(&extradata_flag, venc_msg.in, + sizeof(u32))) + return -EFAULT; + result = vid_enc_set_get_extradata(client_ctx, + &extradata_flag, true); + } else { + result = vid_enc_set_get_extradata(client_ctx, + &extradata_flag, false); + if (result) { + if (copy_to_user(venc_msg.out, &extradata_flag, + sizeof(u32))) + return -EFAULT; + } + } + 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; + } + case VEN_IOCTL_SET_AC_PREDICTION: + case VEN_IOCTL_GET_AC_PREDICTION: + case VEN_IOCTL_SET_RVLC: + case VEN_IOCTL_GET_RVLC: + case VEN_IOCTL_SET_ROTATION: + case VEN_IOCTL_GET_ROTATION: + case VEN_IOCTL_SET_DATA_PARTITION: + case VEN_IOCTL_GET_DATA_PARTITION: + case VEN_IOCTL_GET_CAPABILITY: + default: + ERR("%s(): Unsupported ioctl %d\n", __func__, cmd); + return -ENOTTY; + + break; + } + return 0; +} + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Video encoder driver"); +MODULE_VERSION("1.0"); + +module_init(vid_enc_init); +module_exit(vid_enc_exit); diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c new file mode 100644 index 0000000000000000000000000000000000000000..2fb71d40dc8a20b001989ff70ba4ca6390d070de --- /dev/null +++ b/drivers/video/msm/vidc/common/enc/venc_internal.c @@ -0,0 +1,1995 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vcd_res_tracker_api.h" +#include "venc_internal.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define ERR(x...) printk(KERN_ERR x) +static unsigned int vidc_mmu_subsystem[] = { + MSM_SUBSYSTEM_VIDEO}; + + +u32 vid_enc_set_get_base_cfg(struct video_client_ctx *client_ctx, + struct venc_basecfg *base_config, u32 set_flag) +{ + struct venc_targetbitrate venc_bitrate; + struct venc_framerate frame_rate; + u32 current_codec; + + if (!client_ctx || !base_config) + return false; + + if (!vid_enc_set_get_codec(client_ctx, ¤t_codec, false)) + return false; + + DBG("%s(): Current Codec Type = %u\n", __func__, current_codec); + if (current_codec != base_config->codectype) { + if (!vid_enc_set_get_codec(client_ctx, + (u32 *)&base_config->codectype, set_flag)) + return false; + } + + if (!vid_enc_set_get_inputformat(client_ctx, + (u32 *)&base_config->inputformat, set_flag)) + return false; + + if (!vid_enc_set_get_framesize(client_ctx, + (u32 *)&base_config->input_height, + (u32 *)&base_config->input_width, set_flag)) + return false; + + if (set_flag) + venc_bitrate.target_bitrate = base_config->targetbitrate; + + if (!vid_enc_set_get_bitrate(client_ctx, &venc_bitrate, set_flag)) + return false; + + if (!set_flag) + base_config->targetbitrate = venc_bitrate.target_bitrate; + + if (set_flag) { + frame_rate.fps_denominator = base_config->fps_den; + frame_rate.fps_numerator = base_config->fps_num; + } + + if (!vid_enc_set_get_framerate(client_ctx, &frame_rate, set_flag)) + return false; + + if (!set_flag) { + base_config->fps_den = frame_rate.fps_denominator; + base_config->fps_num = frame_rate.fps_numerator; + } + + return true; +} + +u32 vid_enc_set_get_inputformat(struct video_client_ctx *client_ctx, + u32 *input_format, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_buffer_format format; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !input_format) + return false; + + vcd_property_hdr.prop_id = VCD_I_BUFFER_FORMAT; + vcd_property_hdr.sz = + sizeof(struct vcd_property_buffer_format); + + if (set_flag) { + switch (*input_format) { + case VEN_INPUTFMT_NV12: + format.buffer_format = VCD_BUFFER_FORMAT_NV12; + break; + case VEN_INPUTFMT_NV12_16M2KA: + format.buffer_format = + VCD_BUFFER_FORMAT_NV12_16M2KA; + break; + default: + status = false; + break; + } + + if (status) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &format); + if (vcd_status) { + status = false; + ERR("%s(): Set VCD_I_BUFFER_FORMAT Failed\n", + __func__); + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &format); + + if (vcd_status) { + status = false; + ERR("%s(): Get VCD_I_BUFFER_FORMAT Failed\n", __func__); + } else { + switch (format.buffer_format) { + case VCD_BUFFER_FORMAT_NV12: + *input_format = VEN_INPUTFMT_NV12; + break; + case VCD_BUFFER_FORMAT_TILE_4x2: + *input_format = VEN_INPUTFMT_NV21; + break; + default: + status = false; + break; + } + } + } + return status; +} + +u32 vid_enc_set_get_codec(struct video_client_ctx *client_ctx, u32 *codec, + u32 set_flag) +{ + struct vcd_property_codec vcd_property_codec; + struct vcd_property_hdr vcd_property_hdr; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !codec) + return false; + + vcd_property_hdr.prop_id = VCD_I_CODEC; + vcd_property_hdr.sz = sizeof(struct vcd_property_codec); + + if (set_flag) { + switch (*codec) { + case VEN_CODEC_MPEG4: + vcd_property_codec.codec = VCD_CODEC_MPEG4; + break; + case VEN_CODEC_H263: + vcd_property_codec.codec = VCD_CODEC_H263; + break; + case VEN_CODEC_H264: + vcd_property_codec.codec = VCD_CODEC_H264; + break; + default: + status = false; + break; + } + + if (status) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_property_codec); + if (vcd_status) { + status = false; + ERR("%s(): Set VCD_I_CODEC Failed\n", __func__); + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_property_codec); + + if (vcd_status) { + status = false; + ERR("%s(): Get VCD_I_CODEC Failed\n", + __func__); + } else { + switch (vcd_property_codec.codec) { + case VCD_CODEC_H263: + *codec = VEN_CODEC_H263; + break; + case VCD_CODEC_H264: + *codec = VEN_CODEC_H264; + break; + case VCD_CODEC_MPEG4: + *codec = VEN_CODEC_MPEG4; + break; + case VCD_CODEC_DIVX_3: + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_MPEG1: + case VCD_CODEC_MPEG2: + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + case VCD_CODEC_XVID: + default: + status = false; + break; + } + } + } + return status; +} + +u32 vid_enc_set_get_framesize(struct video_client_ctx *client_ctx, + u32 *height, u32 *width, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_frame_size frame_size; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !height || !width) + return false; + + vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_frame_size); + + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &frame_size); + + if (vcd_status) { + ERR("%s(): Get VCD_I_FRAME_SIZE Failed\n", + __func__); + return false; + } + if (set_flag) { + if (frame_size.height != *height || + frame_size.width != *width) { + DBG("%s(): ENC Set Size (%d x %d)\n", + __func__, *height, *width); + frame_size.height = *height; + frame_size.width = *width; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &frame_size); + if (vcd_status) { + ERR("%s(): Set VCD_I_FRAME_SIZE Failed\n", + __func__); + return false; + } + } + } else { + *height = frame_size.height; + *width = frame_size.width; + } + return true; +} + +u32 vid_enc_set_get_bitrate(struct video_client_ctx *client_ctx, + struct venc_targetbitrate *venc_bitrate, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_target_bitrate bit_rate; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !venc_bitrate) + return false; + + vcd_property_hdr.prop_id = VCD_I_TARGET_BITRATE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_target_bitrate); + if (set_flag) { + bit_rate.target_bitrate = venc_bitrate->target_bitrate; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &bit_rate); + + if (vcd_status) { + ERR("%s(): Set VCD_I_TARGET_BITRATE Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &bit_rate); + + if (vcd_status) { + ERR("%s(): Get VCD_I_TARGET_BITRATE Failed\n", + __func__); + return false; + } + venc_bitrate->target_bitrate = bit_rate.target_bitrate; + } + return true; +} + +u32 vid_enc_set_get_extradata(struct video_client_ctx *client_ctx, + u32 *extradata_flag, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_meta_data_enable vcd_meta_data; + u32 vcd_status = VCD_ERR_FAIL; + if (!client_ctx || !extradata_flag) + return false; + vcd_property_hdr.prop_id = VCD_I_METADATA_ENABLE; + vcd_property_hdr.sz = sizeof(struct vcd_property_meta_data_enable); + if (set_flag) { + DBG("vcd_set_property: VCD_I_METADATA_ENABLE = %d\n", + *extradata_flag); + vcd_meta_data.meta_data_enable_flag = *extradata_flag; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_meta_data); + if (vcd_status) { + ERR("%s(): Set VCD_I_METADATA_ENABLE Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_meta_data); + if (vcd_status) { + ERR("%s(): Get VCD_I_METADATA_ENABLE Failed\n", + __func__); + return false; + } + *extradata_flag = vcd_meta_data.meta_data_enable_flag; + DBG("vcd_get_property: VCD_I_METADATA_ENABLE = %d\n", + *extradata_flag); + } + return true; +} + +u32 vid_enc_set_get_framerate(struct video_client_ctx *client_ctx, + struct venc_framerate *frame_rate, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_frame_rate vcd_frame_rate; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !frame_rate) + return false; + + vcd_property_hdr.prop_id = VCD_I_FRAME_RATE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_frame_rate); + + if (set_flag) { + vcd_frame_rate.fps_denominator = frame_rate->fps_denominator; + vcd_frame_rate.fps_numerator = frame_rate->fps_numerator; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_frame_rate); + + if (vcd_status) { + ERR("%s(): Set VCD_I_FRAME_RATE Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_frame_rate); + + if (vcd_status) { + ERR("%s(): Get VCD_I_FRAME_RATE Failed\n", + __func__); + return false; + } + frame_rate->fps_denominator = vcd_frame_rate.fps_denominator; + frame_rate->fps_numerator = vcd_frame_rate.fps_numerator; + } + return true; +} + +u32 vid_enc_set_get_live_mode(struct video_client_ctx *client_ctx, + struct venc_switch *encoder_switch, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_live live_mode; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx) + return false; + + vcd_property_hdr.prop_id = VCD_I_LIVE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_live); + + if (set_flag) { + live_mode.live = 1; + if (!encoder_switch->status) + live_mode.live = 0; + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &live_mode); + if (vcd_status) { + ERR("%s(): Set VCD_I_LIVE Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &live_mode); + + if (vcd_status) { + ERR("%s(): Get VCD_I_LIVE Failed\n", + __func__); + return false; + } else { + encoder_switch->status = 1; + if (!live_mode.live) + encoder_switch->status = 0; + } + } + return true; +} + +u32 vid_enc_set_get_short_header(struct video_client_ctx *client_ctx, + struct venc_switch *encoder_switch, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_short_header short_header; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !encoder_switch) + return false; + + vcd_property_hdr.prop_id = VCD_I_SHORT_HEADER; + vcd_property_hdr.sz = + sizeof(struct vcd_property_short_header); + + if (set_flag) { + short_header.short_header = (u32) encoder_switch->status; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &short_header); + + if (vcd_status) { + ERR("%s(): Set VCD_I_SHORT_HEADER Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &short_header); + + if (vcd_status) { + ERR("%s(): Get VCD_I_SHORT_HEADER Failed\n", + __func__); + return false; + } else { + encoder_switch->status = + (u8) short_header.short_header; + } + } + return true; +} + +u32 vid_enc_set_get_profile(struct video_client_ctx *client_ctx, + struct venc_profile *profile, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_profile profile_type; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !profile) + return false; + + vcd_property_hdr.prop_id = VCD_I_PROFILE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_profile); + + if (set_flag) { + switch (profile->profile) { + case VEN_PROFILE_MPEG4_SP: + profile_type.profile = VCD_PROFILE_MPEG4_SP; + break; + case VEN_PROFILE_MPEG4_ASP: + profile_type.profile = VCD_PROFILE_MPEG4_ASP; + break; + case VEN_PROFILE_H264_BASELINE: + profile_type.profile = VCD_PROFILE_H264_BASELINE; + break; + case VEN_PROFILE_H264_MAIN: + profile_type.profile = VCD_PROFILE_H264_MAIN; + break; + case VEN_PROFILE_H264_HIGH: + profile_type.profile = VCD_PROFILE_H264_HIGH; + break; + case VEN_PROFILE_H263_BASELINE: + profile_type.profile = VCD_PROFILE_H263_BASELINE; + break; + default: + status = false; + break; + } + + if (status) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &profile_type); + + if (vcd_status) { + ERR("%s(): Set VCD_I_PROFILE Failed\n", + __func__); + return false; + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &profile_type); + + if (vcd_status) { + ERR("%s(): Get VCD_I_PROFILE Failed\n", + __func__); + return false; + } else { + switch (profile_type.profile) { + case VCD_PROFILE_H263_BASELINE: + profile->profile = VEN_PROFILE_H263_BASELINE; + break; + case VCD_PROFILE_H264_BASELINE: + profile->profile = VEN_PROFILE_H264_BASELINE; + break; + case VCD_PROFILE_H264_HIGH: + profile->profile = VEN_PROFILE_H264_HIGH; + break; + case VCD_PROFILE_H264_MAIN: + profile->profile = VEN_PROFILE_H264_MAIN; + break; + case VCD_PROFILE_MPEG4_ASP: + profile->profile = VEN_PROFILE_MPEG4_ASP; + break; + case VCD_PROFILE_MPEG4_SP: + profile->profile = VEN_PROFILE_MPEG4_SP; + break; + default: + status = false; + break; + } + } + } + return status; +} + +u32 vid_enc_set_get_profile_level(struct video_client_ctx *client_ctx, + struct ven_profilelevel *profile_level, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_level level; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !profile_level) + return false; + + vcd_property_hdr.prop_id = VCD_I_LEVEL; + vcd_property_hdr.sz = + sizeof(struct vcd_property_level); + + if (set_flag) { + switch (profile_level->level) { + case VEN_LEVEL_MPEG4_0: + level.level = VCD_LEVEL_MPEG4_0; + break; + case VEN_LEVEL_MPEG4_1: + level.level = VCD_LEVEL_MPEG4_1; + break; + case VEN_LEVEL_MPEG4_2: + level.level = VCD_LEVEL_MPEG4_2; + break; + case VEN_LEVEL_MPEG4_3: + level.level = VCD_LEVEL_MPEG4_3; + break; + case VEN_LEVEL_MPEG4_4: + level.level = VCD_LEVEL_MPEG4_4; + break; + case VEN_LEVEL_MPEG4_5: + level.level = VCD_LEVEL_MPEG4_5; + break; + case VEN_LEVEL_MPEG4_3b: + level.level = VCD_LEVEL_MPEG4_3b; + break; + case VEN_LEVEL_MPEG4_6: + level.level = VCD_LEVEL_MPEG4_6; + break; + case VEN_LEVEL_H264_1: + level.level = VCD_LEVEL_H264_1; + break; + case VEN_LEVEL_H264_1b: + level.level = VCD_LEVEL_H264_1b; + break; + case VEN_LEVEL_H264_1p1: + level.level = VCD_LEVEL_H264_1p1; + break; + case VEN_LEVEL_H264_1p2: + level.level = VCD_LEVEL_H264_1p2; + break; + case VEN_LEVEL_H264_1p3: + level.level = VCD_LEVEL_H264_1p3; + break; + case VEN_LEVEL_H264_2: + level.level = VCD_LEVEL_H264_2; + break; + case VEN_LEVEL_H264_2p1: + level.level = VCD_LEVEL_H264_2p1; + break; + case VEN_LEVEL_H264_2p2: + level.level = VCD_LEVEL_H264_2p2; + break; + case VEN_LEVEL_H264_3: + level.level = VCD_LEVEL_H264_3; + break; + case VEN_LEVEL_H264_3p1: + level.level = VCD_LEVEL_H264_3p1; + break; + case VEN_LEVEL_H264_3p2: + level.level = VCD_LEVEL_H264_3p2; + break; + case VEN_LEVEL_H264_4: + level.level = VCD_LEVEL_H264_4; + break; + case VEN_LEVEL_H263_10: + level.level = VCD_LEVEL_H263_10; + break; + case VEN_LEVEL_H263_20: + level.level = VCD_LEVEL_H263_20; + break; + case VEN_LEVEL_H263_30: + level.level = VCD_LEVEL_H263_30; + break; + case VEN_LEVEL_H263_40: + level.level = VCD_LEVEL_H263_40; + break; + case VEN_LEVEL_H263_45: + level.level = VCD_LEVEL_H263_45; + break; + case VEN_LEVEL_H263_50: + level.level = VCD_LEVEL_H263_50; + break; + case VEN_LEVEL_H263_60: + level.level = VCD_LEVEL_H263_60; + break; + case VEN_LEVEL_H263_70: + level.level = VCD_LEVEL_H263_70; + break; + default: + status = false; + break; + } + if (status) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &level); + + if (vcd_status) { + ERR("%s(): Set VCD_I_LEVEL Failed\n", + __func__); + return false; + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &level); + + if (vcd_status) { + ERR("%s(): Get VCD_I_LEVEL Failed\n", + __func__); + return false; + } else { + switch (level.level) { + case VCD_LEVEL_MPEG4_0: + profile_level->level = VEN_LEVEL_MPEG4_0; + break; + case VCD_LEVEL_MPEG4_1: + profile_level->level = VEN_LEVEL_MPEG4_1; + break; + case VCD_LEVEL_MPEG4_2: + profile_level->level = VEN_LEVEL_MPEG4_2; + break; + case VCD_LEVEL_MPEG4_3: + profile_level->level = VEN_LEVEL_MPEG4_3; + break; + case VCD_LEVEL_MPEG4_4: + profile_level->level = VEN_LEVEL_MPEG4_4; + break; + case VCD_LEVEL_MPEG4_5: + profile_level->level = VEN_LEVEL_MPEG4_5; + break; + case VCD_LEVEL_MPEG4_3b: + profile_level->level = VEN_LEVEL_MPEG4_3b; + break; + case VCD_LEVEL_H264_1: + profile_level->level = VEN_LEVEL_H264_1; + break; + case VCD_LEVEL_H264_1b: + profile_level->level = VEN_LEVEL_H264_1b; + break; + case VCD_LEVEL_H264_1p1: + profile_level->level = VEN_LEVEL_H264_1p1; + break; + case VCD_LEVEL_H264_1p2: + profile_level->level = VEN_LEVEL_H264_1p2; + break; + case VCD_LEVEL_H264_1p3: + profile_level->level = VEN_LEVEL_H264_1p3; + break; + case VCD_LEVEL_H264_2: + profile_level->level = VEN_LEVEL_H264_2; + break; + case VCD_LEVEL_H264_2p1: + profile_level->level = VEN_LEVEL_H264_2p1; + break; + case VCD_LEVEL_H264_2p2: + profile_level->level = VEN_LEVEL_H264_2p2; + break; + case VCD_LEVEL_H264_3: + profile_level->level = VEN_LEVEL_H264_3; + break; + case VCD_LEVEL_H264_3p1: + profile_level->level = VEN_LEVEL_H264_3p1; + break; + case VCD_LEVEL_H264_3p2: + profile_level->level = VEN_LEVEL_H264_3p2; + break; + case VCD_LEVEL_H264_4: + profile_level->level = VEN_LEVEL_H264_4; + break; + case VCD_LEVEL_H263_10: + profile_level->level = VEN_LEVEL_H263_10; + break; + case VCD_LEVEL_H263_20: + profile_level->level = VEN_LEVEL_H263_20; + break; + case VCD_LEVEL_H263_30: + profile_level->level = VEN_LEVEL_H263_30; + break; + case VCD_LEVEL_H263_40: + profile_level->level = VEN_LEVEL_H263_40; + break; + case VCD_LEVEL_H263_45: + profile_level->level = VEN_LEVEL_H263_45; + break; + case VCD_LEVEL_H263_50: + profile_level->level = VEN_LEVEL_H263_50; + break; + case VCD_LEVEL_H263_60: + profile_level->level = VEN_LEVEL_H263_60; + break; + case VCD_LEVEL_H263_70: + status = false; + break; + default: + status = false; + break; + } + } + } + return status; +} + +u32 vid_enc_set_get_session_qp(struct video_client_ctx *client_ctx, + struct venc_sessionqp *session_qp, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_session_qp qp; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !session_qp) + return false; + + vcd_property_hdr.prop_id = VCD_I_SESSION_QP; + vcd_property_hdr.sz = + sizeof(struct vcd_property_session_qp); + + if (set_flag) { + qp.i_frame_qp = session_qp->iframeqp; + qp.p_frame_qp = session_qp->pframqp; + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &qp); + + if (vcd_status) { + ERR("%s(): Set VCD_I_SESSION_QP Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &qp); + + if (vcd_status) { + ERR("%s(): Set VCD_I_SESSION_QP Failed\n", + __func__); + return false; + } else { + session_qp->iframeqp = qp.i_frame_qp; + session_qp->pframqp = qp.p_frame_qp; + } + } + return true; +} + +u32 vid_enc_set_get_intraperiod(struct video_client_ctx *client_ctx, + struct venc_intraperiod *intraperiod, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_i_period period; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !intraperiod) + return false; + + vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD; + vcd_property_hdr.sz = + sizeof(struct vcd_property_i_period); + + if (set_flag) { + period.p_frames = intraperiod->num_pframes; + period.b_frames = intraperiod->num_bframes; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &period); + + if (vcd_status) { + ERR("%s(): Set VCD_I_INTRA_PERIOD Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &period); + + if (vcd_status) { + ERR("%s(): Get VCD_I_INTRA_PERIOD Failed\n", + __func__); + return false; + } else + intraperiod->num_pframes = period.p_frames; + } + return true; +} + +u32 vid_enc_request_iframe(struct video_client_ctx *client_ctx) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_req_i_frame request; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx) + return false; + + vcd_property_hdr.prop_id = VCD_I_REQ_IFRAME; + vcd_property_hdr.sz = + sizeof(struct vcd_property_req_i_frame); + request.req_i_frame = 1; + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &request); + + if (vcd_status) { + ERR("%s(): Set VCD_I_REQ_IFRAME Failed\n", + __func__); + return false; + } + return status; +} + +u32 vid_enc_get_sequence_header(struct video_client_ctx *client_ctx, + struct venc_seqheader *seq_header) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_sequence_hdr hdr; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !seq_header || !seq_header->bufsize) + return false; + + vcd_property_hdr.prop_id = VCD_I_SEQ_HEADER; + vcd_property_hdr.sz = sizeof(struct vcd_sequence_hdr); + + hdr.sequence_header = seq_header->hdrbufptr; + hdr.sequence_header_len = seq_header->bufsize; + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &hdr); + seq_header->hdrlen = hdr.sequence_header_len; + + if (vcd_status) { + ERR("%s(): Get VCD_I_SEQ_HEADER Failed\n", + __func__); + status = false; + } + return true; +} + +u32 vid_enc_set_get_entropy_cfg(struct video_client_ctx *client_ctx, + struct venc_entropycfg *entropy_cfg, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_entropy_control control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !entropy_cfg) + return false; + + vcd_property_hdr.prop_id = VCD_I_ENTROPY_CTRL; + vcd_property_hdr.sz = + sizeof(struct vcd_property_entropy_control); + if (set_flag) { + switch (entropy_cfg->longentropysel) { + case VEN_ENTROPY_MODEL_CAVLC: + control.entropy_sel = VCD_ENTROPY_SEL_CAVLC; + break; + case VEN_ENTROPY_MODEL_CABAC: + control.entropy_sel = VCD_ENTROPY_SEL_CABAC; + break; + default: + status = false; + break; + } + + if (status && entropy_cfg->cabacmodel == + VCD_ENTROPY_SEL_CABAC) { + switch (entropy_cfg->cabacmodel) { + case VEN_CABAC_MODEL_0: + control.cabac_model = + VCD_CABAC_MODEL_NUMBER_0; + break; + case VEN_CABAC_MODEL_1: + control.cabac_model = + VCD_CABAC_MODEL_NUMBER_1; + break; + case VEN_CABAC_MODEL_2: + control.cabac_model = + VCD_CABAC_MODEL_NUMBER_2; + break; + default: + status = false; + break; + } + } + if (status) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Set VCD_I_ENTROPY_CTRL Failed\n", + __func__); + status = false; + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Get VCD_I_ENTROPY_CTRL Failed\n", + __func__); + status = false; + } else { + switch (control.entropy_sel) { + case VCD_ENTROPY_SEL_CABAC: + entropy_cfg->cabacmodel = + VEN_ENTROPY_MODEL_CABAC; + break; + case VCD_ENTROPY_SEL_CAVLC: + entropy_cfg->cabacmodel = + VEN_ENTROPY_MODEL_CAVLC; + break; + default: + status = false; + break; + } + + if (status && control.entropy_sel == + VCD_ENTROPY_SEL_CABAC) { + switch (control.cabac_model) { + case VCD_CABAC_MODEL_NUMBER_0: + entropy_cfg->cabacmodel = + VEN_CABAC_MODEL_0; + break; + case VCD_CABAC_MODEL_NUMBER_1: + entropy_cfg->cabacmodel = + VEN_CABAC_MODEL_1; + break; + case VCD_CABAC_MODEL_NUMBER_2: + entropy_cfg->cabacmodel = + VEN_CABAC_MODEL_2; + break; + default: + status = false; + break; + } + } + } + } + return status; +} + +u32 vid_enc_set_get_dbcfg(struct video_client_ctx *client_ctx, + struct venc_dbcfg *dbcfg, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_db_config control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !dbcfg) + return false; + + vcd_property_hdr.prop_id = VCD_I_DEBLOCKING; + vcd_property_hdr.sz = + sizeof(struct vcd_property_db_config); + + if (set_flag) { + switch (dbcfg->db_mode) { + case VEN_DB_DISABLE: + control.db_config = VCD_DB_DISABLE; + break; + case VEN_DB_ALL_BLKG_BNDRY: + control.db_config = VCD_DB_ALL_BLOCKING_BOUNDARY; + break; + case VEN_DB_SKIP_SLICE_BNDRY: + control.db_config = VCD_DB_SKIP_SLICE_BOUNDARY; + break; + default: + status = false; + break; + } + + if (status) { + control.slice_alpha_offset = + dbcfg->slicealpha_offset; + control.slice_beta_offset = + dbcfg->slicebeta_offset; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Set VCD_I_DEBLOCKING Failed\n", + __func__); + status = false; + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Get VCD_I_DEBLOCKING Failed\n", + __func__); + status = false; + } else { + switch (control.db_config) { + case VCD_DB_ALL_BLOCKING_BOUNDARY: + dbcfg->db_mode = VEN_DB_ALL_BLKG_BNDRY; + break; + case VCD_DB_DISABLE: + dbcfg->db_mode = VEN_DB_DISABLE; + break; + case VCD_DB_SKIP_SLICE_BOUNDARY: + dbcfg->db_mode = VEN_DB_SKIP_SLICE_BNDRY; + break; + default: + status = false; + break; + } + dbcfg->slicealpha_offset = + control.slice_alpha_offset; + dbcfg->slicebeta_offset = + control.slice_beta_offset; + } + } + return status; +} + +u32 vid_enc_set_get_intrarefresh(struct video_client_ctx *client_ctx, + struct venc_intrarefresh *intrarefresh, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_intra_refresh_mb_number control; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !intrarefresh) + return false; + + vcd_property_hdr.prop_id = VCD_I_INTRA_REFRESH; + vcd_property_hdr.sz = + sizeof(struct vcd_property_intra_refresh_mb_number); + + if (set_flag) { + control.cir_mb_number = intrarefresh->mbcount; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Set VCD_I_INTRA_REFRESH Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Set VCD_I_INTRA_REFRESH Failed\n", + __func__); + return false; + } else + intrarefresh->mbcount = control.cir_mb_number; + } + return true; +} + +u32 vid_enc_set_get_multiclicecfg(struct video_client_ctx *client_ctx, + struct venc_multiclicecfg *multiclicecfg, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_multi_slice control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !multiclicecfg) + return false; + + vcd_property_hdr.prop_id = VCD_I_MULTI_SLICE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_multi_slice); + + if (set_flag) { + switch (multiclicecfg->mslice_mode) { + case VEN_MSLICE_OFF: + control.m_slice_sel = + VCD_MSLICE_OFF; + break; + case VEN_MSLICE_CNT_MB: + control.m_slice_sel = + VCD_MSLICE_BY_MB_COUNT; + break; + case VEN_MSLICE_CNT_BYTE: + control.m_slice_sel = + VCD_MSLICE_BY_BYTE_COUNT; + break; + case VEN_MSLICE_GOB: + control.m_slice_sel = + VCD_MSLICE_BY_GOB; + break; + default: + status = false; + break; + } + + if (status) { + control.m_slice_size = + multiclicecfg->mslice_size; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Set VCD_I_MULTI_SLICE Failed\n", + __func__); + status = false; + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Get VCD_I_MULTI_SLICE Failed\n", + __func__); + status = false; + } else { + multiclicecfg->mslice_size = + control.m_slice_size; + switch (control.m_slice_sel) { + case VCD_MSLICE_OFF: + multiclicecfg->mslice_mode = VEN_MSLICE_OFF; + break; + case VCD_MSLICE_BY_MB_COUNT: + multiclicecfg->mslice_mode = VEN_MSLICE_CNT_MB; + break; + case VCD_MSLICE_BY_BYTE_COUNT: + multiclicecfg->mslice_mode = + VEN_MSLICE_CNT_BYTE; + break; + case VCD_MSLICE_BY_GOB: + multiclicecfg->mslice_mode = + VEN_MSLICE_GOB; + break; + default: + status = false; + break; + } + } + } + return status; +} + +u32 vid_enc_set_get_ratectrlcfg(struct video_client_ctx *client_ctx, + struct venc_ratectrlcfg *ratectrlcfg, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_rate_control control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !ratectrlcfg) + return false; + + vcd_property_hdr.prop_id = VCD_I_RATE_CONTROL; + vcd_property_hdr.sz = + sizeof(struct vcd_property_rate_control); + + if (set_flag) { + switch (ratectrlcfg->rcmode) { + case VEN_RC_OFF: + control.rate_control = VCD_RATE_CONTROL_OFF; + break; + case VEN_RC_CBR_VFR: + control.rate_control = VCD_RATE_CONTROL_CBR_VFR; + break; + case VEN_RC_VBR_CFR: + control.rate_control = VCD_RATE_CONTROL_VBR_CFR; + break; + case VEN_RC_VBR_VFR: + control.rate_control = VCD_RATE_CONTROL_VBR_VFR; + break; + case VEN_RC_CBR_CFR: + control.rate_control = VCD_RATE_CONTROL_CBR_CFR; + break; + default: + status = false; + break; + } + + if (status) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Set VCD_I_RATE_CONTROL Failed\n", + __func__); + status = false; + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Get VCD_I_RATE_CONTROL Failed\n", + __func__); + status = false; + } else { + switch (control.rate_control) { + case VCD_RATE_CONTROL_OFF: + ratectrlcfg->rcmode = VEN_RC_OFF; + break; + case VCD_RATE_CONTROL_CBR_VFR: + ratectrlcfg->rcmode = VEN_RC_CBR_VFR; + break; + case VCD_RATE_CONTROL_VBR_CFR: + ratectrlcfg->rcmode = VEN_RC_VBR_CFR; + break; + case VCD_RATE_CONTROL_VBR_VFR: + ratectrlcfg->rcmode = VEN_RC_VBR_VFR; + break; + case VCD_RATE_CONTROL_CBR_CFR: + ratectrlcfg->rcmode = VEN_RC_CBR_CFR; + break; + default: + status = false; + break; + } + } + } + return status; +} + +u32 vid_enc_set_get_voptimingcfg(struct video_client_ctx *client_ctx, + struct venc_voptimingcfg *voptimingcfg, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_vop_timing control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !voptimingcfg) + return false; + + vcd_property_hdr.prop_id = VCD_I_VOP_TIMING; + vcd_property_hdr.sz = + sizeof(struct vcd_property_vop_timing); + + if (set_flag) { + control.vop_time_resolution = + voptimingcfg->voptime_resolution; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Set VCD_I_VOP_TIMING Failed\n", + __func__); + status = false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Get VCD_I_VOP_TIMING Failed\n", + __func__); + status = false; + } else + voptimingcfg->voptime_resolution = + control.vop_time_resolution; + } + return status; +} + +u32 vid_enc_set_get_headerextension(struct video_client_ctx *client_ctx, + struct venc_headerextension *headerextension, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + u32 control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !headerextension) + return false; + + vcd_property_hdr.prop_id = VCD_I_HEADER_EXTENSION; + vcd_property_hdr.sz = sizeof(u32); + + if (set_flag) { + control = headerextension->header_extension; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Set VCD_I_HEADER_EXTENSION Failed\n", + __func__); + status = false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Get VCD_I_HEADER_EXTENSION Failed\n", + __func__); + status = false; + } else { + headerextension->header_extension = control; + } + } + return status; +} + +u32 vid_enc_set_get_qprange(struct video_client_ctx *client_ctx, + struct venc_qprange *qprange, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_qp_range control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !qprange) + return false; + + vcd_property_hdr.prop_id = VCD_I_QP_RANGE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_qp_range); + + if (set_flag) { + control.max_qp = qprange->maxqp; + control.min_qp = qprange->minqp; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Set VCD_I_QP_RANGE Failed\n", + __func__); + status = false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Get VCD_I_QP_RANGE Failed\n", + __func__); + status = false; + } else { + qprange->maxqp = control.max_qp; + qprange->minqp = control.min_qp; + } + } + return status; +} + +u32 vid_enc_start_stop(struct video_client_ctx *client_ctx, u32 start) +{ + u32 vcd_status; + + if (!client_ctx) + return false; + + if (start) { + vcd_status = vcd_encode_start(client_ctx->vcd_handle); + + if (vcd_status) { + ERR("%s(): vcd_encode_start failed." + " vcd_status = %u\n", __func__, vcd_status); + return false; + } + } else { + vcd_status = vcd_stop(client_ctx->vcd_handle); + if (vcd_status) { + ERR("%s(): vcd_stop failed. vcd_status = %u\n", + __func__, vcd_status); + return false; + } + DBG("Send STOP_DONE message to client = %p\n", + client_ctx); + } + return true; +} + +u32 vid_enc_pause_resume(struct video_client_ctx *client_ctx, u32 pause) +{ + u32 vcd_status; + + if (!client_ctx) + return false; + + if (pause) { + DBG("PAUSE command from client = %p\n", + client_ctx); + vcd_status = vcd_pause(client_ctx->vcd_handle); + } else { + DBG("Resume command from client = %p\n", + client_ctx); + vcd_status = vcd_resume(client_ctx->vcd_handle); + } + + if (vcd_status) + return false; + + return true; +} + +u32 vid_enc_flush(struct video_client_ctx *client_ctx, + struct venc_bufferflush *bufferflush) +{ + u32 status = true, mode, vcd_status; + + if (!client_ctx || !bufferflush) + return false; + + switch (bufferflush->flush_mode) { + case VEN_FLUSH_INPUT: + mode = VCD_FLUSH_INPUT; + break; + case VEN_FLUSH_OUTPUT: + mode = VCD_FLUSH_OUTPUT; + break; + case VEN_FLUSH_ALL: + mode = VCD_FLUSH_ALL; + break; + default: + status = false; + break; + } + if (status) { + vcd_status = vcd_flush(client_ctx->vcd_handle, mode); + if (vcd_status) + status = false; + } + return status; +} + +u32 vid_enc_get_buffer_req(struct video_client_ctx *client_ctx, + struct venc_allocatorproperty *venc_buf_req, u32 input_dir) +{ + enum vcd_buffer_type buffer; + struct vcd_buffer_requirement buffer_req; + u32 status = true; + u32 vcd_status; + + if (!client_ctx || !venc_buf_req) + return false; + + buffer = VCD_BUFFER_OUTPUT; + if (input_dir) + buffer = VCD_BUFFER_INPUT; + + vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle, + buffer, &buffer_req); + + if (vcd_status) + status = false; + + if (status) { + venc_buf_req->actualcount = buffer_req.actual_count; + venc_buf_req->alignment = buffer_req.align; + venc_buf_req->datasize = buffer_req.sz; + venc_buf_req->mincount = buffer_req.min_count; + venc_buf_req->maxcount = buffer_req.max_count; + venc_buf_req->alignment = buffer_req.align; + venc_buf_req->bufpoolid = buffer_req.buf_pool_id; + venc_buf_req->suffixsize = 0; + DBG("%s: actual_count=%d, align=%d, sz=%d, min_count=%d, " + "max_count=%d, buf_pool_id=%d\n", __func__, + buffer_req.actual_count, buffer_req.align, + buffer_req.sz, buffer_req.min_count, + buffer_req.max_count, buffer_req.buf_pool_id); + } + return status; +} + +u32 vid_enc_set_buffer_req(struct video_client_ctx *client_ctx, + struct venc_allocatorproperty *venc_buf_req, u32 input_dir) +{ + enum vcd_buffer_type buffer; + struct vcd_buffer_requirement buffer_req; + u32 status = true; + u32 vcd_status; + + if (!client_ctx || !venc_buf_req) + return false; + + buffer = VCD_BUFFER_OUTPUT; + if (input_dir) + buffer = VCD_BUFFER_INPUT; + + buffer_req.actual_count = venc_buf_req->actualcount; + buffer_req.align = venc_buf_req->alignment; + buffer_req.sz = venc_buf_req->datasize; + buffer_req.min_count = venc_buf_req->mincount; + buffer_req.max_count = venc_buf_req->maxcount; + buffer_req.align = venc_buf_req->alignment; + buffer_req.buf_pool_id = 0; + + DBG("%s: actual_count=%d, align=%d, sz=%d, min_count=%d, " + "max_count=%d, buf_pool_id=%d\n", __func__, + buffer_req.actual_count, buffer_req.align, buffer_req.sz, + buffer_req.min_count, buffer_req.max_count, + buffer_req.buf_pool_id); + vcd_status = vcd_set_buffer_requirements(client_ctx->vcd_handle, + buffer, &buffer_req); + + if (vcd_status) + status = false; + return status; +} + +u32 vid_enc_set_buffer(struct video_client_ctx *client_ctx, + struct venc_bufferpayload *buffer_info, + enum venc_buffer_dir buffer) +{ + enum vcd_buffer_type vcd_buffer_t = VCD_BUFFER_INPUT; + enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT; + u32 vcd_status = VCD_ERR_FAIL; + unsigned long kernel_vaddr, length = 0; + + if (!client_ctx || !buffer_info) + return false; + + if (buffer == VEN_BUFFER_TYPE_OUTPUT) { + dir_buffer = BUFFER_TYPE_OUTPUT; + vcd_buffer_t = VCD_BUFFER_OUTPUT; + } + length = buffer_info->sz; + /*If buffer cannot be set, ignore */ + if (!vidc_insert_addr_table(client_ctx, dir_buffer, + (unsigned long)buffer_info->pbuffer, + &kernel_vaddr, + buffer_info->fd, + (unsigned long)buffer_info->offset, + VID_ENC_MAX_NUM_OF_BUFF, length)) { + DBG("%s() : user_virt_addr = %p cannot be set.", + __func__, buffer_info->pbuffer); + return false; + } + + vcd_status = vcd_set_buffer(client_ctx->vcd_handle, + vcd_buffer_t, (u8 *) kernel_vaddr, + buffer_info->sz); + + if (!vcd_status) + return true; + else + return false; +} + +u32 vid_enc_free_buffer(struct video_client_ctx *client_ctx, + struct venc_bufferpayload *buffer_info, + enum venc_buffer_dir buffer) +{ + enum vcd_buffer_type buffer_vcd = VCD_BUFFER_INPUT; + enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT; + u32 vcd_status = VCD_ERR_FAIL; + unsigned long kernel_vaddr; + + if (!client_ctx || !buffer_info) + return false; + + if (buffer == VEN_BUFFER_TYPE_OUTPUT) { + dir_buffer = BUFFER_TYPE_OUTPUT; + buffer_vcd = VCD_BUFFER_OUTPUT; + } + /*If buffer NOT set, ignore */ + if (!vidc_delete_addr_table(client_ctx, dir_buffer, + (unsigned long)buffer_info->pbuffer, + &kernel_vaddr)) { + DBG("%s() : user_virt_addr = %p has not been set.", + __func__, buffer_info->pbuffer); + return true; + } + vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer_vcd, + (u8 *)kernel_vaddr); + + if (!vcd_status) + return true; + else + return false; +} + +u32 vid_enc_encode_frame(struct video_client_ctx *client_ctx, + struct venc_buffer *input_frame_info) +{ + struct vcd_frame_data vcd_input_buffer; + unsigned long kernel_vaddr, phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + u32 ion_flag = 0; + struct ion_handle *buff_handle = NULL; + + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !input_frame_info) + return false; + + user_vaddr = (unsigned long)input_frame_info->ptrbuffer; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT, + true, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + /* kernel_vaddr is found. send the frame to VCD */ + memset((void *)&vcd_input_buffer, 0, + sizeof(struct vcd_frame_data)); + + vcd_input_buffer.virtual = + (u8 *) (kernel_vaddr + input_frame_info->offset); + + vcd_input_buffer.offset = input_frame_info->offset; + vcd_input_buffer.frm_clnt_data = + (u32) input_frame_info->clientdata; + vcd_input_buffer.ip_frm_tag = + (u32) input_frame_info->clientdata; + vcd_input_buffer.data_len = input_frame_info->len; + vcd_input_buffer.time_stamp = input_frame_info->timestamp; + + /* Rely on VCD using the same flags as OMX */ + vcd_input_buffer.flags = input_frame_info->flags; + + ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_INPUT, + pmem_fd, kernel_vaddr, buffer_index, + &buff_handle); + + if (vcd_input_buffer.data_len > 0) { + if (ion_flag == CACHED && buff_handle) { + msm_ion_do_cache_op( + client_ctx->user_ion_client, + buff_handle, + (unsigned long *) vcd_input_buffer.virtual, + (unsigned long) vcd_input_buffer.data_len, + ION_IOC_CLEAN_CACHES); + } + } + + vcd_status = vcd_encode_frame(client_ctx->vcd_handle, + &vcd_input_buffer); + if (!vcd_status) + return true; + else { + ERR("%s(): vcd_encode_frame failed = %u\n", + __func__, vcd_status); + return false; + } + + } else { + ERR("%s(): kernel_vaddr not found\n", + __func__); + return false; + } +} + +u32 vid_enc_fill_output_buffer(struct video_client_ctx *client_ctx, + struct venc_buffer *output_frame_info) +{ + unsigned long kernel_vaddr, phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + u32 vcd_status = VCD_ERR_FAIL; + struct ion_handle *buff_handle = NULL; + + struct vcd_frame_data vcd_frame; + + if (!client_ctx || !output_frame_info) + return false; + + user_vaddr = (unsigned long)output_frame_info->ptrbuffer; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, + true, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + memset((void *)&vcd_frame, 0, + sizeof(struct vcd_frame_data)); + vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT, + pmem_fd, kernel_vaddr, buffer_index, + &buff_handle); + vcd_frame.virtual = (u8 *) kernel_vaddr; + vcd_frame.frm_clnt_data = (u32) output_frame_info->clientdata; + vcd_frame.alloc_len = output_frame_info->sz; + vcd_frame.buff_ion_handle = buff_handle; + + vcd_status = vcd_fill_output_buffer(client_ctx->vcd_handle, + &vcd_frame); + if (!vcd_status) + return true; + else { + ERR("%s(): vcd_fill_output_buffer failed = %u\n", + __func__, vcd_status); + return false; + } + } else { + ERR("%s(): kernel_vaddr not found\n", __func__); + return false; + } +} +u32 vid_enc_set_recon_buffers(struct video_client_ctx *client_ctx, + struct venc_recon_addr *venc_recon) +{ + u32 vcd_status = VCD_ERR_FAIL; + u32 len, i, flags = 0; + struct file *file; + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_enc_recon_buffer *control = NULL; + struct msm_mapped_buffer *mapped_buffer = NULL; + int rc = -1; + unsigned long ionflag = 0; + unsigned long iova = 0; + unsigned long buffer_size = 0; + size_t ion_len = -1; + unsigned long phy_addr; + + if (!client_ctx || !venc_recon) { + pr_err("%s() Invalid params", __func__); + return false; + } + len = sizeof(client_ctx->recon_buffer)/ + sizeof(struct vcd_property_enc_recon_buffer); + for (i = 0; i < len; i++) { + if (!client_ctx->recon_buffer[i].kernel_virtual_addr) { + control = &client_ctx->recon_buffer[i]; + break; + } + } + if (!control) { + pr_err("Exceeded max recon buffer setting"); + return false; + } + control->buffer_size = venc_recon->buffer_size; + control->kernel_virtual_addr = NULL; + control->physical_addr = NULL; + control->pmem_fd = venc_recon->pmem_fd; + control->offset = venc_recon->offset; + control->user_virtual_addr = venc_recon->pbuffer; + + if (!vcd_get_ion_status()) { + if (get_pmem_file(control->pmem_fd, (unsigned long *) + (&(control->physical_addr)), (unsigned long *) + (&control->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)control->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; + } + control->client_data = (void *) mapped_buffer; + control->dev_addr = (u8 *)mapped_buffer->iova[0]; + } else { + client_ctx->recon_buffer_ion_handle[i] = ion_import_fd( + client_ctx->user_ion_client, control->pmem_fd); + if (IS_ERR_OR_NULL(client_ctx->recon_buffer_ion_handle[i])) { + ERR("%s(): get_ION_handle failed\n", __func__); + goto import_ion_error; + } + rc = ion_handle_get_flags(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i], + &ionflag); + if (rc) { + ERR("%s():get_ION_flags fail\n", + __func__); + goto import_ion_error; + } + control->kernel_virtual_addr = (u8 *) ion_map_kernel( + client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i], + ionflag); + if (!control->kernel_virtual_addr) { + ERR("%s(): get_ION_kernel virtual addr fail\n", + __func__); + goto import_ion_error; + } + if (res_trk_check_for_sec_session()) { + rc = ion_phys(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i], + &phy_addr, &ion_len); + if (rc) { + ERR("%s():get_ION_kernel physical addr fail\n", + __func__); + goto map_ion_error; + } + control->physical_addr = (u8 *) phy_addr; + len = (unsigned long) ion_len; + control->client_data = NULL; + control->dev_addr = (u8 *)control->physical_addr; + } else { + rc = ion_map_iommu(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i], + VIDEO_DOMAIN, + VIDEO_MAIN_POOL, + SZ_4K, + 0, + (unsigned long *)&iova, + (unsigned long *)&buffer_size, + UNCACHED, 0); + if (rc) { + ERR("%s():ION map iommu addr fail\n", + __func__); + goto map_ion_error; + } + control->physical_addr = (u8 *) iova; + len = buffer_size; + control->client_data = NULL; + control->dev_addr = (u8 *)iova; + } + } + + vcd_property_hdr.prop_id = VCD_I_RECON_BUFFERS; + vcd_property_hdr.sz = + sizeof(struct vcd_property_enc_recon_buffer); + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, control); + if (!vcd_status) { + DBG("vcd_set_property returned success\n"); + return true; + } else { + ERR("%s(): vid_enc_set_recon_buffers failed = %u\n", + __func__, vcd_status); + return false; + } +map_ion_error: + if (control->kernel_virtual_addr) + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i]); + if (client_ctx->recon_buffer_ion_handle[i]) + ion_free(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i]); + client_ctx->recon_buffer_ion_handle[i] = NULL; +import_ion_error: + return false; +} + +u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx, + struct venc_recon_addr *venc_recon) +{ + u32 vcd_status = VCD_ERR_FAIL; + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_enc_recon_buffer *control = NULL; + u32 len = 0, i; + + if (!client_ctx || !venc_recon) { + pr_err("%s() Invalid params", __func__); + return false; + } + len = sizeof(client_ctx->recon_buffer)/ + sizeof(struct vcd_property_enc_recon_buffer); + pr_err(" %s() address %p", __func__, + venc_recon->pbuffer); + for (i = 0; i < len; i++) { + if (client_ctx->recon_buffer[i].user_virtual_addr + == venc_recon->pbuffer) { + control = &client_ctx->recon_buffer[i]; + break; + } + } + if (!control) { + pr_err(" %s() address not found %p", __func__, + venc_recon->pbuffer); + return false; + } + if (control->client_data) + msm_subsystem_unmap_buffer((struct msm_mapped_buffer *) + control->client_data); + + vcd_property_hdr.prop_id = VCD_I_FREE_RECON_BUFFERS; + vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size); + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, control); + if (vcd_get_ion_status()) { + if (client_ctx->recon_buffer_ion_handle[i]) { + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i]); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i], + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + } + ion_free(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i]); + client_ctx->recon_buffer_ion_handle[i] = NULL; + } + } + memset(control, 0, sizeof(struct vcd_property_enc_recon_buffer)); + return true; +} + +u32 vid_enc_get_recon_buffer_size(struct video_client_ctx *client_ctx, + struct venc_recon_buff_size *venc_recon_size) +{ + u32 vcd_status = VCD_ERR_FAIL; + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_buffer_size control; + + control.width = venc_recon_size->width; + control.height = venc_recon_size->height; + + vcd_property_hdr.prop_id = VCD_I_GET_RECON_BUFFER_SIZE; + vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size); + + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + venc_recon_size->width = control.width; + venc_recon_size->height = control.height; + venc_recon_size->size = control.size; + venc_recon_size->alignment = control.alignment; + DBG("W: %d, H: %d, S: %d, A: %d", venc_recon_size->width, + venc_recon_size->height, venc_recon_size->size, + venc_recon_size->alignment); + + if (!vcd_status) { + DBG("vcd_set_property returned success\n"); + return true; + } else { + ERR("%s(): vid_enc_get_recon_buffer_size failed = %u\n", + __func__, vcd_status); + return false; + } +} diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.h b/drivers/video/msm/vidc/common/enc/venc_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..324ed9e610eb5562be04fe8ec11176593f25c167 --- /dev/null +++ b/drivers/video/msm/vidc/common/enc/venc_internal.h @@ -0,0 +1,154 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef VENC_INTERNAL_H +#define VENC_INTERNAL_H + +#include +#include +#include + +#define VID_ENC_MAX_NUM_OF_BUFF 100 + +enum venc_buffer_dir{ + VEN_BUFFER_TYPE_INPUT, + VEN_BUFFER_TYPE_OUTPUT +}; + +struct vid_enc_msg { + struct list_head list; + struct venc_msg venc_msg_info; +}; + +struct vid_enc_dev { + + struct cdev cdev; + struct device *device; + resource_size_t phys_base; + void __iomem *virt_base; + unsigned int irq; + struct clk *hclk; + struct clk *hclk_div2; + struct clk *pclk; + unsigned long hclk_rate; + struct mutex lock; + s32 device_handle; + struct video_client_ctx venc_clients[VIDC_MAX_NUM_CLIENTS]; + u32 num_clients; +}; + +u32 vid_enc_set_get_base_cfg(struct video_client_ctx *client_ctx, + struct venc_basecfg *base_config, u32 set_flag); + +u32 vid_enc_set_get_inputformat(struct video_client_ctx *client_ctx, + u32 *input_format, u32 set_flag); + +u32 vid_enc_set_get_codec(struct video_client_ctx *client_ctx, u32 *codec, + u32 set_flag); + +u32 vid_enc_set_get_framesize(struct video_client_ctx *client_ctx, + u32 *height, u32 *width, u32 set_flag); + +u32 vid_enc_set_get_bitrate(struct video_client_ctx *client_ctx, + struct venc_targetbitrate *venc_bitrate, u32 set_flag); + +u32 vid_enc_set_get_framerate(struct video_client_ctx *client_ctx, + struct venc_framerate *frame_rate, u32 set_flag); + +u32 vid_enc_set_get_live_mode(struct video_client_ctx *client_ctx, + struct venc_switch *encoder_switch, u32 set_flag); + +u32 vid_enc_set_get_extradata(struct video_client_ctx *client_ctx, + u32 *extradata_flag, u32 set_flag); + +u32 vid_enc_set_get_short_header(struct video_client_ctx *client_ctx, + struct venc_switch *encoder_switch, u32 set_flag); + +u32 vid_enc_set_get_profile(struct video_client_ctx *client_ctx, + struct venc_profile *profile, u32 set_flag); + +u32 vid_enc_set_get_profile_level(struct video_client_ctx *client_ctx, + struct ven_profilelevel *profile_level, u32 set_flag); + +u32 vid_enc_set_get_session_qp(struct video_client_ctx *client_ctx, + struct venc_sessionqp *session_qp, u32 set_flag); + +u32 vid_enc_set_get_intraperiod(struct video_client_ctx *client_ctx, + struct venc_intraperiod *intraperiod, u32 set_flag); + +u32 vid_enc_request_iframe(struct video_client_ctx *client_ctx); + +u32 vid_enc_get_sequence_header(struct video_client_ctx *client_ctx, + struct venc_seqheader *seq_header); + +u32 vid_enc_set_get_entropy_cfg(struct video_client_ctx *client_ctx, + struct venc_entropycfg *entropy_cfg, u32 set_flag); + +u32 vid_enc_set_get_dbcfg(struct video_client_ctx *client_ctx, + struct venc_dbcfg *dbcfg, u32 set_flag); + +u32 vid_enc_set_get_intrarefresh(struct video_client_ctx *client_ctx, + struct venc_intrarefresh *intrarefresh, u32 set_flag); + +u32 vid_enc_set_get_multiclicecfg(struct video_client_ctx *client_ctx, + struct venc_multiclicecfg *multiclicecfg, u32 set_flag); + +u32 vid_enc_set_get_ratectrlcfg(struct video_client_ctx *client_ctx, + struct venc_ratectrlcfg *ratectrlcfg, u32 set_flag); + +u32 vid_enc_set_get_voptimingcfg(struct video_client_ctx *client_ctx, + struct venc_voptimingcfg *voptimingcfg, u32 set_flag); + +u32 vid_enc_set_get_headerextension(struct video_client_ctx *client_ctx, + struct venc_headerextension *headerextension, u32 set_flag); + +u32 vid_enc_set_get_qprange(struct video_client_ctx *client_ctx, + struct venc_qprange *qprange, u32 set_flag); + +u32 vid_enc_start_stop(struct video_client_ctx *client_ctx, u32 start); + +u32 vid_enc_pause_resume(struct video_client_ctx *client_ctx, u32 pause); + +u32 vid_enc_flush(struct video_client_ctx *client_ctx, + struct venc_bufferflush *bufferflush); + +u32 vid_enc_get_buffer_req(struct video_client_ctx *client_ctx, + struct venc_allocatorproperty *venc_buf_req, u32 input_dir); + +u32 vid_enc_set_buffer_req(struct video_client_ctx *client_ctx, + struct venc_allocatorproperty *venc_buf_req, u32 input_dir); + +u32 vid_enc_set_buffer(struct video_client_ctx *client_ctx, + struct venc_bufferpayload *buffer_info, + enum venc_buffer_dir buffer); + +u32 vid_enc_free_buffer(struct video_client_ctx *client_ctx, + struct venc_bufferpayload *buffer_info, + enum venc_buffer_dir buffer); + +u32 vid_enc_encode_frame(struct video_client_ctx *client_ctx, + struct venc_buffer *input_frame_info); + +u32 vid_enc_fill_output_buffer(struct video_client_ctx *client_ctx, + struct venc_buffer *output_frame_info); + +u32 vid_enc_set_recon_buffers(struct video_client_ctx *client_ctx, + struct venc_recon_addr *venc_recon); + +u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx, + struct venc_recon_addr *venc_recon); + +u32 vid_enc_get_recon_buffer_size(struct video_client_ctx *client_ctx, + struct venc_recon_buff_size *venc_recon_size); + +#endif diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c new file mode 100644 index 0000000000000000000000000000000000000000..97aa580ba1e956e12f5e2a71d58f0fb704bd0930 --- /dev/null +++ b/drivers/video/msm/vidc/common/init/vidc_init.c @@ -0,0 +1,929 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vidc_init_internal.h" +#include "vcd_res_tracker_api.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define VIDC_NAME "msm_vidc_reg" + +#define ERR(x...) printk(KERN_ERR x) + +static struct vidc_dev *vidc_device_p; +static dev_t vidc_dev_num; +static struct class *vidc_class; +static unsigned int vidc_mmu_subsystem[] = {MSM_SUBSYSTEM_VIDEO}; + +static const struct file_operations vidc_fops = { + .owner = THIS_MODULE, + .open = NULL, + .release = NULL, + .unlocked_ioctl = NULL, +}; + +struct workqueue_struct *vidc_wq; +struct workqueue_struct *vidc_timer_wq; +static irqreturn_t vidc_isr(int irq, void *dev); +static spinlock_t vidc_spin_lock; + +u32 vidc_msg_timing, vidc_msg_pmem, vidc_msg_register; + +#ifdef VIDC_ENABLE_DBGFS +struct dentry *vidc_debugfs_root; + +struct dentry *vidc_get_debugfs_root(void) +{ + if (vidc_debugfs_root == NULL) + vidc_debugfs_root = debugfs_create_dir("vidc", NULL); + return vidc_debugfs_root; +} + +void vidc_debugfs_file_create(struct dentry *root, const char *name, + u32 *var) +{ + struct dentry *vidc_debugfs_file = + debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var); + if (!vidc_debugfs_file) + ERR("%s(): Error creating/opening file %s\n", __func__, name); +} +#endif + +static void vidc_timer_fn(unsigned long data) +{ + unsigned long flag; + struct vidc_timer *hw_timer = NULL; + ERR("%s() Timer expired\n", __func__); + spin_lock_irqsave(&vidc_spin_lock, flag); + hw_timer = (struct vidc_timer *)data; + list_add_tail(&hw_timer->list, &vidc_device_p->vidc_timer_queue); + spin_unlock_irqrestore(&vidc_spin_lock, flag); + DBG("Queue the work for timer\n"); + queue_work(vidc_timer_wq, &vidc_device_p->vidc_timer_worker); +} + +static void vidc_timer_handler(struct work_struct *work) +{ + unsigned long flag = 0; + u32 islist_empty = 0; + struct vidc_timer *hw_timer = NULL; + + ERR("%s() Timer expired\n", __func__); + do { + spin_lock_irqsave(&vidc_spin_lock, flag); + islist_empty = list_empty(&vidc_device_p->vidc_timer_queue); + if (!islist_empty) { + hw_timer = list_first_entry( + &vidc_device_p->vidc_timer_queue, + struct vidc_timer, list); + list_del(&hw_timer->list); + } + spin_unlock_irqrestore(&vidc_spin_lock, flag); + if (!islist_empty && hw_timer && hw_timer->cb_func) + hw_timer->cb_func(hw_timer->userdata); + } while (!islist_empty); +} + +static void vidc_work_handler(struct work_struct *work) +{ + DBG("vidc_work_handler()"); + vcd_read_and_clear_interrupt(); + vcd_response_handler(); + enable_irq(vidc_device_p->irq); + DBG("vidc_work_handler() done"); +} + +static DECLARE_WORK(vidc_work, vidc_work_handler); + +static int vidc_720p_probe(struct platform_device *pdev) +{ + struct resource *resource; + DBG("Enter %s()\n", __func__); + + if (pdev->id) { + ERR("Invalid plaform device ID = %d\n", pdev->id); + return -EINVAL; + } + vidc_device_p->irq = platform_get_irq(pdev, 0); + if (unlikely(vidc_device_p->irq < 0)) { + ERR("%s(): Invalid irq = %d\n", __func__, + vidc_device_p->irq); + return -ENXIO; + } + + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!resource)) { + ERR("%s(): Invalid resource\n", __func__); + return -ENXIO; + } + + vidc_device_p->phys_base = resource->start; + vidc_device_p->virt_base = ioremap(resource->start, + resource->end - resource->start + 1); + + if (!vidc_device_p->virt_base) { + ERR("%s() : ioremap failed\n", __func__); + return -ENOMEM; + } + vidc_device_p->device = &pdev->dev; + mutex_init(&vidc_device_p->lock); + + vidc_wq = create_singlethread_workqueue("vidc_worker_queue"); + if (!vidc_wq) { + ERR("%s: create workque failed\n", __func__); + return -ENOMEM; + } + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + return 0; +} + +static int vidc_720p_remove(struct platform_device *pdev) +{ + if (pdev->id) { + ERR("Invalid plaform device ID = %d\n", pdev->id); + return -EINVAL; + } + pm_runtime_disable(&pdev->dev); + + return 0; +} + +static int vidc_runtime_suspend(struct device *dev) +{ + dev_dbg(dev, "pm_runtime: suspending...\n"); + return 0; +} + +static int vidc_runtime_resume(struct device *dev) +{ + dev_dbg(dev, "pm_runtime: resuming...\n"); + return 0; +} + +static const struct dev_pm_ops vidc_dev_pm_ops = { + .runtime_suspend = vidc_runtime_suspend, + .runtime_resume = vidc_runtime_resume, +}; + +static struct platform_driver msm_vidc_720p_platform_driver = { + .probe = vidc_720p_probe, + .remove = vidc_720p_remove, + .driver = { + .name = "msm_vidc", + .pm = &vidc_dev_pm_ops, + }, +}; + +static void __exit vidc_exit(void) +{ + platform_driver_unregister(&msm_vidc_720p_platform_driver); +} + +static irqreturn_t vidc_isr(int irq, void *dev) +{ + DBG("\n vidc_isr() %d ", irq); + disable_irq_nosync(irq); + queue_work(vidc_wq, &vidc_work); + return IRQ_HANDLED; +} + +static int __init vidc_init(void) +{ + int rc = 0; + struct device *class_devp; +#ifdef VIDC_ENABLE_DBGFS + struct dentry *root = NULL; +#endif + + vidc_device_p = kzalloc(sizeof(struct vidc_dev), GFP_KERNEL); + if (!vidc_device_p) { + ERR("%s Unable to allocate memory for vidc_dev\n", + __func__); + return -ENOMEM; + } + + rc = alloc_chrdev_region(&vidc_dev_num, 0, 1, VIDC_NAME); + if (rc < 0) { + ERR("%s: alloc_chrdev_region Failed rc = %d\n", + __func__, rc); + goto error_vidc_alloc_chrdev_region; + } + + vidc_class = class_create(THIS_MODULE, VIDC_NAME); + if (IS_ERR(vidc_class)) { + rc = PTR_ERR(vidc_class); + ERR("%s: couldn't create vidc_class rc = %d\n", + __func__, rc); + + goto error_vidc_class_create; + } + + class_devp = device_create(vidc_class, NULL, vidc_dev_num, NULL, + VIDC_NAME); + + if (IS_ERR(class_devp)) { + rc = PTR_ERR(class_devp); + ERR("%s: class device_create failed %d\n", + __func__, rc); + goto error_vidc_class_device_create; + } + + cdev_init(&vidc_device_p->cdev, &vidc_fops); + vidc_device_p->cdev.owner = THIS_MODULE; + rc = cdev_add(&(vidc_device_p->cdev), vidc_dev_num, 1); + + if (rc < 0) { + ERR("%s: cdev_add failed %d\n", __func__, rc); + goto error_vidc_cdev_add; + } + + rc = platform_driver_register(&msm_vidc_720p_platform_driver); + if (rc) { + ERR("%s failed to load\n", __func__); + goto error_vidc_platfom_register; + } + + rc = request_irq(vidc_device_p->irq, vidc_isr, IRQF_TRIGGER_HIGH, + "vidc", vidc_device_p->device); + + if (unlikely(rc)) { + ERR("%s() :request_irq failed\n", __func__); + goto error_vidc_request_irq; + } + res_trk_init(vidc_device_p->device, vidc_device_p->irq); + vidc_timer_wq = create_singlethread_workqueue("vidc_timer_wq"); + if (!vidc_timer_wq) { + ERR("%s: create workque failed\n", __func__); + rc = -ENOMEM; + goto error_vidc_create_workqueue; + } + DBG("Disabling IRQ in %s()\n", __func__); + disable_irq_nosync(vidc_device_p->irq); + INIT_WORK(&vidc_device_p->vidc_timer_worker, + vidc_timer_handler); + spin_lock_init(&vidc_spin_lock); + INIT_LIST_HEAD(&vidc_device_p->vidc_timer_queue); + + vidc_device_p->ref_count = 0; + vidc_device_p->firmware_refcount = 0; + vidc_device_p->get_firmware = 0; +#ifdef VIDC_ENABLE_DBGFS + root = vidc_get_debugfs_root(); + if (root) { + vidc_debugfs_file_create(root, "vidc_msg_timing", + (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; + +error_vidc_create_workqueue: + free_irq(vidc_device_p->irq, vidc_device_p->device); +error_vidc_request_irq: + platform_driver_unregister(&msm_vidc_720p_platform_driver); +error_vidc_platfom_register: + cdev_del(&(vidc_device_p->cdev)); +error_vidc_cdev_add: + device_destroy(vidc_class, vidc_dev_num); +error_vidc_class_device_create: + class_destroy(vidc_class); +error_vidc_class_create: + unregister_chrdev_region(vidc_dev_num, 1); +error_vidc_alloc_chrdev_region: + kfree(vidc_device_p); + + return rc; +} + +void __iomem *vidc_get_ioaddr(void) +{ + return (u8 *)vidc_device_p->virt_base; +} +EXPORT_SYMBOL(vidc_get_ioaddr); + +int vidc_load_firmware(void) +{ + u32 status = true; + + if (!res_trk_check_for_sec_session()) { + mutex_lock(&vidc_device_p->lock); + if (!vidc_device_p->get_firmware) { + status = res_trk_download_firmware(); + if (!status) + goto error; + vidc_device_p->get_firmware = 1; + } + vidc_device_p->firmware_refcount++; +error: + mutex_unlock(&vidc_device_p->lock); + } + return status; +} +EXPORT_SYMBOL(vidc_load_firmware); + +void vidc_release_firmware(void) +{ + if (!res_trk_check_for_sec_session()) { + mutex_lock(&vidc_device_p->lock); + if (vidc_device_p->firmware_refcount > 0) + vidc_device_p->firmware_refcount--; + else + vidc_device_p->firmware_refcount = 0; + mutex_unlock(&vidc_device_p->lock); + } +} +EXPORT_SYMBOL(vidc_release_firmware); + +u32 vidc_get_fd_info(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, int pmem_fd, + unsigned long kvaddr, int index, + struct ion_handle **buff_handle) +{ + struct buf_addr_table *buf_addr_table; + u32 rc = 0; + if (!client_ctx) + return false; + if (buffer == BUFFER_TYPE_INPUT) + buf_addr_table = client_ctx->input_buf_addr_table; + else + buf_addr_table = client_ctx->output_buf_addr_table; + if (buf_addr_table[index].pmem_fd == pmem_fd) { + if (buf_addr_table[index].kernel_vaddr == kvaddr) { + rc = buf_addr_table[index].buff_ion_flag; + *buff_handle = buf_addr_table[index].buff_ion_handle; + } else + *buff_handle = NULL; + } else + *buff_handle = NULL; + return rc; +} +EXPORT_SYMBOL(vidc_get_fd_info); + +void vidc_cleanup_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer) +{ + u32 *num_of_buffers = NULL; + u32 i = 0; + struct buf_addr_table *buf_addr_table; + if (buffer == BUFFER_TYPE_INPUT) { + buf_addr_table = client_ctx->input_buf_addr_table; + num_of_buffers = &client_ctx->num_of_input_buffers; + DBG("%s(): buffer = INPUT\n", __func__); + + } else { + buf_addr_table = client_ctx->output_buf_addr_table; + num_of_buffers = &client_ctx->num_of_output_buffers; + DBG("%s(): buffer = OUTPUT\n", __func__); + } + + if (!*num_of_buffers) + goto bail_out_cleanup; + if (!client_ctx->user_ion_client) + goto bail_out_cleanup; + for (i = 0; i < *num_of_buffers; ++i) { + if (buf_addr_table[i].client_data) { + msm_subsystem_unmap_buffer( + (struct msm_mapped_buffer *) + buf_addr_table[i].client_data); + buf_addr_table[i].client_data = NULL; + } + if (!IS_ERR_OR_NULL(buf_addr_table[i].buff_ion_handle)) { + if (!IS_ERR_OR_NULL(client_ctx->user_ion_client)) { + ion_unmap_kernel(client_ctx->user_ion_client, + buf_addr_table[i]. + buff_ion_handle); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu( + client_ctx->user_ion_client, + buf_addr_table[i]. + buff_ion_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + } + ion_free(client_ctx->user_ion_client, + buf_addr_table[i]. + buff_ion_handle); + buf_addr_table[i].buff_ion_handle = NULL; + } + } + } + if (client_ctx->vcd_h264_mv_buffer.client_data) { + msm_subsystem_unmap_buffer((struct msm_mapped_buffer *) + client_ctx->vcd_h264_mv_buffer.client_data); + client_ctx->vcd_h264_mv_buffer.client_data = NULL; + } + if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) { + if (!IS_ERR_OR_NULL(client_ctx->user_ion_client)) { + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + } + ion_free(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle); + client_ctx->h264_mv_ion_handle = NULL; + } + } +bail_out_cleanup: + return; +} +EXPORT_SYMBOL(vidc_cleanup_addr_table); + +u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, + u32 search_with_user_vaddr, + unsigned long *user_vaddr, + unsigned long *kernel_vaddr, + unsigned long *phy_addr, int *pmem_fd, + struct file **file, s32 *buffer_index) +{ + u32 num_of_buffers; + u32 i; + struct buf_addr_table *buf_addr_table; + u32 found = false; + + if (!client_ctx) + return false; + mutex_lock(&client_ctx->enrty_queue_lock); + if (buffer == BUFFER_TYPE_INPUT) { + buf_addr_table = client_ctx->input_buf_addr_table; + num_of_buffers = client_ctx->num_of_input_buffers; + DBG("%s(): buffer = INPUT\n", __func__); + + } else { + buf_addr_table = client_ctx->output_buf_addr_table; + num_of_buffers = client_ctx->num_of_output_buffers; + DBG("%s(): buffer = OUTPUT\n", __func__); + } + + for (i = 0; i < num_of_buffers; ++i) { + if (search_with_user_vaddr) { + if (*user_vaddr == buf_addr_table[i].user_vaddr) { + *kernel_vaddr = buf_addr_table[i].kernel_vaddr; + found = true; + DBG("%s() : client_ctx = %p." + " user_virt_addr = 0x%08lx is found", + __func__, client_ctx, *user_vaddr); + break; + } + } else { + if (*kernel_vaddr == buf_addr_table[i].kernel_vaddr) { + *user_vaddr = buf_addr_table[i].user_vaddr; + found = true; + DBG("%s() : client_ctx = %p." + " kernel_virt_addr = 0x%08lx is found", + __func__, client_ctx, *kernel_vaddr); + break; + } + } + } + + if (found) { + *phy_addr = buf_addr_table[i].dev_addr; + *pmem_fd = buf_addr_table[i].pmem_fd; + *file = buf_addr_table[i].file; + *buffer_index = i; + + if (search_with_user_vaddr) + DBG("kernel_vaddr = 0x%08lx, phy_addr = 0x%08lx " + " pmem_fd = %d, struct *file = %p " + "buffer_index = %d\n", *kernel_vaddr, + *phy_addr, *pmem_fd, *file, *buffer_index); + else + DBG("user_vaddr = 0x%08lx, phy_addr = 0x%08lx " + " pmem_fd = %d, struct *file = %p " + "buffer_index = %d\n", *user_vaddr, *phy_addr, + *pmem_fd, *file, *buffer_index); + mutex_unlock(&client_ctx->enrty_queue_lock); + return true; + } else { + if (search_with_user_vaddr) + DBG("%s() : client_ctx = %p user_virt_addr = 0x%08lx" + " Not Found.\n", __func__, client_ctx, *user_vaddr); + else + DBG("%s() : client_ctx = %p kernel_virt_addr = 0x%08lx" + " Not Found.\n", __func__, client_ctx, + *kernel_vaddr); + mutex_unlock(&client_ctx->enrty_queue_lock); + return false; + } +} +EXPORT_SYMBOL(vidc_lookup_addr_table); + +u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, unsigned long user_vaddr, + unsigned long *kernel_vaddr, int pmem_fd, + unsigned long buffer_addr_offset, unsigned int max_num_buffers, + unsigned long length) +{ + unsigned long len, phys_addr; + struct file *file = NULL; + u32 *num_of_buffers = NULL; + u32 i, flags; + struct buf_addr_table *buf_addr_table; + struct msm_mapped_buffer *mapped_buffer = NULL; + struct ion_handle *buff_ion_handle = NULL; + unsigned long ionflag = 0; + unsigned long iova = 0; + int ret = 0; + unsigned long buffer_size = 0; + size_t ion_len; + + if (!client_ctx || !length) + return false; + mutex_lock(&client_ctx->enrty_queue_lock); + if (buffer == BUFFER_TYPE_INPUT) { + buf_addr_table = client_ctx->input_buf_addr_table; + num_of_buffers = &client_ctx->num_of_input_buffers; + DBG("%s(): buffer = INPUT #Buf = %d\n", + __func__, *num_of_buffers); + + } else { + buf_addr_table = client_ctx->output_buf_addr_table; + num_of_buffers = &client_ctx->num_of_output_buffers; + DBG("%s(): buffer = OUTPUT #Buf = %d\n", + __func__, *num_of_buffers); + length = length * 2; /* workaround for iommu video h/w bug */ + } + + if (*num_of_buffers == max_num_buffers) { + ERR("%s(): Num of buffers reached max value : %d", + __func__, max_num_buffers); + goto bail_out_add; + } + + i = 0; + while (i < *num_of_buffers && + user_vaddr != buf_addr_table[i].user_vaddr) + i++; + if (i < *num_of_buffers) { + DBG("%s() : client_ctx = %p." + " user_virt_addr = 0x%08lx already set", + __func__, client_ctx, user_vaddr); + goto bail_out_add; + } else { + if (!vcd_get_ion_status()) { + if (get_pmem_file(pmem_fd, &phys_addr, + kernel_vaddr, &len, &file)) { + ERR("%s(): get_pmem_file failed\n", __func__); + goto bail_out_add; + } + put_pmem_file(file); + flags = (buffer == BUFFER_TYPE_INPUT) + ? MSM_SUBSYSTEM_MAP_IOVA : + MSM_SUBSYSTEM_MAP_IOVA|MSM_SUBSYSTEM_ALIGN_IOVA_8K; + mapped_buffer = msm_subsystem_map_buffer(phys_addr, + length, flags, vidc_mmu_subsystem, + sizeof(vidc_mmu_subsystem)/sizeof(unsigned int)); + if (IS_ERR(mapped_buffer)) { + pr_err("buffer map failed"); + goto bail_out_add; + } + buf_addr_table[*num_of_buffers].client_data = (void *) + mapped_buffer; + buf_addr_table[*num_of_buffers].dev_addr = + mapped_buffer->iova[0]; + } else { + buff_ion_handle = ion_import_fd( + client_ctx->user_ion_client, pmem_fd); + if (IS_ERR_OR_NULL(buff_ion_handle)) { + ERR("%s(): get_ION_handle failed\n", + __func__); + goto bail_out_add; + } + if (ion_handle_get_flags(client_ctx->user_ion_client, + buff_ion_handle, + &ionflag)) { + ERR("%s():ION flags fail\n", + __func__); + goto bail_out_add; + } + *kernel_vaddr = (unsigned long) + ion_map_kernel( + client_ctx->user_ion_client, + buff_ion_handle, + ionflag); + 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()) { + if (ion_phys(client_ctx->user_ion_client, + buff_ion_handle, + &phys_addr, &ion_len)) { + ERR("%s():ION physical addr fail\n", + __func__); + goto ion_map_error; + } + len = (unsigned long) ion_len; + buf_addr_table[*num_of_buffers].client_data = + NULL; + buf_addr_table[*num_of_buffers].dev_addr = + phys_addr; + } else { + ret = ion_map_iommu(client_ctx->user_ion_client, + buff_ion_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL, + SZ_8K, + length, + (unsigned long *) &iova, + (unsigned long *) &buffer_size, + UNCACHED, + ION_IOMMU_UNMAP_DELAYED); + if (ret) { + ERR("%s():ION iommu map fail\n", + __func__); + goto ion_map_error; + } + phys_addr = iova; + buf_addr_table[*num_of_buffers].client_data = + NULL; + buf_addr_table[*num_of_buffers].dev_addr = + iova; + } + } + phys_addr += buffer_addr_offset; + (*kernel_vaddr) += buffer_addr_offset; + buf_addr_table[*num_of_buffers].user_vaddr = user_vaddr; + buf_addr_table[*num_of_buffers].kernel_vaddr = *kernel_vaddr; + buf_addr_table[*num_of_buffers].pmem_fd = pmem_fd; + buf_addr_table[*num_of_buffers].file = file; + buf_addr_table[*num_of_buffers].phy_addr = phys_addr; + buf_addr_table[*num_of_buffers].buff_ion_handle = + buff_ion_handle; + buf_addr_table[*num_of_buffers].buff_ion_flag = + ionflag; + *num_of_buffers = *num_of_buffers + 1; + DBG("%s() : client_ctx = %p, user_virt_addr = 0x%08lx, " + "kernel_vaddr = 0x%08lx phys_addr=%lu inserted!", + __func__, client_ctx, user_vaddr, *kernel_vaddr, + phys_addr); + } + 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: + mutex_unlock(&client_ctx->enrty_queue_lock); + return false; +} +EXPORT_SYMBOL(vidc_insert_addr_table); + +/* + * Similar to vidc_insert_addr_table except intended for in-kernel + * use where buffers have already been alloced and mapped properly + */ +u32 vidc_insert_addr_table_kernel(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, unsigned long user_vaddr, + unsigned long kernel_vaddr, unsigned long phys_addr, + unsigned int max_num_buffers, + unsigned long length) +{ + u32 *num_of_buffers = NULL; + u32 i; + struct buf_addr_table *buf_addr_table; + struct msm_mapped_buffer *mapped_buffer = NULL; + + if (!client_ctx || !length || !kernel_vaddr || !phys_addr) + return false; + mutex_lock(&client_ctx->enrty_queue_lock); + if (buffer == BUFFER_TYPE_INPUT) { + buf_addr_table = client_ctx->input_buf_addr_table; + num_of_buffers = &client_ctx->num_of_input_buffers; + DBG("%s(): buffer = INPUT #Buf = %d\n", + __func__, *num_of_buffers); + + } else { + buf_addr_table = client_ctx->output_buf_addr_table; + num_of_buffers = &client_ctx->num_of_output_buffers; + DBG("%s(): buffer = OUTPUT #Buf = %d\n", + __func__, *num_of_buffers); + } + + if (*num_of_buffers == max_num_buffers) { + ERR("%s(): Num of buffers reached max value : %d", + __func__, max_num_buffers); + goto bail_out_add; + } + + i = 0; + while (i < *num_of_buffers && + user_vaddr != buf_addr_table[i].user_vaddr) { + i++; + } + if (i < *num_of_buffers) { + DBG("%s() : client_ctx = %p." + " user_virt_addr = 0x%08lx already set", + __func__, client_ctx, user_vaddr); + goto bail_out_add; + } else { + mapped_buffer = NULL; + buf_addr_table[*num_of_buffers].client_data = (void *) + mapped_buffer; + buf_addr_table[*num_of_buffers].dev_addr = phys_addr; + buf_addr_table[*num_of_buffers].user_vaddr = user_vaddr; + buf_addr_table[*num_of_buffers].kernel_vaddr = kernel_vaddr; + buf_addr_table[*num_of_buffers].pmem_fd = -1; + buf_addr_table[*num_of_buffers].file = NULL; + buf_addr_table[*num_of_buffers].phy_addr = phys_addr; + buf_addr_table[*num_of_buffers].buff_ion_handle = NULL; + *num_of_buffers = *num_of_buffers + 1; + DBG("%s() : client_ctx = %p, user_virt_addr = 0x%08lx, " + "kernel_vaddr = 0x%08lx inserted!", __func__, + client_ctx, user_vaddr, *kernel_vaddr); + } + mutex_unlock(&client_ctx->enrty_queue_lock); + return true; +bail_out_add: + mutex_unlock(&client_ctx->enrty_queue_lock); + return false; +} +EXPORT_SYMBOL(vidc_insert_addr_table_kernel); + +u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, + unsigned long user_vaddr, + unsigned long *kernel_vaddr) +{ + u32 *num_of_buffers = NULL; + u32 i; + struct buf_addr_table *buf_addr_table; + + if (!client_ctx) + return false; + mutex_lock(&client_ctx->enrty_queue_lock); + if (buffer == BUFFER_TYPE_INPUT) { + buf_addr_table = client_ctx->input_buf_addr_table; + num_of_buffers = &client_ctx->num_of_input_buffers; + + } else { + buf_addr_table = client_ctx->output_buf_addr_table; + num_of_buffers = &client_ctx->num_of_output_buffers; + } + + if (!*num_of_buffers) + goto bail_out_del; + + i = 0; + while (i < *num_of_buffers && + user_vaddr != buf_addr_table[i].user_vaddr) + i++; + if (i == *num_of_buffers) { + pr_err("%s() : client_ctx = %p." + " user_virt_addr = 0x%08lx NOT found", + __func__, client_ctx, user_vaddr); + goto bail_out_del; + } + if (buf_addr_table[i].client_data) { + msm_subsystem_unmap_buffer( + (struct msm_mapped_buffer *)buf_addr_table[i].client_data); + buf_addr_table[i].client_data = NULL; + } + *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()) { + ion_unmap_iommu(client_ctx->user_ion_client, + buf_addr_table[i].buff_ion_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + } + ion_free(client_ctx->user_ion_client, + buf_addr_table[i].buff_ion_handle); + buf_addr_table[i].buff_ion_handle = NULL; + } + if (i < (*num_of_buffers - 1)) { + buf_addr_table[i].client_data = + buf_addr_table[*num_of_buffers - 1].client_data; + buf_addr_table[i].dev_addr = + buf_addr_table[*num_of_buffers - 1].dev_addr; + buf_addr_table[i].user_vaddr = + buf_addr_table[*num_of_buffers - 1].user_vaddr; + buf_addr_table[i].kernel_vaddr = + buf_addr_table[*num_of_buffers - 1].kernel_vaddr; + buf_addr_table[i].phy_addr = + buf_addr_table[*num_of_buffers - 1].phy_addr; + buf_addr_table[i].pmem_fd = + buf_addr_table[*num_of_buffers - 1].pmem_fd; + buf_addr_table[i].file = + buf_addr_table[*num_of_buffers - 1].file; + buf_addr_table[i].buff_ion_handle = + buf_addr_table[*num_of_buffers - 1].buff_ion_handle; + } + *num_of_buffers = *num_of_buffers - 1; + DBG("%s() : client_ctx = %p." + " user_virt_addr = 0x%08lx is found and deleted", + __func__, client_ctx, user_vaddr); + mutex_unlock(&client_ctx->enrty_queue_lock); + return true; +bail_out_del: + mutex_unlock(&client_ctx->enrty_queue_lock); + return false; +} +EXPORT_SYMBOL(vidc_delete_addr_table); + +u32 vidc_timer_create(void (*timer_handler)(void *), + void *user_data, void **timer_handle) +{ + struct vidc_timer *hw_timer = NULL; + if (!timer_handler || !timer_handle) { + DBG("%s(): timer creation failed\n ", __func__); + return false; + } + hw_timer = kzalloc(sizeof(struct vidc_timer), GFP_KERNEL); + if (!hw_timer) { + DBG("%s(): timer creation failed in allocation\n ", __func__); + return false; + } + init_timer(&hw_timer->hw_timeout); + hw_timer->hw_timeout.data = (unsigned long)hw_timer; + hw_timer->hw_timeout.function = vidc_timer_fn; + hw_timer->cb_func = timer_handler; + hw_timer->userdata = user_data; + *timer_handle = hw_timer; + return true; +} +EXPORT_SYMBOL(vidc_timer_create); + +void vidc_timer_release(void *timer_handle) +{ + kfree(timer_handle); +} +EXPORT_SYMBOL(vidc_timer_release); + +void vidc_timer_start(void *timer_handle, u32 time_out) +{ + struct vidc_timer *hw_timer = (struct vidc_timer *)timer_handle; + DBG("%s(): start timer\n ", __func__); + if (hw_timer) { + hw_timer->hw_timeout.expires = jiffies + 1*HZ; + add_timer(&hw_timer->hw_timeout); + } +} +EXPORT_SYMBOL(vidc_timer_start); + +void vidc_timer_stop(void *timer_handle) +{ + struct vidc_timer *hw_timer = (struct vidc_timer *)timer_handle; + DBG("%s(): stop timer\n ", __func__); + if (hw_timer) + del_timer(&hw_timer->hw_timeout); +} +EXPORT_SYMBOL(vidc_timer_stop); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Video decoder/encoder driver Init Module"); +MODULE_VERSION("1.0"); +module_init(vidc_init); +module_exit(vidc_exit); diff --git a/drivers/video/msm/vidc/common/init/vidc_init_internal.h b/drivers/video/msm/vidc/common/init/vidc_init_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..b62280faebac1db8c1f3a652a11f40771f8afc5d --- /dev/null +++ b/drivers/video/msm/vidc/common/init/vidc_init_internal.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2010, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef VIDC_INIT_INTERNAL_H +#define VIDC_INIT_INTERNAL_H + +#include + +struct vidc_timer { + struct list_head list; + struct timer_list hw_timeout; + void (*cb_func)(void *); + void *userdata; +}; + +struct vidc_dev { + struct cdev cdev; + struct device *device; + resource_size_t phys_base; + void __iomem *virt_base; + unsigned int irq; + unsigned int ref_count; + unsigned int firmware_refcount; + unsigned int get_firmware; + struct mutex lock; + s32 device_handle; + struct list_head vidc_timer_queue; + struct work_struct vidc_timer_worker; +}; + +#endif diff --git a/drivers/video/msm/vidc/common/vcd/vcd.h b/drivers/video/msm/vidc/common/vcd/vcd.h new file mode 100644 index 0000000000000000000000000000000000000000..9650193ddf47446255c7f3506f71ae560644d61d --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd.h @@ -0,0 +1,400 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_H_ +#define _VCD_H_ + +#include +#include "vcd_util.h" +#include "vcd_ddl_api.h" +#include "vcd_res_tracker_api.h" +#include "vcd_client_sm.h" +#include "vcd_core.h" +#include "vcd_device_sm.h" + +void vcd_reset_device_channels(struct vcd_dev_ctxt *dev_ctxt); + +u32 vcd_get_command_channel + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc **transc); + +u32 vcd_get_command_channel_in_loop + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc **transc); + +void vcd_mark_command_channel + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc); + +void vcd_release_command_channel + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc); + +void vcd_release_multiple_command_channels(struct vcd_dev_ctxt *dev_ctxt, + u32 channels); + +void vcd_release_interim_command_channels(struct vcd_dev_ctxt *dev_ctxt); + +u32 vcd_get_frame_channel + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc **transc); + +u32 vcd_get_frame_channel_in_loop + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc **transc); + +void vcd_mark_frame_channel(struct vcd_dev_ctxt *dev_ctxt); + +void vcd_release_frame_channel + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc); + +void vcd_release_multiple_frame_channels(struct vcd_dev_ctxt *dev_ctxt, + u32 channels); + +void vcd_release_interim_frame_channels(struct vcd_dev_ctxt *dev_ctxt); +u32 vcd_core_is_busy(struct vcd_dev_ctxt *dev_ctxt); + +void vcd_device_timer_start(struct vcd_dev_ctxt *dev_ctxt); +void vcd_device_timer_stop(struct vcd_dev_ctxt *dev_ctxt); + + +u32 vcd_init_device_context + (struct vcd_drv_ctxt *drv_ctxt, u32 ev_code); + +u32 vcd_deinit_device_context + (struct vcd_drv_ctxt *drv_ctxt, u32 ev_code); + +u32 vcd_init_client_context(struct vcd_clnt_ctxt *cctxt); + +void vcd_destroy_client_context(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_check_for_client_context + (struct vcd_dev_ctxt *dev_ctxt, s32 driver_id); + +u32 vcd_validate_driver_handle + (struct vcd_dev_ctxt *dev_ctxt, s32 driver_handle); + +void vcd_handle_for_last_clnt_close + (struct vcd_dev_ctxt *dev_ctxt, u32 send_deinit); + +u32 vcd_common_allocate_set_buffer + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer, + u32 buf_size, struct vcd_buffer_pool **buf_pool); + +u32 vcd_set_buffer_internal + (struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool, u8 *buffer, u32 buf_size); + +u32 vcd_allocate_buffer_internal + (struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool, + u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr); + +u32 vcd_free_one_buffer_internal + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type, u8 *buffer); + +u32 vcd_free_buffers_internal + (struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool); + +u32 vcd_alloc_buffer_pool_entries + (struct vcd_buffer_pool *buf_pool, + struct vcd_buffer_requirement *buf_req); + +void vcd_free_buffer_pool_entries(struct vcd_buffer_pool *buf_pool); + +void vcd_flush_in_use_buffer_pool_entries(struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool, u32 event); + +void vcd_reset_buffer_pool_for_reuse(struct vcd_buffer_pool *buf_pool); + +struct vcd_buffer_entry *vcd_get_free_buffer_pool_entry + (struct vcd_buffer_pool *pool); + +struct vcd_buffer_entry *vcd_find_buffer_pool_entry + (struct vcd_buffer_pool *pool, u8 *v_addr); + +struct vcd_buffer_entry *vcd_buffer_pool_entry_de_q + (struct vcd_buffer_pool *pool); + +u32 vcd_buffer_pool_entry_en_q + (struct vcd_buffer_pool *pool, + struct vcd_buffer_entry *entry); + +u32 vcd_check_if_buffer_req_met(struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type); + +u32 vcd_client_cmd_en_q + (struct vcd_clnt_ctxt *cctxt, enum vcd_command command); + +void vcd_client_cmd_flush_and_en_q + (struct vcd_clnt_ctxt *cctxt, enum vcd_command command); + +u32 vcd_client_cmd_de_q + (struct vcd_clnt_ctxt *cctxt, enum vcd_command *command); + +u32 vcd_handle_recvd_eos + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame, u32 * pb_eos_handled); + +u32 vcd_handle_first_decode_frame(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_handle_input_frame + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame); + +u32 vcd_store_seq_hdr + (struct vcd_clnt_ctxt *cctxt, + struct vcd_sequence_hdr *seq_hdr); + +u32 vcd_set_frame_size + (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_frame_size *frm_size); + +u32 vcd_set_frame_rate + (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_frame_rate *fps); + +u32 vcd_calculate_frame_delta + (struct vcd_clnt_ctxt *cctxt, struct vcd_frame_data *frame); + +struct vcd_buffer_entry *vcd_check_fill_output_buffer + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer); + +u32 vcd_handle_first_fill_output_buffer + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer, u32 *b_handled); + +u32 vcd_handle_first_fill_output_buffer_for_enc + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *frm_entry, u32 *b_handled); + +u32 vcd_handle_first_fill_output_buffer_for_dec + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *frm_entry, u32 *b_handled); + +u32 vcd_schedule_frame(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt **cctxt, struct vcd_buffer_entry + **ip_buf_entry); + +u32 vcd_submit_command_in_continue + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc); + +u32 vcd_submit_cmd_sess_start(struct vcd_transc *transc); + +u32 vcd_submit_cmd_sess_end(struct vcd_transc *transc); + +void vcd_submit_cmd_client_close(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_submit_frame + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc); + +u32 vcd_try_submit_frame_in_continue(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc *transc); + +u32 vcd_process_cmd_sess_start(struct vcd_clnt_ctxt *cctxt); + +void vcd_try_submit_frame(struct vcd_dev_ctxt *dev_ctxt); + +u32 vcd_setup_with_ddl_capabilities(struct vcd_dev_ctxt *dev_ctxt); +void vcd_handle_submit_frame_failed(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc *transc); + +struct vcd_transc *vcd_get_free_trans_tbl_entry + (struct vcd_dev_ctxt *dev_ctxt); + +void vcd_release_trans_tbl_entry(struct vcd_transc *trans_entry); + +void vcd_release_all_clnt_frm_transc(struct vcd_clnt_ctxt *cctxt); +void vcd_release_all_clnt_transc(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_handle_input_done + (struct vcd_clnt_ctxt *cctxt, + void *payload, u32 event, u32 status); + +u32 vcd_handle_input_done_in_eos + (struct vcd_clnt_ctxt *cctxt, void *payload, u32 status); + +void vcd_handle_input_done_failed + (struct vcd_clnt_ctxt *cctxt, struct vcd_transc *transc); + +void vcd_handle_input_done_with_codec_config + (struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, + struct ddl_frame_data_tag *frm); + +void vcd_handle_input_done_for_interlacing + (struct vcd_clnt_ctxt *cctxt); + +void vcd_handle_input_done_with_trans_end + (struct vcd_clnt_ctxt *cctxt); + +u32 vcd_handle_frame_done + (struct vcd_clnt_ctxt *cctxt, + void *payload, u32 event, u32 status); + +void vcd_handle_frame_done_for_interlacing + (struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc_ip1, + struct ddl_frame_data_tag *op_frm, u32 status); + + +u32 vcd_handle_frame_done_in_eos + (struct vcd_clnt_ctxt *cctxt, void *payload, u32 status); + +u32 vcd_handle_output_required(struct vcd_clnt_ctxt *cctxt, + void *payload, u32 status); + +u32 vcd_handle_output_required_in_flushing(struct vcd_clnt_ctxt *cctxt, + void *payload); + +u32 vcd_handle_output_req_tran_end_in_eos(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_validate_io_done_pyld + (struct vcd_clnt_ctxt *cctxt, void *payload, u32 status); + +void vcd_handle_eos_trans_end(struct vcd_clnt_ctxt *cctxt); + + +void vcd_handle_eos_done + (struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status); + +void vcd_send_frame_done_in_eos + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame, u32 valid_opbuf); + +void vcd_send_frame_done_in_eos_for_dec + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame); + +void vcd_send_frame_done_in_eos_for_enc + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame); + +void vcd_handle_start_done(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status); + +void vcd_handle_stop_done(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status); + +void vcd_handle_stop_done_in_starting(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status); + +void vcd_handle_stop_done_in_invalid(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status); + +void vcd_send_flush_done(struct vcd_clnt_ctxt *cctxt, u32 status); + +void vcd_process_pending_flush_in_eos(struct vcd_clnt_ctxt *cctxt); + +void vcd_process_pending_stop_in_eos(struct vcd_clnt_ctxt *cctxt); + +void vcd_handle_trans_pending(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_handle_ind_output_reconfig + (struct vcd_clnt_ctxt *cctxt, void* payload, u32 status); + +u32 vcd_handle_ind_output_reconfig_in_flushing + (struct vcd_clnt_ctxt *cctxt, void* payload, u32 status); + +void vcd_flush_output_buffers(struct vcd_clnt_ctxt *cctxt); + +void vcd_flush_bframe_buffers(struct vcd_clnt_ctxt *cctxt, u32 mode); + +u32 vcd_flush_buffers(struct vcd_clnt_ctxt *cctxt, u32 mode); +void vcd_flush_buffers_in_err_fatal(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_power_event + (struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt, u32 event); + +u32 vcd_device_power_event(struct vcd_dev_ctxt *dev_ctxt, u32 event, + struct vcd_clnt_ctxt *cctxt); + +u32 vcd_client_power_event + (struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt, u32 event); + +u32 vcd_enable_clock(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt); + +u32 vcd_disable_clock(struct vcd_dev_ctxt *dev_ctxt); + +u32 vcd_set_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_lvl); + +u32 vcd_update_clnt_perf_lvl + (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_frame_rate *fps, u32 frm_p_units); + +u32 vcd_gate_clock(struct vcd_dev_ctxt *dev_ctxt); + +u32 vcd_un_gate_clock(struct vcd_dev_ctxt *dev_ctxt); + +void vcd_handle_err_fatal(struct vcd_clnt_ctxt *cctxt, + u32 event, u32 status); + +void vcd_handle_device_err_fatal(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt); + +void vcd_clnt_handle_device_err_fatal(struct vcd_clnt_ctxt *cctxt, + u32 event); + +void vcd_handle_err_in_starting(struct vcd_clnt_ctxt *cctxt, + u32 status); + +void vcd_handle_ind_hw_err_fatal(struct vcd_clnt_ctxt *cctxt, + u32 event, u32 status); + +u32 vcd_return_op_buffer_to_hw(struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_entry *buf_entry); + +u32 vcd_sched_create(struct list_head *sched_list); + +void vcd_sched_destroy(struct list_head *sched_clnt_list); + +u32 vcd_sched_add_client(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_sched_remove_client(struct vcd_sched_clnt_ctx *sched_cctxt); + +u32 vcd_sched_update_config(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_sched_queue_buffer( + struct vcd_sched_clnt_ctx *sched_cctxt, + struct vcd_buffer_entry *buffer, u32 b_tail); + +u32 vcd_sched_dequeue_buffer( + struct vcd_sched_clnt_ctx *sched_cctxt, + struct vcd_buffer_entry **buffer); + +u32 vcd_sched_mark_client_eof(struct vcd_sched_clnt_ctx *sched_cctxt); + +u32 vcd_sched_suspend_resume_clnt( + struct vcd_clnt_ctxt *cctxt, u32 b_state); + +u32 vcd_sched_get_client_frame(struct list_head *sched_clnt_list, + struct vcd_clnt_ctxt **cctxt, + struct vcd_buffer_entry **buffer); + +void vcd_handle_clnt_fatal(struct vcd_clnt_ctxt *cctxt, u32 trans_end); + +void vcd_handle_clnt_fatal_input_done(struct vcd_clnt_ctxt *cctxt, + u32 trans_end); + +void vcd_handle_ind_info_output_reconfig + (struct vcd_clnt_ctxt *cctxt, u32 status); + +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); + +u32 vcd_update_decoder_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_lvl); + +#endif diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.c b/drivers/video/msm/vidc/common/vcd/vcd_api.c new file mode 100644 index 0000000000000000000000000000000000000000..facde348bab3e408de4242c941963c8858e9fd7c --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_api.c @@ -0,0 +1,986 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include "vcd.h" + +u32 vcd_init(struct vcd_init_config *config, s32 *driver_handle) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_drv_ctxt *drv_ctxt; + + VCD_MSG_MED("vcd_init:"); + + if (!config || + !driver_handle || !config->map_dev_base_addr) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_ILLEGAL_PARM; + } + + drv_ctxt = vcd_get_drv_context(); + mutex_init(&drv_ctxt->dev_mutex); + mutex_lock(&drv_ctxt->dev_mutex); + + if (drv_ctxt->dev_state.state_table->ev_hdlr.init) { + rc = drv_ctxt->dev_state.state_table->ev_hdlr. + init(drv_ctxt, config, driver_handle); + } else { + VCD_MSG_ERROR("Unsupported API in device state %d", + drv_ctxt->dev_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_init); + +u32 vcd_term(s32 driver_handle) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_drv_ctxt *drv_ctxt; + + VCD_MSG_MED("vcd_term:"); + + drv_ctxt = vcd_get_drv_context(); + mutex_lock(&drv_ctxt->dev_mutex); + + if (drv_ctxt->dev_state.state_table->ev_hdlr.term) { + rc = drv_ctxt->dev_state.state_table->ev_hdlr. + term(drv_ctxt, driver_handle); + } else { + VCD_MSG_ERROR("Unsupported API in device state %d", + drv_ctxt->dev_state.state); + + rc = VCD_ERR_BAD_STATE; + } + mutex_unlock(&drv_ctxt->dev_mutex); + return rc; + +} +EXPORT_SYMBOL(vcd_term); + +struct client_security_info { + int secure_enc; + int secure_dec; + int non_secure_enc; + int non_secure_dec; +}; + +static int vcd_get_clients_security_info(struct client_security_info *sec_info) +{ + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_clnt_ctxt *cctxt; + int count = 0; + if (!sec_info) { + VCD_MSG_ERROR("Invalid argument\n"); + return -EINVAL; + } + memset(sec_info, 0 , sizeof(*sec_info)); + drv_ctxt = vcd_get_drv_context(); + mutex_lock(&drv_ctxt->dev_mutex); + cctxt = drv_ctxt->dev_ctxt.cctxt_list_head; + while (cctxt) { + if (cctxt->secure && cctxt->decoding) + sec_info->secure_dec++; + else if (cctxt->secure && !cctxt->decoding) + sec_info->secure_enc++; + else if (!cctxt->secure && cctxt->decoding) + sec_info->non_secure_dec++; + else + sec_info->non_secure_enc++; + count++; + cctxt = cctxt->next; + } + mutex_unlock(&drv_ctxt->dev_mutex); + return count; +} + +static int is_session_invalid(u32 decoding, u32 flags) +{ + int is_secure; + struct client_security_info sec_info; + int client_count = 0; + int secure_session_running = 0; + is_secure = (flags & VCD_CP_SESSION) ? 1 : 0; + client_count = vcd_get_clients_security_info(&sec_info); + secure_session_running = (sec_info.secure_enc > 0) || + (sec_info.secure_dec > 0); + if (!decoding && is_secure) { + if ((sec_info.secure_dec == 1)) + VCD_MSG_LOW("SE-SD: SUCCESS\n"); + else { + VCD_MSG_LOW("SE is permitted only with SD: FAILURE\n"); + return -EACCES; + } + } else if (!decoding && !is_secure) { + if (secure_session_running) { + VCD_MSG_LOW("SD-NSE: FAILURE\n"); + VCD_MSG_LOW("SE-NSE: FAILURE\n"); + return -EACCES; + } + } else if (decoding && is_secure) { + if (client_count > 0) { + VCD_MSG_LOW("S/NS-SD: FAILURE\n"); + if (sec_info.secure_enc > 0 || + sec_info.non_secure_enc > 0) { + return -EAGAIN; + } + return -EACCES; + } + } else { + if (sec_info.secure_dec > 0) { + VCD_MSG_LOW("SD-NSD: FAILURE\n"); + return -EACCES; + } + } + return 0; +} + +u32 vcd_open(s32 driver_handle, u32 decoding, + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data), + void *client_data, int flags) +{ + u32 rc = 0; + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_clnt_ctxt *cctxt; + int is_secure = (flags & VCD_CP_SESSION) ? 1 : 0; + VCD_MSG_MED("vcd_open:"); + + if (!callback) { + VCD_MSG_ERROR("Bad parameters"); + return -EINVAL; + } + rc = is_session_invalid(decoding, flags); + if (rc) { + VCD_MSG_ERROR("Invalid Session: is_decoder: %d, secure: %d\n", + decoding, flags); + return rc; + } + if (is_secure) + res_trk_secure_set(); + drv_ctxt = vcd_get_drv_context(); + mutex_lock(&drv_ctxt->dev_mutex); + + if (drv_ctxt->dev_state.state_table->ev_hdlr.open) { + rc = drv_ctxt->dev_state.state_table->ev_hdlr. + open(drv_ctxt, driver_handle, decoding, callback, + client_data); + if (rc) { + rc = -ENODEV; + } + } else { + VCD_MSG_ERROR("Unsupported API in device state %d", + drv_ctxt->dev_state.state); + rc = -EPERM; + } + if (!rc) { + cctxt = drv_ctxt->dev_ctxt.cctxt_list_head; + cctxt->secure = is_secure; + } else if (is_secure) + res_trk_secure_unset(); + + mutex_unlock(&drv_ctxt->dev_mutex); + return rc; +} +EXPORT_SYMBOL(vcd_open); + +u32 vcd_close(void *handle) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + int is_secure = 0; + VCD_MSG_MED("vcd_close:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + is_secure = cctxt->secure; + drv_ctxt = vcd_get_drv_context(); + mutex_lock(&drv_ctxt->dev_mutex); + if (drv_ctxt->dev_state.state_table->ev_hdlr.close) { + rc = drv_ctxt->dev_state.state_table->ev_hdlr. + close(drv_ctxt, cctxt); + } else { + VCD_MSG_ERROR("Unsupported API in device state %d", + drv_ctxt->dev_state.state); + + rc = VCD_ERR_BAD_STATE; + } + mutex_unlock(&drv_ctxt->dev_mutex); + if (is_secure) + res_trk_secure_unset(); + return rc; + +} +EXPORT_SYMBOL(vcd_close); + +u32 vcd_encode_start(void *handle) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_encode_start:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.encode_start && + drv_ctxt->dev_ctxt.pwr_state != VCD_PWR_STATE_SLEEP) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + encode_start(cctxt); + } else { + VCD_MSG_ERROR + ("Unsupported API in dev power state %d OR client state %d", + drv_ctxt->dev_ctxt.pwr_state, + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_encode_start); + +u32 vcd_encode_frame(void *handle, struct vcd_frame_data *input_frame) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_encode_frame:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!input_frame) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.encode_frame) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + encode_frame(cctxt, input_frame); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_encode_frame); + +u32 vcd_decode_start(void *handle, struct vcd_sequence_hdr *seq_hdr) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_decode_start:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.decode_start && + drv_ctxt->dev_ctxt.pwr_state != VCD_PWR_STATE_SLEEP) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + decode_start(cctxt, seq_hdr); + } else { + VCD_MSG_ERROR + ("Unsupported API in dev power state %d OR client state %d", + drv_ctxt->dev_ctxt.pwr_state, + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_decode_start); + +u32 vcd_decode_frame(void *handle, struct vcd_frame_data *input_frame) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_decode_frame:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!input_frame) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.decode_frame) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + decode_frame(cctxt, input_frame); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_decode_frame); + +u32 vcd_pause(void *handle) +{ + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + u32 rc; + + VCD_MSG_MED("vcd_pause:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.pause) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + pause(cctxt); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_pause); + +u32 vcd_resume(void *handle) +{ + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + u32 rc; + + VCD_MSG_MED("vcd_resume:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (drv_ctxt->dev_state.state_table->ev_hdlr.resume && + drv_ctxt->dev_ctxt.pwr_state != VCD_PWR_STATE_SLEEP) { + rc = drv_ctxt->dev_state.state_table->ev_hdlr. + resume(drv_ctxt, cctxt); + } else { + VCD_MSG_ERROR + ("Unsupported API in dev power state %d OR client state %d", + drv_ctxt->dev_ctxt.pwr_state, + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_resume); + +u32 vcd_flush(void *handle, u32 mode) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_flush:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.flush) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + flush(cctxt, mode); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_flush); + +u32 vcd_stop(void *handle) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_stop:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.stop && + drv_ctxt->dev_ctxt.pwr_state != VCD_PWR_STATE_SLEEP) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + stop(cctxt); + } else { + VCD_MSG_ERROR + ("Unsupported API in dev power state %d OR client state %d", + drv_ctxt->dev_ctxt.pwr_state, + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_stop); + +u32 vcd_set_property(void *handle, + struct vcd_property_hdr *prop_hdr, void *prop_val) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_set_property:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!prop_hdr || !prop_val) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.set_property) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + set_property(cctxt, prop_hdr, prop_val); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_set_property); + +u32 vcd_get_property(void *handle, + struct vcd_property_hdr *prop_hdr, void *prop_val) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_get_property:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!prop_hdr || !prop_val) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.get_property) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + get_property(cctxt, prop_hdr, prop_val); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_get_property); + +u32 vcd_set_buffer_requirements(void *handle, + enum vcd_buffer_type buffer, + struct vcd_buffer_requirement *buffer_req) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_set_buffer_requirements:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!buffer_req) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr. + set_buffer_requirements) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + set_buffer_requirements(cctxt, buffer, buffer_req); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_set_buffer_requirements); + +u32 vcd_get_buffer_requirements(void *handle, + enum vcd_buffer_type buffer, + struct vcd_buffer_requirement *buffer_req) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_get_buffer_requirements:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!buffer_req) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr. + get_buffer_requirements) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + get_buffer_requirements(cctxt, buffer, buffer_req); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_get_buffer_requirements); + +u32 vcd_set_buffer(void *handle, + enum vcd_buffer_type buffer_type, u8 *buffer, u32 buf_size) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_set_buffer:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!buffer || !buf_size) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.set_buffer) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + set_buffer(cctxt, buffer_type, buffer, buf_size); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_set_buffer); + +u32 vcd_allocate_buffer(void *handle, + enum vcd_buffer_type buffer, + u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_allocate_buffer:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!vir_buf_addr || !phy_buf_addr + || !buf_size) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.allocate_buffer) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + allocate_buffer(cctxt, buffer, buf_size, + vir_buf_addr, phy_buf_addr); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_allocate_buffer); + +u32 vcd_free_buffer(void *handle, enum vcd_buffer_type buffer_type, u8 *buffer) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_free_buffer:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.free_buffer) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + free_buffer(cctxt, buffer_type, buffer); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_free_buffer); + +u32 vcd_fill_output_buffer(void *handle, struct vcd_frame_data *buffer) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_fill_output_buffer:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!buffer) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.fill_output_buffer) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + fill_output_buffer(cctxt, buffer); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_fill_output_buffer); + +u32 vcd_set_device_power(s32 driver_handle, + enum vcd_power_state pwr_state) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_drv_ctxt *drv_ctxt; + + VCD_MSG_MED("vcd_set_device_power:"); + + drv_ctxt = vcd_get_drv_context(); + mutex_lock(&drv_ctxt->dev_mutex); + + if (drv_ctxt->dev_state.state_table->ev_hdlr.set_dev_pwr) { + rc = drv_ctxt->dev_state.state_table->ev_hdlr. + set_dev_pwr(drv_ctxt, pwr_state); + } else { + VCD_MSG_ERROR("Unsupported API in device state %d", + drv_ctxt->dev_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_set_device_power); + +void vcd_read_and_clear_interrupt(void) +{ + VCD_MSG_LOW("vcd_read_and_clear_interrupt:"); + ddl_read_and_clear_interrupt(); +} + + +void vcd_response_handler(void) +{ + struct vcd_drv_ctxt *drv_ctxt; + + VCD_MSG_LOW("vcd_response_handler:"); + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (!ddl_process_core_response()) { + VCD_MSG_HIGH + ("ddl_process_core_response indicated no further" + "processing"); + mutex_unlock(&drv_ctxt->dev_mutex); + return; + } + + if (drv_ctxt->dev_ctxt.command_continue) + vcd_continue(); + mutex_unlock(&drv_ctxt->dev_mutex); +} +EXPORT_SYMBOL(vcd_response_handler); + +u8 vcd_get_num_of_clients(void) +{ + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_clnt_ctxt *cctxt; + u8 count = 0; + + VCD_MSG_LOW("vcd_get_num_of_clients:"); + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + cctxt = drv_ctxt->dev_ctxt.cctxt_list_head; + while (cctxt) { + count++; + cctxt = cctxt->next; + } + mutex_unlock(&drv_ctxt->dev_mutex); + return count; +} +EXPORT_SYMBOL(vcd_get_num_of_clients); + +u32 vcd_get_ion_status(void) +{ + return res_trk_get_enable_ion(); +} +EXPORT_SYMBOL(vcd_get_ion_status); + +struct ion_client *vcd_get_ion_client(void) +{ + return res_trk_get_ion_client(); +} +EXPORT_SYMBOL(vcd_get_ion_client); + + + + diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c new file mode 100644 index 0000000000000000000000000000000000000000..6c384cf509bb2bcc32b7d838f1904820ca241854 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c @@ -0,0 +1,1884 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "vcd.h" + +static const struct vcd_clnt_state_table *vcd_clnt_state_table[]; + +void vcd_clnt_handle_device_err_fatal(struct vcd_clnt_ctxt *cctxt, + u32 event) +{ + if (cctxt->clnt_state.state == VCD_CLIENT_STATE_NULL) { + cctxt->callback(VCD_EVT_RESP_OPEN, VCD_ERR_HW_FATAL, NULL, 0, + cctxt, cctxt->client_data); + vcd_destroy_client_context(cctxt); + return; + } + if (event == VCD_EVT_RESP_BASE) + event = VCD_EVT_IND_HWERRFATAL; + if (cctxt->clnt_state.state != VCD_CLIENT_STATE_INVALID) { + cctxt->callback(event, VCD_ERR_HW_FATAL, NULL, 0, + cctxt, cctxt->client_data); + vcd_flush_buffers_in_err_fatal(cctxt); + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_INVALID, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } +} + +static u32 vcd_close_in_open(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_close_in_open:"); + if (cctxt->in_buf_pool.allocated || + cctxt->out_buf_pool.allocated) { + VCD_MSG_ERROR("\n Allocated buffers are not freed yet"); + return VCD_ERR_ILLEGAL_OP; + } + vcd_destroy_client_context(cctxt); + return rc; +} + +static u32 vcd_close_in_invalid(struct vcd_clnt_ctxt *cctxt) +{ + VCD_MSG_LOW("vcd_close_in_invalid:"); + if (cctxt->in_buf_pool.allocated || + cctxt->out_buf_pool.allocated){ + VCD_MSG_ERROR("Allocated buffers are not freed yet"); + return VCD_ERR_ILLEGAL_OP; + } + + if (cctxt->status.mask & VCD_CLEANING_UP) + cctxt->status.mask |= VCD_CLOSE_PENDING; + else + vcd_destroy_client_context(cctxt); + return VCD_S_SUCCESS; +} + +static u32 vcd_start_in_run_cmn(struct vcd_clnt_ctxt *cctxt) +{ + VCD_MSG_LOW("vcd_start_in_run_cmn:"); + cctxt->callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, NULL, 0, + cctxt, cctxt->client_data); + return VCD_S_SUCCESS; + +} + +static u32 vcd_encode_start_in_open(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_property_hdr prop_hdr; + struct vcd_property_vop_timing timing; + + VCD_MSG_LOW("vcd_encode_start_in_open:"); + + if (cctxt->decoding) { + VCD_MSG_ERROR("vcd_encode_init for decoder client"); + + return VCD_ERR_ILLEGAL_OP; + } + + if ((!cctxt->meta_mode && !cctxt->in_buf_pool.entries) || + !cctxt->out_buf_pool.entries || + (!cctxt->meta_mode && + cctxt->in_buf_pool.validated != cctxt->in_buf_pool.count) || + cctxt->out_buf_pool.validated != + cctxt->out_buf_pool.count) { + VCD_MSG_HIGH("%s: Buffer pool is not completely setup yet", + __func__); + } + + rc = vcd_sched_add_client(cctxt); + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_add_client"); + + prop_hdr.prop_id = VCD_I_VOP_TIMING; + prop_hdr.sz = sizeof(struct vcd_property_vop_timing); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &timing); + + VCD_FAILED_RETURN(rc, "Failed: Get VCD_I_VOP_TIMING"); + if (!timing.vop_time_resolution) { + VCD_MSG_ERROR("Vop_time_resolution value is zero"); + return VCD_ERR_FAIL; + } + cctxt->time_resoln = timing.vop_time_resolution; + + rc = vcd_process_cmd_sess_start(cctxt); + + if (!VCD_FAILED(rc)) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_STARTING, + CLIENT_STATE_EVENT_NUMBER + (encode_start)); + } + + return rc; +} + +static u32 vcd_encode_start_in_run(struct vcd_clnt_ctxt + *cctxt) +{ + VCD_MSG_LOW("vcd_encode_start_in_run:"); + (void) vcd_start_in_run_cmn(cctxt); + return VCD_S_SUCCESS; +} + + +static u32 vcd_encode_frame_cmn(struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame) +{ + VCD_MSG_LOW("vcd_encode_frame_cmn in %d:", cctxt->clnt_state.state); + + if (cctxt->decoding) { + VCD_MSG_ERROR("vcd_encode_frame for decoder client"); + + return VCD_ERR_ILLEGAL_OP; + } + + return vcd_handle_input_frame(cctxt, input_frame); +} + +static u32 vcd_decode_start_in_open + (struct vcd_clnt_ctxt *cctxt, + struct vcd_sequence_hdr *seq_hdr) +{ + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_decode_start_in_open:"); + + if (!cctxt->decoding) { + VCD_MSG_ERROR("vcd_decode_init for encoder client"); + + return VCD_ERR_ILLEGAL_OP; + } + + if (seq_hdr) { + VCD_MSG_HIGH("Seq hdr supplied. len = %d", + seq_hdr->sequence_header_len); + + rc = vcd_store_seq_hdr(cctxt, seq_hdr); + + } else { + VCD_MSG_HIGH("Seq hdr not supplied"); + + cctxt->seq_hdr.sequence_header_len = 0; + cctxt->seq_hdr.sequence_header = NULL; + } + + VCD_FAILED_RETURN(rc, "Err processing seq hdr"); + + rc = vcd_process_cmd_sess_start(cctxt); + + if (!VCD_FAILED(rc)) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_STARTING, + CLIENT_STATE_EVENT_NUMBER + (decode_start)); + } + + return rc; +} + +static u32 vcd_decode_start_in_run(struct vcd_clnt_ctxt *cctxt, + struct vcd_sequence_hdr *seqhdr) +{ + VCD_MSG_LOW("vcd_decode_start_in_run:"); + (void) vcd_start_in_run_cmn(cctxt); + return VCD_S_SUCCESS; +} + +static u32 vcd_decode_frame_cmn + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame) +{ + VCD_MSG_LOW("vcd_decode_frame_cmn in %d:", cctxt->clnt_state.state); + + if (!cctxt->decoding) { + VCD_MSG_ERROR("Decode_frame api called for Encoder client"); + + return VCD_ERR_ILLEGAL_OP; + } + + return vcd_handle_input_frame(cctxt, input_frame); +} + +static u32 vcd_pause_in_run(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_pause_in_run:"); + + if (cctxt->sched_clnt_hdl) { + rc = vcd_sched_suspend_resume_clnt(cctxt, false); + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_suspend_resume_clnt"); + } + + if (cctxt->status.frame_submitted > 0) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_PAUSING, + CLIENT_STATE_EVENT_NUMBER + (pause)); + + } else { + VCD_MSG_HIGH("No client frames are currently being processed"); + + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_PAUSED, + CLIENT_STATE_EVENT_NUMBER + (pause)); + + cctxt->callback(VCD_EVT_RESP_PAUSE, + VCD_S_SUCCESS, + NULL, 0, cctxt, cctxt->client_data); + + rc = vcd_power_event(cctxt->dev_ctxt, cctxt, + VCD_EVT_PWR_CLNT_PAUSE); + + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_PAUSE_END failed"); + + } + + return VCD_S_SUCCESS; +} + +static u32 vcd_resume_in_paused(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_resume_in_paused:"); + + + if (cctxt->sched_clnt_hdl) { + rc = vcd_power_event(cctxt->dev_ctxt, + cctxt, VCD_EVT_PWR_CLNT_RESUME); + + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_RESUME failed"); + } else { + rc = vcd_sched_suspend_resume_clnt(cctxt, true); + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR + ("rc = 0x%x. Failed: " + "vcd_sched_suspend_resume_clnt", + rc); + } + + } + if (!VCD_FAILED(rc)) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER + (resume)); + vcd_try_submit_frame(dev_ctxt); + } + } else { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER + (resume)); + } + + return rc; +} + +static u32 vcd_flush_cmn(struct vcd_clnt_ctxt *cctxt, u32 mode) +{ + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_flush_cmn in %d:", cctxt->clnt_state.state); + + rc = vcd_flush_buffers(cctxt, mode); + + VCD_FAILED_RETURN(rc, "Failed: vcd_flush_buffers"); + + if (cctxt->status.frame_submitted > 0) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_FLUSHING, + CLIENT_STATE_EVENT_NUMBER + (flush)); + } else { + VCD_MSG_HIGH("All buffers are flushed"); + cctxt->status.mask |= (mode & VCD_FLUSH_ALL); + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); + } + + return rc; +} + +static u32 vcd_flush_inopen(struct vcd_clnt_ctxt *cctxt, + u32 mode) +{ + VCD_MSG_LOW("vcd_flush_inopen:"); + cctxt->status.mask |= (mode & VCD_FLUSH_ALL); + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); + return VCD_S_SUCCESS; +} + +static u32 vcd_flush_in_flushing + (struct vcd_clnt_ctxt *cctxt, u32 mode) +{ + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_flush_in_flushing:"); + + rc = vcd_flush_buffers(cctxt, mode); + + return rc; +} + +static u32 vcd_flush_in_eos(struct vcd_clnt_ctxt *cctxt, + u32 mode) +{ + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("vcd_flush_in_eos:"); + + if (mode > VCD_FLUSH_ALL || !mode) { + VCD_MSG_ERROR("Invalid flush mode %d", mode); + + return VCD_ERR_ILLEGAL_PARM; + } + + VCD_MSG_MED("Flush mode requested %d", mode); + if (!(cctxt->status.frame_submitted) && + (!cctxt->decoding)) { + rc = vcd_flush_buffers(cctxt, mode); + if (!VCD_FAILED(rc)) { + VCD_MSG_HIGH("All buffers are flushed"); + cctxt->status.mask |= (mode & VCD_FLUSH_ALL); + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); + } + } else + cctxt->status.mask |= (mode & VCD_FLUSH_ALL); + + return rc; +} + +static u32 vcd_flush_in_invalid(struct vcd_clnt_ctxt *cctxt, + u32 mode) +{ + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("vcd_flush_in_invalid:"); + if (!(cctxt->status.mask & VCD_CLEANING_UP)) { + rc = vcd_flush_buffers(cctxt, mode); + if (!VCD_FAILED(rc)) { + VCD_MSG_HIGH("All buffers are flushed"); + cctxt->status.mask |= (mode & VCD_FLUSH_ALL); + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); + } + } else + cctxt->status.mask |= (mode & VCD_FLUSH_ALL); + return rc; +} + +static u32 vcd_stop_cmn(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + struct vcd_transc *transc; + + VCD_MSG_LOW("vcd_stop_cmn in %d:", cctxt->clnt_state.state); + + rc = vcd_flush_buffers(cctxt, VCD_FLUSH_ALL); + + VCD_FAILED_RETURN(rc, "Failed: vcd_flush_buffers"); + + if (!cctxt->status.frame_submitted) { + + if (vcd_get_command_channel(dev_ctxt, &transc)) { + rc = vcd_power_event(dev_ctxt, cctxt, + VCD_EVT_PWR_CLNT_CMD_BEGIN); + + if (!VCD_FAILED(rc)) { + transc->type = VCD_CMD_CODEC_STOP; + transc->cctxt = cctxt; + + rc = vcd_submit_cmd_sess_end(transc); + } else { + VCD_MSG_ERROR("Failed:" + " VCD_EVT_PWR_CLNT_CMD_BEGIN"); + } + + if (VCD_FAILED(rc)) { + vcd_release_command_channel(dev_ctxt, + transc); + } + + } else { + vcd_client_cmd_flush_and_en_q(cctxt, + VCD_CMD_CODEC_STOP); + } + } + + if (VCD_FAILED(rc)) { + (void)vcd_power_event(dev_ctxt, cctxt, + VCD_EVT_PWR_CLNT_CMD_FAIL); + } else { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_STOPPING, + CLIENT_STATE_EVENT_NUMBER + (stop)); + } + + return rc; +} + + +static u32 vcd_stop_inopen(struct vcd_clnt_ctxt *cctxt) +{ + VCD_MSG_LOW("vcd_stop_inopen:"); + + cctxt->callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS, + NULL, 0, cctxt, + cctxt->client_data); + + return VCD_S_SUCCESS; +} + +static u32 vcd_stop_in_run(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("vcd_stop_in_run:"); + rc = vcd_stop_cmn(cctxt); + if (!VCD_FAILED(rc) && + (cctxt->status.mask & VCD_FIRST_IP_RCVD)) { + rc = vcd_power_event(cctxt->dev_ctxt, + cctxt, VCD_EVT_PWR_CLNT_LAST_FRAME); + } + return rc; +} + +static u32 vcd_stop_in_eos(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("vcd_stop_in_eos:"); + if (cctxt->status.mask & VCD_EOS_WAIT_OP_BUF) { + rc = vcd_stop_cmn(cctxt); + if (!VCD_FAILED(rc)) { + rc = vcd_power_event(cctxt->dev_ctxt, + cctxt, VCD_EVT_PWR_CLNT_LAST_FRAME); + cctxt->status.mask &= ~VCD_EOS_WAIT_OP_BUF; + } + } else + cctxt->status.mask |= VCD_STOP_PENDING; + return rc; +} + +static u32 vcd_stop_in_invalid(struct vcd_clnt_ctxt *cctxt) +{ + VCD_MSG_LOW("vcd_stop_in_invalid:"); + if (cctxt->status.mask & VCD_CLEANING_UP) { + cctxt->status.mask |= VCD_STOP_PENDING; + } else { + (void) vcd_flush_buffers(cctxt, VCD_FLUSH_ALL); + cctxt->callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS, NULL, + 0, cctxt, cctxt->client_data); + } + return VCD_S_SUCCESS; +} + +static u32 vcd_set_property_cmn + (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_hdr *prop_hdr, void *prop_val) +{ + u32 rc; + VCD_MSG_LOW("vcd_set_property_cmn in %d:", cctxt->clnt_state.state); + VCD_MSG_LOW("property Id = %d", prop_hdr->prop_id); + if (!prop_hdr->sz || !prop_hdr->prop_id) { + VCD_MSG_MED("Bad parameters"); + return VCD_ERR_ILLEGAL_PARM; + } + + rc = ddl_set_property(cctxt->ddl_handle, prop_hdr, prop_val); + if (rc) { + /* Some properties aren't known to ddl that we can handle */ + if (prop_hdr->prop_id != VCD_I_VOP_TIMING_CONSTANT_DELTA) + VCD_FAILED_RETURN(rc, "Failed: ddl_set_property"); + } + + switch (prop_hdr->prop_id) { + case VCD_I_META_BUFFER_MODE: + { + struct vcd_property_live *live = + (struct vcd_property_live *)prop_val; + cctxt->meta_mode = live->live; + break; + } + case VCD_I_LIVE: + { + struct vcd_property_live *live = + (struct vcd_property_live *)prop_val; + cctxt->live = live->live; + break; + } + case VCD_I_FRAME_RATE: + { + if (cctxt->sched_clnt_hdl) { + rc = vcd_set_frame_rate(cctxt, + (struct vcd_property_frame_rate *) + prop_val); + } + break; + } + case VCD_I_FRAME_SIZE: + { + if (cctxt->sched_clnt_hdl) { + rc = vcd_set_frame_size(cctxt, + (struct vcd_property_frame_size *) + prop_val); + } + break; + } + case VCD_I_INTRA_PERIOD: + { + struct vcd_property_i_period *iperiod = + (struct vcd_property_i_period *)prop_val; + cctxt->bframe = iperiod->b_frames; + break; + } + case VCD_REQ_PERF_LEVEL: + rc = vcd_req_perf_level(cctxt, + (struct vcd_property_perf_level *)prop_val); + break; + case VCD_I_VOP_TIMING_CONSTANT_DELTA: + { + struct vcd_property_vop_timing_constant_delta *delta = + prop_val; + + if (delta->constant_delta > 0) { + cctxt->time_frame_delta = delta->constant_delta; + rc = VCD_S_SUCCESS; + } else { + VCD_MSG_ERROR("Frame delta must be positive"); + rc = VCD_ERR_ILLEGAL_PARM; + } + break; + } + default: + { + break; + } + } + return rc; +} + +static u32 vcd_get_property_cmn + (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_hdr *prop_hdr, void *prop_val) +{ + int rc; + VCD_MSG_LOW("vcd_get_property_cmn in %d:", cctxt->clnt_state.state); + VCD_MSG_LOW("property Id = %d", prop_hdr->prop_id); + if (!prop_hdr->sz || !prop_hdr->prop_id) { + VCD_MSG_MED("Bad parameters"); + + return VCD_ERR_ILLEGAL_PARM; + } + rc = ddl_get_property(cctxt->ddl_handle, prop_hdr, prop_val); + if (rc) { + /* Some properties aren't known to ddl that we can handle */ + if (prop_hdr->prop_id != VCD_I_VOP_TIMING_CONSTANT_DELTA) + VCD_FAILED_RETURN(rc, "Failed: ddl_set_property"); + } + + switch (prop_hdr->prop_id) { + case VCD_I_VOP_TIMING_CONSTANT_DELTA: + { + struct vcd_property_vop_timing_constant_delta *delta = + (struct vcd_property_vop_timing_constant_delta *) + prop_val; + delta->constant_delta = cctxt->time_frame_delta; + rc = VCD_S_SUCCESS; + } + } + return rc; +} + +static u32 vcd_set_buffer_requirements_cmn + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer, + struct vcd_buffer_requirement *buffer_req) +{ + struct vcd_property_hdr Prop_hdr; + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_pool *buf_pool; + u32 first_frm_recvd = 0; + + VCD_MSG_LOW("vcd_set_buffer_requirements_cmn in %d:", + cctxt->clnt_state.state); + + if (!cctxt->decoding && + cctxt->clnt_state.state != VCD_CLIENT_STATE_OPEN) { + VCD_MSG_ERROR("Bad state (%d) for encoder", + cctxt->clnt_state.state); + + return VCD_ERR_BAD_STATE; + } + + VCD_MSG_MED("Buffer type = %d", buffer); + + if (buffer == VCD_BUFFER_INPUT) { + Prop_hdr.prop_id = DDL_I_INPUT_BUF_REQ; + buf_pool = &cctxt->in_buf_pool; + first_frm_recvd = VCD_FIRST_IP_RCVD; + } else if (buffer == VCD_BUFFER_OUTPUT) { + Prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ; + buf_pool = &cctxt->out_buf_pool; + first_frm_recvd = VCD_FIRST_OP_RCVD; + } else { + rc = VCD_ERR_ILLEGAL_PARM; + } + + VCD_FAILED_RETURN(rc, "Invalid buffer type provided"); + + if (buf_pool->validated > 0) { + VCD_MSG_ERROR("Need to free allocated buffers"); + return VCD_ERR_ILLEGAL_OP; + } + + first_frm_recvd &= cctxt->status.mask; + if (first_frm_recvd) { + VCD_MSG_ERROR("VCD SetBufReq called when data path is active"); + return VCD_ERR_BAD_STATE; + } + Prop_hdr.sz = sizeof(*buffer_req); + rc = ddl_set_property(cctxt->ddl_handle, &Prop_hdr, buffer_req); + VCD_FAILED_RETURN(rc, "Failed: ddl_set_property"); + if (buf_pool->entries) { + VCD_MSG_MED("Resetting buffer requirements"); + vcd_free_buffer_pool_entries(buf_pool); + } + return rc; +} + +static u32 vcd_get_buffer_requirements_cmn + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer, + struct vcd_buffer_requirement *buffer_req) +{ + struct vcd_property_hdr Prop_hdr; + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_get_buffer_requirements_cmn in %d:", + cctxt->clnt_state.state); + + VCD_MSG_MED("Buffer type = %d", buffer); + + if (buffer == VCD_BUFFER_INPUT) + Prop_hdr.prop_id = DDL_I_INPUT_BUF_REQ; + else if (buffer == VCD_BUFFER_OUTPUT) + Prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ; + else + rc = VCD_ERR_ILLEGAL_PARM; + + VCD_FAILED_RETURN(rc, "Invalid buffer type provided"); + + Prop_hdr.sz = sizeof(*buffer_req); + + return ddl_get_property(cctxt->ddl_handle, &Prop_hdr, buffer_req); + +} + +static u32 vcd_set_buffer_cmn + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type, u8 *buffer, u32 buf_size) +{ + u32 rc; + struct vcd_buffer_pool *buf_pool; + + VCD_MSG_LOW("vcd_set_buffer_cmn in %d:", cctxt->clnt_state.state); + + rc = vcd_common_allocate_set_buffer(cctxt, buffer_type, buf_size, + &buf_pool); + + if (!VCD_FAILED(rc)) { + rc = vcd_set_buffer_internal(cctxt, buf_pool, buffer, + buf_size); + } + + return rc; +} + +static u32 vcd_allocate_buffer_cmn + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer, + u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr) +{ + u32 rc; + struct vcd_buffer_pool *buf_pool; + + VCD_MSG_LOW("vcd_allocate_buffer_cmn in %d:", + cctxt->clnt_state.state); + + rc = vcd_common_allocate_set_buffer(cctxt, buffer, buf_size, + &buf_pool); + + if (!VCD_FAILED(rc)) { + rc = vcd_allocate_buffer_internal(cctxt, + buf_pool, + buf_size, + vir_buf_addr, + phy_buf_addr); + } + + return rc; +} + +static u32 vcd_free_buffer_cmn + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type, u8 *buffer) +{ + + VCD_MSG_LOW("vcd_free_buffer_cmn in %d:", cctxt->clnt_state.state); + + return vcd_free_one_buffer_internal(cctxt, buffer_type, buffer); +} + +static u32 vcd_fill_output_buffer_cmn + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_entry *buf_entry; + u32 result = true; + u32 handled = true; + if (!cctxt || !buffer) { + VCD_MSG_ERROR("%s(): Inavlid params cctxt %p buffer %p", + __func__, cctxt, buffer); + return VCD_ERR_BAD_POINTER; + } + VCD_MSG_LOW("vcd_fill_output_buffer_cmn in %d:", + cctxt->clnt_state.state); + if (cctxt->status.mask & VCD_IN_RECONFIG) { + buffer->time_stamp = 0; + buffer->data_len = 0; + VCD_MSG_LOW("In reconfig: Return output buffer"); + cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, + buffer, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + return rc; + } + buf_entry = vcd_check_fill_output_buffer(cctxt, buffer); + if (!buf_entry) + return VCD_ERR_BAD_POINTER; + + if (!(cctxt->status.mask & VCD_FIRST_OP_RCVD)) { + rc = vcd_handle_first_fill_output_buffer(cctxt, buffer, + &handled); + VCD_FAILED_RETURN(rc, + "Failed: vcd_handle_first_fill_output_buffer"); + if (handled) + return rc ; + } + + result = + vcd_buffer_pool_entry_en_q(&cctxt->out_buf_pool, buf_entry); + + if (!result && !cctxt->decoding) { + VCD_MSG_ERROR("Failed: vcd_buffer_pool_entry_en_q"); + + return VCD_ERR_FAIL; + } + + buf_entry->frame = *buffer; + rc = vcd_return_op_buffer_to_hw(cctxt, buf_entry); + if (!VCD_FAILED(rc) && cctxt->sched_clnt_hdl) { + cctxt->sched_clnt_hdl->tkns++; + vcd_try_submit_frame(cctxt->dev_ctxt); + } + return rc; +} + +static u32 vcd_fill_output_buffer_in_eos + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_entry *buf_entry; + + VCD_MSG_LOW("vcd_fill_output_buffer_in_eos:"); + + buf_entry = vcd_check_fill_output_buffer(cctxt, buffer); + if (!buf_entry) + return VCD_ERR_BAD_POINTER; + + if (cctxt->status.mask & VCD_EOS_WAIT_OP_BUF) { + VCD_MSG_HIGH("Got an output buffer we were waiting for"); + + buf_entry->frame = *buffer; + + buf_entry->frame.data_len = 0; + buf_entry->frame.flags |= VCD_FRAME_FLAG_EOS; + buf_entry->frame.ip_frm_tag = + cctxt->status.eos_trig_ip_frm.ip_frm_tag; + buf_entry->frame.time_stamp = + cctxt->status.eos_trig_ip_frm.time_stamp; + + cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, + &buf_entry->frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + + cctxt->status.mask &= ~VCD_EOS_WAIT_OP_BUF; + + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER + (fill_output_buffer)); + + } else { + rc = vcd_fill_output_buffer_cmn(cctxt, buffer); + } + + return rc; +} + +static void vcd_clnt_cb_in_starting + (struct vcd_clnt_ctxt *cctxt, + u32 event, u32 status, void *payload, size_t sz, + u32 *ddl_handle, void *const client_data) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + struct vcd_transc *transc = + (struct vcd_transc *)client_data; + VCD_MSG_LOW("vcd_clnt_cb_in_starting:"); + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("vcd_clnt_cb_in_initing: Wrong DDL handle %p", + ddl_handle); + return; + } + + switch (event) { + case VCD_EVT_RESP_START: + { + vcd_handle_start_done(cctxt, + (struct vcd_transc *)client_data, + status); + break; + } + case VCD_EVT_RESP_STOP: + { + vcd_handle_stop_done_in_starting(cctxt, + (struct vcd_transc *)client_data, + status); + break; + } + case VCD_EVT_IND_HWERRFATAL: + { + cctxt->status.cmd_submitted--; + vcd_mark_command_channel(cctxt->dev_ctxt, transc); + vcd_handle_err_fatal(cctxt, VCD_EVT_RESP_START, + status); + break; + } + default: + { + VCD_MSG_ERROR("Unexpected callback event=%d status=%d " + "from DDL", event, status); + dev_ctxt->command_continue = false; + break; + } + } +} + +static void vcd_clnt_cb_in_run + (struct vcd_clnt_ctxt *cctxt, + u32 event, + u32 status, + void *payload, size_t sz, u32 *ddl_handle, void *const client_data) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("ddl_handle mismatch"); + + return; + } + + switch (event) { + case VCD_EVT_RESP_INPUT_DONE: + { + rc = vcd_handle_input_done(cctxt, payload, event, + status); + + break; + } + + case VCD_EVT_RESP_OUTPUT_DONE: + { + + rc = vcd_handle_frame_done(cctxt, payload, event, + status); + + break; + } + case VCD_EVT_RESP_OUTPUT_REQ: + { + rc = vcd_handle_output_required(cctxt, payload, + status); + break; + } + + case VCD_EVT_IND_OUTPUT_RECONFIG: + { + rc = vcd_handle_ind_output_reconfig(cctxt, payload, + status); + break; + } + case VCD_EVT_RESP_TRANSACTION_PENDING: + { + vcd_handle_trans_pending(cctxt); + break; + } + + case VCD_EVT_IND_HWERRFATAL: + { + vcd_handle_ind_hw_err_fatal(cctxt, + VCD_EVT_IND_HWERRFATAL, status); + break; + } + case VCD_EVT_IND_INFO_OUTPUT_RECONFIG: + { + vcd_handle_ind_info_output_reconfig(cctxt, status); + break; + } + default: + { + VCD_MSG_ERROR + ("Unexpected callback event=%d status=%d from DDL", + event, status); + dev_ctxt->command_continue = false; + + break; + } + } + + if (!VCD_FAILED(rc) && + (event == VCD_EVT_RESP_INPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_REQ)) { + + if (((struct ddl_frame_data_tag *) + payload)->frm_trans_end) + vcd_mark_frame_channel(cctxt->dev_ctxt); + } +} + +static void vcd_clnt_cb_in_eos + (struct vcd_clnt_ctxt *cctxt, + u32 event, + u32 status, + void *payload, size_t sz, u32 *ddl_handle, void *const client_data) { + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + struct vcd_transc *transc = NULL; + u32 frm_trans_end = false, rc = VCD_S_SUCCESS; + + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("ddl_handle mismatch"); + + return; + } + + switch (event) { + case VCD_EVT_RESP_INPUT_DONE: + { + rc = vcd_handle_input_done_in_eos(cctxt, payload, + status); + + break; + } + + case VCD_EVT_RESP_OUTPUT_DONE: + { + rc = vcd_handle_frame_done_in_eos(cctxt, payload, + status); + + break; + } + case VCD_EVT_RESP_OUTPUT_REQ: + { + rc = vcd_handle_output_required(cctxt, payload, + status); + break; + } + case VCD_EVT_RESP_EOS_DONE: + { + transc = (struct vcd_transc *)client_data; + vcd_handle_eos_done(cctxt, transc, status); + vcd_mark_frame_channel(cctxt->dev_ctxt); + break; + } + case VCD_EVT_IND_OUTPUT_RECONFIG: + { + rc = vcd_handle_ind_output_reconfig(cctxt, + payload, status); + if (!VCD_FAILED(rc)) { + frm_trans_end = true; + payload = NULL; + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER + (clnt_cb)); + VCD_MSG_LOW + ("RECONFIGinEOS:Suspending Client"); + rc = vcd_sched_suspend_resume_clnt(cctxt, + false); + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR + ("Failed: suspend_resume_clnt. rc=0x%x", + rc); + } + } + break; + } + case VCD_EVT_IND_HWERRFATAL: + { + vcd_handle_ind_hw_err_fatal(cctxt, + VCD_EVT_IND_HWERRFATAL, status); + break; + } + case VCD_EVT_IND_INFO_OUTPUT_RECONFIG: + { + vcd_handle_ind_info_output_reconfig(cctxt, status); + break; + } + default: + { + VCD_MSG_ERROR + ("Unexpected callback event=%d status=%d from DDL", + event, status); + + dev_ctxt->command_continue = false; + + break; + } + + } + if (!VCD_FAILED(rc) && + (event == VCD_EVT_RESP_INPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_REQ || + event == VCD_EVT_IND_OUTPUT_RECONFIG)) { + if (payload && ((struct ddl_frame_data_tag *) + payload)->frm_trans_end) { + vcd_mark_frame_channel(cctxt->dev_ctxt); + frm_trans_end = true; + } + if (frm_trans_end && !cctxt->status.frame_submitted) + vcd_handle_eos_trans_end(cctxt); + } +} + +static void vcd_clnt_cb_in_flushing + (struct vcd_clnt_ctxt *cctxt, + u32 event, + u32 status, + void *payload, size_t sz, u32 *ddl_handle, void *const client_data) { + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + u32 frm_trans_end = false; + + VCD_MSG_LOW("vcd_clnt_cb_in_flushing:"); + + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("ddl_handle mismatch"); + + return; + } + + switch (event) { + case VCD_EVT_RESP_INPUT_DONE: + { + rc = vcd_handle_input_done(cctxt, + payload, + VCD_EVT_RESP_INPUT_FLUSHED, + status); + + break; + } + + case VCD_EVT_RESP_OUTPUT_DONE: + { + + rc = vcd_handle_frame_done(cctxt, + payload, + VCD_EVT_RESP_OUTPUT_FLUSHED, + status); + + break; + } + case VCD_EVT_RESP_OUTPUT_REQ: + { + rc = vcd_handle_output_required_in_flushing(cctxt, + payload); + break; + } + case VCD_EVT_IND_OUTPUT_RECONFIG: + { + rc = vcd_handle_ind_output_reconfig(cctxt, + payload, status); + if (!VCD_FAILED(rc)) { + frm_trans_end = true; + payload = NULL; + } + break; + } + case VCD_EVT_IND_HWERRFATAL: + { + vcd_handle_ind_hw_err_fatal(cctxt, + VCD_EVT_IND_HWERRFATAL, status); + break; + } + default: + { + VCD_MSG_ERROR + ("Unexpected callback event=%d status=%d from DDL", + event, status); + + dev_ctxt->command_continue = false; + + break; + } + } + if (!VCD_FAILED(rc) && ((event == VCD_EVT_RESP_INPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_REQ || + event == VCD_EVT_IND_OUTPUT_RECONFIG))) { + if (payload && + ((struct ddl_frame_data_tag *)\ + payload)->frm_trans_end) { + + vcd_mark_frame_channel(cctxt->dev_ctxt); + frm_trans_end = true; + } + if (frm_trans_end && !cctxt->status.frame_submitted) { + VCD_MSG_HIGH + ("All pending frames recvd from DDL"); + if (cctxt->status.mask & VCD_FLUSH_INPUT) + vcd_flush_bframe_buffers(cctxt, + VCD_FLUSH_INPUT); + if (cctxt->status.mask & VCD_FLUSH_OUTPUT) + vcd_flush_output_buffers(cctxt); + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); + vcd_release_interim_frame_channels(dev_ctxt); + VCD_MSG_HIGH("Flush complete"); + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER + (clnt_cb)); + } + } +} + +static void vcd_clnt_cb_in_stopping + (struct vcd_clnt_ctxt *cctxt, + u32 event, + u32 status, + void *payload, size_t sz, u32 *ddl_handle, void *const client_data) { + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + u32 frm_trans_end = false; + + VCD_MSG_LOW("vcd_clnt_cb_in_stopping:"); + + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("ddl_handle mismatch"); + + return; + } + + switch (event) { + + case VCD_EVT_RESP_INPUT_DONE: + { + rc = vcd_handle_input_done(cctxt, + payload, + VCD_EVT_RESP_INPUT_FLUSHED, + status); + + break; + } + + case VCD_EVT_RESP_OUTPUT_DONE: + { + + rc = vcd_handle_frame_done(cctxt, + payload, + VCD_EVT_RESP_OUTPUT_FLUSHED, + status); + + break; + } + case VCD_EVT_RESP_OUTPUT_REQ: + { + rc = vcd_handle_output_required_in_flushing(cctxt, + payload); + break; + } + case VCD_EVT_RESP_STOP: + { + vcd_handle_stop_done(cctxt, + (struct vcd_transc *) + client_data, status); + + break; + } + case VCD_EVT_IND_OUTPUT_RECONFIG: + { + (void) vcd_handle_ind_output_reconfig(cctxt, + payload, status); + + frm_trans_end = true; + payload = NULL; + + break; + } + case VCD_EVT_IND_HWERRFATAL: + { + vcd_handle_ind_hw_err_fatal(cctxt, VCD_EVT_RESP_STOP, + status); + break; + } + + default: + { + VCD_MSG_ERROR + ("Unexpected callback event=%d status=%d from DDL", + event, status); + + dev_ctxt->command_continue = false; + + break; + } + } + + if (!VCD_FAILED(rc) && ((event == VCD_EVT_RESP_INPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_DONE) || + event == VCD_EVT_RESP_OUTPUT_REQ || + event == VCD_EVT_IND_OUTPUT_RECONFIG)) { + + if (payload && + ((struct ddl_frame_data_tag *)\ + payload)->frm_trans_end) { + + vcd_mark_frame_channel(cctxt->dev_ctxt); + frm_trans_end = true; + } + if (frm_trans_end && !cctxt->status.frame_submitted) { + VCD_MSG_HIGH + ("All pending frames recvd from DDL"); + vcd_flush_bframe_buffers(cctxt, + VCD_FLUSH_INPUT); + vcd_flush_output_buffers(cctxt); + cctxt->status.mask &= ~VCD_FLUSH_ALL; + vcd_release_all_clnt_frm_transc(cctxt); + VCD_MSG_HIGH + ("All buffers flushed. Enqueuing stop cmd"); + vcd_client_cmd_flush_and_en_q(cctxt, + VCD_CMD_CODEC_STOP); + } + } +} + +static void vcd_clnt_cb_in_pausing + (struct vcd_clnt_ctxt *cctxt, + u32 event, + u32 status, + void *payload, size_t sz, u32 *ddl_handle, void *const client_data) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + u32 frm_trans_end = false; + + VCD_MSG_LOW("vcd_clnt_cb_in_pausing:"); + + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("ddl_handle mismatch"); + + return; + } + + switch (event) { + case VCD_EVT_RESP_INPUT_DONE: + { + rc = vcd_handle_input_done(cctxt, payload, event, + status); + + break; + } + + case VCD_EVT_RESP_OUTPUT_DONE: + { + rc = vcd_handle_frame_done(cctxt, payload, event, + status); + break; + } + case VCD_EVT_RESP_OUTPUT_REQ: + { + rc = vcd_handle_output_required(cctxt, payload, + status); + break; + } + case VCD_EVT_IND_OUTPUT_RECONFIG: + { + rc = vcd_handle_ind_output_reconfig(cctxt, + payload, status); + if (!VCD_FAILED(rc)) { + frm_trans_end = true; + payload = NULL; + } + break; + } + case VCD_EVT_IND_HWERRFATAL: + { + vcd_handle_ind_hw_err_fatal(cctxt, + VCD_EVT_RESP_PAUSE, status); + rc = VCD_ERR_FAIL; + break; + } + default: + { + VCD_MSG_ERROR + ("Unexpected callback event=%d status=%d from DDL", + event, status); + + dev_ctxt->command_continue = false; + + break; + } + + } + + if (!VCD_FAILED(rc)) { + + if (payload && + ((struct ddl_frame_data_tag *)\ + payload)->frm_trans_end) { + + vcd_mark_frame_channel(cctxt->dev_ctxt); + frm_trans_end = true; + } + if (frm_trans_end && !cctxt->status.frame_submitted) { + VCD_MSG_HIGH + ("All pending frames recvd from DDL"); + + cctxt->callback(VCD_EVT_RESP_PAUSE, + VCD_S_SUCCESS, + NULL, + 0, + cctxt, + cctxt->client_data); + + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_PAUSED, + CLIENT_STATE_EVENT_NUMBER + (clnt_cb)); + + rc = vcd_power_event(cctxt->dev_ctxt, + cctxt, + VCD_EVT_PWR_CLNT_PAUSE); + + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR + ("VCD_EVT_PWR_CLNT_PAUSE_END" + "failed"); + } + } + } +} + +static void vcd_clnt_cb_in_invalid( + struct vcd_clnt_ctxt *cctxt, u32 event, u32 status, + void *payload, size_t sz, u32 *ddl_handle, + void *const client_data +) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + VCD_MSG_LOW("vcd_clnt_cb_in_invalid:"); + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("ddl_handle mismatch"); + return; + } + switch (event) { + case VCD_EVT_RESP_STOP: + { + vcd_handle_stop_done_in_invalid(cctxt, + (struct vcd_transc *)client_data, + status); + break; + } + case VCD_EVT_RESP_INPUT_DONE: + case VCD_EVT_RESP_OUTPUT_REQ: + { + if (cctxt->status.frame_submitted) + cctxt->status.frame_submitted--; + if (payload && ((struct ddl_frame_data_tag *) + payload)->frm_trans_end) + vcd_mark_frame_channel(cctxt->dev_ctxt); + break; + } + case VCD_EVT_RESP_OUTPUT_DONE: + { + if (payload && ((struct ddl_frame_data_tag *) + payload)->frm_trans_end) + vcd_mark_frame_channel(cctxt->dev_ctxt); + break; + } + case VCD_EVT_RESP_TRANSACTION_PENDING: + { + if (cctxt->status.frame_submitted) + cctxt->status.frame_submitted--; + vcd_mark_frame_channel(cctxt->dev_ctxt); + break; + } + case VCD_EVT_IND_HWERRFATAL: + { + if (status == VCD_ERR_HW_FATAL) + vcd_handle_stop_done_in_invalid(cctxt, + (struct vcd_transc *)client_data, + status); + + break; + } + case VCD_EVT_RESP_EOS_DONE: + { + vcd_mark_frame_channel(cctxt->dev_ctxt); + break; + } + case VCD_EVT_IND_OUTPUT_RECONFIG: + { + if (cctxt->status.frame_submitted > 0) + cctxt->status.frame_submitted--; + else + cctxt->status.frame_delayed--; + vcd_mark_frame_channel(cctxt->dev_ctxt); + break; + } + default: + { + VCD_MSG_ERROR("Unexpected callback event=%d status=%d" + "from DDL", event, status); + dev_ctxt->command_continue = false; + break; + } + } +} + +static void vcd_clnt_enter_open + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Entering CLIENT_STATE_OPEN on api %d", state_event); +} + +static void vcd_clnt_enter_starting + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Entering CLIENT_STATE_STARTING on api %d", + state_event); + cctxt->status.last_evt = VCD_EVT_RESP_START; +} + +static void vcd_clnt_enter_run + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Entering CLIENT_STATE_RUN on api %d", state_event); +} + +static void vcd_clnt_enter_flushing + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Entering CLIENT_STATE_FLUSHING on api %d", + state_event); +} + +static void vcd_clnt_enter_stopping + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Entering CLIENT_STATE_STOPPING on api %d", + state_event); + cctxt->status.last_evt = VCD_EVT_RESP_STOP; +} + +static void vcd_clnt_enter_eos(struct vcd_clnt_ctxt *cctxt, + s32 state_event) +{ + u32 rc; + VCD_MSG_MED("Entering CLIENT_STATE_EOS on api %d", state_event); + rc = vcd_sched_suspend_resume_clnt(cctxt, false); + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("Failed: vcd_sched_suspend_resume_clnt." + "rc=0x%x", rc); +} + +static void vcd_clnt_enter_pausing + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Entering CLIENT_STATE_PAUSING on api %d", + state_event); + cctxt->status.last_evt = VCD_EVT_RESP_PAUSE; +} + +static void vcd_clnt_enter_paused + (struct vcd_clnt_ctxt *cctxt, s32 state_event) +{ + VCD_MSG_MED("Entering CLIENT_STATE_PAUSED on api %d", + state_event); +} + +static void vcd_clnt_enter_invalid(struct vcd_clnt_ctxt *cctxt, + s32 state_event) +{ + VCD_MSG_MED("Entering CLIENT_STATE_INVALID on api %d", + state_event); + cctxt->ddl_hdl_valid = false; + cctxt->status.mask &= ~(VCD_FIRST_IP_RCVD | VCD_FIRST_OP_RCVD); + if (cctxt->sched_clnt_hdl) + vcd_sched_suspend_resume_clnt(cctxt, false); +} + +static void vcd_clnt_exit_open + (struct vcd_clnt_ctxt *cctxt, s32 state_event) +{ + VCD_MSG_MED("Exiting CLIENT_STATE_OPEN on api %d", state_event); +} + +static void vcd_clnt_exit_starting + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Exiting CLIENT_STATE_STARTING on api %d", + state_event); + cctxt->status.last_evt = VCD_EVT_RESP_BASE; +} + +static void vcd_clnt_exit_run + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Exiting CLIENT_STATE_RUN on api %d", state_event); +} + +static void vcd_clnt_exit_flushing + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Exiting CLIENT_STATE_FLUSHING on api %d", + state_event); +} + +static void vcd_clnt_exit_stopping + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Exiting CLIENT_STATE_STOPPING on api %d", + state_event); + cctxt->status.last_evt = VCD_EVT_RESP_BASE; +} + +static void vcd_clnt_exit_eos + (struct vcd_clnt_ctxt *cctxt, s32 state_event) +{ + u32 rc; + VCD_MSG_MED("Exiting CLIENT_STATE_EOS on api %d", state_event); + rc = vcd_sched_suspend_resume_clnt(cctxt, true); + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("Failed: vcd_sched_suspend_resume_clnt. rc=0x%x", + rc); +} + +static void vcd_clnt_exit_pausing + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Exiting CLIENT_STATE_PAUSING on api %d", + state_event); + cctxt->status.last_evt = VCD_EVT_RESP_BASE; +} + +static void vcd_clnt_exit_paused + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Exiting CLIENT_STATE_PAUSED on api %d", + state_event); +} + +static void vcd_clnt_exit_invalid(struct vcd_clnt_ctxt *cctxt, + s32 state_event) +{ + VCD_MSG_MED("Exiting CLIENT_STATE_INVALID on api %d", + state_event); +} + +void vcd_do_client_state_transition(struct vcd_clnt_ctxt *cctxt, + enum vcd_clnt_state_enum to_state, u32 ev_code) +{ + struct vcd_clnt_state_ctxt *state_ctxt; + + if (!cctxt || to_state >= VCD_CLIENT_STATE_MAX) { + VCD_MSG_ERROR("Bad parameters. cctxt=%p, to_state=%d", + cctxt, to_state); + } + + state_ctxt = &cctxt->clnt_state; + + if (state_ctxt->state == to_state) { + VCD_MSG_HIGH("Client already in requested to_state=%d", + to_state); + + return; + } + + VCD_MSG_MED("vcd_do_client_state_transition: C%d -> C%d, for api %d", + (int)state_ctxt->state, (int)to_state, ev_code); + + if (state_ctxt->state_table->exit) + state_ctxt->state_table->exit(cctxt, ev_code); + + + state_ctxt->state = to_state; + state_ctxt->state_table = vcd_clnt_state_table[to_state]; + + if (state_ctxt->state_table->entry) + state_ctxt->state_table->entry(cctxt, ev_code); +} + +const struct vcd_clnt_state_table *vcd_get_client_state_table + (enum vcd_clnt_state_enum state) { + return vcd_clnt_state_table[state]; +} + +static const struct vcd_clnt_state_table vcd_clnt_table_open = { + { + vcd_close_in_open, + vcd_encode_start_in_open, + NULL, + vcd_decode_start_in_open, + NULL, + NULL, + NULL, + vcd_flush_inopen, + vcd_stop_inopen, + vcd_set_property_cmn, + vcd_get_property_cmn, + vcd_set_buffer_requirements_cmn, + vcd_get_buffer_requirements_cmn, + vcd_set_buffer_cmn, + vcd_allocate_buffer_cmn, + vcd_free_buffer_cmn, + vcd_fill_output_buffer_cmn, + NULL, + }, + vcd_clnt_enter_open, + vcd_clnt_exit_open +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_starting = { + { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + vcd_get_property_cmn, + NULL, + vcd_get_buffer_requirements_cmn, + NULL, + NULL, + NULL, + NULL, + vcd_clnt_cb_in_starting, + }, + vcd_clnt_enter_starting, + vcd_clnt_exit_starting +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_run = { + { + NULL, + vcd_encode_start_in_run, + vcd_encode_frame_cmn, + vcd_decode_start_in_run, + vcd_decode_frame_cmn, + vcd_pause_in_run, + NULL, + vcd_flush_cmn, + vcd_stop_in_run, + vcd_set_property_cmn, + vcd_get_property_cmn, + vcd_set_buffer_requirements_cmn, + vcd_get_buffer_requirements_cmn, + vcd_set_buffer_cmn, + vcd_allocate_buffer_cmn, + vcd_free_buffer_cmn, + vcd_fill_output_buffer_cmn, + vcd_clnt_cb_in_run, + }, + vcd_clnt_enter_run, + vcd_clnt_exit_run +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_flushing = { + { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + vcd_flush_in_flushing, + NULL, + vcd_set_property_cmn, + vcd_get_property_cmn, + NULL, + vcd_get_buffer_requirements_cmn, + NULL, + NULL, + NULL, + vcd_fill_output_buffer_cmn, + vcd_clnt_cb_in_flushing, + }, + vcd_clnt_enter_flushing, + vcd_clnt_exit_flushing +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_stopping = { + { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + vcd_get_property_cmn, + NULL, + vcd_get_buffer_requirements_cmn, + NULL, + NULL, + NULL, + NULL, + vcd_clnt_cb_in_stopping, + }, + vcd_clnt_enter_stopping, + vcd_clnt_exit_stopping +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_eos = { + { + NULL, + NULL, + vcd_encode_frame_cmn, + NULL, + vcd_decode_frame_cmn, + NULL, + NULL, + vcd_flush_in_eos, + vcd_stop_in_eos, + NULL, + vcd_get_property_cmn, + NULL, + vcd_get_buffer_requirements_cmn, + NULL, + NULL, + NULL, + vcd_fill_output_buffer_in_eos, + vcd_clnt_cb_in_eos, + }, + vcd_clnt_enter_eos, + vcd_clnt_exit_eos +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_pausing = { + { + NULL, + NULL, + vcd_encode_frame_cmn, + NULL, + vcd_decode_frame_cmn, + NULL, + NULL, + NULL, + NULL, + vcd_set_property_cmn, + vcd_get_property_cmn, + NULL, + vcd_get_buffer_requirements_cmn, + NULL, + NULL, + NULL, + vcd_fill_output_buffer_cmn, + vcd_clnt_cb_in_pausing, + }, + vcd_clnt_enter_pausing, + vcd_clnt_exit_pausing +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_paused = { + { + NULL, + NULL, + vcd_encode_frame_cmn, + NULL, + vcd_decode_frame_cmn, + NULL, + vcd_resume_in_paused, + vcd_flush_cmn, + vcd_stop_cmn, + vcd_set_property_cmn, + vcd_get_property_cmn, + vcd_set_buffer_requirements_cmn, + vcd_get_buffer_requirements_cmn, + vcd_set_buffer_cmn, + vcd_allocate_buffer_cmn, + NULL, + vcd_fill_output_buffer_cmn, + NULL, + }, + vcd_clnt_enter_paused, + vcd_clnt_exit_paused +}; +static const struct vcd_clnt_state_table vcd_clnt_table_invalid = { + { + vcd_close_in_invalid, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + vcd_flush_in_invalid, + vcd_stop_in_invalid, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + vcd_free_buffer_cmn, + NULL, + vcd_clnt_cb_in_invalid, + }, + vcd_clnt_enter_invalid, + vcd_clnt_exit_invalid +}; + +static const struct vcd_clnt_state_table *vcd_clnt_state_table[] = { + NULL, + &vcd_clnt_table_open, + &vcd_clnt_table_starting, + &vcd_clnt_table_run, + &vcd_clnt_table_flushing, + &vcd_clnt_table_pausing, + &vcd_clnt_table_paused, + &vcd_clnt_table_stopping, + &vcd_clnt_table_eos, + &vcd_clnt_table_invalid +}; diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h new file mode 100644 index 0000000000000000000000000000000000000000..ba1884dd601dcb7839d10e130977ab6116a3947d --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h @@ -0,0 +1,110 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_CLIENT_SM_H_ +#define _VCD_CLIENT_SM_H_ +#include +#include "vcd_ddl_api.h" + +struct vcd_clnt_state_table; +struct vcd_clnt_state_ctxt; +struct vcd_clnt_ctxt; + +enum vcd_clnt_state_enum { + VCD_CLIENT_STATE_NULL = 0, + VCD_CLIENT_STATE_OPEN, + VCD_CLIENT_STATE_STARTING, + VCD_CLIENT_STATE_RUN, + VCD_CLIENT_STATE_FLUSHING, + VCD_CLIENT_STATE_PAUSING, + VCD_CLIENT_STATE_PAUSED, + VCD_CLIENT_STATE_STOPPING, + VCD_CLIENT_STATE_EOS, + VCD_CLIENT_STATE_INVALID, + VCD_CLIENT_STATE_MAX, + VCD_CLIENT_STATE_32BIT = 0x7FFFFFFF +}; + +#define CLIENT_STATE_EVENT_NUMBER(ppf) \ + ((u32 *) (&(((struct vcd_clnt_state_table*)0)->ev_hdlr.ppf)) - \ + (u32 *) (&(((struct vcd_clnt_state_table*)0)->ev_hdlr.close)) \ + + 1) + +struct vcd_clnt_state_table { + struct { + u32(*close) (struct vcd_clnt_ctxt *cctxt); + u32(*encode_start) (struct vcd_clnt_ctxt *cctxt); + u32(*encode_frame) (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame); + u32(*decode_start) (struct vcd_clnt_ctxt *cctxt, + struct vcd_sequence_hdr *seq_hdr); + u32(*decode_frame) (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame); + u32(*pause) (struct vcd_clnt_ctxt *cctxt); + u32(*resume) (struct vcd_clnt_ctxt *cctxt); + u32(*flush) (struct vcd_clnt_ctxt *cctxt, + u32 mode); + u32(*stop) (struct vcd_clnt_ctxt *cctxt); + u32(*set_property) (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_hdr *prop_hdr, + void *prop); + u32(*get_property) (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_hdr *prop_hdr, + void *prop); + u32(*set_buffer_requirements) (struct vcd_clnt_ctxt * + cctxt, + enum vcd_buffer_type buffer, + struct + vcd_buffer_requirement * + buffer_req); + u32(*get_buffer_requirements) (struct vcd_clnt_ctxt * + cctxt, + enum vcd_buffer_type buffer, + struct + vcd_buffer_requirement * + buffer_req); + u32(*set_buffer) (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type, u8 *buffer, + u32 buf_size); + u32(*allocate_buffer) (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer, u32 buf_size, + u8 **vir_buf_addr, u8 **phy_buf_addr); + u32(*free_buffer) (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type, u8 *buffer); + u32(*fill_output_buffer) ( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer); + void (*clnt_cb) (struct vcd_clnt_ctxt *cctxt, + u32 event, u32 status, void *payload, + size_t sz, u32 *ddl_handle, + void *const client_data); + } ev_hdlr; + + void (*entry) (struct vcd_clnt_ctxt *cctxt, + s32 state_event); + void (*exit) (struct vcd_clnt_ctxt *cctxt, + s32 state_event); +}; + +struct vcd_clnt_state_ctxt { + const struct vcd_clnt_state_table *state_table; + enum vcd_clnt_state_enum state; +}; + +extern void vcd_do_client_state_transition + (struct vcd_clnt_ctxt *cctxt, + enum vcd_clnt_state_enum to_state, u32 ev_code); + +extern const struct vcd_clnt_state_table *vcd_get_client_state_table( + enum vcd_clnt_state_enum state); + +#endif diff --git a/drivers/video/msm/vidc/common/vcd/vcd_core.h b/drivers/video/msm/vidc/common/vcd/vcd_core.h new file mode 100644 index 0000000000000000000000000000000000000000..1ffedf7ca54552482d960cb02348f07bf2de5077 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_core.h @@ -0,0 +1,228 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_CORE_H_ +#define _VCD_CORE_H_ + +#include +#include +#include "vcd_ddl_api.h" + +#include "vcd_util.h" +#include "vcd_client_sm.h" +#include "vcd_power_sm.h" + +#define VCD_SIGNATURE 0x75017591U + +#define VCD_MIN_PERF_LEVEL 37900 + +#define VCD_DRIVER_INSTANCE_MAX 4 + +#define VCD_MAX_CLIENT_TRANSACTIONS 32 + +#define VCD_MAX_BUFFER_ENTRIES 32 + +#define VCD_SEQ_HDR_PADDING_BYTES 256 + +#define VCD_DEC_NUM_INTERLACED_FIELDS 2 + +#define VCD_TIMESTAMP_RESOLUTION 1000000 +#define VCD_DEC_INITIAL_FRAME_RATE 30 + +#define VCD_FIRST_IP_RCVD 0x00000004 +#define VCD_FIRST_OP_RCVD 0x00000008 +#define VCD_EOS_PREV_VALID 0x00000010 +#define VCD_EOS_WAIT_OP_BUF 0x00000020 +#define VCD_CLEANING_UP 0x00000040 +#define VCD_STOP_PENDING 0x00000080 +#define VCD_CLOSE_PENDING 0x00000100 +#define VCD_IN_RECONFIG 0x00000200 +#define VCD_FIRST_IP_DONE 0x00000400 + +enum vcd_command { + VCD_CMD_NONE, + VCD_CMD_DEVICE_INIT, + VCD_CMD_DEVICE_TERM, + VCD_CMD_DEVICE_RESET, + VCD_CMD_CODEC_START, + VCD_CMD_CODEC_STOP, + VCD_CMD_CODE_FRAME, + VCD_CMD_OUTPUT_FLUSH, + VCD_CMD_CLIENT_CLOSE +}; + +enum vcd_core_type { + VCD_CORE_1080P, + VCD_CORE_720P +}; + +struct vcd_cmd_q_element { + enum vcd_command pending_cmd; +}; + +struct vcd_buffer_entry { + struct list_head sched_list; + struct list_head list; + u32 valid; + u8 *alloc; + u8 *virtual; + u8 *physical; + size_t sz; + u32 allocated; + u32 in_use; + struct vcd_frame_data frame; + +}; + +struct vcd_buffer_pool { + struct vcd_buffer_entry *entries; + u32 count; + struct vcd_buffer_requirement buf_req; + u32 validated; + u32 allocated; + u32 in_use; + struct list_head queue; + u16 q_len; +}; + +struct vcd_transc { + u32 in_use; + enum vcd_command type; + struct vcd_clnt_ctxt *cctxt; + + struct vcd_buffer_entry *ip_buf_entry; + + s64 time_stamp; + u32 flags; + u32 ip_frm_tag; + enum vcd_frame frame; + + struct vcd_buffer_entry *op_buf_entry; + + u32 input_done; + u32 frame_done; +}; + +struct vcd_dev_ctxt { + u32 ddl_cmd_concurrency; + u32 ddl_frame_ch_depth; + u32 ddl_cmd_ch_depth; + u32 ddl_frame_ch_interim; + u32 ddl_cmd_ch_interim; + u32 ddl_frame_ch_free; + u32 ddl_cmd_ch_free; + + struct list_head sched_clnt_list; + + struct vcd_init_config config; + + u32 driver_ids[VCD_DRIVER_INSTANCE_MAX]; + u32 refs; + u8 *device_base_addr; + void *hw_timer_handle; + u32 hw_time_out; + struct vcd_clnt_ctxt *cctxt_list_head; + + enum vcd_command pending_cmd; + + u32 command_continue; + + struct vcd_transc *trans_tbl; + u32 trans_tbl_size; + + enum vcd_power_state pwr_state; + enum vcd_pwr_clk_state pwr_clk_state; + u32 active_clnts; + u32 max_perf_lvl; + u32 reqd_perf_lvl; + u32 curr_perf_lvl; + u32 set_perf_lvl_pending; + +}; + +struct vcd_clnt_status { + u32 req_perf_lvl; + u32 frame_submitted; + u32 frame_delayed; + u32 cmd_submitted; + u32 int_field_cnt; + s64 first_ts; + s64 prev_ts; + u64 time_elapsed; + struct vcd_frame_data eos_trig_ip_frm; + struct ddl_frame_data_tag eos_prev_op_frm; + u32 eos_prev_op_frm_status; + u32 last_err; + u32 last_evt; + u32 mask; +}; + +struct vcd_sched_clnt_ctx { + struct list_head list; + u32 clnt_active; + void *clnt_data; + u32 tkns; + u32 round_perfrm; + u32 rounds; + struct list_head ip_frm_list; +}; + +struct vcd_clnt_ctxt { + u32 signature; + struct vcd_clnt_state_ctxt clnt_state; + + s32 driver_id; + + u32 live; + u32 decoding; + u32 bframe; + u32 num_slices; + + struct vcd_property_frame_rate frm_rate; + u32 frm_p_units; + u32 reqd_perf_lvl; + u32 time_resoln; + u32 time_frame_delta; + + struct vcd_buffer_pool in_buf_pool; + struct vcd_buffer_pool out_buf_pool; + + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data); + void *client_data; + struct vcd_sched_clnt_ctx *sched_clnt_hdl; + u32 ddl_hdl_valid; + u32 *ddl_handle; + struct vcd_dev_ctxt *dev_ctxt; + struct vcd_cmd_q_element cmd_q; + struct vcd_sequence_hdr seq_hdr; + u8 *seq_hdr_phy_addr; + struct vcd_clnt_status status; + struct ion_client *vcd_ion_client; + u32 vcd_enable_ion; + struct vcd_clnt_ctxt *next; + u32 meta_mode; + int perf_set_by_client; + int secure; +}; + +#define VCD_BUFFERPOOL_INUSE_DECREMENT(val) \ +do { \ + if ((val) > 0) \ + val--; \ + else { \ + VCD_MSG_ERROR("%s(): Inconsistent val given in " \ + " VCD_BUFFERPOOL_INUSE_DECREMENT\n", __func__); \ + } \ +} while (0) + +#endif diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c new file mode 100644 index 0000000000000000000000000000000000000000..5f2343db67b829d3619e15e678eaf1ace66c1e8d --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c @@ -0,0 +1,1218 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "vcd.h" + +static const struct vcd_dev_state_table *vcd_dev_state_table[]; +static const struct vcd_dev_state_table vcd_dev_table_null; + +struct vcd_drv_ctxt *vcd_get_drv_context(void) +{ + static struct vcd_drv_ctxt drv_context = { + {&vcd_dev_table_null, VCD_DEVICE_STATE_NULL}, + {0}, + }; + + return &drv_context; + +} + +void vcd_do_device_state_transition(struct vcd_drv_ctxt *drv_ctxt, + enum vcd_dev_state_enum to_state, u32 ev_code) +{ + struct vcd_dev_state_ctxt *state_ctxt; + + if (!drv_ctxt || to_state >= VCD_DEVICE_STATE_MAX) { + VCD_MSG_ERROR("Bad parameters. drv_ctxt=%p, to_state=%d", + drv_ctxt, to_state); + } + + state_ctxt = &drv_ctxt->dev_state; + + if (state_ctxt->state == to_state) { + VCD_MSG_HIGH("Device already in requested to_state=%d", + to_state); + + return; + } + + VCD_MSG_MED("vcd_do_device_state_transition: D%d -> D%d, for api %d", + (int)state_ctxt->state, (int)to_state, ev_code); + + if (state_ctxt->state_table->exit) + state_ctxt->state_table->exit(drv_ctxt, ev_code); + + + state_ctxt->state = to_state; + state_ctxt->state_table = vcd_dev_state_table[to_state]; + + if (state_ctxt->state_table->entry) + state_ctxt->state_table->entry(drv_ctxt, ev_code); +} + +void vcd_hw_timeout_handler(void *user_data) +{ + struct vcd_drv_ctxt *drv_ctxt; + + VCD_MSG_HIGH("vcd_hw_timeout_handler:"); + user_data = NULL; + drv_ctxt = vcd_get_drv_context(); + mutex_lock(&drv_ctxt->dev_mutex); + if (drv_ctxt->dev_state.state_table->ev_hdlr.timeout) + drv_ctxt->dev_state.state_table->ev_hdlr. + timeout(drv_ctxt, user_data); + else + VCD_MSG_ERROR("hw_timeout unsupported in device state %d", + drv_ctxt->dev_state.state); + mutex_unlock(&drv_ctxt->dev_mutex); +} + +void vcd_ddl_callback(u32 event, u32 status, void *payload, + size_t sz, u32 *ddl_handle, void *const client_data) +{ + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_dev_ctxt *dev_ctxt; + struct vcd_dev_state_ctxt *dev_state; + struct vcd_clnt_ctxt *cctxt; + struct vcd_transc *transc; + + VCD_MSG_LOW("vcd_ddl_callback:"); + + VCD_MSG_LOW("event=0x%x status=0x%x", event, status); + + drv_ctxt = vcd_get_drv_context(); + dev_ctxt = &drv_ctxt->dev_ctxt; + dev_state = &drv_ctxt->dev_state; + + dev_ctxt->command_continue = true; + vcd_device_timer_stop(dev_ctxt); + + switch (dev_state->state) { + case VCD_DEVICE_STATE_NULL: + { + VCD_MSG_HIGH("Callback unexpected in NULL state"); + break; + } + + case VCD_DEVICE_STATE_NOT_INIT: + { + VCD_MSG_HIGH("Callback unexpected in NOT_INIT state"); + break; + } + + case VCD_DEVICE_STATE_INITING: + { + if (dev_state->state_table->ev_hdlr.dev_cb) { + dev_state->state_table->ev_hdlr. + dev_cb(drv_ctxt, event, status, + payload, sz, ddl_handle, + client_data); + } else { + VCD_MSG_HIGH("No device handler in %d state", + dev_state->state); + } + break; + } + + case VCD_DEVICE_STATE_READY: + { + transc = (struct vcd_transc *)client_data; + + if (!transc || !transc->in_use || !transc->cctxt) { + VCD_MSG_ERROR("Invalid clientdata " + "received from DDL, transc = 0x%x\n", + (u32)transc); + if (transc) { + VCD_MSG_ERROR("transc->in_use = %u, " + "transc->cctxt = 0x%x\n", + transc->in_use, + (u32)transc->cctxt); + } + } else { + cctxt = transc->cctxt; + + if (cctxt->clnt_state.state_table->ev_hdlr. + clnt_cb) { + cctxt->clnt_state.state_table-> + ev_hdlr.clnt_cb(cctxt, + event, status, payload, + sz, ddl_handle, + client_data); + } else { + VCD_MSG_HIGH + ("No client handler in" + " (dsm:READY, csm:%d) state", + (int)cctxt->clnt_state.state); + + if (VCD_FAILED(status)) { + VCD_MSG_FATAL("DDL callback" + " returned failure 0x%x", + status); + } + } + } + break; + } + + default: + { + VCD_MSG_ERROR("Unknown state"); + break; + } + + } + +} + +u32 vcd_init_device_context(struct vcd_drv_ctxt *drv_ctxt, + u32 ev_code) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + u32 rc; + struct ddl_init_config ddl_init; + + VCD_MSG_LOW("vcd_init_device_context:"); + + dev_ctxt->pending_cmd = VCD_CMD_NONE; + + rc = vcd_power_event(dev_ctxt, NULL, VCD_EVT_PWR_DEV_INIT_BEGIN); + VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_INIT_BEGIN failed"); + + VCD_MSG_HIGH("Device powered ON and clocked"); + rc = vcd_sched_create(&dev_ctxt->sched_clnt_list); + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_sched_create", rc); + + (void)vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_DEV_INIT_FAIL); + + return rc; + } + + VCD_MSG_HIGH("Created scheduler instance."); + + ddl_init.core_virtual_base_addr = dev_ctxt->device_base_addr; + ddl_init.interrupt_clr = dev_ctxt->config.interrupt_clr; + ddl_init.ddl_callback = vcd_ddl_callback; + + rc = ddl_device_init(&ddl_init, NULL); + + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("rc = 0x%x. Failed: ddl_device_init", rc); + vcd_sched_destroy(&dev_ctxt->sched_clnt_list); + (void)vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_DEV_INIT_FAIL); + } else { + vcd_device_timer_start(dev_ctxt); + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_INITING, + ev_code); + } + + return rc; +} + +void vcd_handle_device_init_failed(struct vcd_drv_ctxt *drv_ctxt, + u32 status) +{ + struct vcd_clnt_ctxt *client; + struct vcd_clnt_ctxt *tmp_client; + + VCD_MSG_ERROR("Device init failed. status = %d", status); + + client = drv_ctxt->dev_ctxt.cctxt_list_head; + while (client) { + client->callback(VCD_EVT_RESP_OPEN, + status, NULL, 0, 0, client->client_data); + + tmp_client = client; + client = client->next; + + vcd_destroy_client_context(tmp_client); + } + if (ddl_device_release(NULL)) + VCD_MSG_ERROR("Failed: ddl_device_release"); + + vcd_sched_destroy(&drv_ctxt->dev_ctxt.sched_clnt_list); + if (vcd_power_event(&drv_ctxt->dev_ctxt, + NULL, VCD_EVT_PWR_DEV_INIT_FAIL)) + VCD_MSG_ERROR("VCD_EVT_PWR_DEV_INIT_FAIL failed"); + + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_NOT_INIT, + DEVICE_STATE_EVENT_NUMBER(dev_cb)); +} + +u32 vcd_deinit_device_context(struct vcd_drv_ctxt *drv_ctxt, + u32 ev_code) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_deinit_device_context:"); + + rc = vcd_power_event(&drv_ctxt->dev_ctxt, NULL, + VCD_EVT_PWR_DEV_TERM_BEGIN); + + VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_TERM_BEGIN failed"); + + rc = ddl_device_release(NULL); + + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("rc = 0x%x. Failed: ddl_device_release", rc); + + (void)vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_DEV_TERM_FAIL); + } else { + vcd_sched_destroy(&dev_ctxt->sched_clnt_list); + (void) vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_DEV_TERM_END); + + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_NOT_INIT, ev_code); + } + return rc; +} + +void vcd_term_driver_context(struct vcd_drv_ctxt *drv_ctxt) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + + VCD_MSG_HIGH("All driver instances terminated"); + + if (dev_ctxt->config.deregister_isr) + dev_ctxt->config.deregister_isr(); + + if (dev_ctxt->config.un_map_dev_base_addr) + dev_ctxt->config.un_map_dev_base_addr(); + + if (dev_ctxt->config.timer_release) + dev_ctxt->config.timer_release( + dev_ctxt->hw_timer_handle); + + kfree(dev_ctxt->trans_tbl); + + memset(dev_ctxt, 0, sizeof(struct vcd_dev_ctxt)); + + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_NULL, + DEVICE_STATE_EVENT_NUMBER(term)); + +} + +u32 vcd_reset_device_context(struct vcd_drv_ctxt *drv_ctxt, + u32 ev_code) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_reset_device_context:"); + vcd_reset_device_channels(dev_ctxt); + rc = vcd_power_event(&drv_ctxt->dev_ctxt, NULL, + VCD_EVT_PWR_DEV_TERM_BEGIN); + VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_TERM_BEGIN failed"); + if (ddl_reset_hw(0)) + VCD_MSG_HIGH("HW Reset done"); + else + VCD_MSG_FATAL("HW Reset failed"); + + (void)vcd_power_event(dev_ctxt, NULL, VCD_EVT_PWR_DEV_TERM_END); + + return VCD_S_SUCCESS; +} + +void vcd_handle_device_err_fatal(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *trig_clnt) +{ + struct vcd_clnt_ctxt *cctxt = dev_ctxt->cctxt_list_head; + struct vcd_clnt_ctxt *tmp_clnt = NULL; + VCD_MSG_LOW("vcd_handle_device_err_fatal:"); + while (cctxt) { + tmp_clnt = cctxt; + cctxt = cctxt->next; + if (tmp_clnt != trig_clnt) + vcd_clnt_handle_device_err_fatal(tmp_clnt, + tmp_clnt->status.last_evt); + } + dev_ctxt->pending_cmd = VCD_CMD_DEVICE_RESET; + if (!dev_ctxt->cctxt_list_head) + vcd_do_device_state_transition(vcd_get_drv_context(), + VCD_DEVICE_STATE_NOT_INIT, + DEVICE_STATE_EVENT_NUMBER(timeout)); + else + vcd_do_device_state_transition(vcd_get_drv_context(), + VCD_DEVICE_STATE_INVALID, + DEVICE_STATE_EVENT_NUMBER(dev_cb)); +} + +void vcd_handle_for_last_clnt_close( + struct vcd_dev_ctxt *dev_ctxt, u32 send_deinit) +{ + if (!dev_ctxt->cctxt_list_head) { + VCD_MSG_HIGH("All clients are closed"); + if (send_deinit) + (void) vcd_deinit_device_context( + vcd_get_drv_context(), + DEVICE_STATE_EVENT_NUMBER(close)); + else + dev_ctxt->pending_cmd = + VCD_CMD_DEVICE_TERM; + } +} +void vcd_continue(void) +{ + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_dev_ctxt *dev_ctxt; + u32 command_continue; + struct vcd_transc *transc; + u32 rc; + VCD_MSG_LOW("vcd_continue:"); + + drv_ctxt = vcd_get_drv_context(); + dev_ctxt = &drv_ctxt->dev_ctxt; + + dev_ctxt->command_continue = false; + + if (dev_ctxt->pending_cmd == VCD_CMD_DEVICE_INIT) { + VCD_MSG_HIGH("VCD_CMD_DEVICE_INIT is pending"); + + dev_ctxt->pending_cmd = VCD_CMD_NONE; + + (void)vcd_init_device_context(drv_ctxt, + DEVICE_STATE_EVENT_NUMBER(open)); + } else if (dev_ctxt->pending_cmd == VCD_CMD_DEVICE_TERM) { + VCD_MSG_HIGH("VCD_CMD_DEVICE_TERM is pending"); + + dev_ctxt->pending_cmd = VCD_CMD_NONE; + + (void)vcd_deinit_device_context(drv_ctxt, + DEVICE_STATE_EVENT_NUMBER(close)); + } else if (dev_ctxt->pending_cmd == VCD_CMD_DEVICE_RESET) { + VCD_MSG_HIGH("VCD_CMD_DEVICE_RESET is pending"); + dev_ctxt->pending_cmd = VCD_CMD_NONE; + (void)vcd_reset_device_context(drv_ctxt, + DEVICE_STATE_EVENT_NUMBER(dev_cb)); + } else { + if (dev_ctxt->set_perf_lvl_pending) { + rc = vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_DEV_SET_PERFLVL); + + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR + ("VCD_EVT_PWR_CLNT_SET_PERFLVL failed"); + VCD_MSG_HIGH + ("Not running at desired perf level." + "curr=%d, reqd=%d", + dev_ctxt->curr_perf_lvl, + dev_ctxt->reqd_perf_lvl); + } else { + dev_ctxt->set_perf_lvl_pending = false; + } + } + + do { + command_continue = false; + + if (vcd_get_command_channel_in_loop + (dev_ctxt, &transc)) { + if (vcd_submit_command_in_continue(dev_ctxt, + transc)) + command_continue = true; + else { + VCD_MSG_MED + ("No more commands to submit"); + + vcd_release_command_channel(dev_ctxt, + transc); + + vcd_release_interim_command_channels + (dev_ctxt); + } + } + } while (command_continue); + + do { + command_continue = false; + + if (vcd_get_frame_channel_in_loop + (dev_ctxt, &transc)) { + if (vcd_try_submit_frame_in_continue(dev_ctxt, + transc)) { + command_continue = true; + } else { + VCD_MSG_MED("No more frames to submit"); + + vcd_release_frame_channel(dev_ctxt, + transc); + + vcd_release_interim_frame_channels + (dev_ctxt); + } + } + + } while (command_continue); + + if (!vcd_core_is_busy(dev_ctxt)) { + rc = vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_CLNT_CMD_END); + + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("Failed:" + "VCD_EVT_PWR_CLNT_CMD_END"); + } + } +} + +static void vcd_pause_all_sessions(struct vcd_dev_ctxt *dev_ctxt) +{ + struct vcd_clnt_ctxt *cctxt = dev_ctxt->cctxt_list_head; + u32 rc; + + while (cctxt) { + if (cctxt->clnt_state.state_table->ev_hdlr.pause) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + pause(cctxt); + + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("Client pause failed"); + + } + + cctxt = cctxt->next; + } +} + +static void vcd_resume_all_sessions(struct vcd_dev_ctxt *dev_ctxt) +{ + struct vcd_clnt_ctxt *cctxt = dev_ctxt->cctxt_list_head; + u32 rc; + + while (cctxt) { + if (cctxt->clnt_state.state_table->ev_hdlr.resume) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + resume(cctxt); + + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("Client resume failed"); + + } + + cctxt = cctxt->next; + } +} + +static u32 vcd_init_cmn + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_init_config *config, s32 *driver_handle) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + s32 driver_id; + + if (dev_ctxt->config.interrupt_clr != + config->interrupt_clr + || dev_ctxt->config.register_isr != + config->register_isr + || dev_ctxt->config.deregister_isr != + config->deregister_isr + || dev_ctxt->config.map_dev_base_addr != + config->map_dev_base_addr + || dev_ctxt->config.un_map_dev_base_addr != + config->un_map_dev_base_addr) { + VCD_MSG_HIGH("Device config mismatch. " + "VCD will be using config from 1st vcd_init"); + } + + *driver_handle = 0; + + driver_id = 0; + while (driver_id < VCD_DRIVER_INSTANCE_MAX && + dev_ctxt->driver_ids[driver_id]) { + ++driver_id; + } + + if (driver_id == VCD_DRIVER_INSTANCE_MAX) { + VCD_MSG_ERROR("Max driver instances reached"); + + return VCD_ERR_FAIL; + } + + ++dev_ctxt->refs; + dev_ctxt->driver_ids[driver_id] = true; + *driver_handle = driver_id + 1; + + VCD_MSG_HIGH("Driver_id = %d. No of driver instances = %d", + driver_id, dev_ctxt->refs); + + return VCD_S_SUCCESS; + +} + +static u32 vcd_init_in_null + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_init_config *config, s32 *driver_handle) { + u32 rc = VCD_S_SUCCESS; + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + u32 done_create_timer = false; + VCD_MSG_LOW("vcd_init_in_dev_null:"); + + + dev_ctxt->config = *config; + + dev_ctxt->device_base_addr = + (u8 *)config->map_dev_base_addr( + dev_ctxt->config.device_name); + + if (!dev_ctxt->device_base_addr) { + VCD_MSG_ERROR("NULL Device_base_addr"); + + return VCD_ERR_FAIL; + } + + if (config->register_isr) { + config->register_isr(dev_ctxt->config. + device_name); + } + + if (config->timer_create) { + if (config->timer_create(vcd_hw_timeout_handler, + NULL, &dev_ctxt->hw_timer_handle)) + done_create_timer = true; + else { + VCD_MSG_ERROR("timercreate failed"); + return VCD_ERR_FAIL; + } + } + + + rc = vcd_init_cmn(drv_ctxt, config, driver_handle); + + if (!VCD_FAILED(rc)) { + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_NOT_INIT, + DEVICE_STATE_EVENT_NUMBER + (init)); + } else { + if (dev_ctxt->config.un_map_dev_base_addr) + dev_ctxt->config.un_map_dev_base_addr(); + + if (dev_ctxt->config.deregister_isr) + dev_ctxt->config.deregister_isr(); + + if (done_create_timer && dev_ctxt->config.timer_release) + dev_ctxt->config.timer_release(dev_ctxt-> + hw_timer_handle); + + } + + return rc; + +} + +static u32 vcd_init_in_not_init + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_init_config *config, s32 *driver_handle) +{ + + VCD_MSG_LOW("vcd_init_in_dev_not_init:"); + + return vcd_init_cmn(drv_ctxt, config, driver_handle); + +} + +static u32 vcd_init_in_initing + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_init_config *config, s32 *driver_handle) { + + VCD_MSG_LOW("vcd_init_in_dev_initing:"); + + return vcd_init_cmn(drv_ctxt, config, driver_handle); + +} + +static u32 vcd_init_in_ready + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_init_config *config, s32 *driver_handle) +{ + VCD_MSG_LOW("vcd_init_in_dev_ready:"); + + return vcd_init_cmn(drv_ctxt, config, driver_handle); +} + +static u32 vcd_term_cmn + (struct vcd_drv_ctxt *drv_ctxt, s32 driver_handle) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + + if (!vcd_validate_driver_handle(dev_ctxt, driver_handle)) { + VCD_MSG_ERROR("Invalid driver handle = %d", driver_handle); + + return VCD_ERR_BAD_HANDLE; + } + + if (vcd_check_for_client_context(dev_ctxt, + driver_handle - 1)) { + VCD_MSG_ERROR("Driver has active client"); + + return VCD_ERR_BAD_STATE; + } + + --dev_ctxt->refs; + dev_ctxt->driver_ids[driver_handle - 1] = false; + + VCD_MSG_HIGH("Driver_id %d terminated. No of driver instances = %d", + driver_handle - 1, dev_ctxt->refs); + + return VCD_S_SUCCESS; +} + +static u32 vcd_term_in_not_init + (struct vcd_drv_ctxt *drv_ctxt, s32 driver_handle) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + u32 rc; + + VCD_MSG_LOW("vcd_term_in_dev_not_init:"); + + rc = vcd_term_cmn(drv_ctxt, driver_handle); + + if (!VCD_FAILED(rc) && !dev_ctxt->refs) + vcd_term_driver_context(drv_ctxt); + + return rc; +} + +static u32 vcd_term_in_initing + (struct vcd_drv_ctxt *drv_ctxt, s32 driver_handle) +{ + VCD_MSG_LOW("vcd_term_in_dev_initing:"); + + return vcd_term_cmn(drv_ctxt, driver_handle); +} + +static u32 vcd_term_in_ready + (struct vcd_drv_ctxt *drv_ctxt, s32 driver_handle) +{ + VCD_MSG_LOW("vcd_term_in_dev_ready:"); + + return vcd_term_cmn(drv_ctxt, driver_handle); +} + +static u32 vcd_term_in_invalid(struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle) +{ + u32 rc; + VCD_MSG_LOW("vcd_term_in_invalid:"); + rc = vcd_term_cmn(drv_ctxt, driver_handle); + if (!VCD_FAILED(rc) && !drv_ctxt->dev_ctxt.refs) + vcd_term_driver_context(drv_ctxt); + + return rc; +} + +static u32 vcd_open_cmn + (struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle, + u32 decoding, + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data), + void *client_data, struct vcd_clnt_ctxt ** clnt_cctxt) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + struct vcd_clnt_ctxt *cctxt; + struct vcd_clnt_ctxt *client; + + if (!vcd_validate_driver_handle(dev_ctxt, driver_handle)) { + VCD_MSG_ERROR("Invalid driver handle = %d", driver_handle); + + return VCD_ERR_BAD_HANDLE; + } + + cctxt = (struct vcd_clnt_ctxt *) + kmalloc(sizeof(struct vcd_clnt_ctxt), GFP_KERNEL); + if (!cctxt) { + VCD_MSG_ERROR("No memory for client ctxt"); + + return VCD_ERR_ALLOC_FAIL; + } + + memset(cctxt, 0, sizeof(struct vcd_clnt_ctxt)); + cctxt->dev_ctxt = dev_ctxt; + cctxt->driver_id = driver_handle - 1; + cctxt->decoding = decoding; + cctxt->callback = callback; + cctxt->client_data = client_data; + cctxt->status.last_evt = VCD_EVT_RESP_OPEN; + INIT_LIST_HEAD(&cctxt->in_buf_pool.queue); + INIT_LIST_HEAD(&cctxt->out_buf_pool.queue); + client = dev_ctxt->cctxt_list_head; + dev_ctxt->cctxt_list_head = cctxt; + cctxt->next = client; + + *clnt_cctxt = cctxt; + + return VCD_S_SUCCESS; + +} + +static u32 vcd_open_in_not_init + (struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle, + u32 decoding, + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data), + void *client_data) +{ + struct vcd_clnt_ctxt *cctxt; + u32 rc; + + VCD_MSG_LOW("vcd_open_in_dev_not_init:"); + + rc = vcd_open_cmn(drv_ctxt, driver_handle, decoding, callback, + client_data, &cctxt); + + VCD_FAILED_RETURN(rc, "Failed: vcd_open_cmn"); + + rc = vcd_init_device_context(drv_ctxt, + DEVICE_STATE_EVENT_NUMBER(open)); + + if (VCD_FAILED(rc)) + vcd_destroy_client_context(cctxt); + + return rc; +} + +static u32 vcd_open_in_initing(struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle, u32 decoding, + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data), + void *client_data) +{ + struct vcd_clnt_ctxt *cctxt; + + VCD_MSG_LOW("vcd_open_in_dev_initing:"); + + return vcd_open_cmn(drv_ctxt, driver_handle, decoding, callback, + client_data, &cctxt); +} + +static u32 vcd_open_in_ready + (struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle, + u32 decoding, + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data), + void *client_data) +{ + struct vcd_clnt_ctxt *cctxt; + struct vcd_handle_container container; + u32 rc; + + VCD_MSG_LOW("vcd_open_in_dev_ready:"); + + rc = vcd_open_cmn(drv_ctxt, driver_handle, decoding, callback, + client_data, &cctxt); + + VCD_FAILED_RETURN(rc, "Failed: vcd_open_cmn"); + + rc = vcd_init_client_context(cctxt); + + if (!VCD_FAILED(rc)) { + container.handle = (void *)cctxt; + + callback(VCD_EVT_RESP_OPEN, + VCD_S_SUCCESS, + &container, + sizeof(container), container.handle, client_data); + } else { + VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_init_client_context", rc); + + vcd_destroy_client_context(cctxt); + } + + return rc; +} + +static u32 vcd_close_in_ready + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_clnt_ctxt *cctxt) { + u32 rc; + + VCD_MSG_LOW("vcd_close_in_dev_ready:"); + + if (cctxt->clnt_state.state_table->ev_hdlr.close) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + close(cctxt); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + if (!VCD_FAILED(rc)) + vcd_handle_for_last_clnt_close(&drv_ctxt->dev_ctxt, true); + + return rc; +} + +static u32 vcd_close_in_dev_invalid(struct vcd_drv_ctxt *drv_ctxt, + struct vcd_clnt_ctxt *cctxt) +{ + u32 rc; + VCD_MSG_LOW("vcd_close_in_dev_invalid:"); + if (cctxt->clnt_state.state_table->ev_hdlr.close) { + rc = cctxt->clnt_state.state_table-> + ev_hdlr.close(cctxt); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + rc = VCD_ERR_BAD_STATE; + } + if (!VCD_FAILED(rc) && !drv_ctxt->dev_ctxt. + cctxt_list_head) { + VCD_MSG_HIGH("All INVALID clients are closed"); + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_NOT_INIT, + DEVICE_STATE_EVENT_NUMBER(close)); + } + return rc; +} + +static u32 vcd_resume_in_ready + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_clnt_ctxt *cctxt) { + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_resume_in_ready:"); + + if (cctxt->clnt_state.state_table->ev_hdlr.resume) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + resume(cctxt); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + return rc; +} + +static u32 vcd_set_dev_pwr_in_ready + (struct vcd_drv_ctxt *drv_ctxt, + enum vcd_power_state pwr_state) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + + VCD_MSG_LOW("vcd_set_dev_pwr_in_ready:"); + + switch (pwr_state) { + case VCD_PWR_STATE_SLEEP: + { + if (dev_ctxt->pwr_state == VCD_PWR_STATE_ON) + vcd_pause_all_sessions(dev_ctxt); + dev_ctxt->pwr_state = VCD_PWR_STATE_SLEEP; + break; + } + + case VCD_PWR_STATE_ON: + { + if (dev_ctxt->pwr_state == VCD_PWR_STATE_SLEEP) + vcd_resume_all_sessions(dev_ctxt); + dev_ctxt->pwr_state = VCD_PWR_STATE_ON; + break; + } + + default: + { + VCD_MSG_ERROR("Invalid power state requested %d", + pwr_state); + break; + } + + } + + return rc; +} + +static void vcd_dev_cb_in_initing + (struct vcd_drv_ctxt *drv_ctxt, + u32 event, + u32 status, + void *payload, size_t sz, u32 *ddl_handle, void *const client_data) +{ + struct vcd_dev_ctxt *dev_ctxt; + struct vcd_clnt_ctxt *client; + struct vcd_clnt_ctxt *tmp_client; + struct vcd_handle_container container; + u32 rc = VCD_S_SUCCESS; + u32 client_inited = false; + u32 fail_all_open = false; + struct ddl_context *ddl_context; + + ddl_context = ddl_get_context(); + + VCD_MSG_LOW("vcd_dev_cb_in_initing:"); + + if (event != VCD_EVT_RESP_DEVICE_INIT) { + VCD_MSG_ERROR("vcd_dev_cb_in_initing: Unexpected event %d", + (int)event); + return; + } + + dev_ctxt = &drv_ctxt->dev_ctxt; + + dev_ctxt->command_continue = false; + + if (VCD_FAILED(status)) { + vcd_handle_device_init_failed(drv_ctxt, status); + + return; + } + + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_READY, + DEVICE_STATE_EVENT_NUMBER(open)); + + if (!dev_ctxt->cctxt_list_head) { + VCD_MSG_HIGH("All clients are closed"); + + dev_ctxt->pending_cmd = VCD_CMD_DEVICE_TERM; + + return; + } + + if (!dev_ctxt->ddl_cmd_ch_depth + || !dev_ctxt->trans_tbl) + rc = vcd_setup_with_ddl_capabilities(dev_ctxt); + + + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR + ("rc = 0x%x: Failed vcd_setup_with_ddl_capabilities", + rc); + + fail_all_open = true; + } + + client = dev_ctxt->cctxt_list_head; + while (client) { + if (!fail_all_open) + rc = vcd_init_client_context(client); + + + if (!VCD_FAILED(rc)) { + container.handle = (void *)client; + client->callback(VCD_EVT_RESP_OPEN, + VCD_S_SUCCESS, + &container, + sizeof(container), + container.handle, + client->client_data); + + client = client->next; + + client_inited = true; + } else { + VCD_MSG_ERROR + ("rc = 0x%x, Failed: vcd_init_client_context", + rc); + + client->callback(VCD_EVT_RESP_OPEN, + rc, + NULL, 0, 0, client->client_data); + + tmp_client = client; + client = client->next; + if (tmp_client == dev_ctxt->cctxt_list_head) + fail_all_open = true; + + vcd_destroy_client_context(tmp_client); + } + } + + if (!client_inited || fail_all_open) { + VCD_MSG_ERROR("All client open requests failed"); + + DDL_IDLE(ddl_context); + + vcd_handle_device_init_failed(drv_ctxt, + DEVICE_STATE_EVENT_NUMBER(close)); + dev_ctxt->pending_cmd = VCD_CMD_DEVICE_TERM; + } else { + if (vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_DEV_INIT_END)) { + VCD_MSG_ERROR("VCD_EVT_PWR_DEV_INIT_END failed"); + } + } +} + +static void vcd_hw_timeout_cmn(struct vcd_drv_ctxt *drv_ctxt, + void *user_data) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + VCD_MSG_LOW("vcd_hw_timeout_cmn:"); + vcd_device_timer_stop(dev_ctxt); + + vcd_handle_device_err_fatal(dev_ctxt, NULL); + + /* Reset HW. */ + (void) vcd_reset_device_context(drv_ctxt, + DEVICE_STATE_EVENT_NUMBER(timeout)); +} + +static void vcd_dev_enter_null + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Entering DEVICE_STATE_NULL on api %d", state_event); + +} + +static void vcd_dev_enter_not_init + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Entering DEVICE_STATE_NOT_INIT on api %d", + state_event); + +} + +static void vcd_dev_enter_initing + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Entering DEVICE_STATE_INITING on api %d", + state_event); + +} + +static void vcd_dev_enter_ready + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Entering DEVICE_STATE_READY on api %d", + state_event); +} + +static void vcd_dev_enter_invalid(struct vcd_drv_ctxt *drv_ctxt, + s32 state_event) +{ + VCD_MSG_MED("Entering DEVICE_STATE_INVALID on api %d", state_event); +} + +static void vcd_dev_exit_null + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Exiting DEVICE_STATE_NULL on api %d", state_event); +} + +static void vcd_dev_exit_not_init + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Exiting DEVICE_STATE_NOT_INIT on api %d", + state_event); + +} + +static void vcd_dev_exit_initing + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Exiting DEVICE_STATE_INITING on api %d", + state_event); +} + +static void vcd_dev_exit_ready + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Exiting DEVICE_STATE_READY on api %d", state_event); +} + +static void vcd_dev_exit_invalid(struct vcd_drv_ctxt *drv_ctxt, + s32 state_event) +{ + VCD_MSG_MED("Exiting DEVICE_STATE_INVALID on api %d", state_event); +} + +static const struct vcd_dev_state_table vcd_dev_table_null = { + { + vcd_init_in_null, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }, + vcd_dev_enter_null, + vcd_dev_exit_null +}; + +static const struct vcd_dev_state_table vcd_dev_table_not_init = { + { + vcd_init_in_not_init, + vcd_term_in_not_init, + vcd_open_in_not_init, + NULL, + NULL, + NULL, + NULL, + NULL, + }, + vcd_dev_enter_not_init, + vcd_dev_exit_not_init +}; + +static const struct vcd_dev_state_table vcd_dev_table_initing = { + { + vcd_init_in_initing, + vcd_term_in_initing, + vcd_open_in_initing, + NULL, + NULL, + NULL, + vcd_dev_cb_in_initing, + vcd_hw_timeout_cmn, + }, + vcd_dev_enter_initing, + vcd_dev_exit_initing +}; + +static const struct vcd_dev_state_table vcd_dev_table_ready = { + { + vcd_init_in_ready, + vcd_term_in_ready, + vcd_open_in_ready, + vcd_close_in_ready, + vcd_resume_in_ready, + vcd_set_dev_pwr_in_ready, + NULL, + vcd_hw_timeout_cmn, + }, + vcd_dev_enter_ready, + vcd_dev_exit_ready +}; + +static const struct vcd_dev_state_table vcd_dev_table_in_invalid = { + { + NULL, + vcd_term_in_invalid, + NULL, + vcd_close_in_dev_invalid, + NULL, + NULL, + NULL, + NULL, + }, + vcd_dev_enter_invalid, + vcd_dev_exit_invalid +}; + +static const struct vcd_dev_state_table *vcd_dev_state_table[] = { + &vcd_dev_table_null, + &vcd_dev_table_not_init, + &vcd_dev_table_initing, + &vcd_dev_table_ready, + &vcd_dev_table_in_invalid +}; diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h new file mode 100644 index 0000000000000000000000000000000000000000..898f284bee8e3978d000ff9d66522024848eb4e0 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h @@ -0,0 +1,96 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_DEVICE_SM_H_ +#define _VCD_DEVICE_SM_H_ + +#include +#include "vcd_ddl_api.h" +#include "vcd_core.h" + +struct vcd_dev_state_table; +struct vcd_dev_state_ctxt; +struct vcd_drv_ctxt; + +enum vcd_dev_state_enum { + VCD_DEVICE_STATE_NULL = 0, + VCD_DEVICE_STATE_NOT_INIT, + VCD_DEVICE_STATE_INITING, + VCD_DEVICE_STATE_READY, + VCD_DEVICE_STATE_INVALID, + VCD_DEVICE_STATE_MAX, + VCD_DEVICE_STATE_32BIT = 0x7FFFFFFF +}; + +struct vcd_dev_state_table { + struct { + u32(*init) (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_init_config *config, + s32 *driver_handle); + + u32(*term) (struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle); + + u32(*open) (struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle, u32 decoding, + void (*callback) (u32 event, u32 status, + void *info, size_t sz, void *handle, + void *const client_data), + void *client_data); + + u32(*close) (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_clnt_ctxt *cctxt); + + u32(*resume) (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_clnt_ctxt *cctxt); + + u32(*set_dev_pwr) (struct vcd_drv_ctxt *drv_ctxt, + enum vcd_power_state pwr_state); + + void (*dev_cb) (struct vcd_drv_ctxt *drv_ctxt, + u32 event, u32 status, void *payload, + size_t sz, u32 *ddl_handle, + void *const client_data); + + void (*timeout) (struct vcd_drv_ctxt *drv_ctxt, + void *user_data); + } ev_hdlr; + + void (*entry) (struct vcd_drv_ctxt *drv_ctxt, + s32 state_event); + void (*exit) (struct vcd_drv_ctxt *drv_ctxt, + s32 state_event); +}; + +#define DEVICE_STATE_EVENT_NUMBER(ppf) \ + ((u32 *) (&(((struct vcd_dev_state_table*)0)->ev_hdlr.ppf)) - \ + (u32 *) (&(((struct vcd_dev_state_table*)0)->ev_hdlr.init)) \ + + 1) + +struct vcd_dev_state_ctxt { + const struct vcd_dev_state_table *state_table; + + enum vcd_dev_state_enum state; +}; + +struct vcd_drv_ctxt { + struct vcd_dev_state_ctxt dev_state; + struct vcd_dev_ctxt dev_ctxt; + struct mutex dev_mutex; +}; + + +extern struct vcd_drv_ctxt *vcd_get_drv_context(void); + +void vcd_continue(void); + +#endif diff --git a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c new file mode 100644 index 0000000000000000000000000000000000000000..c69cff3c283a3276003bb78c82cf5b60be26da1f --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c @@ -0,0 +1,366 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "vcd_power_sm.h" +#include "vcd_core.h" +#include "vcd.h" + +u32 vcd_power_event( + struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt, u32 event) +{ + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_MED("Device power state = %d", dev_ctxt->pwr_clk_state); + VCD_MSG_MED("event = 0x%x", event); + switch (event) { + + case VCD_EVT_PWR_DEV_INIT_BEGIN: + case VCD_EVT_PWR_DEV_INIT_END: + case VCD_EVT_PWR_DEV_INIT_FAIL: + case VCD_EVT_PWR_DEV_TERM_BEGIN: + case VCD_EVT_PWR_DEV_TERM_END: + case VCD_EVT_PWR_DEV_TERM_FAIL: + case VCD_EVT_PWR_DEV_SLEEP_BEGIN: + case VCD_EVT_PWR_DEV_SLEEP_END: + case VCD_EVT_PWR_DEV_SET_PERFLVL: + case VCD_EVT_PWR_DEV_HWTIMEOUT: + { + rc = vcd_device_power_event(dev_ctxt, event, + cctxt); + break; + } + + case VCD_EVT_PWR_CLNT_CMD_BEGIN: + case VCD_EVT_PWR_CLNT_CMD_END: + case VCD_EVT_PWR_CLNT_CMD_FAIL: + case VCD_EVT_PWR_CLNT_PAUSE: + case VCD_EVT_PWR_CLNT_RESUME: + case VCD_EVT_PWR_CLNT_FIRST_FRAME: + case VCD_EVT_PWR_CLNT_LAST_FRAME: + case VCD_EVT_PWR_CLNT_ERRFATAL: + { + rc = vcd_client_power_event(dev_ctxt, cctxt, event); + break; + } + + } + + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("vcd_power_event: event 0x%x failed", event); + + + return rc; + +} + +u32 vcd_device_power_event(struct vcd_dev_ctxt *dev_ctxt, u32 event, + struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_ERR_FAIL; + u32 set_perf_lvl; + + switch (event) { + + case VCD_EVT_PWR_DEV_INIT_BEGIN: + { + if (dev_ctxt->pwr_clk_state == + VCD_PWRCLK_STATE_OFF) { + if (res_trk_get_max_perf_level(&dev_ctxt-> + max_perf_lvl)) { + if (res_trk_power_up()) { + dev_ctxt->pwr_clk_state = + VCD_PWRCLK_STATE_ON_NOTCLOCKED; + dev_ctxt->curr_perf_lvl = 0; + dev_ctxt->reqd_perf_lvl = 0; + dev_ctxt->active_clnts = 0; + dev_ctxt-> + set_perf_lvl_pending = false; + rc = vcd_enable_clock(dev_ctxt, + cctxt); + if (VCD_FAILED(rc)) { + (void)res_trk_power_down(); + dev_ctxt->pwr_clk_state = + VCD_PWRCLK_STATE_OFF; + } + } + } + } + + break; + } + + case VCD_EVT_PWR_DEV_INIT_END: + case VCD_EVT_PWR_DEV_TERM_FAIL: + case VCD_EVT_PWR_DEV_SLEEP_BEGIN: + case VCD_EVT_PWR_DEV_HWTIMEOUT: + { + rc = vcd_gate_clock(dev_ctxt); + + break; + } + + case VCD_EVT_PWR_DEV_INIT_FAIL: + case VCD_EVT_PWR_DEV_TERM_END: + { + if (dev_ctxt->pwr_clk_state != + VCD_PWRCLK_STATE_OFF) { + (void)vcd_disable_clock(dev_ctxt); + (void)res_trk_power_down(); + + dev_ctxt->pwr_clk_state = + VCD_PWRCLK_STATE_OFF; + dev_ctxt->curr_perf_lvl = 0; + dev_ctxt->reqd_perf_lvl = 0; + dev_ctxt->active_clnts = 0; + dev_ctxt->set_perf_lvl_pending = false; + rc = VCD_S_SUCCESS; + } + + break; + } + + case VCD_EVT_PWR_DEV_TERM_BEGIN: + case VCD_EVT_PWR_DEV_SLEEP_END: + { + rc = vcd_un_gate_clock(dev_ctxt); + + break; + } + + case VCD_EVT_PWR_DEV_SET_PERFLVL: + { + set_perf_lvl = + dev_ctxt->reqd_perf_lvl > + 0 ? dev_ctxt-> + reqd_perf_lvl : VCD_MIN_PERF_LEVEL; + rc = vcd_set_perf_level(dev_ctxt, set_perf_lvl); + break; + } + } + return rc; +} + +u32 vcd_client_power_event( + struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt, u32 event) +{ + u32 rc = VCD_ERR_FAIL; + + switch (event) { + + case VCD_EVT_PWR_CLNT_CMD_BEGIN: + { + rc = vcd_un_gate_clock(dev_ctxt); + break; + } + + case VCD_EVT_PWR_CLNT_CMD_END: + { + rc = vcd_gate_clock(dev_ctxt); + break; + } + + case VCD_EVT_PWR_CLNT_CMD_FAIL: + { + if (!vcd_core_is_busy(dev_ctxt)) + rc = vcd_gate_clock(dev_ctxt); + + break; + } + + case VCD_EVT_PWR_CLNT_PAUSE: + case VCD_EVT_PWR_CLNT_LAST_FRAME: + case VCD_EVT_PWR_CLNT_ERRFATAL: + { + if (cctxt) { + rc = VCD_S_SUCCESS; + if (cctxt->status.req_perf_lvl) { + dev_ctxt->reqd_perf_lvl -= + cctxt->reqd_perf_lvl; + cctxt->status.req_perf_lvl = false; + rc = vcd_set_perf_level(dev_ctxt, + dev_ctxt->reqd_perf_lvl); + } + } + + break; + } + + case VCD_EVT_PWR_CLNT_RESUME: + case VCD_EVT_PWR_CLNT_FIRST_FRAME: + { + if (cctxt) { + rc = VCD_S_SUCCESS; + if (!cctxt->status.req_perf_lvl) { + dev_ctxt->reqd_perf_lvl += + cctxt->reqd_perf_lvl; + cctxt->status.req_perf_lvl = true; + + rc = vcd_set_perf_level(dev_ctxt, + dev_ctxt->reqd_perf_lvl); + } + } + break; + } + } + + return rc; +} + +u32 vcd_enable_clock(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + u32 set_perf_lvl; + + if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_OFF) { + VCD_MSG_ERROR("vcd_enable_clock(): Already in state " + "VCD_PWRCLK_STATE_OFF\n"); + rc = VCD_ERR_FAIL; + } else if (dev_ctxt->pwr_clk_state == + VCD_PWRCLK_STATE_ON_NOTCLOCKED) { + set_perf_lvl = + dev_ctxt->reqd_perf_lvl > + 0 ? dev_ctxt-> + reqd_perf_lvl : VCD_MIN_PERF_LEVEL; + rc = vcd_set_perf_level(dev_ctxt, set_perf_lvl); + if (!VCD_FAILED(rc)) { + if (res_trk_enable_clocks()) { + dev_ctxt->pwr_clk_state = + VCD_PWRCLK_STATE_ON_CLOCKED; + } + } else { + rc = VCD_ERR_FAIL; + } + + } + + if (!VCD_FAILED(rc)) + dev_ctxt->active_clnts++; + + return rc; +} + +u32 vcd_disable_clock(struct vcd_dev_ctxt *dev_ctxt) +{ + u32 rc = VCD_S_SUCCESS; + + if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_OFF) { + VCD_MSG_ERROR("vcd_disable_clock(): Already in state " + "VCD_PWRCLK_STATE_OFF\n"); + rc = VCD_ERR_FAIL; + } else if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_CLOCKED || + dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_CLOCKGATED) { + dev_ctxt->active_clnts--; + + if (!dev_ctxt->active_clnts) { + if (!res_trk_disable_clocks()) + rc = VCD_ERR_FAIL; + + dev_ctxt->pwr_clk_state = + VCD_PWRCLK_STATE_ON_NOTCLOCKED; + dev_ctxt->curr_perf_lvl = 0; + } + } + + return rc; +} + +u32 vcd_set_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_lvl) +{ + u32 rc = VCD_S_SUCCESS; + if (!vcd_core_is_busy(dev_ctxt)) { + if (res_trk_set_perf_level(perf_lvl, + &dev_ctxt->curr_perf_lvl, dev_ctxt)) { + dev_ctxt->set_perf_lvl_pending = false; + } else { + rc = VCD_ERR_FAIL; + dev_ctxt->set_perf_lvl_pending = true; + } + + } else { + dev_ctxt->set_perf_lvl_pending = true; + } + + return rc; +} + +u32 vcd_update_decoder_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_lvl) +{ + u32 rc = VCD_S_SUCCESS; + + if (res_trk_set_perf_level(perf_lvl, + &dev_ctxt->curr_perf_lvl, dev_ctxt)) { + dev_ctxt->set_perf_lvl_pending = false; + } else { + rc = VCD_ERR_FAIL; + dev_ctxt->set_perf_lvl_pending = true; + } + + return rc; +} + +u32 vcd_update_clnt_perf_lvl( + struct vcd_clnt_ctxt *cctxt, + struct vcd_property_frame_rate *fps, u32 frm_p_units) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 new_perf_lvl; + new_perf_lvl = frm_p_units *\ + (fps->fps_numerator / fps->fps_denominator); + if (cctxt->status.req_perf_lvl) { + dev_ctxt->reqd_perf_lvl = + dev_ctxt->reqd_perf_lvl - cctxt->reqd_perf_lvl + + new_perf_lvl; + rc = vcd_set_perf_level(cctxt->dev_ctxt, + dev_ctxt->reqd_perf_lvl); + } + cctxt->reqd_perf_lvl = new_perf_lvl; + return rc; +} + +u32 vcd_gate_clock(struct vcd_dev_ctxt *dev_ctxt) +{ + u32 rc = VCD_S_SUCCESS; + if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_OFF || + dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_NOTCLOCKED) { + VCD_MSG_ERROR("%s(): Clk is Off or Not Clked yet\n", __func__); + rc = VCD_ERR_FAIL; + } else if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_CLOCKGATED) + rc = VCD_S_SUCCESS; + else if (res_trk_disable_clocks()) + dev_ctxt->pwr_clk_state = VCD_PWRCLK_STATE_ON_CLOCKGATED; + else + rc = VCD_ERR_FAIL; + return rc; +} + +u32 vcd_un_gate_clock(struct vcd_dev_ctxt *dev_ctxt) +{ + u32 rc = VCD_S_SUCCESS; + if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_OFF || + dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_NOTCLOCKED) { + VCD_MSG_ERROR("%s(): Clk is Off or Not Clked yet\n", __func__); + rc = VCD_ERR_FAIL; + } else if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_CLOCKED) + rc = VCD_S_SUCCESS; + else if (res_trk_enable_clocks()) + dev_ctxt->pwr_clk_state = VCD_PWRCLK_STATE_ON_CLOCKED; + else + rc = VCD_ERR_FAIL; + return rc; +} + diff --git a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h new file mode 100644 index 0000000000000000000000000000000000000000..aecbc8d58f283536c99e42920146f306da399c39 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h @@ -0,0 +1,43 @@ +/* Copyright (c) 2010, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_POWERSM_H_ +#define _VCD_POWERSM_H_ + +#define VCD_EVT_PWR_BASE 0x5000 +#define VCD_EVT_PWR_DEV_INIT_BEGIN (VCD_EVT_PWR_BASE + 0x1) +#define VCD_EVT_PWR_DEV_INIT_END (VCD_EVT_PWR_BASE + 0x2) +#define VCD_EVT_PWR_DEV_INIT_FAIL (VCD_EVT_PWR_BASE + 0x3) +#define VCD_EVT_PWR_DEV_TERM_BEGIN (VCD_EVT_PWR_BASE + 0x4) +#define VCD_EVT_PWR_DEV_TERM_END (VCD_EVT_PWR_BASE + 0x5) +#define VCD_EVT_PWR_DEV_TERM_FAIL (VCD_EVT_PWR_BASE + 0x6) +#define VCD_EVT_PWR_DEV_SLEEP_BEGIN (VCD_EVT_PWR_BASE + 0x7) +#define VCD_EVT_PWR_DEV_SLEEP_END (VCD_EVT_PWR_BASE + 0x8) +#define VCD_EVT_PWR_DEV_SET_PERFLVL (VCD_EVT_PWR_BASE + 0x9) +#define VCD_EVT_PWR_DEV_HWTIMEOUT (VCD_EVT_PWR_BASE + 0xa) +#define VCD_EVT_PWR_CLNT_CMD_BEGIN (VCD_EVT_PWR_BASE + 0xb) +#define VCD_EVT_PWR_CLNT_CMD_END (VCD_EVT_PWR_BASE + 0xc) +#define VCD_EVT_PWR_CLNT_CMD_FAIL (VCD_EVT_PWR_BASE + 0xd) +#define VCD_EVT_PWR_CLNT_PAUSE (VCD_EVT_PWR_BASE + 0xe) +#define VCD_EVT_PWR_CLNT_RESUME (VCD_EVT_PWR_BASE + 0xf) +#define VCD_EVT_PWR_CLNT_FIRST_FRAME (VCD_EVT_PWR_BASE + 0x10) +#define VCD_EVT_PWR_CLNT_LAST_FRAME (VCD_EVT_PWR_BASE + 0x11) +#define VCD_EVT_PWR_CLNT_ERRFATAL (VCD_EVT_PWR_BASE + 0x12) + +enum vcd_pwr_clk_state { + VCD_PWRCLK_STATE_OFF = 0, + VCD_PWRCLK_STATE_ON_NOTCLOCKED, + VCD_PWRCLK_STATE_ON_CLOCKED, + VCD_PWRCLK_STATE_ON_CLOCKGATED +}; + +#endif diff --git a/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c new file mode 100644 index 0000000000000000000000000000000000000000..e3924143962a72fb9a9d55ec4166a6904497c225 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c @@ -0,0 +1,287 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "vcd.h" + +#define NORMALIZATION_FACTOR 3600 +#define ADJUST_CLIENT_ROUNDS(client, round_adjustment) \ +do {\ + if ((client)->rounds < round_adjustment) {\ + (client)->rounds = 0;\ + VCD_MSG_HIGH("%s(): WARNING: Scheduler list unsorted",\ + __func__);\ + } else\ + (client)->rounds -= round_adjustment;\ +} while (0) + +u32 vcd_sched_create(struct list_head *sched_list) +{ + u32 rc = VCD_S_SUCCESS; + if (!sched_list) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else + INIT_LIST_HEAD(sched_list); + return rc; +} + +void vcd_sched_destroy(struct list_head *sched_clnt_list) +{ + struct vcd_sched_clnt_ctx *sched_clnt, *sched_clnt_next; + if (sched_clnt_list) + list_for_each_entry_safe(sched_clnt, + sched_clnt_next, sched_clnt_list, list) { + list_del_init(&sched_clnt->list); + sched_clnt->clnt_active = false; + } +} + +void insert_client_in_list(struct list_head *sched_clnt_list, + struct vcd_sched_clnt_ctx *sched_new_clnt, bool tail) +{ + struct vcd_sched_clnt_ctx *sched_clnt; + if (!list_empty(sched_clnt_list)) { + if (tail) + sched_clnt = list_entry(sched_clnt_list->prev, + struct vcd_sched_clnt_ctx, list); + else + sched_clnt = list_first_entry(sched_clnt_list, + struct vcd_sched_clnt_ctx, list); + sched_new_clnt->rounds = sched_clnt->rounds; + } else + sched_new_clnt->rounds = 0; + if (tail) + list_add_tail(&sched_new_clnt->list, sched_clnt_list); + else + list_add(&sched_new_clnt->list, sched_clnt_list); +} + +u32 vcd_sched_add_client(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_property_hdr prop_hdr; + struct vcd_sched_clnt_ctx *sched_cctxt; + u32 rc = VCD_S_SUCCESS; + if (!cctxt) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else if (cctxt->sched_clnt_hdl) + VCD_MSG_HIGH( + "%s(): Scheduler client already exists!", __func__); + else { + sched_cctxt = (struct vcd_sched_clnt_ctx *) + kmalloc(sizeof(struct vcd_sched_clnt_ctx), + GFP_KERNEL); + if (sched_cctxt) { + + prop_hdr.prop_id = DDL_I_FRAME_PROC_UNITS; + prop_hdr.sz = sizeof(cctxt->frm_p_units); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, + &cctxt->frm_p_units); + VCD_FAILED_RETURN(rc, + "Failed: Get DDL_I_FRAME_PROC_UNITS"); + if (cctxt->decoding) { + cctxt->frm_rate.fps_numerator = + VCD_DEC_INITIAL_FRAME_RATE; + cctxt->frm_rate.fps_denominator = 1; + } else { + prop_hdr.prop_id = VCD_I_FRAME_RATE; + prop_hdr.sz = sizeof(cctxt->frm_rate); + rc = ddl_get_property(cctxt->ddl_handle, + &prop_hdr, &cctxt->frm_rate); + VCD_FAILED_RETURN(rc, + "Failed: Get VCD_I_FRAME_RATE"); + } + if (!cctxt->perf_set_by_client) + cctxt->reqd_perf_lvl = cctxt->frm_p_units * + cctxt->frm_rate.fps_numerator / + cctxt->frm_rate.fps_denominator; + + cctxt->sched_clnt_hdl = sched_cctxt; + memset(sched_cctxt, 0, + sizeof(struct vcd_sched_clnt_ctx)); + sched_cctxt->tkns = 0; + sched_cctxt->round_perfrm = NORMALIZATION_FACTOR * + cctxt->frm_rate.fps_denominator / + cctxt->frm_rate.fps_numerator; + sched_cctxt->clnt_active = true; + sched_cctxt->clnt_data = cctxt; + INIT_LIST_HEAD(&sched_cctxt->ip_frm_list); + + insert_client_in_list( + &cctxt->dev_ctxt->sched_clnt_list, + sched_cctxt, false); + } + } + return rc; +} + +u32 vcd_sched_remove_client(struct vcd_sched_clnt_ctx *sched_cctxt) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_clnt_ctxt *cctxt; + if (!sched_cctxt) { + VCD_MSG_ERROR("%s(): Invalid handle ptr", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else if (!list_empty(&sched_cctxt->ip_frm_list)) { + VCD_MSG_ERROR( + "%s(): Cannot remove client, queue no empty", __func__); + rc = VCD_ERR_ILLEGAL_OP; + } else { + cctxt = sched_cctxt->clnt_data; + list_del(&sched_cctxt->list); + memset(sched_cctxt, 0, + sizeof(struct vcd_sched_clnt_ctx)); + kfree(sched_cctxt); + } + return rc; +} + +u32 vcd_sched_update_config(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + if (!cctxt || !cctxt->sched_clnt_hdl) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else { + cctxt->sched_clnt_hdl->rounds /= + cctxt->sched_clnt_hdl->round_perfrm; + cctxt->sched_clnt_hdl->round_perfrm = + NORMALIZATION_FACTOR * + cctxt->frm_rate.fps_denominator / + cctxt->frm_rate.fps_numerator; + cctxt->sched_clnt_hdl->rounds *= + cctxt->sched_clnt_hdl->round_perfrm; + } + return rc; +} + +u32 vcd_sched_queue_buffer( + struct vcd_sched_clnt_ctx *sched_cctxt, + struct vcd_buffer_entry *buffer, u32 tail) +{ + u32 rc = VCD_S_SUCCESS; + if (!sched_cctxt || !buffer) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else if (tail) + list_add_tail(&buffer->sched_list, + &sched_cctxt->ip_frm_list); + else + list_add(&buffer->sched_list, &sched_cctxt->ip_frm_list); + return rc; +} + +u32 vcd_sched_dequeue_buffer( + struct vcd_sched_clnt_ctx *sched_cctxt, + struct vcd_buffer_entry **buffer) +{ + u32 rc = VCD_ERR_QEMPTY; + if (!sched_cctxt || !buffer) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else { + *buffer = NULL; + if (!list_empty(&sched_cctxt->ip_frm_list)) { + *buffer = list_first_entry( + &sched_cctxt->ip_frm_list, + struct vcd_buffer_entry, + sched_list); + list_del(&(*buffer)->sched_list); + rc = VCD_S_SUCCESS; + } + } + return rc; +} + +u32 vcd_sched_mark_client_eof(struct vcd_sched_clnt_ctx *sched_cctxt) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_entry *buffer = NULL; + if (!sched_cctxt) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else if (!list_empty(&sched_cctxt->ip_frm_list)) { + buffer = list_entry(sched_cctxt->ip_frm_list.prev, + struct vcd_buffer_entry, sched_list); + buffer->frame.flags |= VCD_FRAME_FLAG_EOS; + } else + rc = VCD_ERR_QEMPTY; + return rc; +} + +u32 vcd_sched_suspend_resume_clnt( + struct vcd_clnt_ctxt *cctxt, u32 state) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_sched_clnt_ctx *sched_cctxt; + if (!cctxt || !cctxt->sched_clnt_hdl) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else { + sched_cctxt = cctxt->sched_clnt_hdl; + if (state != sched_cctxt->clnt_active) { + sched_cctxt->clnt_active = state; + if (state) + insert_client_in_list(&cctxt->dev_ctxt->\ + sched_clnt_list, sched_cctxt, false); + else + list_del_init(&sched_cctxt->list); + } + } + return rc; +} + +u32 vcd_sched_get_client_frame(struct list_head *sched_clnt_list, + struct vcd_clnt_ctxt **cctxt, + struct vcd_buffer_entry **buffer) +{ + u32 rc = VCD_ERR_QEMPTY, round_adjustment = 0; + struct vcd_sched_clnt_ctx *sched_clnt, *clnt_nxt; + if (!sched_clnt_list || !cctxt || !buffer) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else if (!list_empty(sched_clnt_list)) { + *cctxt = NULL; + *buffer = NULL; + list_for_each_entry_safe(sched_clnt, + clnt_nxt, sched_clnt_list, list) { + if (&sched_clnt->list == sched_clnt_list->next) + round_adjustment = sched_clnt->rounds; + if (*cctxt) { + if ((*cctxt)->sched_clnt_hdl->rounds >= + sched_clnt->rounds) + list_move(&(*cctxt)->sched_clnt_hdl\ + ->list, &sched_clnt->list); + ADJUST_CLIENT_ROUNDS(sched_clnt, + round_adjustment); + } else if (sched_clnt->tkns && + !list_empty(&sched_clnt->ip_frm_list)) { + *cctxt = sched_clnt->clnt_data; + sched_clnt->rounds += sched_clnt->round_perfrm; + } else + ADJUST_CLIENT_ROUNDS(sched_clnt, + round_adjustment); + } + if (*cctxt) { + rc = vcd_sched_dequeue_buffer( + (*cctxt)->sched_clnt_hdl, buffer); + if (rc == VCD_S_SUCCESS) { + (*cctxt)->sched_clnt_hdl->tkns--; + ADJUST_CLIENT_ROUNDS((*cctxt)->\ + sched_clnt_hdl, round_adjustment); + } + } + } + return rc; +} diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c new file mode 100644 index 0000000000000000000000000000000000000000..9cbf7d5b92f9d95db0ed48b9d73ceb06fb42a722 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c @@ -0,0 +1,3433 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include "vcd.h" +#include "vdec_internal.h" + +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#define MAP_TABLE_SZ 64 +#define VCD_ENC_MAX_OUTBFRS_PER_FRAME 8 +#define MAX_DEC_TIME 33 + +struct vcd_msm_map_buffer { + phys_addr_t phy_addr; + struct msm_mapped_buffer *mapped_buffer; + struct ion_handle *alloc_handle; + u32 in_use; +}; +static struct vcd_msm_map_buffer msm_mapped_buffer_table[MAP_TABLE_SZ]; +static unsigned int vidc_mmu_subsystem[] = {MSM_SUBSYSTEM_VIDEO}; + +static int vcd_pmem_alloc(size_t sz, u8 **kernel_vaddr, u8 **phy_addr, + struct vcd_clnt_ctxt *cctxt) +{ + u32 memtype, i = 0, flags = 0; + struct vcd_msm_map_buffer *map_buffer = NULL; + struct msm_mapped_buffer *mapped_buffer = NULL; + unsigned long iova = 0; + unsigned long buffer_size = 0; + int ret = 0; + unsigned long ionflag = 0; + + if (!kernel_vaddr || !phy_addr || !cctxt) { + pr_err("\n%s: Invalid parameters", __func__); + goto bailout; + } + *phy_addr = NULL; + *kernel_vaddr = NULL; + for (i = 0; i < MAP_TABLE_SZ; i++) { + if (!msm_mapped_buffer_table[i].in_use) { + map_buffer = &msm_mapped_buffer_table[i]; + map_buffer->in_use = 1; + break; + } + } + if (!map_buffer) { + pr_err("%s() map table is full", __func__); + goto bailout; + } + res_trk_set_mem_type(DDL_MM_MEM); + memtype = res_trk_get_mem_type(); + if (!cctxt->vcd_enable_ion) { + map_buffer->phy_addr = (phys_addr_t) + allocate_contiguous_memory_nomap(sz, memtype, SZ_4K); + if (!map_buffer->phy_addr) { + pr_err("%s() acm alloc failed", __func__); + goto free_map_table; + } + flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR; + map_buffer->mapped_buffer = + msm_subsystem_map_buffer((unsigned long)map_buffer->phy_addr, + sz, flags, vidc_mmu_subsystem, + sizeof(vidc_mmu_subsystem)/sizeof(unsigned int)); + if (IS_ERR(map_buffer->mapped_buffer)) { + pr_err(" %s() buffer map failed", __func__); + goto free_acm_alloc; + } + mapped_buffer = map_buffer->mapped_buffer; + if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) { + pr_err("%s() map buffers failed", __func__); + goto free_map_buffers; + } + *phy_addr = (u8 *) mapped_buffer->iova[0]; + *kernel_vaddr = (u8 *) mapped_buffer->vaddr; + } else { + map_buffer->alloc_handle = ion_alloc( + cctxt->vcd_ion_client, sz, SZ_4K, + memtype); + if (!map_buffer->alloc_handle) { + pr_err("%s() ION alloc failed", __func__); + goto bailout; + } + if (ion_handle_get_flags(cctxt->vcd_ion_client, + map_buffer->alloc_handle, + &ionflag)) { + pr_err("%s() ION get flag failed", __func__); + goto bailout; + } + *kernel_vaddr = (u8 *) ion_map_kernel( + cctxt->vcd_ion_client, + map_buffer->alloc_handle, + ionflag); + if (!(*kernel_vaddr)) { + pr_err("%s() ION map failed", __func__); + goto ion_free_bailout; + } + ret = ion_map_iommu(cctxt->vcd_ion_client, + map_buffer->alloc_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL, + SZ_4K, + 0, + (unsigned long *)&iova, + (unsigned long *)&buffer_size, + UNCACHED, 0); + if (ret) { + pr_err("%s() ION iommu map failed", __func__); + goto ion_map_bailout; + } + map_buffer->phy_addr = iova; + if (!map_buffer->phy_addr) { + pr_err("%s() acm alloc failed", __func__); + goto free_map_table; + } + *phy_addr = (u8 *)iova; + mapped_buffer = NULL; + map_buffer->mapped_buffer = NULL; + } + + return 0; + +free_map_buffers: + if (map_buffer->mapped_buffer) + msm_subsystem_unmap_buffer(map_buffer->mapped_buffer); +free_acm_alloc: + if (!cctxt->vcd_enable_ion) { + free_contiguous_memory_by_paddr( + (unsigned long)map_buffer->phy_addr); + } + return -ENOMEM; +ion_map_bailout: + ion_unmap_kernel(cctxt->vcd_ion_client, map_buffer->alloc_handle); +ion_free_bailout: + ion_free(cctxt->vcd_ion_client, map_buffer->alloc_handle); +free_map_table: + map_buffer->in_use = 0; +bailout: + return -ENOMEM; +} + +static int vcd_pmem_free(u8 *kernel_vaddr, u8 *phy_addr, + struct vcd_clnt_ctxt *cctxt) +{ + u32 i = 0; + struct vcd_msm_map_buffer *map_buffer = NULL; + + if (!kernel_vaddr || !phy_addr || !cctxt) { + pr_err("\n%s: Invalid parameters", __func__); + goto bailout; + } + for (i = 0; i < MAP_TABLE_SZ; i++) { + if (msm_mapped_buffer_table[i].in_use && + (msm_mapped_buffer_table[i] + .mapped_buffer->vaddr == kernel_vaddr)) { + map_buffer = &msm_mapped_buffer_table[i]; + map_buffer->in_use = 0; + break; + } + } + if (!map_buffer) { + pr_err("%s() Entry not found", __func__); + goto bailout; + } + if (map_buffer->mapped_buffer) + msm_subsystem_unmap_buffer(map_buffer->mapped_buffer); + if (cctxt->vcd_enable_ion) { + if (map_buffer->alloc_handle) { + ion_unmap_kernel(cctxt->vcd_ion_client, + map_buffer->alloc_handle); + ion_unmap_iommu(cctxt->vcd_ion_client, + map_buffer->alloc_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + ion_free(cctxt->vcd_ion_client, + map_buffer->alloc_handle); + } + } else { + free_contiguous_memory_by_paddr( + (unsigned long)map_buffer->phy_addr); + } +bailout: + kernel_vaddr = NULL; + phy_addr = NULL; + return 0; +} + + +u8 *vcd_pmem_get_physical(struct video_client_ctx *client_ctx, + unsigned long kernel_vaddr) +{ + unsigned long phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT, + false, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + return (u8 *) phy_addr; + } else if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, + false, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file, + &buffer_index)) { + return (u8 *) phy_addr; + } else { + VCD_MSG_ERROR("Couldn't get physical address"); + + return NULL; + } + +} + +u32 vcd_get_ion_flag(struct video_client_ctx *client_ctx, + unsigned long kernel_vaddr, + struct ion_handle **buff_ion_handle) +{ + unsigned long phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + u32 ion_flag = 0; + struct ion_handle *buff_handle = NULL; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT, + false, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_INPUT, + pmem_fd, kernel_vaddr, buffer_index, + &buff_handle); + *buff_ion_handle = buff_handle; + return ion_flag; + } else if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, + false, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file, + &buffer_index)) { + ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT, + pmem_fd, kernel_vaddr, buffer_index, + &buff_handle); + *buff_ion_handle = buff_handle; + return ion_flag; + } else { + VCD_MSG_ERROR("Couldn't get ion flag"); + return 0; + } + +} + +void vcd_reset_device_channels(struct vcd_dev_ctxt *dev_ctxt) +{ + dev_ctxt->ddl_frame_ch_free = dev_ctxt->ddl_frame_ch_depth; + dev_ctxt->ddl_cmd_ch_free = dev_ctxt->ddl_cmd_ch_depth; + dev_ctxt->ddl_frame_ch_interim = 0; + dev_ctxt->ddl_cmd_ch_interim = 0; +} + +u32 vcd_get_command_channel( + struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc **transc) +{ + u32 result = false; + + *transc = NULL; + + if (dev_ctxt->ddl_cmd_ch_free > 0) { + if (dev_ctxt->ddl_cmd_concurrency) { + --dev_ctxt->ddl_cmd_ch_free; + result = true; + } else if ((dev_ctxt->ddl_frame_ch_free + + dev_ctxt->ddl_frame_ch_interim) + == dev_ctxt->ddl_frame_ch_depth) { + --dev_ctxt->ddl_cmd_ch_free; + result = true; + } + } + + if (result) { + *transc = vcd_get_free_trans_tbl_entry(dev_ctxt); + + if (!*transc) { + result = false; + + vcd_release_command_channel(dev_ctxt, *transc); + } + + } + return result; +} + +u32 vcd_get_command_channel_in_loop( + struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc **transc) +{ + u32 result = false; + + *transc = NULL; + + if (dev_ctxt->ddl_cmd_ch_interim > 0) { + if (dev_ctxt->ddl_cmd_concurrency) { + --dev_ctxt->ddl_cmd_ch_interim; + result = true; + } else if ((dev_ctxt->ddl_frame_ch_free + + dev_ctxt->ddl_frame_ch_interim) + == dev_ctxt->ddl_frame_ch_depth) { + --dev_ctxt->ddl_cmd_ch_interim; + result = true; + } + } else { + result = vcd_get_command_channel(dev_ctxt, transc); + } + + if (result && !*transc) { + *transc = vcd_get_free_trans_tbl_entry(dev_ctxt); + + if (!*transc) { + result = false; + + ++dev_ctxt->ddl_cmd_ch_interim; + } + + } + + return result; +} + +void vcd_mark_command_channel(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc *transc) +{ + ++dev_ctxt->ddl_cmd_ch_interim; + + vcd_release_trans_tbl_entry(transc); + if (dev_ctxt->ddl_cmd_ch_interim + + dev_ctxt->ddl_cmd_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_ERROR("\n Command channel access counters messed up"); + } +} + +void vcd_release_command_channel( + struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc) +{ + ++dev_ctxt->ddl_cmd_ch_free; + + vcd_release_trans_tbl_entry(transc); + if (dev_ctxt->ddl_cmd_ch_interim + dev_ctxt->ddl_cmd_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_ERROR("\n Command channel access counters messed up"); + } +} + +void vcd_release_multiple_command_channels(struct vcd_dev_ctxt + *dev_ctxt, u32 channels) +{ + dev_ctxt->ddl_cmd_ch_free += channels; + + if (dev_ctxt->ddl_cmd_ch_interim + + dev_ctxt->ddl_cmd_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_ERROR("\n Command channel access counters messed up"); + } +} + +void vcd_release_interim_command_channels(struct vcd_dev_ctxt *dev_ctxt) +{ + dev_ctxt->ddl_cmd_ch_free += dev_ctxt->ddl_cmd_ch_interim; + dev_ctxt->ddl_cmd_ch_interim = 0; + + if (dev_ctxt->ddl_cmd_ch_interim + dev_ctxt->ddl_cmd_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_ERROR("\n Command channel access counters messed up"); + } +} + +u32 vcd_get_frame_channel(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc **transc) +{ + u32 result = false; + + if (dev_ctxt->ddl_frame_ch_free > 0) { + if (dev_ctxt->ddl_cmd_concurrency) { + --dev_ctxt->ddl_frame_ch_free; + result = true; + } else if ((dev_ctxt->ddl_cmd_ch_free + + dev_ctxt->ddl_cmd_ch_interim) + == dev_ctxt->ddl_cmd_ch_depth) { + --dev_ctxt->ddl_frame_ch_free; + result = true; + } + } + + if (result) { + *transc = vcd_get_free_trans_tbl_entry(dev_ctxt); + + if (!*transc) { + result = false; + + vcd_release_frame_channel(dev_ctxt, *transc); + } else { + (*transc)->type = VCD_CMD_CODE_FRAME; + } + + } + + return result; +} + +u32 vcd_get_frame_channel_in_loop( + struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc **transc) +{ + u32 result = false; + + *transc = NULL; + + if (dev_ctxt->ddl_frame_ch_interim > 0) { + if (dev_ctxt->ddl_cmd_concurrency) { + --dev_ctxt->ddl_frame_ch_interim; + result = true; + } else if ((dev_ctxt->ddl_cmd_ch_free + + dev_ctxt->ddl_cmd_ch_interim) + == dev_ctxt->ddl_cmd_ch_depth) { + --dev_ctxt->ddl_frame_ch_interim; + result = true; + } + } else { + result = vcd_get_frame_channel(dev_ctxt, transc); + } + + if (result && !*transc) { + *transc = vcd_get_free_trans_tbl_entry(dev_ctxt); + + if (!*transc) { + result = false; + VCD_MSG_FATAL("\n%s: All transactions are busy;" + "Couldnt find free one\n", __func__); + ++dev_ctxt->ddl_frame_ch_interim; + } else + (*transc)->type = VCD_CMD_CODE_FRAME; + } + + return result; +} + +void vcd_mark_frame_channel(struct vcd_dev_ctxt *dev_ctxt) +{ + ++dev_ctxt->ddl_frame_ch_interim; + + if (dev_ctxt->ddl_frame_ch_interim + + dev_ctxt->ddl_frame_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_FATAL("Frame channel access counters messed up"); + } +} + +void vcd_release_frame_channel(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc *transc) +{ + ++dev_ctxt->ddl_frame_ch_free; + + vcd_release_trans_tbl_entry(transc); + + if (dev_ctxt->ddl_frame_ch_interim + + dev_ctxt->ddl_frame_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_FATAL("Frame channel access counters messed up"); + } +} + +void vcd_release_multiple_frame_channels(struct vcd_dev_ctxt + *dev_ctxt, u32 channels) +{ + dev_ctxt->ddl_frame_ch_free += channels; + + if (dev_ctxt->ddl_frame_ch_interim + + dev_ctxt->ddl_frame_ch_free > + dev_ctxt->ddl_frame_ch_depth) { + VCD_MSG_FATAL("Frame channel access counters messed up"); + } +} + +void vcd_release_interim_frame_channels(struct vcd_dev_ctxt + *dev_ctxt) +{ + dev_ctxt->ddl_frame_ch_free += + dev_ctxt->ddl_frame_ch_interim; + dev_ctxt->ddl_frame_ch_interim = 0; + + if (dev_ctxt->ddl_frame_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_FATAL("Frame channel access counters messed up"); + } +} + +u32 vcd_core_is_busy(struct vcd_dev_ctxt *dev_ctxt) +{ + if (((dev_ctxt->ddl_cmd_ch_free + + dev_ctxt->ddl_cmd_ch_interim) != + dev_ctxt->ddl_cmd_ch_depth) + || + ((dev_ctxt->ddl_frame_ch_free + + dev_ctxt->ddl_frame_ch_interim) != + dev_ctxt->ddl_frame_ch_depth) + ) { + return true; + } else { + return false; + } +} + +void vcd_device_timer_start(struct vcd_dev_ctxt *dev_ctxt) +{ + if (dev_ctxt->config.timer_start) + dev_ctxt->config.timer_start(dev_ctxt->hw_timer_handle, + dev_ctxt->hw_time_out); +} + +void vcd_device_timer_stop(struct vcd_dev_ctxt *dev_ctxt) +{ + if (dev_ctxt->config.timer_stop) + dev_ctxt->config.timer_stop(dev_ctxt->hw_timer_handle); +} + + +u32 vcd_common_allocate_set_buffer( + struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer, + u32 buf_size, struct vcd_buffer_pool **buffer_pool) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_requirement Buf_req; + struct vcd_property_hdr Prop_hdr; + struct vcd_buffer_pool *buf_pool; + + if (buffer == VCD_BUFFER_INPUT) { + Prop_hdr.prop_id = DDL_I_INPUT_BUF_REQ; + buf_pool = &cctxt->in_buf_pool; + } else if (buffer == VCD_BUFFER_OUTPUT) { + Prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ; + buf_pool = &cctxt->out_buf_pool; + } else { + rc = VCD_ERR_ILLEGAL_PARM; + } + VCD_FAILED_RETURN(rc, "Invalid buffer type provided"); + + *buffer_pool = buf_pool; + + if (buf_pool->count > 0 && + buf_pool->validated == buf_pool->count) { + VCD_MSG_ERROR("Buffer pool is full"); + return VCD_ERR_FAIL; + } + + if (!buf_pool->entries) { + Prop_hdr.sz = sizeof(Buf_req); + rc = ddl_get_property(cctxt->ddl_handle, &Prop_hdr, &Buf_req); + if (!VCD_FAILED(rc)) { + rc = vcd_alloc_buffer_pool_entries(buf_pool, + &Buf_req); + } else { + VCD_MSG_ERROR("rc = 0x%x. Failed: ddl_get_property", + rc); + } + } + + if (!VCD_FAILED(rc)) { + if (buf_pool->buf_req.sz > buf_size) { + VCD_MSG_ERROR("\n required buffer sz %u " + "allocated sz %u", buf_pool->buf_req. + sz, buf_size); + + rc = VCD_ERR_ILLEGAL_PARM; + } + } + + return rc; +} + +u32 vcd_set_buffer_internal( + struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool, u8 *buffer, u32 buf_size) +{ + struct vcd_buffer_entry *buf_entry; + u8 *physical; + u32 ion_flag = 0; + struct ion_handle *buff_handle = NULL; + + buf_entry = vcd_find_buffer_pool_entry(buf_pool, buffer); + if (buf_entry) { + VCD_MSG_ERROR("This buffer address already exists"); + + return VCD_ERR_ILLEGAL_OP; + } + + physical = (u8 *) vcd_pmem_get_physical( + cctxt->client_data, (unsigned long)buffer); + + ion_flag = vcd_get_ion_flag(cctxt->client_data, + (unsigned long)buffer, + &buff_handle); + if (!physical) { + VCD_MSG_ERROR("Couldn't get physical address"); + return VCD_ERR_BAD_POINTER; + } + if (((u32) physical % buf_pool->buf_req.align)) { + VCD_MSG_ERROR("Physical addr is not aligned"); + return VCD_ERR_BAD_POINTER; + } + + buf_entry = vcd_get_free_buffer_pool_entry(buf_pool); + if (!buf_entry) { + VCD_MSG_ERROR("Can't allocate buffer pool is full"); + return VCD_ERR_FAIL; + } + buf_entry->virtual = buffer; + buf_entry->physical = physical; + buf_entry->sz = buf_size; + buf_entry->frame.alloc_len = buf_size; + buf_entry->allocated = false; + + buf_entry->frame.virtual = buf_entry->virtual; + buf_entry->frame.physical = buf_entry->physical; + buf_entry->frame.ion_flag = ion_flag; + buf_entry->frame.buff_ion_handle = buff_handle; + + buf_pool->validated++; + + return VCD_S_SUCCESS; + +} + +u32 vcd_allocate_buffer_internal( + struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool, + u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr) +{ + struct vcd_buffer_entry *buf_entry; + struct vcd_buffer_requirement *buf_req; + u32 addr; + int rc = 0; + + buf_entry = vcd_get_free_buffer_pool_entry(buf_pool); + if (!buf_entry) { + VCD_MSG_ERROR("Can't allocate buffer pool is full"); + + return VCD_ERR_FAIL; + } + + buf_req = &buf_pool->buf_req; + + buf_size += buf_req->align; + + rc = vcd_pmem_alloc(buf_size, &buf_entry->alloc, + &buf_entry->physical, cctxt); + + if (rc < 0) { + VCD_MSG_ERROR("Buffer allocation failed"); + + return VCD_ERR_ALLOC_FAIL; + } + + buf_entry->sz = buf_size; + buf_entry->frame.alloc_len = buf_size; + + if (!buf_entry->physical) { + VCD_MSG_ERROR("Couldn't get physical address"); + + return VCD_ERR_BAD_POINTER; + } + + buf_entry->allocated = true; + + if (buf_req->align > 0) { + + addr = (u32) buf_entry->physical; + addr += buf_req->align; + addr -= (addr % buf_req->align); + buf_entry->virtual = buf_entry->alloc; + buf_entry->virtual += (u32) (addr - (u32) + buf_entry->physical); + buf_entry->physical = (u8 *) addr; + } else { + VCD_MSG_LOW("No buffer alignment required"); + + buf_entry->virtual = buf_entry->alloc; + + } + + buf_entry->frame.virtual = buf_entry->virtual; + buf_entry->frame.physical = buf_entry->physical; + + *vir_buf_addr = buf_entry->virtual; + *phy_buf_addr = buf_entry->physical; + + buf_pool->allocated++; + buf_pool->validated++; + + return VCD_S_SUCCESS; +} + +u32 vcd_free_one_buffer_internal( + struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type, u8 *buffer) +{ + struct vcd_buffer_pool *buf_pool; + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_entry *buf_entry; + u32 first_frm_recvd = 0; + + if (buffer_type == VCD_BUFFER_INPUT) { + buf_pool = &cctxt->in_buf_pool; + first_frm_recvd = VCD_FIRST_IP_RCVD; + } else if (buffer_type == VCD_BUFFER_OUTPUT) { + buf_pool = &cctxt->out_buf_pool; + first_frm_recvd = VCD_FIRST_OP_RCVD; + } else + rc = VCD_ERR_ILLEGAL_PARM; + + VCD_FAILED_RETURN(rc, "Invalid buffer type provided"); + + first_frm_recvd &= cctxt->status.mask; + if (first_frm_recvd && !cctxt->meta_mode) { + VCD_MSG_ERROR( + "VCD free buffer called when data path is active"); + return VCD_ERR_BAD_STATE; + } + + buf_entry = vcd_find_buffer_pool_entry(buf_pool, buffer); + if (!buf_entry) { + VCD_MSG_ERROR("Buffer addr %p not found. Can't free buffer", + buffer); + + return VCD_ERR_ILLEGAL_PARM; + } + if (buf_entry->in_use) { + VCD_MSG_ERROR("\n Buffer is in use and is not flushed"); + return VCD_ERR_ILLEGAL_OP; + } + + VCD_MSG_LOW("Freeing buffer %p. Allocated %d", + buf_entry->virtual, buf_entry->allocated); + + if (buf_entry->allocated) { + vcd_pmem_free(buf_entry->alloc, buf_entry->physical, cctxt); + buf_pool->allocated--; + } + + memset(buf_entry, 0, sizeof(struct vcd_buffer_entry)); + buf_pool->validated--; + if (buf_pool->validated == 0) + vcd_free_buffer_pool_entries(buf_pool); + + return VCD_S_SUCCESS; +} + +u32 vcd_free_buffers_internal( + struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool) +{ + u32 rc = VCD_S_SUCCESS; + u32 i; + + VCD_MSG_LOW("vcd_free_buffers_internal:"); + + if (buf_pool->entries) { + for (i = 1; i <= buf_pool->count; i++) { + if (buf_pool->entries[i].valid && + buf_pool->entries[i].allocated) { + vcd_pmem_free(buf_pool->entries[i].alloc, + buf_pool->entries[i]. + physical, cctxt); + } + } + + } + + vcd_reset_buffer_pool_for_reuse(buf_pool); + + return rc; +} + +u32 vcd_alloc_buffer_pool_entries( + struct vcd_buffer_pool *buf_pool, + struct vcd_buffer_requirement *buf_req) +{ + + VCD_MSG_LOW("vcd_alloc_buffer_pool_entries:"); + + buf_pool->buf_req = *buf_req; + + buf_pool->count = buf_req->actual_count; + buf_pool->entries = (struct vcd_buffer_entry *) + kzalloc((sizeof(struct vcd_buffer_entry) * + (VCD_MAX_BUFFER_ENTRIES + 1)), GFP_KERNEL); + + if (!buf_pool->entries) { + VCD_MSG_ERROR("Buf_pool entries alloc failed"); + return VCD_ERR_ALLOC_FAIL; + } + + INIT_LIST_HEAD(&buf_pool->queue); + buf_pool->entries[0].valid = true; + buf_pool->q_len = 0; + + buf_pool->validated = 0; + buf_pool->allocated = 0; + buf_pool->in_use = 0; + + return VCD_S_SUCCESS; +} + +void vcd_free_buffer_pool_entries(struct vcd_buffer_pool *buf_pool) +{ + VCD_MSG_LOW("vcd_free_buffer_pool_entries:"); + kfree(buf_pool->entries); + memset(buf_pool, 0, sizeof(struct vcd_buffer_pool)); + INIT_LIST_HEAD(&buf_pool->queue); +} + +void vcd_flush_in_use_buffer_pool_entries(struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool, u32 event) +{ + u32 i; + VCD_MSG_LOW("vcd_flush_buffer_pool_entries: event=0x%x", event); + + if (buf_pool->entries) { + for (i = 0; i <= buf_pool->count; i++) { + if (buf_pool->entries[i].virtual && + buf_pool->entries[i].in_use) { + cctxt->callback(event, VCD_S_SUCCESS, + &buf_pool->entries[i].frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + buf_pool->entries[i].in_use = false; + VCD_BUFFERPOOL_INUSE_DECREMENT( + buf_pool->in_use); + } + } + } +} + + +void vcd_reset_buffer_pool_for_reuse(struct vcd_buffer_pool *buf_pool) +{ + VCD_MSG_LOW("vcd_reset_buffer_pool_for_reuse:"); + + if (buf_pool->entries) { + memset(&buf_pool->entries[1], 0, + sizeof(struct vcd_buffer_entry) * + VCD_MAX_BUFFER_ENTRIES); + } + buf_pool->q_len = 0; + + buf_pool->validated = 0; + buf_pool->allocated = 0; + buf_pool->in_use = 0; + INIT_LIST_HEAD(&buf_pool->queue); +} + +struct vcd_buffer_entry *vcd_get_free_buffer_pool_entry + (struct vcd_buffer_pool *pool) { + u32 i; + + i = 1; + while (i <= pool->count && pool->entries[i].valid) + i++; + + + if (i <= pool->count) { + pool->entries[i].valid = true; + + return &pool->entries[i]; + } else { + return NULL; + } +} + +struct vcd_buffer_entry *vcd_find_buffer_pool_entry + (struct vcd_buffer_pool *pool, u8 *addr) +{ + u32 i; + u32 found = false; + + for (i = 0; i <= pool->count && !found; i++) { + if (pool->entries[i].virtual == addr) + found = true; + + } + + if (found) + return &pool->entries[i - 1]; + else + return NULL; + +} + +u32 vcd_buffer_pool_entry_en_q( + struct vcd_buffer_pool *pool, + struct vcd_buffer_entry *entry) +{ + struct vcd_buffer_entry *list_itr; + + if (pool->q_len == pool->count) + return false; + + list_for_each_entry(list_itr, &pool->queue, list) + if (list_itr == entry) { + VCD_MSG_HIGH("\n this output buffer is already present" + " in queue"); + VCD_MSG_HIGH("\n Vir Addr %p Phys Addr %p", + entry->virtual, entry->physical); + return false; + } + + list_add_tail(&entry->list, &pool->queue); + pool->q_len++; + + return true; +} + +struct vcd_buffer_entry *vcd_buffer_pool_entry_de_q + (struct vcd_buffer_pool *pool) { + struct vcd_buffer_entry *entry; + + if (!pool || !pool->q_len) + return NULL; + + entry = list_first_entry(&pool->queue, + struct vcd_buffer_entry, list); + + if (entry) { + list_del(&entry->list); + pool->q_len--; + } + return entry; +} + +void vcd_flush_bframe_buffers(struct vcd_clnt_ctxt *cctxt, u32 mode) +{ + int i; + struct vcd_buffer_pool *buf_pool; + + if (!cctxt->decoding && cctxt->bframe) { + buf_pool = (mode == VCD_FLUSH_INPUT) ? + &cctxt->in_buf_pool : &cctxt->out_buf_pool; + if (buf_pool->entries != NULL) { + for (i = 1; i <= buf_pool->count; i++) { + if ((buf_pool->entries[i].in_use) && + (buf_pool->entries[i].frame.virtual + != NULL)) { + if (mode == VCD_FLUSH_INPUT) { + cctxt->callback( + VCD_EVT_RESP_INPUT_FLUSHED, + VCD_S_SUCCESS, + &(buf_pool->entries[i].frame), + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + } else { + buf_pool->entries[i]. + frame.data_len = 0; + cctxt->callback( + VCD_EVT_RESP_OUTPUT_FLUSHED, + VCD_S_SUCCESS, + &(buf_pool->entries[i].frame), + sizeof(struct vcd_frame_data), + cctxt, + cctxt->client_data); + } + VCD_BUFFERPOOL_INUSE_DECREMENT( + buf_pool->in_use); + buf_pool->entries[i].in_use = false; + } + } + } + } +} + +void vcd_flush_output_buffers(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_buffer_pool *buf_pool; + struct vcd_buffer_entry *buf_entry; + u32 count = 0; + struct vcd_property_hdr prop_hdr; + + VCD_MSG_LOW("vcd_flush_output_buffers:"); + buf_pool = &cctxt->out_buf_pool; + buf_entry = vcd_buffer_pool_entry_de_q(buf_pool); + while (buf_entry) { + if (!cctxt->decoding || buf_entry->in_use) { + buf_entry->frame.data_len = 0; + cctxt->callback(VCD_EVT_RESP_OUTPUT_FLUSHED, + VCD_S_SUCCESS, + &buf_entry->frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + if (buf_entry->in_use) { + VCD_BUFFERPOOL_INUSE_DECREMENT( + buf_pool->in_use); + buf_entry->in_use = false; + } + count++; + } + buf_entry = vcd_buffer_pool_entry_de_q(buf_pool); + } + vcd_flush_bframe_buffers(cctxt, VCD_FLUSH_OUTPUT); + if (buf_pool->in_use || buf_pool->q_len) { + VCD_MSG_ERROR("%s(): WARNING in_use(%u) or q_len(%u) not zero!", + __func__, buf_pool->in_use, buf_pool->q_len); + buf_pool->in_use = buf_pool->q_len = 0; + } + if (cctxt->sched_clnt_hdl) { + if (count > cctxt->sched_clnt_hdl->tkns) + cctxt->sched_clnt_hdl->tkns = 0; + else + cctxt->sched_clnt_hdl->tkns -= count; + } + + if (cctxt->ddl_hdl_valid && cctxt->decoding) { + prop_hdr.prop_id = DDL_I_REQ_OUTPUT_FLUSH; + prop_hdr.sz = sizeof(u32); + count = 0x1; + + (void)ddl_set_property(cctxt->ddl_handle, &prop_hdr, + &count); + } + vcd_release_all_clnt_frm_transc(cctxt); + cctxt->status.mask &= ~VCD_IN_RECONFIG; +} + +u32 vcd_flush_buffers(struct vcd_clnt_ctxt *cctxt, u32 mode) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_entry *buf_entry; + + VCD_MSG_LOW("vcd_flush_buffers:"); + + if (mode > VCD_FLUSH_ALL || !(mode & VCD_FLUSH_ALL)) { + VCD_MSG_ERROR("Invalid flush mode %d", mode); + return VCD_ERR_ILLEGAL_PARM; + } + + VCD_MSG_MED("Flush mode %d requested", mode); + if ((mode & VCD_FLUSH_INPUT) && + cctxt->sched_clnt_hdl) { + + rc = vcd_sched_dequeue_buffer( + cctxt->sched_clnt_hdl, &buf_entry); + while (!VCD_FAILED(rc) && buf_entry) { + if (buf_entry->virtual) { + cctxt->callback(VCD_EVT_RESP_INPUT_FLUSHED, + VCD_S_SUCCESS, + &buf_entry->frame, + sizeof(struct + vcd_frame_data), + cctxt, + cctxt->client_data); + } + + buf_entry->in_use = false; + VCD_BUFFERPOOL_INUSE_DECREMENT( + cctxt->in_buf_pool.in_use); + buf_entry = NULL; + rc = vcd_sched_dequeue_buffer( + cctxt->sched_clnt_hdl, &buf_entry); + } + } + if (rc != VCD_ERR_QEMPTY) + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_dequeue_buffer"); + if (cctxt->status.frame_submitted > 0) + cctxt->status.mask |= mode; + else { + if (mode & VCD_FLUSH_INPUT) + vcd_flush_bframe_buffers(cctxt, VCD_FLUSH_INPUT); + if (mode & VCD_FLUSH_OUTPUT) + vcd_flush_output_buffers(cctxt); + } + return VCD_S_SUCCESS; +} + +void vcd_flush_buffers_in_err_fatal(struct vcd_clnt_ctxt *cctxt) +{ + VCD_MSG_LOW("\n vcd_flush_buffers_in_err_fatal:"); + (void) vcd_flush_buffers(cctxt, VCD_FLUSH_ALL); + vcd_flush_in_use_buffer_pool_entries(cctxt, + &cctxt->in_buf_pool, VCD_EVT_RESP_INPUT_FLUSHED); + vcd_flush_in_use_buffer_pool_entries(cctxt, + &cctxt->out_buf_pool, VCD_EVT_RESP_OUTPUT_FLUSHED); + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); +} + +u32 vcd_init_client_context(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc; + VCD_MSG_LOW("vcd_init_client_context:"); + rc = ddl_open(&cctxt->ddl_handle, cctxt->decoding); + VCD_FAILED_RETURN(rc, "Failed: ddl_open"); + cctxt->vcd_enable_ion = res_trk_get_enable_ion(); + if (cctxt->vcd_enable_ion) { + cctxt->vcd_ion_client = res_trk_get_ion_client(); + if (!cctxt->vcd_ion_client) { + VCD_MSG_LOW("vcd_init_ion_get_client_failed:"); + return -EINVAL; + } + } + cctxt->ddl_hdl_valid = true; + cctxt->clnt_state.state = VCD_CLIENT_STATE_OPEN; + cctxt->clnt_state.state_table = + vcd_get_client_state_table(VCD_CLIENT_STATE_OPEN); + cctxt->signature = VCD_SIGNATURE; + cctxt->live = true; + 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; +} + +void vcd_destroy_client_context(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_dev_ctxt *dev_ctxt; + struct vcd_clnt_ctxt *client; + struct vcd_buffer_entry *buf_entry; + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("vcd_destroy_client_context:"); + + dev_ctxt = cctxt->dev_ctxt; + + if (cctxt == dev_ctxt->cctxt_list_head) { + VCD_MSG_MED("Clnt list head clnt being removed"); + + dev_ctxt->cctxt_list_head = cctxt->next; + } else { + client = dev_ctxt->cctxt_list_head; + while (client && cctxt != client->next) + client = client->next; + if (client) + client->next = cctxt->next; + if (!client) { + rc = VCD_ERR_FAIL; + VCD_MSG_ERROR("Client not found in client list"); + } + } + + if (VCD_FAILED(rc)) + return; + + if (cctxt->sched_clnt_hdl) { + rc = VCD_S_SUCCESS; + while (!VCD_FAILED(rc)) { + rc = vcd_sched_dequeue_buffer( + cctxt->sched_clnt_hdl, &buf_entry); + if (rc != VCD_ERR_QEMPTY && VCD_FAILED(rc)) + VCD_MSG_ERROR("\n Failed: " + "vcd_sched_de_queue_buffer"); + } + rc = vcd_sched_remove_client(cctxt->sched_clnt_hdl); + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("\n Failed: sched_remove_client"); + cctxt->sched_clnt_hdl = NULL; + } + + if (cctxt->seq_hdr.sequence_header) { + vcd_pmem_free(cctxt->seq_hdr.sequence_header, + cctxt->seq_hdr_phy_addr, cctxt); + cctxt->seq_hdr.sequence_header = NULL; + } + + vcd_free_buffers_internal(cctxt, &cctxt->in_buf_pool); + vcd_free_buffers_internal(cctxt, &cctxt->out_buf_pool); + vcd_free_buffer_pool_entries(&cctxt->in_buf_pool); + vcd_free_buffer_pool_entries(&cctxt->out_buf_pool); + vcd_release_all_clnt_transc(cctxt); + + if (cctxt->ddl_hdl_valid) { + (void)ddl_close(&cctxt->ddl_handle); + cctxt->ddl_hdl_valid = false; + } + + cctxt->signature = 0; + cctxt->clnt_state.state = VCD_CLIENT_STATE_NULL; + cctxt->clnt_state.state_table = NULL; + cctxt->vcd_ion_client = NULL; + kfree(cctxt); +} + +u32 vcd_check_for_client_context( + struct vcd_dev_ctxt *dev_ctxt, s32 driver_id) +{ + struct vcd_clnt_ctxt *client; + + client = dev_ctxt->cctxt_list_head; + while (client && client->driver_id != driver_id) + client = client->next; + + if (!client) + return false; + else + return true; +} + +u32 vcd_validate_driver_handle( + struct vcd_dev_ctxt *dev_ctxt, s32 driver_handle) +{ + driver_handle--; + + if (driver_handle < 0 || + driver_handle >= VCD_DRIVER_INSTANCE_MAX || + !dev_ctxt->driver_ids[driver_handle]) { + return false; + } else { + return true; + } +} + +u32 vcd_client_cmd_en_q( + struct vcd_clnt_ctxt *cctxt, enum vcd_command command) +{ + u32 result; + + if (cctxt->cmd_q.pending_cmd == VCD_CMD_NONE) { + cctxt->cmd_q.pending_cmd = command; + result = true; + } else { + result = false; + } + + return result; +} + +void vcd_client_cmd_flush_and_en_q( + struct vcd_clnt_ctxt *cctxt, enum vcd_command command) +{ + cctxt->cmd_q.pending_cmd = command; +} + +u32 vcd_client_cmd_de_q(struct vcd_clnt_ctxt *cctxt, + enum vcd_command *command) +{ + if (cctxt->cmd_q.pending_cmd == VCD_CMD_NONE) + return false; + + *command = cctxt->cmd_q.pending_cmd; + cctxt->cmd_q.pending_cmd = VCD_CMD_NONE; + + return true; +} + +u32 vcd_get_next_queued_client_cmd(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt **cctxt, enum vcd_command *command) +{ + struct vcd_clnt_ctxt *client = dev_ctxt->cctxt_list_head; + u32 result = false; + + while (client && !result) { + *cctxt = client; + result = vcd_client_cmd_de_q(client, command); + client = client->next; + } + return result; +} + +u32 vcd_submit_cmd_sess_start(struct vcd_transc *transc) +{ + u32 rc; + struct vcd_sequence_hdr Seq_hdr; + + VCD_MSG_LOW("vcd_submit_cmd_sess_start:"); + + if (transc->cctxt->decoding) { + + if (transc->cctxt->seq_hdr.sequence_header) { + Seq_hdr.sequence_header_len = + transc->cctxt->seq_hdr. + sequence_header_len; + Seq_hdr.sequence_header = + transc->cctxt->seq_hdr_phy_addr; + + rc = ddl_decode_start(transc->cctxt->ddl_handle, + &Seq_hdr, (void *)transc); + } else { + rc = ddl_decode_start(transc->cctxt->ddl_handle, + NULL, (void *)transc); + } + + } else { + vcd_set_num_slices(transc->cctxt); + rc = ddl_encode_start(transc->cctxt->ddl_handle, + (void *)transc); + } + if (!VCD_FAILED(rc)) { + transc->cctxt->status.cmd_submitted++; + vcd_device_timer_start(transc->cctxt->dev_ctxt); + } else + VCD_MSG_ERROR("rc = 0x%x. Failed: ddl start", rc); + + return rc; +} + +u32 vcd_submit_cmd_sess_end(struct vcd_transc *transc) +{ + u32 rc; + + VCD_MSG_LOW("vcd_submit_cmd_sess_end:"); + + if (transc->cctxt->decoding) { + rc = ddl_decode_end(transc->cctxt->ddl_handle, + (void *)transc); + } else { + rc = ddl_encode_end(transc->cctxt->ddl_handle, + (void *)transc); + } + if (!VCD_FAILED(rc)) { + transc->cctxt->status.cmd_submitted++; + vcd_device_timer_start(transc->cctxt->dev_ctxt); + } else + VCD_MSG_ERROR("rc = 0x%x. Failed: ddl end", rc); + + return rc; +} + +void vcd_submit_cmd_client_close(struct vcd_clnt_ctxt *cctxt) +{ + (void) ddl_close(&cctxt->ddl_handle); + cctxt->ddl_hdl_valid = false; + cctxt->status.mask &= ~VCD_CLEANING_UP; + if (cctxt->status.mask & VCD_CLOSE_PENDING) { + vcd_destroy_client_context(cctxt); + vcd_handle_for_last_clnt_close(cctxt->dev_ctxt, true); + } +} + +u32 vcd_submit_command_in_continue(struct vcd_dev_ctxt + *dev_ctxt, struct vcd_transc *transc) +{ + struct vcd_property_hdr prop_hdr; + struct vcd_clnt_ctxt *client = NULL; + enum vcd_command cmd = VCD_CMD_NONE; + u32 rc = VCD_ERR_FAIL; + u32 result = false, flush = 0, event = 0; + u32 command_break = false; + + VCD_MSG_LOW("\n vcd_submit_command_in_continue:"); + + while (!command_break) { + result = vcd_get_next_queued_client_cmd(dev_ctxt, + &client, &cmd); + + if (!result) + command_break = true; + else { + transc->type = cmd; + transc->cctxt = client; + + switch (cmd) { + case VCD_CMD_CODEC_START: + { + rc = vcd_submit_cmd_sess_start(transc); + event = VCD_EVT_RESP_START; + break; + } + case VCD_CMD_CODEC_STOP: + { + rc = vcd_submit_cmd_sess_end(transc); + event = VCD_EVT_RESP_STOP; + break; + } + case VCD_CMD_OUTPUT_FLUSH: + { + prop_hdr.prop_id = DDL_I_REQ_OUTPUT_FLUSH; + prop_hdr.sz = sizeof(u32); + flush = 0x1; + (void) ddl_set_property(client->ddl_handle, + &prop_hdr, &flush); + vcd_release_command_channel(dev_ctxt, + transc); + rc = VCD_S_SUCCESS; + break; + } + case VCD_CMD_CLIENT_CLOSE: + { + vcd_submit_cmd_client_close(client); + vcd_release_command_channel(dev_ctxt, + transc); + rc = VCD_S_SUCCESS; + break; + } + default: + { + VCD_MSG_ERROR("\n vcd_submit_command: Unknown" + "command %d", (int)cmd); + break; + } + } + + if (!VCD_FAILED(rc)) { + command_break = true; + } else { + VCD_MSG_ERROR("vcd_submit_command %d: failed 0x%x", + cmd, rc); + client->callback(event, rc, NULL, 0, client, + client->client_data); + } + } + } + return result; +} + +u32 vcd_schedule_frame(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt **cctxt, struct vcd_buffer_entry + **ip_buf_entry) +{ + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("vcd_schedule_frame:"); + + if (!dev_ctxt->cctxt_list_head) { + VCD_MSG_HIGH("Client list empty"); + return false; + } + rc = vcd_sched_get_client_frame(&dev_ctxt->sched_clnt_list, + cctxt, ip_buf_entry); + if (rc == VCD_ERR_QEMPTY) { + VCD_MSG_HIGH("No frame available. Sched queues are empty"); + return false; + } + if (VCD_FAILED(rc)) { + VCD_MSG_FATAL("vcd_submit_frame: sched_de_queue_frame" + "failed 0x%x", rc); + return false; + } + if (!*cctxt || !*ip_buf_entry) { + VCD_MSG_FATAL("Sched returned invalid values. ctxt=%p," + "ipbuf=%p", *cctxt, *ip_buf_entry); + return false; + } + return true; +} + +void vcd_try_submit_frame(struct vcd_dev_ctxt *dev_ctxt) +{ + struct vcd_transc *transc; + u32 rc = VCD_S_SUCCESS; + struct vcd_clnt_ctxt *cctxt = NULL; + struct vcd_buffer_entry *ip_buf_entry = NULL; + u32 result = false; + + VCD_MSG_LOW("vcd_try_submit_frame:"); + + if (!vcd_get_frame_channel(dev_ctxt, &transc)) + return; + + if (!vcd_schedule_frame(dev_ctxt, &cctxt, &ip_buf_entry)) { + vcd_release_frame_channel(dev_ctxt, transc); + return; + } + + rc = vcd_power_event(dev_ctxt, cctxt, VCD_EVT_PWR_CLNT_CMD_BEGIN); + + if (!VCD_FAILED(rc)) { + transc->cctxt = cctxt; + transc->ip_buf_entry = ip_buf_entry; + + result = vcd_submit_frame(dev_ctxt, transc); + } else { + VCD_MSG_ERROR("Failed: VCD_EVT_PWR_CLNT_CMD_BEGIN"); + (void) vcd_sched_queue_buffer( + cctxt->sched_clnt_hdl, ip_buf_entry, false); + cctxt->sched_clnt_hdl->tkns++; + } + + if (!result) { + vcd_release_frame_channel(dev_ctxt, transc); + (void) vcd_power_event(dev_ctxt, cctxt, + VCD_EVT_PWR_CLNT_CMD_FAIL); + } +} + +u32 vcd_submit_frame(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc *transc) +{ + struct vcd_clnt_ctxt *cctxt = NULL; + struct vcd_frame_data *ip_frm_entry; + struct vcd_buffer_entry *op_buf_entry = NULL; + u32 rc = VCD_S_SUCCESS; + u32 evcode = 0; + u32 perf_level = 0; + int decodeTime = 0; + struct ddl_frame_data_tag ddl_ip_frm; + struct ddl_frame_data_tag *ddl_op_frm; + u32 out_buf_cnt = 0; + + VCD_MSG_LOW("vcd_submit_frame:"); + cctxt = transc->cctxt; + ip_frm_entry = &transc->ip_buf_entry->frame; + + transc->op_buf_entry = op_buf_entry; + transc->ip_frm_tag = ip_frm_entry->ip_frm_tag; + transc->time_stamp = ip_frm_entry->time_stamp; + transc->flags = ip_frm_entry->flags; + ip_frm_entry->ip_frm_tag = (u32) transc; + memset(&ddl_ip_frm, 0, sizeof(ddl_ip_frm)); + if (cctxt->decoding) { + decodeTime = ddl_get_core_decode_proc_time(cctxt->ddl_handle); + if (decodeTime > MAX_DEC_TIME) { + if (res_trk_get_curr_perf_level(&perf_level)) { + vcd_update_decoder_perf_level(dev_ctxt, + res_trk_estimate_perf_level(perf_level)); + ddl_reset_avg_dec_time(cctxt->ddl_handle); + } else + VCD_MSG_ERROR("%s(): retrieve curr_perf_level" + "returned FALSE\n", __func__); + } + 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); + } 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_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)) { + vcd_device_timer_start(dev_ctxt); + cctxt->status.frame_submitted++; + if (ip_frm_entry->flags & VCD_FRAME_FLAG_EOS) + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_EOS, evcode); + } else { + VCD_MSG_ERROR("Frame submission failed. rc = 0x%x", rc); + vcd_handle_submit_frame_failed(dev_ctxt, transc); + } + return true; +} + +u32 vcd_try_submit_frame_in_continue(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc *transc) +{ + struct vcd_clnt_ctxt *cctxt = NULL; + struct vcd_buffer_entry *ip_buf_entry = NULL; + + VCD_MSG_LOW("vcd_try_submit_frame_in_continue:"); + + if (!vcd_schedule_frame(dev_ctxt, &cctxt, &ip_buf_entry)) + return false; + + transc->cctxt = cctxt; + transc->ip_buf_entry = ip_buf_entry; + + return vcd_submit_frame(dev_ctxt, transc); +} + +u32 vcd_process_cmd_sess_start(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_transc *transc; + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_process_cmd_sess_start:"); + if (vcd_get_command_channel(cctxt->dev_ctxt, &transc)) { + rc = vcd_power_event(cctxt->dev_ctxt, + cctxt, VCD_EVT_PWR_CLNT_CMD_BEGIN); + + if (!VCD_FAILED(rc)) { + transc->type = VCD_CMD_CODEC_START; + transc->cctxt = cctxt; + rc = vcd_submit_cmd_sess_start(transc); + } else { + VCD_MSG_ERROR("Failed: VCD_EVT_PWR_CLNT_CMD_BEGIN"); + } + + if (VCD_FAILED(rc)) { + vcd_release_command_channel(cctxt->dev_ctxt, + transc); + } + } else { + u32 result; + + result = vcd_client_cmd_en_q(cctxt, VCD_CMD_CODEC_START); + if (!result) { + rc = VCD_ERR_BUSY; + VCD_MSG_ERROR("%s(): vcd_client_cmd_en_q() " + "failed\n", __func__); + } + } + + if (VCD_FAILED(rc)) { + (void)vcd_power_event(cctxt->dev_ctxt, + cctxt, VCD_EVT_PWR_CLNT_CMD_FAIL); + } + + return rc; +} + +void vcd_send_frame_done_in_eos(struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame, u32 valid_opbuf) +{ + VCD_MSG_LOW("vcd_send_frame_done_in_eos:"); + + if (!input_frame->virtual && !valid_opbuf) { + VCD_MSG_MED("Sending NULL output with EOS"); + + cctxt->out_buf_pool.entries[0].frame.flags = + VCD_FRAME_FLAG_EOS; + cctxt->out_buf_pool.entries[0].frame.data_len = 0; + cctxt->out_buf_pool.entries[0].frame.time_stamp = + input_frame->time_stamp; + cctxt->out_buf_pool.entries[0].frame.ip_frm_tag = + input_frame->ip_frm_tag; + + cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, + &cctxt->out_buf_pool.entries[0].frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + + memset(&cctxt->out_buf_pool.entries[0].frame, + 0, sizeof(struct vcd_frame_data)); + } else if (!input_frame->data_len) { + if (cctxt->decoding) { + vcd_send_frame_done_in_eos_for_dec(cctxt, + input_frame); + } else { + vcd_send_frame_done_in_eos_for_enc(cctxt, + input_frame); + } + + } +} + +void vcd_send_frame_done_in_eos_for_dec( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame) +{ + struct vcd_buffer_entry *buf_entry; + struct vcd_property_hdr prop_hdr; + u32 rc; + struct ddl_frame_data_tag ddl_frm; + + prop_hdr.prop_id = DDL_I_DPB_RETRIEVE; + prop_hdr.sz = sizeof(struct ddl_frame_data_tag); + memset(&ddl_frm, 0, sizeof(ddl_frm)); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &ddl_frm); + + if (VCD_FAILED(rc) || !ddl_frm.vcd_frm.virtual) { + cctxt->status.eos_trig_ip_frm = *input_frame; + cctxt->status.mask |= VCD_EOS_WAIT_OP_BUF; + return; + } + + buf_entry = vcd_find_buffer_pool_entry(&cctxt->out_buf_pool, + ddl_frm.vcd_frm.virtual); + if (!buf_entry) { + VCD_MSG_ERROR("Unrecognized buffer address provided = %p", + ddl_frm.vcd_frm.virtual); + return; + } else { + if (cctxt->sched_clnt_hdl->tkns) + cctxt->sched_clnt_hdl->tkns--; + + VCD_MSG_MED("Sending non-NULL output with EOS"); + + buf_entry->frame.data_len = 0; + buf_entry->frame.offset = 0; + buf_entry->frame.flags |= VCD_FRAME_FLAG_EOS; + buf_entry->frame.ip_frm_tag = input_frame->ip_frm_tag; + buf_entry->frame.time_stamp = input_frame->time_stamp; + + cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, + &buf_entry->frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + + buf_entry->in_use = false; + VCD_BUFFERPOOL_INUSE_DECREMENT(cctxt->out_buf_pool.in_use); + } +} + +void vcd_send_frame_done_in_eos_for_enc( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame) +{ + struct vcd_buffer_entry *op_buf_entry; + + if (!cctxt->out_buf_pool.q_len) { + cctxt->status.eos_trig_ip_frm = *input_frame; + + cctxt->status.mask |= VCD_EOS_WAIT_OP_BUF; + + return; + } + + op_buf_entry = vcd_buffer_pool_entry_de_q(&cctxt->out_buf_pool); + if (!op_buf_entry) { + VCD_MSG_ERROR("%s(): vcd_buffer_pool_entry_de_q() " + "failed\n", __func__); + } else { + if (cctxt->sched_clnt_hdl->tkns) + cctxt->sched_clnt_hdl->tkns--; + + VCD_MSG_MED("Sending non-NULL output with EOS"); + + op_buf_entry->frame.data_len = 0; + op_buf_entry->frame.flags |= VCD_FRAME_FLAG_EOS; + op_buf_entry->frame.ip_frm_tag = + input_frame->ip_frm_tag; + op_buf_entry->frame.time_stamp = input_frame->time_stamp; + + cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, + &op_buf_entry->frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + } +} + +u32 vcd_handle_recvd_eos( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame, u32 *pb_eos_handled) +{ + u32 rc; + + VCD_MSG_LOW("vcd_handle_recvd_eos:"); + + *pb_eos_handled = false; + + if (input_frame->virtual && + input_frame->data_len) + return VCD_S_SUCCESS; + + input_frame->data_len = 0; + rc = vcd_sched_mark_client_eof(cctxt->sched_clnt_hdl); + if (VCD_FAILED(rc) && rc != VCD_ERR_QEMPTY) + return rc; + + if (rc == VCD_S_SUCCESS) + *pb_eos_handled = true; + else if (cctxt->decoding && !input_frame->virtual) + cctxt->sched_clnt_hdl->tkns++; + else if (!cctxt->decoding) { + vcd_send_frame_done_in_eos(cctxt, input_frame, false); + if (cctxt->status.mask & VCD_EOS_WAIT_OP_BUF) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_EOS, + CLIENT_STATE_EVENT_NUMBER + (encode_frame)); + } + *pb_eos_handled = true; + } + + if (*pb_eos_handled && + input_frame->virtual && + !input_frame->data_len) { + cctxt->callback(VCD_EVT_RESP_INPUT_DONE, + VCD_S_SUCCESS, + input_frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + } + return VCD_S_SUCCESS; +} + +u32 vcd_handle_first_decode_frame(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_ERR_BAD_STATE; + + VCD_MSG_LOW("vcd_handle_first_decode_frame:"); + if (!cctxt->in_buf_pool.entries || + !cctxt->out_buf_pool.entries || + cctxt->in_buf_pool.validated != + cctxt->in_buf_pool.count || + cctxt->out_buf_pool.validated != + cctxt->out_buf_pool.count) + VCD_MSG_ERROR("Buffer pool is not completely setup yet"); + else if (!cctxt->sched_clnt_hdl) { + rc = vcd_sched_add_client(cctxt); + VCD_FAILED_RETURN(rc, "Failed: vcd_add_client_to_sched"); + cctxt->sched_clnt_hdl->tkns = + cctxt->out_buf_pool.q_len; + } else + rc = vcd_sched_suspend_resume_clnt(cctxt, true); + return rc; +} + +u32 vcd_setup_with_ddl_capabilities(struct vcd_dev_ctxt *dev_ctxt) +{ + struct vcd_property_hdr Prop_hdr; + struct ddl_property_capability capability; + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_setup_with_ddl_capabilities:"); + + if (!dev_ctxt->ddl_cmd_ch_depth) { + Prop_hdr.prop_id = DDL_I_CAPABILITY; + Prop_hdr.sz = sizeof(capability); + + /* + ** Since this is underlying core's property we don't need a + ** ddl client handle. + */ + rc = ddl_get_property(NULL, &Prop_hdr, &capability); + + if (!VCD_FAILED(rc)) { + /* + ** Allocate the transaction table. + */ + dev_ctxt->trans_tbl_size = + (VCD_MAX_CLIENT_TRANSACTIONS * + capability.max_num_client) + + capability.general_command_depth; + + dev_ctxt->trans_tbl = (struct vcd_transc *) + kzalloc((sizeof(struct vcd_transc) * + dev_ctxt->trans_tbl_size), GFP_KERNEL); + + if (!dev_ctxt->trans_tbl) { + VCD_MSG_ERROR("Transaction table alloc failed"); + rc = VCD_ERR_ALLOC_FAIL; + } else { + dev_ctxt->ddl_cmd_concurrency = + !capability.exclusive; + dev_ctxt->ddl_frame_ch_depth = + capability.frame_command_depth; + dev_ctxt->ddl_cmd_ch_depth = + capability.general_command_depth; + + vcd_reset_device_channels(dev_ctxt); + + dev_ctxt->hw_time_out = + capability.ddl_time_out_in_ms; + + } + } + } + return rc; +} + +struct vcd_transc *vcd_get_free_trans_tbl_entry + (struct vcd_dev_ctxt *dev_ctxt) { + u32 i; + + if (!dev_ctxt->trans_tbl) + return NULL; + + i = 0; + while (i < dev_ctxt->trans_tbl_size && + dev_ctxt->trans_tbl[i].in_use) + i++; + + if (i == dev_ctxt->trans_tbl_size) { + return NULL; + } else { + memset(&dev_ctxt->trans_tbl[i], 0, + sizeof(struct vcd_transc)); + dev_ctxt->trans_tbl[i].in_use = true; + VCD_MSG_LOW("%s: Get transc = 0x%x, in_use = %u\n", + __func__, (u32)(&dev_ctxt->trans_tbl[i]), + dev_ctxt->trans_tbl[i].in_use); + return &dev_ctxt->trans_tbl[i]; + } +} + +void vcd_release_trans_tbl_entry(struct vcd_transc *trans_entry) +{ + if (trans_entry) { + trans_entry->in_use = false; + VCD_MSG_LOW("%s: Free transc = 0x%x, in_use = %u\n", + __func__, (u32)trans_entry, trans_entry->in_use); + } +} + +u32 vcd_handle_input_done( + struct vcd_clnt_ctxt *cctxt, + void *payload, u32 event, u32 status) +{ + struct vcd_transc *transc; + struct ddl_frame_data_tag *frame = + (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) { + VCD_MSG_ERROR("Input done was not expected"); + return VCD_ERR_BAD_STATE; + } + + 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); + VCD_FAILED_RETURN(rc, "Bad input done payload"); + + transc = (struct vcd_transc *)frame->vcd_frm.ip_frm_tag; + orig_frame = vcd_find_buffer_pool_entry(&cctxt->in_buf_pool, + transc->ip_buf_entry->virtual); + + if ((transc->ip_buf_entry->frame.virtual != + frame->vcd_frm.virtual) + || !transc->ip_buf_entry->in_use) { + VCD_MSG_ERROR("Bad frm transaction state"); + vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end); + return VCD_ERR_BAD_POINTER; + } + + frame->vcd_frm.ip_frm_tag = transc->ip_frm_tag; + transc->frame = frame->vcd_frm.frame; + + cctxt->callback(event, + status, + &frame->vcd_frm, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + + orig_frame->in_use--; + VCD_BUFFERPOOL_INUSE_DECREMENT(cctxt->in_buf_pool.in_use); + + if (cctxt->decoding && orig_frame->in_use) { + VCD_MSG_ERROR("When decoding same input buffer not " + "supposed to be queued multiple times"); + return VCD_ERR_FAIL; + } + + if (orig_frame != transc->ip_buf_entry) + kfree(transc->ip_buf_entry); + transc->ip_buf_entry = NULL; + transc->input_done = true; + + 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); + vcd_handle_input_done_failed(cctxt, transc); + } else + cctxt->status.mask |= VCD_FIRST_IP_DONE; + + if (cctxt->status.frame_submitted > 0) + cctxt->status.frame_submitted--; + else + cctxt->status.frame_delayed--; + + if (!VCD_FAILED(status) && + cctxt->decoding) { + if (frame->vcd_frm.flags & VCD_FRAME_FLAG_CODECCONFIG) { + VCD_MSG_HIGH( + "INPUT_DONE with VCD_FRAME_FLAG_CODECCONFIG"); + vcd_handle_input_done_with_codec_config(cctxt, + transc, frame); + frame->vcd_frm.flags &= ~VCD_FRAME_FLAG_CODECCONFIG; + } + if (frame->vcd_frm.interlaced) + vcd_handle_input_done_for_interlacing(cctxt); + if (frame->frm_trans_end) + vcd_handle_input_done_with_trans_end(cctxt); + } + + return VCD_S_SUCCESS; +} + +u32 vcd_handle_input_done_in_eos( + struct vcd_clnt_ctxt *cctxt, void *payload, u32 status) +{ + struct vcd_transc *transc; + struct ddl_frame_data_tag *frame = + (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); + VCD_FAILED_RETURN(rc, "Failed: vcd_validate_io_done_pyld"); + transc = (struct vcd_transc *)frame->vcd_frm.ip_frm_tag; + codec_config = frame->vcd_frm.flags & VCD_FRAME_FLAG_CODECCONFIG; + rc = vcd_handle_input_done(cctxt, + payload, VCD_EVT_RESP_INPUT_DONE, status); + VCD_FAILED_RETURN(rc, "Failed: vcd_handle_input_done"); + if (frame->vcd_frm.flags & VCD_FRAME_FLAG_EOS) { + VCD_MSG_HIGH("Got input done for EOS initiator"); + transc->input_done = false; + transc->in_use = true; + if ((codec_config && + (status != VCD_ERR_BITSTREAM_ERR)) || + ((status == VCD_ERR_BITSTREAM_ERR) && + !(cctxt->status.mask & VCD_FIRST_IP_DONE) && + (core_type == VCD_CORE_720P))) + vcd_handle_eos_done(cctxt, transc, VCD_S_SUCCESS); + } + return rc; +} + +u32 vcd_validate_io_done_pyld( + struct vcd_clnt_ctxt *cctxt, void *payload, u32 status) +{ + struct ddl_frame_data_tag *frame = + (struct ddl_frame_data_tag *) payload; + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + struct vcd_transc *transc = NULL; + u32 rc = VCD_S_SUCCESS, i = 0; + + if (!frame) { + VCD_MSG_ERROR("Bad payload from DDL"); + return VCD_ERR_BAD_POINTER; + } + + transc = (struct vcd_transc *)frame->vcd_frm.ip_frm_tag; + if (dev_ctxt->trans_tbl) { + while (i < dev_ctxt->trans_tbl_size && + transc != &dev_ctxt->trans_tbl[i]) + i++; + if (i == dev_ctxt->trans_tbl_size || + !dev_ctxt->trans_tbl[i].in_use) + rc = VCD_ERR_CLIENT_FATAL; + } else + rc = VCD_ERR_CLIENT_FATAL; + + if (VCD_FAILED(rc)) { + VCD_MSG_FATAL("vcd_validate_io_done_pyld: "\ + "invalid transaction 0x%x", (u32)transc); + } else if (!frame->vcd_frm.virtual && + status != VCD_ERR_INTRLCD_FIELD_DROP) + rc = VCD_ERR_BAD_POINTER; + + return rc; +} + +void vcd_handle_input_done_failed( + struct vcd_clnt_ctxt *cctxt, struct vcd_transc *transc) +{ + if (cctxt->decoding) { + cctxt->sched_clnt_hdl->tkns++; + vcd_release_trans_tbl_entry(transc); + } +} + +void vcd_handle_input_done_with_codec_config( + struct vcd_clnt_ctxt *cctxt, struct vcd_transc *transc, + struct ddl_frame_data_tag *frm) +{ + cctxt->sched_clnt_hdl->tkns++; + if (frm->frm_trans_end) + vcd_release_trans_tbl_entry(transc); +} + +void vcd_handle_input_done_for_interlacing(struct vcd_clnt_ctxt *cctxt) +{ + cctxt->status.int_field_cnt++; + if (cctxt->status.int_field_cnt == 1) + cctxt->sched_clnt_hdl->tkns++; + else if (cctxt->status.int_field_cnt == + VCD_DEC_NUM_INTERLACED_FIELDS) + cctxt->status.int_field_cnt = 0; +} + +void vcd_handle_input_done_with_trans_end( + struct vcd_clnt_ctxt *cctxt) +{ + if (!cctxt->decoding) + return; + if (cctxt->out_buf_pool.in_use < + cctxt->out_buf_pool.buf_req.min_count) + return; + if (!cctxt->sched_clnt_hdl->tkns) + cctxt->sched_clnt_hdl->tkns++; +} + +u32 vcd_handle_output_required(struct vcd_clnt_ctxt + *cctxt, void *payload, u32 status) +{ + struct vcd_transc *transc; + 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) { + VCD_MSG_ERROR("\n Input done was not expected"); + return VCD_ERR_BAD_STATE; + } + + 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); + VCD_FAILED_RETURN(rc, "\n Bad input done payload"); + + transc = (struct vcd_transc *)frame-> + vcd_frm.ip_frm_tag; + + if ((transc->ip_buf_entry->frame.virtual != + frame->vcd_frm.virtual) || + !transc->ip_buf_entry->in_use) { + VCD_MSG_ERROR("\n Bad frm transaction state"); + vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end); + return VCD_ERR_BAD_STATE; + } + rc = vcd_sched_queue_buffer(cctxt->sched_clnt_hdl, + transc->ip_buf_entry, false); + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_queue_buffer"); + + transc->ip_buf_entry = NULL; + vcd_release_trans_tbl_entry(transc); + frame->frm_trans_end = true; + + if (VCD_FAILED(status)) + VCD_MSG_ERROR("\n OUTPUT_REQ returned err = 0x%x", + status); + + if (cctxt->status.frame_submitted > 0) + cctxt->status.frame_submitted--; + else + cctxt->status.frame_delayed--; + + + if (!VCD_FAILED(status) && + cctxt->decoding && + frame->vcd_frm.interlaced) { + if (cctxt->status.int_field_cnt > 0) { + VCD_MSG_ERROR("\n Not expected: OUTPUT_REQ" + "for 2nd interlace field"); + rc = VCD_ERR_FAIL; + } + } + + return rc; +} + +u32 vcd_handle_output_required_in_flushing( +struct vcd_clnt_ctxt *cctxt, void *payload) +{ + u32 rc; + 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) + vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end); + VCD_FAILED_RETURN(rc, "Bad input done payload"); + + transc = (struct vcd_transc *) + (((struct ddl_frame_data_tag *)payload)-> + vcd_frm.ip_frm_tag); + + ((struct ddl_frame_data_tag *)payload)-> + vcd_frm.interlaced = false; + + rc = vcd_handle_input_done(cctxt, payload, + VCD_EVT_RESP_INPUT_FLUSHED, VCD_S_SUCCESS); + VCD_FAILED_RETURN(rc, "Failed: vcd_handle_input_done"); + + vcd_release_trans_tbl_entry(transc); + ((struct ddl_frame_data_tag *)payload)->frm_trans_end = true; + + return rc; +} + +u32 vcd_handle_frame_done( + struct vcd_clnt_ctxt *cctxt, + void *payload, u32 event, u32 status) +{ + struct vcd_buffer_entry *op_buf_entry = NULL; + struct ddl_frame_data_tag *op_frm = + (struct ddl_frame_data_tag *) payload; + 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) + vcd_handle_clnt_fatal(cctxt, op_frm->frm_trans_end); + VCD_FAILED_RETURN(rc, "Bad payload recvd"); + + transc = (struct vcd_transc *)op_frm->vcd_frm.ip_frm_tag; + + if (op_frm->vcd_frm.virtual) { + + if (!transc->op_buf_entry) { + op_buf_entry = + vcd_find_buffer_pool_entry( + &cctxt->out_buf_pool, + op_frm->vcd_frm. + virtual); + } else { + op_buf_entry = transc->op_buf_entry; + } + + if (!op_buf_entry) { + VCD_MSG_ERROR("Invalid output buffer returned" + "from DDL"); + vcd_handle_clnt_fatal(cctxt, op_frm->frm_trans_end); + rc = VCD_ERR_BAD_POINTER; + } else if (!op_buf_entry->in_use) { + VCD_MSG_ERROR("Bad output buffer 0x%p recvd from DDL", + op_buf_entry->frame.virtual); + vcd_handle_clnt_fatal(cctxt, op_frm->frm_trans_end); + rc = VCD_ERR_BAD_POINTER; + } else { + op_buf_entry->in_use = false; + VCD_BUFFERPOOL_INUSE_DECREMENT( + cctxt->out_buf_pool.in_use); + VCD_MSG_LOW("outBufPool.InUse = %d", + cctxt->out_buf_pool.in_use); + } + } + VCD_FAILED_RETURN(rc, "Bad output buffer pointer"); + op_frm->vcd_frm.time_stamp = transc->time_stamp; + op_frm->vcd_frm.ip_frm_tag = transc->ip_frm_tag; + + if (transc->flags & VCD_FRAME_FLAG_EOSEQ) + op_frm->vcd_frm.flags |= VCD_FRAME_FLAG_EOSEQ; + else + op_frm->vcd_frm.flags &= ~VCD_FRAME_FLAG_EOSEQ; + + if (cctxt->decoding) + op_frm->vcd_frm.frame = transc->frame; + else + transc->frame = op_frm->vcd_frm.frame; + transc->frame_done = true; + + if (transc->input_done && transc->frame_done) { + time_stamp = transc->time_stamp; + vcd_release_trans_tbl_entry(transc); + } + + if (status == VCD_ERR_INTRLCD_FIELD_DROP || + (op_frm->vcd_frm.intrlcd_ip_frm_tag != + VCD_FRAMETAG_INVALID && + op_frm->vcd_frm.intrlcd_ip_frm_tag)) { + vcd_handle_frame_done_for_interlacing(cctxt, transc, + op_frm, status); + if (status == VCD_ERR_INTRLCD_FIELD_DROP) { + cctxt->callback(VCD_EVT_IND_INFO_FIELD_DROPPED, + VCD_S_SUCCESS, + &time_stamp, + sizeof(time_stamp), + cctxt, cctxt->client_data); + } + } + + if (status != VCD_ERR_INTRLCD_FIELD_DROP) { + cctxt->callback(event, + status, + &op_frm->vcd_frm, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + } + return rc; +} + +u32 vcd_handle_frame_done_in_eos( + struct vcd_clnt_ctxt *cctxt, void *payload, u32 status) +{ + struct ddl_frame_data_tag *frame = + (struct ddl_frame_data_tag *) payload; + u32 rc = VCD_S_SUCCESS; + 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); + VCD_FAILED_RETURN(rc, "Bad payload received"); + + if (cctxt->status.mask & VCD_EOS_PREV_VALID) { + rc = vcd_handle_frame_done(cctxt, + (void *)&cctxt->status. + eos_prev_op_frm, + VCD_EVT_RESP_OUTPUT_DONE, + cctxt->status.eos_prev_op_frm_status); + VCD_FAILED_RETURN(rc, "Failed: vcd_handle_frame_done"); + } + + cctxt->status.eos_prev_op_frm = *frame; + cctxt->status.eos_prev_op_frm_status = status; + cctxt->status.mask |= VCD_EOS_PREV_VALID; + return rc; +} + +void vcd_handle_frame_done_for_interlacing( + struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc_ip1, + struct ddl_frame_data_tag *op_frm, u32 status) +{ + struct vcd_transc *transc_ip2 = + (struct vcd_transc *)op_frm->\ + vcd_frm.intrlcd_ip_frm_tag; + + if (status == VCD_ERR_INTRLCD_FIELD_DROP) { + cctxt->status.int_field_cnt = 0; + return; + } + + op_frm->vcd_frm.intrlcd_ip_frm_tag = transc_ip2->ip_frm_tag; + + transc_ip2->frame_done = true; + + if (transc_ip2->input_done && transc_ip2->frame_done) + vcd_release_trans_tbl_entry(transc_ip2); + + if (!transc_ip1->frame || !transc_ip2->frame) { + VCD_MSG_ERROR("DDL didn't provided frame type"); + return; + } +} + +u32 vcd_handle_first_fill_output_buffer( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer, + u32 *handled) +{ + u32 rc = VCD_S_SUCCESS; + rc = vcd_check_if_buffer_req_met(cctxt, VCD_BUFFER_OUTPUT); + VCD_FAILED_RETURN(rc, "Output buffer requirements not met"); + if (cctxt->out_buf_pool.q_len > 0) { + VCD_MSG_ERROR("Old output buffers were not flushed out"); + return VCD_ERR_BAD_STATE; + } + cctxt->status.mask |= VCD_FIRST_OP_RCVD; + if (cctxt->sched_clnt_hdl) + rc = vcd_sched_suspend_resume_clnt(cctxt, true); + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_suspend_resume_clnt"); + if (cctxt->decoding) + rc = vcd_handle_first_fill_output_buffer_for_dec( + cctxt, buffer, handled); + else + rc = vcd_handle_first_fill_output_buffer_for_enc( + cctxt, buffer, handled); + return rc; +} + +u32 vcd_handle_first_fill_output_buffer_for_enc( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *frm_entry, + u32 *handled) +{ + u32 rc, seqhdr_present = 0; + struct vcd_property_hdr prop_hdr; + struct vcd_sequence_hdr seq_hdr; + struct vcd_property_sps_pps_for_idr_enable idr_enable; + struct vcd_property_codec codec; + *handled = true; + prop_hdr.prop_id = DDL_I_SEQHDR_PRESENT; + prop_hdr.sz = sizeof(seqhdr_present); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &seqhdr_present); + VCD_FAILED_RETURN(rc, "Failed: DDL_I_SEQHDR_PRESENT"); + if (!seqhdr_present) { + *handled = false; + return VCD_S_SUCCESS; + } + + prop_hdr.prop_id = VCD_I_CODEC; + prop_hdr.sz = sizeof(struct vcd_property_codec); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &codec); + if (!VCD_FAILED(rc)) { + if (codec.codec != VCD_CODEC_H263) { + /* + * The seq. header is stored in a seperate internal + * buffer and is memcopied into the output buffer + * that we provide. In secure sessions, we aren't + * allowed to touch these buffers. In these cases + * seq. headers are returned to client as part of + * I-frames. So for secure session, just return + * empty buffer. + */ + 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; + seq_hdr.sequence_header_len = + frm_entry->alloc_len; + rc = ddl_get_property(cctxt->ddl_handle, + &prop_hdr, &seq_hdr); + if (!VCD_FAILED(rc)) { + frm_entry->data_len = + seq_hdr.sequence_header_len; + frm_entry->time_stamp = 0; + frm_entry->flags |= + VCD_FRAME_FLAG_CODECCONFIG; + } else + VCD_MSG_ERROR("rc = 0x%x. Failed:" + "ddl_get_property: VCD_I_SEQ_HEADER", + rc); + } else { + /* + * First check that the proper props are enabled + * so client can get the proper info eventually + */ + prop_hdr.prop_id = VCD_I_ENABLE_SPS_PPS_FOR_IDR; + prop_hdr.sz = sizeof(idr_enable); + rc = ddl_get_property(cctxt->ddl_handle, + &prop_hdr, &idr_enable); + if (!VCD_FAILED(rc)) { + if (!idr_enable. + sps_pps_for_idr_enable_flag) { + VCD_MSG_ERROR("SPS/PPS per IDR " + "needs to be enabled"); + rc = VCD_ERR_BAD_STATE; + } else { + /* Send zero len frame */ + frm_entry->data_len = 0; + frm_entry->time_stamp = 0; + frm_entry->flags = 0; + } + } + + } + + if (!VCD_FAILED(rc)) + cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, frm_entry, + sizeof(struct vcd_frame_data), + cctxt, + cctxt->client_data); + } else + VCD_MSG_LOW("Codec Type is H.263\n"); + } else + VCD_MSG_ERROR( + "rc = 0x%x. Failed: ddl_get_property:VCD_I_CODEC", + rc); + return rc; +} + +u32 vcd_handle_first_fill_output_buffer_for_dec( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *frm_entry, + u32 *handled) +{ + u32 rc; + struct vcd_property_hdr prop_hdr; + struct vcd_buffer_pool *out_buf_pool; + struct ddl_property_dec_pic_buffers dpb; + struct ddl_frame_data_tag *dpb_list; + u8 i; + + (void)frm_entry; + *handled = true; + prop_hdr.prop_id = DDL_I_DPB; + prop_hdr.sz = sizeof(dpb); + out_buf_pool = &cctxt->out_buf_pool; + + dpb_list = (struct ddl_frame_data_tag *) + kmalloc((sizeof(struct ddl_frame_data_tag) * + out_buf_pool->count), GFP_KERNEL); + + if (!dpb_list) { + VCD_MSG_ERROR("Memory allocation failure"); + return VCD_ERR_ALLOC_FAIL; + } + + for (i = 1; i <= out_buf_pool->count; i++) + dpb_list[i - 1].vcd_frm = out_buf_pool->entries[i].frame; + + dpb.dec_pic_buffers = dpb_list; + dpb.no_of_dec_pic_buf = out_buf_pool->count; + rc = ddl_set_property(cctxt->ddl_handle, &prop_hdr, &dpb); + + kfree(dpb_list); + *handled = false; + + return VCD_S_SUCCESS; +} + +void vcd_handle_eos_trans_end(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + if (cctxt->status.mask & VCD_EOS_PREV_VALID) { + rc = vcd_handle_frame_done(cctxt, + (void *)&cctxt->status.eos_prev_op_frm, + VCD_EVT_RESP_OUTPUT_DONE, + cctxt->status.eos_prev_op_frm_status); + cctxt->status.mask &= ~VCD_EOS_PREV_VALID; + } + if (VCD_FAILED(rc)) + return; + + if (cctxt->status.mask & VCD_FLUSH_ALL) + vcd_process_pending_flush_in_eos(cctxt); + + if (cctxt->status.mask & VCD_STOP_PENDING) + vcd_process_pending_stop_in_eos(cctxt); + else { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } +} + +void vcd_handle_eos_done(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status) +{ + struct vcd_frame_data vcd_frm; + u32 rc = VCD_S_SUCCESS, sent_eos_frm = false; + VCD_MSG_LOW("vcd_handle_eos_done:"); + + if (VCD_FAILED(status)) + VCD_MSG_ERROR("EOS DONE returned error = 0x%x", status); + + if (cctxt->status.mask & VCD_EOS_PREV_VALID) { + cctxt->status.eos_prev_op_frm.vcd_frm.flags |= + VCD_FRAME_FLAG_EOS; + + rc = vcd_handle_frame_done(cctxt, + (void *)&cctxt->status. + eos_prev_op_frm, + VCD_EVT_RESP_OUTPUT_DONE, + cctxt->status. + eos_prev_op_frm_status); + cctxt->status.mask &= ~VCD_EOS_PREV_VALID; + if (!VCD_FAILED(rc) && + cctxt->status.eos_prev_op_frm_status != + VCD_ERR_INTRLCD_FIELD_DROP) + sent_eos_frm = true; + } + if (!sent_eos_frm) { + if (transc->ip_buf_entry) { + transc->ip_buf_entry->frame.ip_frm_tag = + transc->ip_frm_tag; + + vcd_send_frame_done_in_eos(cctxt, + &transc->ip_buf_entry->frame, false); + } else { + memset(&vcd_frm, 0, sizeof(struct vcd_frame_data)); + vcd_frm.ip_frm_tag = transc->ip_frm_tag; + vcd_frm.time_stamp = transc->time_stamp; + vcd_frm.flags = VCD_FRAME_FLAG_EOS; + vcd_send_frame_done_in_eos(cctxt, &vcd_frm, true); + } + } + if (VCD_FAILED(rc)) + return; + if (transc->ip_buf_entry) { + if (transc->ip_buf_entry->frame.virtual) { + transc->ip_buf_entry->frame.ip_frm_tag = + transc->ip_frm_tag; + cctxt->callback(VCD_EVT_RESP_INPUT_DONE, + VCD_S_SUCCESS, + &transc->ip_buf_entry->frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + } + transc->ip_buf_entry->in_use = false; + VCD_BUFFERPOOL_INUSE_DECREMENT(cctxt->in_buf_pool.in_use); + transc->ip_buf_entry = NULL; + if (cctxt->status.frame_submitted) + cctxt->status.frame_submitted--; + else + cctxt->status.frame_delayed--; + } + + vcd_release_trans_tbl_entry(transc); + if (cctxt->status.mask & VCD_FLUSH_ALL) + vcd_process_pending_flush_in_eos(cctxt); + + if (cctxt->status.mask & VCD_STOP_PENDING) { + vcd_process_pending_stop_in_eos(cctxt); + } else if (!(cctxt->status.mask & VCD_EOS_WAIT_OP_BUF)) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER + (clnt_cb)); + } +} + +void vcd_handle_start_done(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status) +{ + cctxt->status.cmd_submitted--; + vcd_mark_command_channel(cctxt->dev_ctxt, transc); + + if (!VCD_FAILED(status)) { + cctxt->callback(VCD_EVT_RESP_START, status, NULL, + 0, cctxt, cctxt->client_data); + + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } else { + VCD_MSG_ERROR("ddl callback returned failure." + "status = 0x%x", status); + vcd_handle_err_in_starting(cctxt, status); + } +} + +void vcd_handle_stop_done(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status) +{ + + VCD_MSG_LOW("vcd_handle_stop_done:"); + cctxt->status.cmd_submitted--; + vcd_mark_command_channel(cctxt->dev_ctxt, transc); + + if (!VCD_FAILED(status)) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_OPEN, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } else { + VCD_MSG_FATAL("STOP_DONE returned error = 0x%x", status); + status = VCD_ERR_HW_FATAL; + vcd_handle_device_err_fatal(cctxt->dev_ctxt, cctxt); + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_INVALID, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } + + cctxt->callback(VCD_EVT_RESP_STOP, status, NULL, 0, cctxt, + cctxt->client_data); + + memset(&cctxt->status, 0, sizeof(struct vcd_clnt_status)); +} + +void vcd_handle_stop_done_in_starting(struct vcd_clnt_ctxt + *cctxt, struct vcd_transc *transc, u32 status) +{ + VCD_MSG_LOW("vcd_handle_stop_done_in_starting:"); + cctxt->status.cmd_submitted--; + vcd_mark_command_channel(cctxt->dev_ctxt, transc); + if (!VCD_FAILED(status)) { + cctxt->callback(VCD_EVT_RESP_START, cctxt->status. + last_err, NULL, 0, cctxt, cctxt->client_data); + vcd_do_client_state_transition(cctxt, VCD_CLIENT_STATE_OPEN, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } else { + VCD_MSG_FATAL("VCD Cleanup: STOP_DONE returned error " + "= 0x%x", status); + vcd_handle_err_fatal(cctxt, VCD_EVT_RESP_START, + VCD_ERR_HW_FATAL); + } +} + +void vcd_handle_stop_done_in_invalid(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status) +{ + u32 rc; + VCD_MSG_LOW("vcd_handle_stop_done_in_invalid:"); + + cctxt->status.cmd_submitted--; + vcd_mark_command_channel(cctxt->dev_ctxt, transc); + + if (!VCD_FAILED(status)) { + vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CLIENT_CLOSE); + if (cctxt->status.frame_submitted) { + vcd_release_multiple_frame_channels(cctxt->dev_ctxt, + cctxt->status.frame_submitted); + + cctxt->status.frame_submitted = 0; + cctxt->status.frame_delayed = 0; + } + if (cctxt->status.cmd_submitted) { + vcd_release_multiple_command_channels( + cctxt->dev_ctxt, + cctxt->status.cmd_submitted); + cctxt->status.cmd_submitted = 0; + } + } else { + VCD_MSG_FATAL("VCD Cleanup: STOP_DONE returned error " + "= 0x%x", status); + vcd_handle_device_err_fatal(cctxt->dev_ctxt, cctxt); + cctxt->status.mask &= ~VCD_CLEANING_UP; + } + vcd_flush_buffers_in_err_fatal(cctxt); + VCD_MSG_HIGH("VCD cleanup: All buffers are returned"); + if (cctxt->status.mask & VCD_STOP_PENDING) { + cctxt->callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS, NULL, 0, + cctxt, cctxt->client_data); + cctxt->status.mask &= ~VCD_STOP_PENDING; + } + rc = vcd_power_event(cctxt->dev_ctxt, cctxt, + VCD_EVT_PWR_CLNT_ERRFATAL); + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_ERRFATAL failed"); + if (!(cctxt->status.mask & VCD_CLEANING_UP) && + cctxt->status.mask & VCD_CLOSE_PENDING) { + vcd_destroy_client_context(cctxt); + vcd_handle_for_last_clnt_close(cctxt->dev_ctxt, false); + } +} + +u32 vcd_handle_input_frame( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + struct vcd_buffer_entry *buf_entry, *orig_frame; + struct vcd_frame_data *frm_entry; + u32 rc = VCD_S_SUCCESS; + u32 eos_handled = false; + + VCD_MSG_LOW("vcd_handle_input_frame:"); + + VCD_MSG_LOW("input buffer: addr=(0x%p), sz=(%d), len=(%d)", + input_frame->virtual, input_frame->alloc_len, + input_frame->data_len); + + if (!input_frame->virtual && + !(input_frame->flags & VCD_FRAME_FLAG_EOS)) { + VCD_MSG_ERROR("Bad frame ptr/len/EOS combination"); + return VCD_ERR_ILLEGAL_PARM; + } + + + if (!input_frame->data_len && + !(input_frame->flags & VCD_FRAME_FLAG_EOS)) { + VCD_MSG_MED("data_len = 0, returning INPUT DONE"); + cctxt->callback(VCD_EVT_RESP_INPUT_DONE, + VCD_ERR_INPUT_NOT_PROCESSED, + input_frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + return VCD_S_SUCCESS; + } + + if (!(cctxt->status.mask & VCD_FIRST_IP_RCVD)) { + if (cctxt->decoding) + rc = vcd_handle_first_decode_frame(cctxt); + + if (!VCD_FAILED(rc)) { + cctxt->status.first_ts = input_frame->time_stamp; + cctxt->status.prev_ts = cctxt->status.first_ts; + + cctxt->status.mask |= VCD_FIRST_IP_RCVD; + + (void)vcd_power_event(cctxt->dev_ctxt, + cctxt, + VCD_EVT_PWR_CLNT_FIRST_FRAME); + } + } + VCD_FAILED_RETURN(rc, "Failed: First frame handling"); + + orig_frame = vcd_find_buffer_pool_entry(&cctxt->in_buf_pool, + input_frame->virtual); + if (!orig_frame) { + VCD_MSG_ERROR("Bad buffer addr: %p", input_frame->virtual); + return VCD_ERR_FAIL; + } + + if (orig_frame->in_use) { + /* + * This path only allowed for enc., dec. not allowed + * to queue same buffer multiple times + */ + if (cctxt->decoding) { + VCD_MSG_ERROR("An inuse input frame is being " + "re-queued to scheduler"); + return VCD_ERR_FAIL; + } + + buf_entry = kzalloc(sizeof(*buf_entry), GFP_KERNEL); + if (!buf_entry) { + VCD_MSG_ERROR("Unable to alloc memory"); + return VCD_ERR_FAIL; + } + + INIT_LIST_HEAD(&buf_entry->sched_list); + /* + * Pre-emptively poisoning this, as these dupe entries + * shouldn't get added to any list + */ + INIT_LIST_HEAD(&buf_entry->list); + buf_entry->list.next = LIST_POISON1; + buf_entry->list.prev = LIST_POISON2; + + buf_entry->valid = orig_frame->valid; + buf_entry->alloc = orig_frame->alloc; + buf_entry->virtual = orig_frame->virtual; + buf_entry->physical = orig_frame->physical; + buf_entry->sz = orig_frame->sz; + buf_entry->allocated = orig_frame->allocated; + buf_entry->in_use = 1; /* meaningless for the dupe buffers */ + buf_entry->frame = orig_frame->frame; + } else + buf_entry = orig_frame; + + if (input_frame->alloc_len > buf_entry->sz) { + VCD_MSG_ERROR("Bad buffer Alloc_len %d, Actual sz=%d", + input_frame->alloc_len, buf_entry->sz); + + return VCD_ERR_ILLEGAL_PARM; + } + + frm_entry = &buf_entry->frame; + + *frm_entry = *input_frame; + frm_entry->physical = buf_entry->physical; + + if (input_frame->flags & VCD_FRAME_FLAG_EOS) { + rc = vcd_handle_recvd_eos(cctxt, input_frame, + &eos_handled); + } + + if (VCD_FAILED(rc) || eos_handled) { + VCD_MSG_HIGH("rc = 0x%x, eos_handled = %d", rc, + eos_handled); + + return rc; + } + rc = vcd_sched_queue_buffer( + cctxt->sched_clnt_hdl, buf_entry, true); + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_queue_buffer"); + + orig_frame->in_use++; + cctxt->in_buf_pool.in_use++; + vcd_try_submit_frame(dev_ctxt); + return rc; +} + +void vcd_release_all_clnt_frm_transc(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 i, cntr = 0; + VCD_MSG_LOW("vcd_release_all_clnt_frm_transc:"); + for (i = 0; i < dev_ctxt->trans_tbl_size; i++) { + if (dev_ctxt->trans_tbl[i].in_use && + cctxt == dev_ctxt->trans_tbl[i].cctxt) { + if (dev_ctxt->trans_tbl[i]. + type == VCD_CMD_CODE_FRAME || + dev_ctxt->trans_tbl[i]. + type == VCD_CMD_NONE) { + vcd_release_trans_tbl_entry(&dev_ctxt-> + trans_tbl[i]); + } else { + VCD_MSG_LOW("vcd_transaction in use type(%u)", + dev_ctxt->trans_tbl[i].type); + cntr++; + } + } + } + if (cntr) + VCD_MSG_ERROR("vcd_transactions still in use: (%d)", cntr); +} + +void vcd_release_all_clnt_transc(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 i; + + VCD_MSG_LOW("vcd_release_all_clnt_transc:"); + + for (i = 0; i < dev_ctxt->trans_tbl_size; i++) { + if (dev_ctxt->trans_tbl[i].in_use && + cctxt == dev_ctxt->trans_tbl[i].cctxt) { + vcd_release_trans_tbl_entry( + &dev_ctxt->trans_tbl[i]); + } + } +} + +void vcd_send_flush_done(struct vcd_clnt_ctxt *cctxt, u32 status) +{ + VCD_MSG_LOW("vcd_send_flush_done:"); + + if (cctxt->status.mask & VCD_FLUSH_INPUT) { + cctxt->callback(VCD_EVT_RESP_FLUSH_INPUT_DONE, + status, NULL, 0, cctxt, cctxt->client_data); + cctxt->status.mask &= ~VCD_FLUSH_INPUT; + } + + if (cctxt->status.mask & VCD_FLUSH_OUTPUT) { + cctxt->callback(VCD_EVT_RESP_FLUSH_OUTPUT_DONE, + status, NULL, 0, cctxt, cctxt->client_data); + cctxt->status.mask &= ~VCD_FLUSH_OUTPUT; + } +} + +u32 vcd_store_seq_hdr( + struct vcd_clnt_ctxt *cctxt, + struct vcd_sequence_hdr *seq_hdr) +{ + u32 rc; + struct vcd_property_hdr prop_hdr; + u32 align; + u8 *virtual_aligned; + u32 addr; + int ret = 0; + + if (!seq_hdr->sequence_header_len + || !seq_hdr->sequence_header) { + VCD_MSG_ERROR("Bad seq hdr"); + + return VCD_ERR_BAD_POINTER; + } + + if (cctxt->seq_hdr.sequence_header) { + VCD_MSG_HIGH("Old seq hdr detected"); + + vcd_pmem_free(cctxt->seq_hdr.sequence_header, + cctxt->seq_hdr_phy_addr, cctxt); + cctxt->seq_hdr.sequence_header = NULL; + } + + cctxt->seq_hdr.sequence_header_len = + seq_hdr->sequence_header_len; + + prop_hdr.prop_id = DDL_I_SEQHDR_ALIGN_BYTES; + prop_hdr.sz = sizeof(u32); + + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &align); + + VCD_FAILED_RETURN(rc, + "Failed: ddl_get_property DDL_I_SEQHDR_ALIGN_BYTES"); + + VCD_MSG_MED("Seq hdr alignment bytes = %d", align); + + ret = vcd_pmem_alloc(cctxt->seq_hdr.sequence_header_len + align + + VCD_SEQ_HDR_PADDING_BYTES, + &(cctxt->seq_hdr.sequence_header), + &(cctxt->seq_hdr_phy_addr), cctxt); + + if (ret < 0) { + VCD_MSG_ERROR("Seq hdr allocation failed"); + + return VCD_ERR_ALLOC_FAIL; + } + + if (!cctxt->seq_hdr_phy_addr) { + VCD_MSG_ERROR("Couldn't get physical address"); + + return VCD_ERR_BAD_POINTER; + } + + if (align > 0) { + addr = (u32) cctxt->seq_hdr_phy_addr; + addr += align; + addr -= (addr % align); + virtual_aligned = cctxt->seq_hdr.sequence_header; + virtual_aligned += (u32) (addr - + (u32) cctxt->seq_hdr_phy_addr); + cctxt->seq_hdr_phy_addr = (u8 *) addr; + } else { + virtual_aligned = cctxt->seq_hdr.sequence_header; + } + + memcpy(virtual_aligned, seq_hdr->sequence_header, + seq_hdr->sequence_header_len); + + return VCD_S_SUCCESS; +} + +u32 vcd_set_frame_rate( + struct vcd_clnt_ctxt *cctxt, + struct vcd_property_frame_rate *fps) +{ + u32 rc; + cctxt->frm_rate = *fps; + rc = vcd_update_clnt_perf_lvl(cctxt, &cctxt->frm_rate, + cctxt->frm_p_units); + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_update_clnt_perf_lvl", + rc); + } + rc = vcd_sched_update_config(cctxt); + return rc; +} + +u32 vcd_req_perf_level( + struct vcd_clnt_ctxt *cctxt, + struct vcd_property_perf_level *perf_level) +{ + u32 rc; + u32 res_trk_perf_level; + if (!perf_level) { + VCD_MSG_ERROR("Invalid parameters\n"); + return -EINVAL; + } + res_trk_perf_level = get_res_trk_perf_level(perf_level->level); + if (res_trk_perf_level < 0) { + rc = -ENOTSUPP; + goto perf_level_not_supp; + } + rc = vcd_set_perf_level(cctxt->dev_ctxt, res_trk_perf_level); + if (!rc) { + cctxt->reqd_perf_lvl = res_trk_perf_level; + cctxt->perf_set_by_client = 1; + } +perf_level_not_supp: + return rc; +} + +u32 vcd_set_frame_size( + struct vcd_clnt_ctxt *cctxt, + struct vcd_property_frame_size *frm_size) +{ + struct vcd_property_hdr prop_hdr; + u32 rc; + u32 frm_p_units; + (void)frm_size; + if (res_trk_get_disable_fullhd() && frm_size && + (frm_size->width * frm_size->height > 1280 * 720)) { + VCD_MSG_ERROR("Frame size = %dX%d greater than 1280X720 not" + "supported", frm_size->width, frm_size->height); + return VCD_ERR_FAIL; + } + prop_hdr.prop_id = DDL_I_FRAME_PROC_UNITS; + prop_hdr.sz = sizeof(frm_p_units); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &frm_p_units); + VCD_FAILED_RETURN(rc, "Failed: Get DDL_I_FRAME_PROC_UNITS"); + + cctxt->frm_p_units = frm_p_units; + + rc = vcd_update_clnt_perf_lvl(cctxt, &cctxt->frm_rate, + frm_p_units); + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_update_clnt_perf_lvl", + rc); + } + return rc; +} + +void vcd_process_pending_flush_in_eos(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + VCD_MSG_HIGH("Buffer flush is pending"); + rc = vcd_flush_buffers(cctxt, cctxt->status.mask & VCD_FLUSH_ALL); + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_flush_buffers", rc); + cctxt->status.mask &= ~VCD_EOS_WAIT_OP_BUF; + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); +} + +void vcd_process_pending_stop_in_eos(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + rc = vcd_flush_buffers(cctxt, VCD_FLUSH_ALL); + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_flush_buffers", rc); + VCD_MSG_HIGH("All buffers are returned. Enqueuing stop cmd"); + vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CODEC_STOP); + cctxt->status.mask &= ~VCD_STOP_PENDING; + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_STOPPING, + CLIENT_STATE_EVENT_NUMBER(stop)); +} + +u32 vcd_calculate_frame_delta( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *frame) +{ + u32 frm_delta; + u64 temp, max = ~((u64)0); + + if (cctxt->time_frame_delta) + temp = cctxt->time_frame_delta; + else if (frame->time_stamp >= cctxt->status.prev_ts) + temp = frame->time_stamp - cctxt->status.prev_ts; + else + temp = (max - cctxt->status.prev_ts) + + frame->time_stamp; + + VCD_MSG_LOW("Curr_ts=%lld Prev_ts=%lld Diff=%llu\n", + frame->time_stamp, cctxt->status.prev_ts, temp); + + temp *= cctxt->time_resoln; + (void)do_div(temp, VCD_TIMESTAMP_RESOLUTION); + frm_delta = temp; + cctxt->status.time_elapsed += frm_delta; + + temp = (cctxt->status.time_elapsed * VCD_TIMESTAMP_RESOLUTION); + (void)do_div(temp, cctxt->time_resoln); + cctxt->status.prev_ts = cctxt->status.first_ts + temp; + + VCD_MSG_LOW("Time_elapsed=%llu, Drift=%llu, new Prev_ts=%lld", + cctxt->status.time_elapsed, temp, + cctxt->status.prev_ts); + + return frm_delta; +} + +struct vcd_buffer_entry *vcd_check_fill_output_buffer + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer) { + struct vcd_buffer_pool *buf_pool = &cctxt->out_buf_pool; + struct vcd_buffer_entry *buf_entry; + + if (!buf_pool->entries) { + VCD_MSG_ERROR("Buffers not set or allocated yet"); + + return NULL; + } + + if (!buffer->virtual) { + VCD_MSG_ERROR("NULL buffer address provided"); + return NULL; + } + + buf_entry = + vcd_find_buffer_pool_entry(buf_pool, buffer->virtual); + if (!buf_entry) { + VCD_MSG_ERROR("Unrecognized buffer address provided = %p", + buffer->virtual); + return NULL; + } + + if (buf_entry->in_use) { + VCD_MSG_ERROR + ("An inuse output frame is being provided for reuse"); + return NULL; + } + + if ((buffer->alloc_len < buf_pool->buf_req.sz || + buffer->alloc_len > buf_entry->sz) && + !(cctxt->status.mask & VCD_IN_RECONFIG)) { + VCD_MSG_ERROR + ("Bad buffer Alloc_len = %d, Actual sz = %d, " + " Min sz = %u", + buffer->alloc_len, buf_entry->sz, + buf_pool->buf_req.sz); + return NULL; + } + + return buf_entry; +} + +void vcd_handle_ind_hw_err_fatal(struct vcd_clnt_ctxt *cctxt, + u32 event, u32 status) +{ + if (cctxt->status.frame_submitted) { + cctxt->status.frame_submitted--; + vcd_mark_frame_channel(cctxt->dev_ctxt); + } + vcd_handle_err_fatal(cctxt, event, status); +} + +void vcd_handle_err_fatal(struct vcd_clnt_ctxt *cctxt, u32 event, + u32 status) +{ + VCD_MSG_LOW("vcd_handle_err_fatal: event=%x, err=%x", event, status); + if (!VCD_FAILED_FATAL(status)) + return; + + if (VCD_FAILED_DEVICE_FATAL(status)) { + vcd_clnt_handle_device_err_fatal(cctxt, event); + vcd_handle_device_err_fatal(cctxt->dev_ctxt, cctxt); + } else if (VCD_FAILED_CLIENT_FATAL(status)) { + cctxt->status.last_evt = event; + cctxt->callback(event, VCD_ERR_HW_FATAL, NULL, 0, cctxt, + cctxt->client_data); + cctxt->status.mask |= VCD_CLEANING_UP; + vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CODEC_STOP); + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_INVALID, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } +} + +void vcd_handle_err_in_starting(struct vcd_clnt_ctxt *cctxt, + u32 status) +{ + VCD_MSG_LOW("\n vcd_handle_err_in_starting:"); + if (VCD_FAILED_FATAL(status)) { + vcd_handle_err_fatal(cctxt, VCD_EVT_RESP_START, status); + } else { + cctxt->status.last_err = status; + VCD_MSG_HIGH("\n VCD cleanup: Enqueuing stop cmd"); + vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CODEC_STOP); + } +} + +void vcd_handle_trans_pending(struct vcd_clnt_ctxt *cctxt) +{ + if (!cctxt->status.frame_submitted) { + VCD_MSG_ERROR("Transaction pending response was not expected"); + return; + } + cctxt->status.frame_submitted--; + cctxt->status.frame_delayed++; + vcd_mark_frame_channel(cctxt->dev_ctxt); +} +void vcd_handle_submit_frame_failed(struct vcd_dev_ctxt + *dev_ctxt, struct vcd_transc *transc) +{ + struct vcd_clnt_ctxt *cctxt = transc->cctxt; + u32 rc; + + vcd_mark_frame_channel(dev_ctxt); + vcd_release_trans_tbl_entry(transc); + + vcd_handle_err_fatal(cctxt, VCD_EVT_IND_HWERRFATAL, + VCD_ERR_CLIENT_FATAL); + + if (vcd_get_command_channel(dev_ctxt, &transc)) { + transc->type = VCD_CMD_CODEC_STOP; + transc->cctxt = cctxt; + rc = vcd_submit_cmd_sess_end(transc); + if (VCD_FAILED(rc)) { + vcd_release_command_channel(dev_ctxt, transc); + VCD_MSG_ERROR("rc = 0x%x. Failed: VCD_SubmitCmdSessEnd", + rc); + } + } +} + +u32 vcd_check_if_buffer_req_met(struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer) +{ + struct vcd_property_hdr prop_hdr; + struct vcd_buffer_pool *buf_pool; + struct vcd_buffer_requirement buf_req; + u32 rc; + u8 i; + + if (buffer == VCD_BUFFER_INPUT) { + prop_hdr.prop_id = DDL_I_INPUT_BUF_REQ; + buf_pool = &cctxt->in_buf_pool; + } else { + prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ; + buf_pool = &cctxt->out_buf_pool; + } + + prop_hdr.sz = sizeof(buf_req); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &buf_req); + VCD_FAILED_RETURN(rc, "Failed: ddl_GetProperty"); + + buf_pool->buf_req = buf_req; + if (buf_pool->count < buf_req.actual_count) { + VCD_MSG_ERROR("Buf requirement count not met"); + return VCD_ERR_FAIL; + } + + if (buf_pool->count > buf_req.actual_count) + buf_pool->count = buf_req.actual_count; + + if (!buf_pool->entries || + buf_pool->validated != buf_pool->count) { + VCD_MSG_ERROR("Buffer pool is not completely setup yet"); + return VCD_ERR_BAD_STATE; + } + for (i = 1; (rc == VCD_S_SUCCESS && i <= buf_pool->count); i++) { + if (buf_pool->entries[i].sz < + buf_pool->buf_req.sz) { + VCD_MSG_ERROR( + "BufReq sz not met:\ + addr=(0x%p) sz=%d ReqSize=%d", + buf_pool->entries[i].virtual, + buf_pool->entries[i].sz, + buf_pool->buf_req.sz); + rc = VCD_ERR_FAIL; + } + } + return rc; +} + +u32 vcd_handle_ind_output_reconfig( + struct vcd_clnt_ctxt *cctxt, void* payload, u32 status) +{ + struct ddl_frame_data_tag *frame = + (struct ddl_frame_data_tag *)payload; + struct vcd_property_hdr prop_hdr; + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_pool *out_buf_pool; + struct vcd_buffer_requirement buf_req; + + if (frame) + rc = vcd_handle_output_required(cctxt, payload, status); + VCD_FAILED_RETURN(rc, "Failed: vcd_handle_output_required in reconfig"); + vcd_mark_frame_channel(cctxt->dev_ctxt); + + rc = vcd_sched_suspend_resume_clnt(cctxt, false); + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_suspend_resume_clnt"); + out_buf_pool = &cctxt->out_buf_pool; + prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ; + prop_hdr.sz = sizeof(buf_req); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &buf_req); + VCD_FAILED_RETURN(rc, "Failed: ddl_GetProperty"); + + out_buf_pool->buf_req = buf_req; + + if (out_buf_pool->count < buf_req.actual_count) { + VCD_MSG_HIGH("Output buf requirement count increased"); + out_buf_pool->count = buf_req.actual_count; + } + + if (buf_req.actual_count > VCD_MAX_BUFFER_ENTRIES) { + VCD_MSG_ERROR("\n New act count exceeds Max count(32)"); + return VCD_ERR_FAIL; + } + + if (!VCD_FAILED(rc)) { + rc = vcd_set_frame_size(cctxt, NULL); + VCD_FAILED_RETURN(rc, "Failed: set_frame_size in reconfig"); + cctxt->status.mask &= ~VCD_FIRST_OP_RCVD; + cctxt->status.mask |= VCD_IN_RECONFIG; + cctxt->callback(VCD_EVT_IND_OUTPUT_RECONFIG, + status, NULL, 0, cctxt, + cctxt->client_data); + } + return rc; +} + +u32 vcd_handle_ind_output_reconfig_in_flushing( + struct vcd_clnt_ctxt *cctxt, void* payload, u32 status) +{ + u32 rc = VCD_S_SUCCESS; + if (cctxt->status.mask & VCD_FLUSH_INPUT && payload) { + (void)vcd_handle_input_done(cctxt, payload, + VCD_EVT_RESP_INPUT_FLUSHED, status); + payload = NULL; + } + rc = vcd_handle_ind_output_reconfig(cctxt, payload, status); + return rc; +} + +u32 vcd_return_op_buffer_to_hw(struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_entry *buf_entry) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_frame_data *frm_entry = &buf_entry->frame; + + VCD_MSG_LOW("vcd_return_op_buffer_to_hw in %d:", + cctxt->clnt_state.state); + frm_entry->physical = buf_entry->physical; + frm_entry->ip_frm_tag = VCD_FRAMETAG_INVALID; + frm_entry->intrlcd_ip_frm_tag = VCD_FRAMETAG_INVALID; + frm_entry->data_len = 0; + + if (cctxt->decoding) { + struct vcd_property_hdr Prop_hdr; + struct ddl_frame_data_tag ddl_frm; + Prop_hdr.prop_id = DDL_I_DPB_RELEASE; + Prop_hdr.sz = + sizeof(struct ddl_frame_data_tag); + memset(&ddl_frm, 0, sizeof(ddl_frm)); + ddl_frm.vcd_frm = *frm_entry; + rc = ddl_set_property(cctxt->ddl_handle, &Prop_hdr, + &ddl_frm); + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("Error returning output buffer to" + " HW. rc = 0x%x", rc); + buf_entry->in_use = false; + } else { + cctxt->out_buf_pool.in_use++; + buf_entry->in_use = true; + } + } + return rc; +} + +void vcd_handle_clnt_fatal(struct vcd_clnt_ctxt *cctxt, u32 trans_end) +{ + if (trans_end) + vcd_mark_frame_channel(cctxt->dev_ctxt); + vcd_handle_err_fatal(cctxt, + VCD_EVT_IND_HWERRFATAL, VCD_ERR_CLIENT_FATAL); +} + +void vcd_handle_clnt_fatal_input_done(struct vcd_clnt_ctxt *cctxt, + u32 trans_end) +{ + if (cctxt->status.frame_submitted > 0) + cctxt->status.frame_submitted--; + vcd_handle_clnt_fatal(cctxt, trans_end); +} + +void vcd_handle_ind_info_output_reconfig( + struct vcd_clnt_ctxt *cctxt, u32 status) +{ + if (cctxt) { + cctxt->callback(VCD_EVT_IND_INFO_OUTPUT_RECONFIG, status, NULL, + 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/drivers/video/msm/vidc/common/vcd/vcd_util.c b/drivers/video/msm/vidc/common/vcd/vcd_util.c new file mode 100644 index 0000000000000000000000000000000000000000..98bc7f553e96ce4a5c4f1f3620c57881a2a6a4c1 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_util.c @@ -0,0 +1,106 @@ +/* Copyright (c) 2010, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "vidc_type.h" +#include "vcd_util.h" + +u32 vcd_critical_section_create(u32 **p_cs) +{ + struct mutex *lock; + if (!p_cs) { + VCD_MSG_ERROR("Bad critical section ptr"); + return VCD_ERR_BAD_POINTER; + } else { + lock = kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (!lock) { + VCD_MSG_ERROR("Failed: vcd_critical_section_create"); + return VCD_ERR_ALLOC_FAIL; + } + mutex_init(lock); + *p_cs = (u32 *) lock; + return VCD_S_SUCCESS; + } +} + +u32 vcd_critical_section_release(u32 *cs) +{ + struct mutex *lock = (struct mutex *)cs; + if (!lock) { + VCD_MSG_ERROR("Bad critical section object"); + return VCD_ERR_BAD_POINTER; + } + + mutex_destroy(lock); + kfree(cs); + return VCD_S_SUCCESS; +} + +u32 vcd_critical_section_enter(u32 *cs) +{ + struct mutex *lock = (struct mutex *)cs; + if (!lock) { + VCD_MSG_ERROR("Bad critical section object"); + return VCD_ERR_BAD_POINTER; + } else + mutex_lock(lock); + + return VCD_S_SUCCESS; +} + +u32 vcd_critical_section_leave(u32 *cs) +{ + struct mutex *lock = (struct mutex *)cs; + + if (!lock) { + VCD_MSG_ERROR("Bad critical section object"); + + return VCD_ERR_BAD_POINTER; + } else + mutex_unlock(lock); + + return VCD_S_SUCCESS; +} + +int vcd_pmem_alloc(u32 size, u8 **kernel_vaddr, u8 **phy_addr) +{ + *phy_addr = + (u8 *) pmem_kalloc(size, PMEM_MEMTYPE | PMEM_ALIGNMENT_4K); + + if (!IS_ERR((void *)*phy_addr)) { + + *kernel_vaddr = ioremap((unsigned long)*phy_addr, size); + + if (!*kernel_vaddr) { + pr_err("%s: could not ioremap in kernel pmem buffers\n", + __func__); + pmem_kfree((s32) *phy_addr); + return -ENOMEM; + } + pr_debug("write buf: phy addr 0x%08x kernel addr 0x%08x\n", + (u32) *phy_addr, (u32) *kernel_vaddr); + return 0; + } else { + pr_err("%s: could not allocte in kernel pmem buffers\n", + __func__); + return -ENOMEM; + } + +} + +int vcd_pmem_free(u8 *kernel_vaddr, u8 *phy_addr) +{ + iounmap((void *)kernel_vaddr); + pmem_kfree((s32) phy_addr); + + return 0; +} diff --git a/drivers/video/msm/vidc/common/vcd/vcd_util.h b/drivers/video/msm/vidc/common/vcd/vcd_util.h new file mode 100644 index 0000000000000000000000000000000000000000..7571b25fcebad5b4daf6c7519bb405631cbf3f78 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_util.h @@ -0,0 +1,52 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_UTIL_H_ +#define _VCD_UTIL_H_ +#include +#include + +#if DEBUG + +#define VCD_MSG_LOW(xx_fmt...) printk(KERN_INFO "\n\t* " xx_fmt) +#define VCD_MSG_MED(xx_fmt...) printk(KERN_INFO "\n * " xx_fmt) +#define VCD_MSG_HIGH(xx_fmt...) printk(KERN_WARNING "\n" xx_fmt) + +#else + +#define VCD_MSG_LOW(xx_fmt...) +#define VCD_MSG_MED(xx_fmt...) +#define VCD_MSG_HIGH(xx_fmt...) + +#endif + +#define VCD_MSG_ERROR(xx_fmt...) printk(KERN_ERR "\n err: " xx_fmt) +#define VCD_MSG_FATAL(xx_fmt...) printk(KERN_ERR "\n " xx_fmt) + +#define VCD_FAILED_RETURN(rc, xx_fmt...) \ + do { \ + if (VCD_FAILED(rc)) { \ + printk(KERN_ERR xx_fmt); \ + return rc; \ + } \ + } while (0) + +#define VCD_FAILED_DEVICE_FATAL(rc) \ + (rc == VCD_ERR_HW_FATAL ? true : false) +#define VCD_FAILED_CLIENT_FATAL(rc) \ + (rc == VCD_ERR_CLIENT_FATAL ? true : false) + +#define VCD_FAILED_FATAL(rc) \ + ((VCD_FAILED_DEVICE_FATAL(rc) || VCD_FAILED_CLIENT_FATAL(rc)) \ + ? true : false) + +#endif diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h index fe722c1fb61d552afa87d0d6e62c0da6bd8f82af..b4821a2b4d698fa0b78cf67bde7176fe9376959d 100644 --- a/include/linux/msm_mdp.h +++ b/include/linux/msm_mdp.h @@ -1,6 +1,7 @@ /* include/linux/msm_mdp.h * * Copyright (C) 2007 Google Incorporated + * Copyright (c) 2012 The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -14,66 +15,19 @@ #ifndef _MSM_MDP_H_ #define _MSM_MDP_H_ -#include - -#define MSMFB_IOCTL_MAGIC 'm' -#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int) -#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int) - -enum { - MDP_RGB_565, /* RGB 565 planar */ - MDP_XRGB_8888, /* RGB 888 padded */ - MDP_Y_CBCR_H2V2, /* Y and CbCr, pseudo planar w/ Cb is in MSB */ - MDP_ARGB_8888, /* ARGB 888 */ - MDP_RGB_888, /* RGB 888 planar */ - MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planar w/ Cr is in MSB */ - MDP_YCRYCB_H2V1, /* YCrYCb interleave */ - MDP_Y_CRCB_H2V1, /* Y and CrCb, pseduo planar w/ Cr is in MSB */ - MDP_Y_CBCR_H2V1, /* Y and CrCb, pseduo planar w/ Cr is in MSB */ - MDP_RGBA_8888, /* ARGB 888 */ - MDP_BGRA_8888, /* ABGR 888 */ - MDP_RGBX_8888, /* RGBX 888 */ - MDP_IMGTYPE_LIMIT /* Non valid image type after this enum */ -}; - -enum { - PMEM_IMG, - FB_IMG, -}; - -/* flag values */ -#define MDP_ROT_NOP 0 -#define MDP_FLIP_LR 0x1 -#define MDP_FLIP_UD 0x2 -#define MDP_ROT_90 0x4 -#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR) -#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR) -#define MDP_DITHER 0x8 -#define MDP_BLUR 0x10 - -#define MDP_TRANSP_NOP 0xffffffff -#define MDP_ALPHA_NOP 0xff - -struct mdp_rect { - u32 x, y, w, h; -}; - -struct mdp_img { - u32 width, height, format, offset; - int memory_id; /* the file descriptor */ -}; - -struct mdp_blit_req { - struct mdp_img src; - struct mdp_img dst; - struct mdp_rect src_rect; - struct mdp_rect dst_rect; - u32 alpha, transp_mask, flags; -}; - -struct mdp_blit_req_list { - u32 count; - struct mdp_blit_req req[]; -}; - -#endif /* _MSM_MDP_H_ */ +#include + +/* get the framebuffer physical address information */ +int get_fb_phys_info(unsigned long *start, unsigned long *len, int fb_num, + int subsys_id); +struct fb_info *msm_fb_get_writeback_fb(void); +int msm_fb_writeback_init(struct fb_info *info); +int msm_fb_writeback_start(struct fb_info *info); +int msm_fb_writeback_queue_buffer(struct fb_info *info, + struct msmfb_data *data); +int msm_fb_writeback_dequeue_buffer(struct fb_info *info, + struct msmfb_data *data); +int msm_fb_writeback_stop(struct fb_info *info); +int msm_fb_writeback_terminate(struct fb_info *info); + +#endif /*_MSM_MDP_H_*/ diff --git a/include/linux/msm_vidc_dec.h b/include/linux/msm_vidc_dec.h new file mode 100644 index 0000000000000000000000000000000000000000..0c03e136c3c9d86407b05022df834444e46c16a6 --- /dev/null +++ b/include/linux/msm_vidc_dec.h @@ -0,0 +1,568 @@ +#ifndef _MSM_VIDC_DEC_H_ +#define _MSM_VIDC_DEC_H_ + +#include +#include + +/* STATUS CODES */ +/* Base value for status codes */ +#define VDEC_S_BASE 0x40000000 +/* Success */ +#define VDEC_S_SUCCESS (VDEC_S_BASE) +/* General failure */ +#define VDEC_S_EFAIL (VDEC_S_BASE + 1) +/* Fatal irrecoverable failure. Need to tear down session. */ +#define VDEC_S_EFATAL (VDEC_S_BASE + 2) +/* Error detected in the passed parameters */ +#define VDEC_S_EBADPARAM (VDEC_S_BASE + 3) +/* Command called in invalid state. */ +#define VDEC_S_EINVALSTATE (VDEC_S_BASE + 4) + /* Insufficient OS resources - thread, memory etc. */ +#define VDEC_S_ENOSWRES (VDEC_S_BASE + 5) + /* Insufficient HW resources - core capacity maxed out. */ +#define VDEC_S_ENOHWRES (VDEC_S_BASE + 6) +/* Invalid command called */ +#define VDEC_S_EINVALCMD (VDEC_S_BASE + 7) +/* Command timeout. */ +#define VDEC_S_ETIMEOUT (VDEC_S_BASE + 8) +/* Pre-requirement is not met for API. */ +#define VDEC_S_ENOPREREQ (VDEC_S_BASE + 9) +/* Command queue is full. */ +#define VDEC_S_ECMDQFULL (VDEC_S_BASE + 10) +/* Command is not supported by this driver */ +#define VDEC_S_ENOTSUPP (VDEC_S_BASE + 11) +/* Command is not implemented by thedriver. */ +#define VDEC_S_ENOTIMPL (VDEC_S_BASE + 12) +/* Command is not implemented by the driver. */ +#define VDEC_S_BUSY (VDEC_S_BASE + 13) +#define VDEC_S_INPUT_BITSTREAM_ERR (VDEC_S_BASE + 14) + +#define VDEC_INTF_VER 1 +#define VDEC_MSG_BASE 0x0000000 +/* Codes to identify asynchronous message responses and events that driver + wants to communicate to the app.*/ +#define VDEC_MSG_INVALID (VDEC_MSG_BASE + 0) +#define VDEC_MSG_RESP_INPUT_BUFFER_DONE (VDEC_MSG_BASE + 1) +#define VDEC_MSG_RESP_OUTPUT_BUFFER_DONE (VDEC_MSG_BASE + 2) +#define VDEC_MSG_RESP_INPUT_FLUSHED (VDEC_MSG_BASE + 3) +#define VDEC_MSG_RESP_OUTPUT_FLUSHED (VDEC_MSG_BASE + 4) +#define VDEC_MSG_RESP_FLUSH_INPUT_DONE (VDEC_MSG_BASE + 5) +#define VDEC_MSG_RESP_FLUSH_OUTPUT_DONE (VDEC_MSG_BASE + 6) +#define VDEC_MSG_RESP_START_DONE (VDEC_MSG_BASE + 7) +#define VDEC_MSG_RESP_STOP_DONE (VDEC_MSG_BASE + 8) +#define VDEC_MSG_RESP_PAUSE_DONE (VDEC_MSG_BASE + 9) +#define VDEC_MSG_RESP_RESUME_DONE (VDEC_MSG_BASE + 10) +#define VDEC_MSG_RESP_RESOURCE_LOADED (VDEC_MSG_BASE + 11) +#define VDEC_EVT_RESOURCES_LOST (VDEC_MSG_BASE + 12) +#define VDEC_MSG_EVT_CONFIG_CHANGED (VDEC_MSG_BASE + 13) +#define VDEC_MSG_EVT_HW_ERROR (VDEC_MSG_BASE + 14) +#define VDEC_MSG_EVT_INFO_CONFIG_CHANGED (VDEC_MSG_BASE + 15) +#define VDEC_MSG_EVT_INFO_FIELD_DROPPED (VDEC_MSG_BASE + 16) + +/*Buffer flags bits masks.*/ +#define VDEC_BUFFERFLAG_EOS 0x00000001 +#define VDEC_BUFFERFLAG_DECODEONLY 0x00000004 +#define VDEC_BUFFERFLAG_DATACORRUPT 0x00000008 +#define VDEC_BUFFERFLAG_ENDOFFRAME 0x00000010 +#define VDEC_BUFFERFLAG_SYNCFRAME 0x00000020 +#define VDEC_BUFFERFLAG_EXTRADATA 0x00000040 +#define VDEC_BUFFERFLAG_CODECCONFIG 0x00000080 + +/*Post processing flags bit masks*/ +#define VDEC_EXTRADATA_NONE 0x001 +#define VDEC_EXTRADATA_QP 0x004 +#define VDEC_EXTRADATA_MB_ERROR_MAP 0x008 +#define VDEC_EXTRADATA_SEI 0x010 +#define VDEC_EXTRADATA_VUI 0x020 +#define VDEC_EXTRADATA_VC1 0x040 + +#define VDEC_CMDBASE 0x800 +#define VDEC_CMD_SET_INTF_VERSION (VDEC_CMDBASE) + +#define VDEC_IOCTL_MAGIC 'v' + +struct vdec_ioctl_msg { + void __user *in; + void __user *out; +}; + +/* CMD params: InputParam:enum vdec_codec + OutputParam: struct vdec_profile_level*/ +#define VDEC_IOCTL_GET_PROFILE_LEVEL_SUPPORTED \ + _IOWR(VDEC_IOCTL_MAGIC, 0, struct vdec_ioctl_msg) + +/*CMD params:InputParam: NULL + OutputParam: uint32_t(bitmask)*/ +#define VDEC_IOCTL_GET_INTERLACE_FORMAT \ + _IOR(VDEC_IOCTL_MAGIC, 1, struct vdec_ioctl_msg) + +/* CMD params: InputParam: enum vdec_codec + OutputParam: struct vdec_profile_level*/ +#define VDEC_IOCTL_GET_CURRENT_PROFILE_LEVEL \ + _IOWR(VDEC_IOCTL_MAGIC, 2, struct vdec_ioctl_msg) + +/*CMD params: SET: InputParam: enum vdec_output_fromat OutputParam: NULL + GET: InputParam: NULL OutputParam: enum vdec_output_fromat*/ +#define VDEC_IOCTL_SET_OUTPUT_FORMAT \ + _IOWR(VDEC_IOCTL_MAGIC, 3, struct vdec_ioctl_msg) +#define VDEC_IOCTL_GET_OUTPUT_FORMAT \ + _IOWR(VDEC_IOCTL_MAGIC, 4, struct vdec_ioctl_msg) + +/*CMD params: SET: InputParam: enum vdec_codec OutputParam: NULL + GET: InputParam: NULL OutputParam: enum vdec_codec*/ +#define VDEC_IOCTL_SET_CODEC \ + _IOW(VDEC_IOCTL_MAGIC, 5, struct vdec_ioctl_msg) +#define VDEC_IOCTL_GET_CODEC \ + _IOR(VDEC_IOCTL_MAGIC, 6, struct vdec_ioctl_msg) + +/*CMD params: SET: InputParam: struct vdec_picsize outputparam: NULL + GET: InputParam: NULL outputparam: struct vdec_picsize*/ +#define VDEC_IOCTL_SET_PICRES \ + _IOW(VDEC_IOCTL_MAGIC, 7, struct vdec_ioctl_msg) +#define VDEC_IOCTL_GET_PICRES \ + _IOR(VDEC_IOCTL_MAGIC, 8, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_SET_EXTRADATA \ + _IOW(VDEC_IOCTL_MAGIC, 9, struct vdec_ioctl_msg) +#define VDEC_IOCTL_GET_EXTRADATA \ + _IOR(VDEC_IOCTL_MAGIC, 10, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_SET_SEQUENCE_HEADER \ + _IOW(VDEC_IOCTL_MAGIC, 11, struct vdec_ioctl_msg) + +/* CMD params: SET: InputParam - vdec_allocatorproperty, OutputParam - NULL + GET: InputParam - NULL, OutputParam - vdec_allocatorproperty*/ +#define VDEC_IOCTL_SET_BUFFER_REQ \ + _IOW(VDEC_IOCTL_MAGIC, 12, struct vdec_ioctl_msg) +#define VDEC_IOCTL_GET_BUFFER_REQ \ + _IOR(VDEC_IOCTL_MAGIC, 13, struct vdec_ioctl_msg) +/* CMD params: InputParam - vdec_buffer, OutputParam - uint8_t** */ +#define VDEC_IOCTL_ALLOCATE_BUFFER \ + _IOWR(VDEC_IOCTL_MAGIC, 14, struct vdec_ioctl_msg) +/* CMD params: InputParam - uint8_t *, OutputParam - NULL.*/ +#define VDEC_IOCTL_FREE_BUFFER \ + _IOW(VDEC_IOCTL_MAGIC, 15, struct vdec_ioctl_msg) + +/*CMD params: CMD: InputParam - struct vdec_setbuffer_cmd, OutputParam - NULL*/ +#define VDEC_IOCTL_SET_BUFFER \ + _IOW(VDEC_IOCTL_MAGIC, 16, struct vdec_ioctl_msg) + +/* CMD params: InputParam - struct vdec_fillbuffer_cmd, OutputParam - NULL*/ +#define VDEC_IOCTL_FILL_OUTPUT_BUFFER \ + _IOW(VDEC_IOCTL_MAGIC, 17, struct vdec_ioctl_msg) + +/*CMD params: InputParam - struct vdec_frameinfo , OutputParam - NULL*/ +#define VDEC_IOCTL_DECODE_FRAME \ + _IOW(VDEC_IOCTL_MAGIC, 18, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_LOAD_RESOURCES _IO(VDEC_IOCTL_MAGIC, 19) +#define VDEC_IOCTL_CMD_START _IO(VDEC_IOCTL_MAGIC, 20) +#define VDEC_IOCTL_CMD_STOP _IO(VDEC_IOCTL_MAGIC, 21) +#define VDEC_IOCTL_CMD_PAUSE _IO(VDEC_IOCTL_MAGIC, 22) +#define VDEC_IOCTL_CMD_RESUME _IO(VDEC_IOCTL_MAGIC, 23) + +/*CMD params: InputParam - enum vdec_bufferflush , OutputParam - NULL */ +#define VDEC_IOCTL_CMD_FLUSH _IOW(VDEC_IOCTL_MAGIC, 24, struct vdec_ioctl_msg) + +/* ======================================================== + * IOCTL for getting asynchronous notification from driver + * ========================================================*/ + +/*IOCTL params: InputParam - NULL, OutputParam - struct vdec_msginfo*/ +#define VDEC_IOCTL_GET_NEXT_MSG \ + _IOR(VDEC_IOCTL_MAGIC, 25, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_STOP_NEXT_MSG _IO(VDEC_IOCTL_MAGIC, 26) + +#define VDEC_IOCTL_GET_NUMBER_INSTANCES \ + _IOR(VDEC_IOCTL_MAGIC, 27, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_SET_PICTURE_ORDER \ + _IOW(VDEC_IOCTL_MAGIC, 28, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_SET_FRAME_RATE \ + _IOW(VDEC_IOCTL_MAGIC, 29, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_SET_H264_MV_BUFFER \ + _IOW(VDEC_IOCTL_MAGIC, 30, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_FREE_H264_MV_BUFFER \ + _IOW(VDEC_IOCTL_MAGIC, 31, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_GET_MV_BUFFER_SIZE \ + _IOR(VDEC_IOCTL_MAGIC, 32, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_SET_IDR_ONLY_DECODING \ + _IO(VDEC_IOCTL_MAGIC, 33) + +#define VDEC_IOCTL_SET_CONT_ON_RECONFIG \ + _IO(VDEC_IOCTL_MAGIC, 34) + +#define VDEC_IOCTL_SET_DISABLE_DMX \ + _IOW(VDEC_IOCTL_MAGIC, 35, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_GET_DISABLE_DMX \ + _IOR(VDEC_IOCTL_MAGIC, 36, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT \ + _IOR(VDEC_IOCTL_MAGIC, 37, struct vdec_ioctl_msg) + +enum vdec_picture { + PICTURE_TYPE_I, + PICTURE_TYPE_P, + PICTURE_TYPE_B, + PICTURE_TYPE_BI, + PICTURE_TYPE_SKIP, + PICTURE_TYPE_IDR, + PICTURE_TYPE_UNKNOWN +}; + +enum vdec_buffer { + VDEC_BUFFER_TYPE_INPUT, + VDEC_BUFFER_TYPE_OUTPUT +}; + +struct vdec_allocatorproperty { + enum vdec_buffer buffer_type; + uint32_t mincount; + uint32_t maxcount; + uint32_t actualcount; + size_t buffer_size; + uint32_t alignment; + uint32_t buf_poolid; +}; + +struct vdec_bufferpayload { + void __user *bufferaddr; + size_t buffer_len; + int pmem_fd; + size_t offset; + size_t mmaped_size; +}; + +struct vdec_setbuffer_cmd { + enum vdec_buffer buffer_type; + struct vdec_bufferpayload buffer; +}; + +struct vdec_fillbuffer_cmd { + struct vdec_bufferpayload buffer; + void *client_data; +}; + +enum vdec_bufferflush { + VDEC_FLUSH_TYPE_INPUT, + VDEC_FLUSH_TYPE_OUTPUT, + VDEC_FLUSH_TYPE_ALL +}; + +enum vdec_codec { + VDEC_CODECTYPE_H264 = 0x1, + VDEC_CODECTYPE_H263 = 0x2, + VDEC_CODECTYPE_MPEG4 = 0x3, + VDEC_CODECTYPE_DIVX_3 = 0x4, + VDEC_CODECTYPE_DIVX_4 = 0x5, + VDEC_CODECTYPE_DIVX_5 = 0x6, + VDEC_CODECTYPE_DIVX_6 = 0x7, + VDEC_CODECTYPE_XVID = 0x8, + VDEC_CODECTYPE_MPEG1 = 0x9, + VDEC_CODECTYPE_MPEG2 = 0xa, + VDEC_CODECTYPE_VC1 = 0xb, + VDEC_CODECTYPE_VC1_RCV = 0xc +}; + +enum vdec_mpeg2_profile { + VDEC_MPEG2ProfileSimple = 0x1, + VDEC_MPEG2ProfileMain = 0x2, + VDEC_MPEG2Profile422 = 0x4, + VDEC_MPEG2ProfileSNR = 0x8, + VDEC_MPEG2ProfileSpatial = 0x10, + VDEC_MPEG2ProfileHigh = 0x20, + VDEC_MPEG2ProfileKhronosExtensions = 0x6F000000, + VDEC_MPEG2ProfileVendorStartUnused = 0x7F000000, + VDEC_MPEG2ProfileMax = 0x7FFFFFFF +}; + +enum vdec_mpeg2_level { + + VDEC_MPEG2LevelLL = 0x1, + VDEC_MPEG2LevelML = 0x2, + VDEC_MPEG2LevelH14 = 0x4, + VDEC_MPEG2LevelHL = 0x8, + VDEC_MPEG2LevelKhronosExtensions = 0x6F000000, + VDEC_MPEG2LevelVendorStartUnused = 0x7F000000, + VDEC_MPEG2LevelMax = 0x7FFFFFFF +}; + +enum vdec_mpeg4_profile { + VDEC_MPEG4ProfileSimple = 0x01, + VDEC_MPEG4ProfileSimpleScalable = 0x02, + VDEC_MPEG4ProfileCore = 0x04, + VDEC_MPEG4ProfileMain = 0x08, + VDEC_MPEG4ProfileNbit = 0x10, + VDEC_MPEG4ProfileScalableTexture = 0x20, + VDEC_MPEG4ProfileSimpleFace = 0x40, + VDEC_MPEG4ProfileSimpleFBA = 0x80, + VDEC_MPEG4ProfileBasicAnimated = 0x100, + VDEC_MPEG4ProfileHybrid = 0x200, + VDEC_MPEG4ProfileAdvancedRealTime = 0x400, + VDEC_MPEG4ProfileCoreScalable = 0x800, + VDEC_MPEG4ProfileAdvancedCoding = 0x1000, + VDEC_MPEG4ProfileAdvancedCore = 0x2000, + VDEC_MPEG4ProfileAdvancedScalable = 0x4000, + VDEC_MPEG4ProfileAdvancedSimple = 0x8000, + VDEC_MPEG4ProfileKhronosExtensions = 0x6F000000, + VDEC_MPEG4ProfileVendorStartUnused = 0x7F000000, + VDEC_MPEG4ProfileMax = 0x7FFFFFFF +}; + +enum vdec_mpeg4_level { + VDEC_MPEG4Level0 = 0x01, + VDEC_MPEG4Level0b = 0x02, + VDEC_MPEG4Level1 = 0x04, + VDEC_MPEG4Level2 = 0x08, + VDEC_MPEG4Level3 = 0x10, + VDEC_MPEG4Level4 = 0x20, + VDEC_MPEG4Level4a = 0x40, + VDEC_MPEG4Level5 = 0x80, + VDEC_MPEG4LevelKhronosExtensions = 0x6F000000, + VDEC_MPEG4LevelVendorStartUnused = 0x7F000000, + VDEC_MPEG4LevelMax = 0x7FFFFFFF +}; + +enum vdec_avc_profile { + VDEC_AVCProfileBaseline = 0x01, + VDEC_AVCProfileMain = 0x02, + VDEC_AVCProfileExtended = 0x04, + VDEC_AVCProfileHigh = 0x08, + VDEC_AVCProfileHigh10 = 0x10, + VDEC_AVCProfileHigh422 = 0x20, + VDEC_AVCProfileHigh444 = 0x40, + VDEC_AVCProfileKhronosExtensions = 0x6F000000, + VDEC_AVCProfileVendorStartUnused = 0x7F000000, + VDEC_AVCProfileMax = 0x7FFFFFFF +}; + +enum vdec_avc_level { + VDEC_AVCLevel1 = 0x01, + VDEC_AVCLevel1b = 0x02, + VDEC_AVCLevel11 = 0x04, + VDEC_AVCLevel12 = 0x08, + VDEC_AVCLevel13 = 0x10, + VDEC_AVCLevel2 = 0x20, + VDEC_AVCLevel21 = 0x40, + VDEC_AVCLevel22 = 0x80, + VDEC_AVCLevel3 = 0x100, + VDEC_AVCLevel31 = 0x200, + VDEC_AVCLevel32 = 0x400, + VDEC_AVCLevel4 = 0x800, + VDEC_AVCLevel41 = 0x1000, + VDEC_AVCLevel42 = 0x2000, + VDEC_AVCLevel5 = 0x4000, + VDEC_AVCLevel51 = 0x8000, + VDEC_AVCLevelKhronosExtensions = 0x6F000000, + VDEC_AVCLevelVendorStartUnused = 0x7F000000, + VDEC_AVCLevelMax = 0x7FFFFFFF +}; + +enum vdec_divx_profile { + VDEC_DIVXProfile_qMobile = 0x01, + VDEC_DIVXProfile_Mobile = 0x02, + VDEC_DIVXProfile_HD = 0x04, + VDEC_DIVXProfile_Handheld = 0x08, + VDEC_DIVXProfile_Portable = 0x10, + VDEC_DIVXProfile_HomeTheater = 0x20 +}; + +enum vdec_xvid_profile { + VDEC_XVIDProfile_Simple = 0x1, + VDEC_XVIDProfile_Advanced_Realtime_Simple = 0x2, + VDEC_XVIDProfile_Advanced_Simple = 0x4 +}; + +enum vdec_xvid_level { + VDEC_XVID_LEVEL_S_L0 = 0x1, + VDEC_XVID_LEVEL_S_L1 = 0x2, + VDEC_XVID_LEVEL_S_L2 = 0x4, + VDEC_XVID_LEVEL_S_L3 = 0x8, + VDEC_XVID_LEVEL_ARTS_L1 = 0x10, + VDEC_XVID_LEVEL_ARTS_L2 = 0x20, + VDEC_XVID_LEVEL_ARTS_L3 = 0x40, + VDEC_XVID_LEVEL_ARTS_L4 = 0x80, + VDEC_XVID_LEVEL_AS_L0 = 0x100, + VDEC_XVID_LEVEL_AS_L1 = 0x200, + VDEC_XVID_LEVEL_AS_L2 = 0x400, + VDEC_XVID_LEVEL_AS_L3 = 0x800, + VDEC_XVID_LEVEL_AS_L4 = 0x1000 +}; + +enum vdec_h263profile { + VDEC_H263ProfileBaseline = 0x01, + VDEC_H263ProfileH320Coding = 0x02, + VDEC_H263ProfileBackwardCompatible = 0x04, + VDEC_H263ProfileISWV2 = 0x08, + VDEC_H263ProfileISWV3 = 0x10, + VDEC_H263ProfileHighCompression = 0x20, + VDEC_H263ProfileInternet = 0x40, + VDEC_H263ProfileInterlace = 0x80, + VDEC_H263ProfileHighLatency = 0x100, + VDEC_H263ProfileKhronosExtensions = 0x6F000000, + VDEC_H263ProfileVendorStartUnused = 0x7F000000, + VDEC_H263ProfileMax = 0x7FFFFFFF +}; + +enum vdec_h263level { + VDEC_H263Level10 = 0x01, + VDEC_H263Level20 = 0x02, + VDEC_H263Level30 = 0x04, + VDEC_H263Level40 = 0x08, + VDEC_H263Level45 = 0x10, + VDEC_H263Level50 = 0x20, + VDEC_H263Level60 = 0x40, + VDEC_H263Level70 = 0x80, + VDEC_H263LevelKhronosExtensions = 0x6F000000, + VDEC_H263LevelVendorStartUnused = 0x7F000000, + VDEC_H263LevelMax = 0x7FFFFFFF +}; + +enum vdec_wmv_format { + VDEC_WMVFormatUnused = 0x01, + VDEC_WMVFormat7 = 0x02, + VDEC_WMVFormat8 = 0x04, + VDEC_WMVFormat9 = 0x08, + VDEC_WMFFormatKhronosExtensions = 0x6F000000, + VDEC_WMFFormatVendorStartUnused = 0x7F000000, + VDEC_WMVFormatMax = 0x7FFFFFFF +}; + +enum vdec_vc1_profile { + VDEC_VC1ProfileSimple = 0x1, + VDEC_VC1ProfileMain = 0x2, + VDEC_VC1ProfileAdvanced = 0x4 +}; + +enum vdec_vc1_level { + VDEC_VC1_LEVEL_S_Low = 0x1, + VDEC_VC1_LEVEL_S_Medium = 0x2, + VDEC_VC1_LEVEL_M_Low = 0x4, + VDEC_VC1_LEVEL_M_Medium = 0x8, + VDEC_VC1_LEVEL_M_High = 0x10, + VDEC_VC1_LEVEL_A_L0 = 0x20, + VDEC_VC1_LEVEL_A_L1 = 0x40, + VDEC_VC1_LEVEL_A_L2 = 0x80, + VDEC_VC1_LEVEL_A_L3 = 0x100, + VDEC_VC1_LEVEL_A_L4 = 0x200 +}; + +struct vdec_profile_level { + uint32_t profiles; + uint32_t levels; +}; + +enum vdec_interlaced_format { + VDEC_InterlaceFrameProgressive = 0x1, + VDEC_InterlaceInterleaveFrameTopFieldFirst = 0x2, + VDEC_InterlaceInterleaveFrameBottomFieldFirst = 0x4 +}; + +enum vdec_output_fromat { + VDEC_YUV_FORMAT_NV12 = 0x1, + VDEC_YUV_FORMAT_TILE_4x2 = 0x2 +}; + +enum vdec_output_order { + VDEC_ORDER_DISPLAY = 0x1, + VDEC_ORDER_DECODE = 0x2 +}; + +struct vdec_picsize { + uint32_t frame_width; + uint32_t frame_height; + uint32_t stride; + uint32_t scan_lines; +}; + +struct vdec_seqheader { + void __user *ptr_seqheader; + size_t seq_header_len; + int pmem_fd; + size_t pmem_offset; +}; + +struct vdec_mberror { + void __user *ptr_errormap; + size_t err_mapsize; +}; + +struct vdec_input_frameinfo { + void __user *bufferaddr; + size_t offset; + size_t datalen; + uint32_t flags; + int64_t timestamp; + void *client_data; + int pmem_fd; + size_t pmem_offset; + void __user *desc_addr; + uint32_t desc_size; +}; + +struct vdec_framesize { + uint32_t left; + uint32_t top; + uint32_t right; + uint32_t bottom; +}; + +struct vdec_aspectratioinfo { + uint32_t aspect_ratio; + uint32_t par_width; + uint32_t par_height; +}; + +struct vdec_output_frameinfo { + void __user *bufferaddr; + size_t offset; + size_t len; + uint32_t flags; + int64_t time_stamp; + enum vdec_picture pic_type; + void *client_data; + void *input_frame_clientdata; + struct vdec_framesize framesize; + enum vdec_interlaced_format interlaced_format; + struct vdec_aspectratioinfo aspect_ratio_info; +}; + +union vdec_msgdata { + struct vdec_output_frameinfo output_frame; + void *input_frame_clientdata; +}; + +struct vdec_msginfo { + uint32_t status_code; + uint32_t msgcode; + union vdec_msgdata msgdata; + size_t msgdatasize; +}; + +struct vdec_framerate { + unsigned long fps_denominator; + unsigned long fps_numerator; +}; + +struct vdec_h264_mv{ + size_t size; + int count; + int pmem_fd; + int offset; +}; + +struct vdec_mv_buff_size{ + int width; + int height; + int size; + int alignment; +}; + +#endif /* end of macro _VDECDECODER_H_ */ diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h new file mode 100644 index 0000000000000000000000000000000000000000..519c537c722ab099e198992d19a7997c0a19ed62 --- /dev/null +++ b/include/linux/msm_vidc_enc.h @@ -0,0 +1,617 @@ +#ifndef _MSM_VIDC_ENC_H_ +#define _MSM_VIDC_ENC_H_ + +#include +#include + +/** STATUS CODES*/ +/* Base value for status codes */ +#define VEN_S_BASE 0x00000000 +#define VEN_S_SUCCESS (VEN_S_BASE)/* Success */ +#define VEN_S_EFAIL (VEN_S_BASE+1)/* General failure */ +#define VEN_S_EFATAL (VEN_S_BASE+2)/* Fatal irrecoverable failure*/ +#define VEN_S_EBADPARAM (VEN_S_BASE+3)/* Error passed parameters*/ +/*Command called in invalid state*/ +#define VEN_S_EINVALSTATE (VEN_S_BASE+4) +#define VEN_S_ENOSWRES (VEN_S_BASE+5)/* Insufficient OS resources*/ +#define VEN_S_ENOHWRES (VEN_S_BASE+6)/*Insufficient HW resources */ +#define VEN_S_EBUFFREQ (VEN_S_BASE+7)/* Buffer requirements were not met*/ +#define VEN_S_EINVALCMD (VEN_S_BASE+8)/* Invalid command called */ +#define VEN_S_ETIMEOUT (VEN_S_BASE+9)/* Command timeout. */ +/*Re-attempt was made when multiple invocation not supported for API.*/ +#define VEN_S_ENOREATMPT (VEN_S_BASE+10) +#define VEN_S_ENOPREREQ (VEN_S_BASE+11)/*Pre-requirement is not met for API*/ +#define VEN_S_ECMDQFULL (VEN_S_BASE+12)/*Command queue is full*/ +#define VEN_S_ENOTSUPP (VEN_S_BASE+13)/*Command not supported*/ +#define VEN_S_ENOTIMPL (VEN_S_BASE+14)/*Command not implemented.*/ +#define VEN_S_ENOTPMEM (VEN_S_BASE+15)/*Buffer is not from PMEM*/ +#define VEN_S_EFLUSHED (VEN_S_BASE+16)/*returned buffer was flushed*/ +#define VEN_S_EINSUFBUF (VEN_S_BASE+17)/*provided buffer size insufficient*/ +#define VEN_S_ESAMESTATE (VEN_S_BASE+18) +#define VEN_S_EINVALTRANS (VEN_S_BASE+19) + +#define VEN_INTF_VER 1 + +/*Asynchronous messages from driver*/ +#define VEN_MSG_INDICATION 0 +#define VEN_MSG_INPUT_BUFFER_DONE 1 +#define VEN_MSG_OUTPUT_BUFFER_DONE 2 +#define VEN_MSG_NEED_OUTPUT_BUFFER 3 +#define VEN_MSG_FLUSH_INPUT_DONE 4 +#define VEN_MSG_FLUSH_OUPUT_DONE 5 +#define VEN_MSG_START 6 +#define VEN_MSG_STOP 7 +#define VEN_MSG_PAUSE 8 +#define VEN_MSG_RESUME 9 +#define VEN_MSG_STOP_READING_MSG 10 + +/*Buffer flags bits masks*/ +#define VEN_BUFFLAG_EOS 0x00000001 +#define VEN_BUFFLAG_ENDOFFRAME 0x00000010 +#define VEN_BUFFLAG_SYNCFRAME 0x00000020 +#define VEN_BUFFLAG_EXTRADATA 0x00000040 +#define VEN_BUFFLAG_CODECCONFIG 0x00000080 + +/*Post processing flags bit masks*/ +#define VEN_EXTRADATA_NONE 0x001 +#define VEN_EXTRADATA_QCOMFILLER 0x002 +#define VEN_EXTRADATA_SLICEINFO 0x100 + +/*ENCODER CONFIGURATION CONSTANTS*/ + +/*Encoded video frame types*/ +#define VEN_FRAME_TYPE_I 1/* I frame type */ +#define VEN_FRAME_TYPE_P 2/* P frame type */ +#define VEN_FRAME_TYPE_B 3/* B frame type */ + +/*Video codec types*/ +#define VEN_CODEC_MPEG4 1/* MPEG4 Codec */ +#define VEN_CODEC_H264 2/* H.264 Codec */ +#define VEN_CODEC_H263 3/* H.263 Codec */ + +/*Video codec profile types.*/ +#define VEN_PROFILE_MPEG4_SP 1/* 1 - MPEG4 SP profile */ +#define VEN_PROFILE_MPEG4_ASP 2/* 2 - MPEG4 ASP profile */ +#define VEN_PROFILE_H264_BASELINE 3/* 3 - H264 Baseline profile */ +#define VEN_PROFILE_H264_MAIN 4/* 4 - H264 Main profile */ +#define VEN_PROFILE_H264_HIGH 5/* 5 - H264 High profile */ +#define VEN_PROFILE_H263_BASELINE 6/* 6 - H263 Baseline profile */ + +/*Video codec profile level types.*/ +#define VEN_LEVEL_MPEG4_0 0x1/* MPEG4 Level 0 */ +#define VEN_LEVEL_MPEG4_1 0x2/* MPEG4 Level 1 */ +#define VEN_LEVEL_MPEG4_2 0x3/* MPEG4 Level 2 */ +#define VEN_LEVEL_MPEG4_3 0x4/* MPEG4 Level 3 */ +#define VEN_LEVEL_MPEG4_4 0x5/* MPEG4 Level 4 */ +#define VEN_LEVEL_MPEG4_5 0x6/* MPEG4 Level 5 */ +#define VEN_LEVEL_MPEG4_3b 0x7/* MPEG4 Level 3b */ +#define VEN_LEVEL_MPEG4_6 0x8/* MPEG4 Level 6 */ + +#define VEN_LEVEL_H264_1 0x9/* H.264 Level 1 */ +#define VEN_LEVEL_H264_1b 0xA/* H.264 Level 1b */ +#define VEN_LEVEL_H264_1p1 0xB/* H.264 Level 1.1 */ +#define VEN_LEVEL_H264_1p2 0xC/* H.264 Level 1.2 */ +#define VEN_LEVEL_H264_1p3 0xD/* H.264 Level 1.3 */ +#define VEN_LEVEL_H264_2 0xE/* H.264 Level 2 */ +#define VEN_LEVEL_H264_2p1 0xF/* H.264 Level 2.1 */ +#define VEN_LEVEL_H264_2p2 0x10/* H.264 Level 2.2 */ +#define VEN_LEVEL_H264_3 0x11/* H.264 Level 3 */ +#define VEN_LEVEL_H264_3p1 0x12/* H.264 Level 3.1 */ +#define VEN_LEVEL_H264_3p2 0x13/* H.264 Level 3.2 */ +#define VEN_LEVEL_H264_4 0x14/* H.264 Level 4 */ + +#define VEN_LEVEL_H263_10 0x15/* H.263 Level 10 */ +#define VEN_LEVEL_H263_20 0x16/* H.263 Level 20 */ +#define VEN_LEVEL_H263_30 0x17/* H.263 Level 30 */ +#define VEN_LEVEL_H263_40 0x18/* H.263 Level 40 */ +#define VEN_LEVEL_H263_45 0x19/* H.263 Level 45 */ +#define VEN_LEVEL_H263_50 0x1A/* H.263 Level 50 */ +#define VEN_LEVEL_H263_60 0x1B/* H.263 Level 60 */ +#define VEN_LEVEL_H263_70 0x1C/* H.263 Level 70 */ + +/*Entropy coding model selection for H.264 encoder.*/ +#define VEN_ENTROPY_MODEL_CAVLC 1 +#define VEN_ENTROPY_MODEL_CABAC 2 +/*Cabac model number (0,1,2) for encoder.*/ +#define VEN_CABAC_MODEL_0 1/* CABAC Model 0. */ +#define VEN_CABAC_MODEL_1 2/* CABAC Model 1. */ +#define VEN_CABAC_MODEL_2 3/* CABAC Model 2. */ + +/*Deblocking filter control type for encoder.*/ +#define VEN_DB_DISABLE 1/* 1 - Disable deblocking filter*/ +#define VEN_DB_ALL_BLKG_BNDRY 2/* 2 - All blocking boundary filtering*/ +#define VEN_DB_SKIP_SLICE_BNDRY 3/* 3 - Filtering except sliceboundary*/ + +/*Different methods of Multi slice selection.*/ +#define VEN_MSLICE_OFF 1 +#define VEN_MSLICE_CNT_MB 2 /*number of MBscount per slice*/ +#define VEN_MSLICE_CNT_BYTE 3 /*number of bytes count per slice.*/ +#define VEN_MSLICE_GOB 4 /*Multi slice by GOB for H.263 only.*/ + +/*Different modes for Rate Control.*/ +#define VEN_RC_OFF 1 +#define VEN_RC_VBR_VFR 2 +#define VEN_RC_VBR_CFR 3 +#define VEN_RC_CBR_VFR 4 +#define VEN_RC_CBR_CFR 5 + +/*Different modes for flushing buffers*/ +#define VEN_FLUSH_INPUT 1 +#define VEN_FLUSH_OUTPUT 2 +#define VEN_FLUSH_ALL 3 + +/*Different input formats for YUV data.*/ +#define VEN_INPUTFMT_NV12 1/* NV12 Linear */ +#define VEN_INPUTFMT_NV21 2/* NV21 Linear */ +#define VEN_INPUTFMT_NV12_16M2KA 3/* NV12 Linear */ + +/*Different allowed rotation modes.*/ +#define VEN_ROTATION_0 1/* 0 degrees */ +#define VEN_ROTATION_90 2/* 90 degrees */ +#define VEN_ROTATION_180 3/* 180 degrees */ +#define VEN_ROTATION_270 4/* 270 degrees */ + +/*IOCTL timeout values*/ +#define VEN_TIMEOUT_INFINITE 0xffffffff + +/*Different allowed intra refresh modes.*/ +#define VEN_IR_OFF 1 +#define VEN_IR_CYCLIC 2 +#define VEN_IR_RANDOM 3 + +/*IOCTL BASE CODES Not to be used directly by the client.*/ +/* Base value for ioctls that are not related to encoder configuration.*/ +#define VEN_IOCTLBASE_NENC 0x800 +/* Base value for encoder configuration ioctls*/ +#define VEN_IOCTLBASE_ENC 0x850 + +struct venc_ioctl_msg{ + void __user *in; + void __user *out; +}; + +/*NON ENCODER CONFIGURATION IOCTLs*/ + +/*IOCTL params:SET: InputData - unsigned long, OutputData - NULL*/ +#define VEN_IOCTL_SET_INTF_VERSION \ + _IOW(VEN_IOCTLBASE_NENC, 0, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - venc_timeout, OutputData - venc_msg*/ +#define VEN_IOCTL_CMD_READ_NEXT_MSG \ + _IOWR(VEN_IOCTLBASE_NENC, 1, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - NULL, OutputData - NULL*/ +#define VEN_IOCTL_CMD_STOP_READ_MSG _IO(VEN_IOCTLBASE_NENC, 2) + +/*IOCTL params:SET: InputData - venc_allocatorproperty, OutputData - NULL + GET: InputData - NULL, OutputData - venc_allocatorproperty*/ +#define VEN_IOCTL_SET_INPUT_BUFFER_REQ \ + _IOW(VEN_IOCTLBASE_NENC, 3, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_INPUT_BUFFER_REQ \ + _IOR(VEN_IOCTLBASE_NENC, 4, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - venc_bufferpayload, OutputData - NULL*/ +#define VEN_IOCTL_CMD_ALLOC_INPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 5, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - venc_bufferpayload, OutputData - NULL*/ +#define VEN_IOCTL_SET_INPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 6, struct venc_ioctl_msg) + +/*IOCTL params: CMD: InputData - venc_bufferpayload, OutputData - NULL*/ +#define VEN_IOCTL_CMD_FREE_INPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 7, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_allocatorproperty, OutputData - NULL + GET: InputData - NULL, OutputData - venc_allocatorproperty*/ +#define VEN_IOCTL_SET_OUTPUT_BUFFER_REQ \ + _IOW(VEN_IOCTLBASE_NENC, 8, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_OUTPUT_BUFFER_REQ \ + _IOR(VEN_IOCTLBASE_NENC, 9, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - venc_bufferpayload, OutputData - NULL*/ +#define VEN_IOCTL_CMD_ALLOC_OUTPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 10, struct venc_ioctl_msg) + + +/*IOCTL params:CMD: InputData - venc_bufferpayload, OutputData - NULL*/ +#define VEN_IOCTL_SET_OUTPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 11, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - venc_bufferpayload, OutputData - NULL.*/ +#define VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 12, struct venc_ioctl_msg) + + +/* Asynchronous respone message code:* VEN_MSG_START*/ +#define VEN_IOCTL_CMD_START _IO(VEN_IOCTLBASE_NENC, 13) + + +/*IOCTL params:CMD: InputData - venc_buffer, OutputData - NULL + Asynchronous respone message code:VEN_MSG_INPUT_BUFFER_DONE*/ +#define VEN_IOCTL_CMD_ENCODE_FRAME \ + _IOW(VEN_IOCTLBASE_NENC, 14, struct venc_ioctl_msg) + + +/*IOCTL params:CMD: InputData - venc_buffer, OutputData - NULL + Asynchronous response message code:VEN_MSG_OUTPUT_BUFFER_DONE*/ +#define VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 15, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - venc_bufferflush, OutputData - NULL + * Asynchronous response message code:VEN_MSG_INPUT_BUFFER_DONE*/ +#define VEN_IOCTL_CMD_FLUSH \ + _IOW(VEN_IOCTLBASE_NENC, 16, struct venc_ioctl_msg) + + +/*Asynchronous respone message code:VEN_MSG_PAUSE*/ +#define VEN_IOCTL_CMD_PAUSE _IO(VEN_IOCTLBASE_NENC, 17) + +/*Asynchronous respone message code:VEN_MSG_RESUME*/ +#define VEN_IOCTL_CMD_RESUME _IO(VEN_IOCTLBASE_NENC, 18) + +/* Asynchronous respone message code:VEN_MSG_STOP*/ +#define VEN_IOCTL_CMD_STOP _IO(VEN_IOCTLBASE_NENC, 19) + +#define VEN_IOCTL_SET_RECON_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 20, struct venc_ioctl_msg) + +#define VEN_IOCTL_FREE_RECON_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 21, struct venc_ioctl_msg) + +#define VEN_IOCTL_GET_RECON_BUFFER_SIZE \ + _IOW(VEN_IOCTLBASE_NENC, 22, struct venc_ioctl_msg) + + + +/*ENCODER PROPERTY CONFIGURATION & CAPABILITY IOCTLs*/ + +/*IOCTL params:SET: InputData - venc_basecfg, OutputData - NULL + GET: InputData - NULL, OutputData - venc_basecfg*/ +#define VEN_IOCTL_SET_BASE_CFG \ + _IOW(VEN_IOCTLBASE_ENC, 1, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_BASE_CFG \ + _IOR(VEN_IOCTLBASE_ENC, 2, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_switch, OutputData - NULL + GET: InputData - NULL, OutputData - venc_switch*/ +#define VEN_IOCTL_SET_LIVE_MODE \ + _IOW(VEN_IOCTLBASE_ENC, 3, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_LIVE_MODE \ + _IOR(VEN_IOCTLBASE_ENC, 4, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_profile, OutputData - NULL + GET: InputData - NULL, OutputData - venc_profile*/ +#define VEN_IOCTL_SET_CODEC_PROFILE \ + _IOW(VEN_IOCTLBASE_ENC, 5, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_CODEC_PROFILE \ + _IOR(VEN_IOCTLBASE_ENC, 6, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - ven_profilelevel, OutputData - NULL + GET: InputData - NULL, OutputData - ven_profilelevel*/ +#define VEN_IOCTL_SET_PROFILE_LEVEL \ + _IOW(VEN_IOCTLBASE_ENC, 7, struct venc_ioctl_msg) + +#define VEN_IOCTL_GET_PROFILE_LEVEL \ + _IOR(VEN_IOCTLBASE_ENC, 8, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_switch, OutputData - NULL + GET: InputData - NULL, OutputData - venc_switch*/ +#define VEN_IOCTL_SET_SHORT_HDR \ + _IOW(VEN_IOCTLBASE_ENC, 9, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_SHORT_HDR \ + _IOR(VEN_IOCTLBASE_ENC, 10, struct venc_ioctl_msg) + + +/*IOCTL params: SET: InputData - venc_sessionqp, OutputData - NULL + GET: InputData - NULL, OutputData - venc_sessionqp*/ +#define VEN_IOCTL_SET_SESSION_QP \ + _IOW(VEN_IOCTLBASE_ENC, 11, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_SESSION_QP \ + _IOR(VEN_IOCTLBASE_ENC, 12, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_intraperiod, OutputData - NULL + GET: InputData - NULL, OutputData - venc_intraperiod*/ +#define VEN_IOCTL_SET_INTRA_PERIOD \ + _IOW(VEN_IOCTLBASE_ENC, 13, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_INTRA_PERIOD \ + _IOR(VEN_IOCTLBASE_ENC, 14, struct venc_ioctl_msg) + + +/* Request an Iframe*/ +#define VEN_IOCTL_CMD_REQUEST_IFRAME _IO(VEN_IOCTLBASE_ENC, 15) + +/*IOCTL params:GET: InputData - NULL, OutputData - venc_capability*/ +#define VEN_IOCTL_GET_CAPABILITY \ + _IOR(VEN_IOCTLBASE_ENC, 16, struct venc_ioctl_msg) + + +/*IOCTL params:GET: InputData - NULL, OutputData - venc_seqheader*/ +#define VEN_IOCTL_GET_SEQUENCE_HDR \ + _IOR(VEN_IOCTLBASE_ENC, 17, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_entropycfg, OutputData - NULL + GET: InputData - NULL, OutputData - venc_entropycfg*/ +#define VEN_IOCTL_SET_ENTROPY_CFG \ + _IOW(VEN_IOCTLBASE_ENC, 18, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_ENTROPY_CFG \ + _IOR(VEN_IOCTLBASE_ENC, 19, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_dbcfg, OutputData - NULL + GET: InputData - NULL, OutputData - venc_dbcfg*/ +#define VEN_IOCTL_SET_DEBLOCKING_CFG \ + _IOW(VEN_IOCTLBASE_ENC, 20, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_DEBLOCKING_CFG \ + _IOR(VEN_IOCTLBASE_ENC, 21, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_intrarefresh, OutputData - NULL + GET: InputData - NULL, OutputData - venc_intrarefresh*/ +#define VEN_IOCTL_SET_INTRA_REFRESH \ + _IOW(VEN_IOCTLBASE_ENC, 22, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_INTRA_REFRESH \ + _IOR(VEN_IOCTLBASE_ENC, 23, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_multiclicecfg, OutputData - NULL + GET: InputData - NULL, OutputData - venc_multiclicecfg*/ +#define VEN_IOCTL_SET_MULTI_SLICE_CFG \ + _IOW(VEN_IOCTLBASE_ENC, 24, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_MULTI_SLICE_CFG \ + _IOR(VEN_IOCTLBASE_ENC, 25, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_ratectrlcfg, OutputData - NULL + GET: InputData - NULL, OutputData - venc_ratectrlcfg*/ +#define VEN_IOCTL_SET_RATE_CTRL_CFG \ + _IOW(VEN_IOCTLBASE_ENC, 26, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_RATE_CTRL_CFG \ + _IOR(VEN_IOCTLBASE_ENC, 27, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_voptimingcfg, OutputData - NULL + GET: InputData - NULL, OutputData - venc_voptimingcfg*/ +#define VEN_IOCTL_SET_VOP_TIMING_CFG \ + _IOW(VEN_IOCTLBASE_ENC, 28, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_VOP_TIMING_CFG \ + _IOR(VEN_IOCTLBASE_ENC, 29, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_framerate, OutputData - NULL + GET: InputData - NULL, OutputData - venc_framerate*/ +#define VEN_IOCTL_SET_FRAME_RATE \ + _IOW(VEN_IOCTLBASE_ENC, 30, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_FRAME_RATE \ + _IOR(VEN_IOCTLBASE_ENC, 31, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_targetbitrate, OutputData - NULL + GET: InputData - NULL, OutputData - venc_targetbitrate*/ +#define VEN_IOCTL_SET_TARGET_BITRATE \ + _IOW(VEN_IOCTLBASE_ENC, 32, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_TARGET_BITRATE \ + _IOR(VEN_IOCTLBASE_ENC, 33, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_rotation, OutputData - NULL + GET: InputData - NULL, OutputData - venc_rotation*/ +#define VEN_IOCTL_SET_ROTATION \ + _IOW(VEN_IOCTLBASE_ENC, 34, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_ROTATION \ + _IOR(VEN_IOCTLBASE_ENC, 35, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_headerextension, OutputData - NULL + GET: InputData - NULL, OutputData - venc_headerextension*/ +#define VEN_IOCTL_SET_HEC \ + _IOW(VEN_IOCTLBASE_ENC, 36, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_HEC \ + _IOR(VEN_IOCTLBASE_ENC, 37, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_switch, OutputData - NULL + GET: InputData - NULL, OutputData - venc_switch*/ +#define VEN_IOCTL_SET_DATA_PARTITION \ + _IOW(VEN_IOCTLBASE_ENC, 38, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_DATA_PARTITION \ + _IOR(VEN_IOCTLBASE_ENC, 39, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_switch, OutputData - NULL + GET: InputData - NULL, OutputData - venc_switch*/ +#define VEN_IOCTL_SET_RVLC \ + _IOW(VEN_IOCTLBASE_ENC, 40, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_RVLC \ + _IOR(VEN_IOCTLBASE_ENC, 41, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_switch, OutputData - NULL + GET: InputData - NULL, OutputData - venc_switch*/ +#define VEN_IOCTL_SET_AC_PREDICTION \ + _IOW(VEN_IOCTLBASE_ENC, 42, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_AC_PREDICTION \ + _IOR(VEN_IOCTLBASE_ENC, 43, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_qprange, OutputData - NULL + GET: InputData - NULL, OutputData - venc_qprange*/ +#define VEN_IOCTL_SET_QP_RANGE \ + _IOW(VEN_IOCTLBASE_ENC, 44, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_QP_RANGE \ + _IOR(VEN_IOCTLBASE_ENC, 45, struct venc_ioctl_msg) + +#define VEN_IOCTL_GET_NUMBER_INSTANCES \ + _IOR(VEN_IOCTLBASE_ENC, 46, struct venc_ioctl_msg) + +#define VEN_IOCTL_SET_METABUFFER_MODE \ + _IOW(VEN_IOCTLBASE_ENC, 47, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - unsigned int, OutputData - NULL.*/ +#define VEN_IOCTL_SET_EXTRADATA \ + _IOW(VEN_IOCTLBASE_ENC, 48, struct venc_ioctl_msg) +/*IOCTL params:GET: InputData - NULL, OutputData - unsigned int.*/ +#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; +}; + +struct venc_allocatorproperty{ + unsigned long mincount; + unsigned long maxcount; + unsigned long actualcount; + unsigned long datasize; + unsigned long suffixsize; + unsigned long alignment; + unsigned long bufpoolid; +}; + +struct venc_bufferpayload{ + unsigned char *pbuffer; + size_t sz; + int fd; + unsigned int offset; + unsigned int maped_size; + unsigned long filled_len; +}; + +struct venc_buffer{ + unsigned char *ptrbuffer; + unsigned long sz; + unsigned long len; + unsigned long offset; + long long timestamp; + unsigned long flags; + void *clientdata; +}; + +struct venc_basecfg{ + unsigned long input_width; + unsigned long input_height; + unsigned long dvs_width; + unsigned long dvs_height; + unsigned long codectype; + unsigned long fps_num; + unsigned long fps_den; + unsigned long targetbitrate; + unsigned long inputformat; +}; + +struct venc_profile{ + unsigned long profile; +}; +struct ven_profilelevel{ + unsigned long level; +}; + +struct venc_sessionqp{ + unsigned long iframeqp; + unsigned long pframqp; +}; + +struct venc_qprange{ + unsigned long maxqp; + unsigned long minqp; +}; +struct venc_intraperiod{ + unsigned long num_pframes; + unsigned long num_bframes; +}; +struct venc_seqheader{ + unsigned char *hdrbufptr; + unsigned long bufsize; + unsigned long hdrlen; +}; + +struct venc_capability{ + unsigned long codec_types; + unsigned long maxframe_width; + unsigned long maxframe_height; + unsigned long maxtarget_bitrate; + unsigned long maxframe_rate; + unsigned long input_formats; + unsigned char dvs; +}; + +struct venc_entropycfg{ + unsigned longentropysel; + unsigned long cabacmodel; +}; + +struct venc_dbcfg{ + unsigned long db_mode; + unsigned long slicealpha_offset; + unsigned long slicebeta_offset; +}; + +struct venc_intrarefresh{ + unsigned long irmode; + unsigned long mbcount; +}; + +struct venc_multiclicecfg{ + unsigned long mslice_mode; + unsigned long mslice_size; +}; + +struct venc_bufferflush{ + unsigned long flush_mode; +}; + +struct venc_ratectrlcfg{ + unsigned long rcmode; +}; + +struct venc_voptimingcfg{ + unsigned long voptime_resolution; +}; +struct venc_framerate{ + unsigned long fps_denominator; + unsigned long fps_numerator; +}; + +struct venc_targetbitrate{ + unsigned long target_bitrate; +}; + + +struct venc_rotation{ + unsigned long rotation; +}; + +struct venc_timeout{ + unsigned long millisec; +}; + +struct venc_headerextension{ + unsigned long header_extension; +}; + +struct venc_msg{ + unsigned long statuscode; + unsigned long msgcode; + struct venc_buffer buf; + unsigned long msgdata_size; +}; + +struct venc_recon_addr{ + unsigned char *pbuffer; + unsigned long buffer_size; + unsigned long pmem_fd; + unsigned long offset; +}; + +struct venc_recon_buff_size{ + int width; + int height; + int size; + int alignment; +}; + +#endif /* _MSM_VIDC_ENC_H_ */ diff --git a/include/media/msm/vcd_api.h b/include/media/msm/vcd_api.h new file mode 100644 index 0000000000000000000000000000000000000000..1db6dc59245af147f4ecfee5600ea6a121c09409 --- /dev/null +++ b/include/media/msm/vcd_api.h @@ -0,0 +1,158 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_API_H_ +#define _VCD_API_H_ +#include "vcd_property.h" +#include "vcd_status.h" + +#define VCD_FRAME_FLAG_EOS 0x00000001 +#define VCD_FRAME_FLAG_DECODEONLY 0x00000004 +#define VCD_FRAME_FLAG_DATACORRUPT 0x00000008 +#define VCD_FRAME_FLAG_ENDOFFRAME 0x00000010 +#define VCD_FRAME_FLAG_SYNCFRAME 0x00000020 +#define VCD_FRAME_FLAG_EXTRADATA 0x00000040 +#define VCD_FRAME_FLAG_CODECCONFIG 0x00000080 +#define VCD_FRAME_FLAG_BFRAME 0x00100000 +#define VCD_FRAME_FLAG_EOSEQ 0x00200000 + +#define VCD_FLUSH_INPUT 0x0001 +#define VCD_FLUSH_OUTPUT 0x0002 +#define VCD_FLUSH_ALL 0x0003 + +#define VCD_FRAMETAG_INVALID 0xffffffff + +struct vcd_handle_container { + void *handle; +}; +struct vcd_flush_cmd { + u32 mode; +}; + +enum vcd_frame { + VCD_FRAME_YUV = 1, + VCD_FRAME_I, + VCD_FRAME_P, + VCD_FRAME_B, + VCD_FRAME_NOTCODED, + VCD_FRAME_IDR, + VCD_FRAME_32BIT = 0x7fffffff +}; + +enum vcd_power_state { + VCD_PWR_STATE_ON = 1, + VCD_PWR_STATE_SLEEP, +}; + +struct vcd_aspect_ratio { + u32 aspect_ratio; + u32 extended_par_width; + u32 extended_par_height; +}; + +struct vcd_frame_data { + u8 *virtual; + u8 *physical; + u32 ion_flag; + u32 alloc_len; + u32 data_len; + u32 offset; + s64 time_stamp; /* in usecs*/ + u32 flags; + u32 frm_clnt_data; + struct vcd_property_dec_output_buffer dec_op_prop; + u32 interlaced; + enum vcd_frame frame; + u32 ip_frm_tag; + u32 intrlcd_ip_frm_tag; + u8 *desc_buf; + u32 desc_size; + struct ion_handle *buff_ion_handle; + struct vcd_aspect_ratio aspect_ratio_info; +}; + +struct vcd_sequence_hdr { + u8 *sequence_header; + u32 sequence_header_len; + +}; + +enum vcd_buffer_type { + VCD_BUFFER_INPUT = 0x1, + VCD_BUFFER_OUTPUT = 0x2, + VCD_BUFFER_INVALID = 0x3, + VCD_BUFFER_32BIT = 0x7FFFFFFF +}; + +struct vcd_buffer_requirement { + u32 min_count; + u32 actual_count; + u32 max_count; + size_t sz; + u32 align; + u32 buf_pool_id; +}; + +struct vcd_init_config { + void *device_name; + void *(*map_dev_base_addr) (void *device_name); + void (*un_map_dev_base_addr) (void); + void (*interrupt_clr) (void); + void (*register_isr) (void *device_name); + void (*deregister_isr) (void); + u32 (*timer_create) (void (*timer_handler)(void *), + void *user_data, void **timer_handle); + void (*timer_release) (void *timer_handle); + void (*timer_start) (void *timer_handle, u32 time_out); + void (*timer_stop) (void *timer_handle); +}; + +/*Flags passed to vcd_open*/ +#define VCD_CP_SESSION 0x00000001 + +u32 vcd_init(struct vcd_init_config *config, s32 *driver_handle); +u32 vcd_term(s32 driver_handle); +u32 vcd_open(s32 driver_handle, u32 decoding, + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data), void *client_data, int flags); +u32 vcd_close(void *handle); +u32 vcd_encode_start(void *handle); +u32 vcd_encode_frame(void *handle, struct vcd_frame_data *input_frame); +u32 vcd_decode_start(void *handle, struct vcd_sequence_hdr *seq_hdr); +u32 vcd_decode_frame(void *handle, struct vcd_frame_data *input_frame); +u32 vcd_pause(void *handle); +u32 vcd_resume(void *handle); +u32 vcd_flush(void *handle, u32 mode); +u32 vcd_stop(void *handle); +u32 vcd_set_property(void *handle, struct vcd_property_hdr *prop_hdr, + void *prop_val); +u32 vcd_get_property(void *handle, struct vcd_property_hdr *prop_hdr, + void *prop_val); +u32 vcd_set_buffer_requirements(void *handle, enum vcd_buffer_type buffer, + struct vcd_buffer_requirement *buffer_req); +u32 vcd_get_buffer_requirements(void *handle, enum vcd_buffer_type buffer, + struct vcd_buffer_requirement *buffer_req); +u32 vcd_set_buffer(void *handle, enum vcd_buffer_type buffer_type, + u8 *buffer, u32 buf_size); +u32 vcd_allocate_buffer(void *handle, enum vcd_buffer_type buffer, + u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr); + +u32 vcd_free_buffer(void *handle, enum vcd_buffer_type buffer_type, u8 *buffer); +u32 vcd_fill_output_buffer(void *handle, struct vcd_frame_data *buffer); +u32 vcd_set_device_power(s32 driver_handle, + enum vcd_power_state pwr_state); +void vcd_read_and_clear_interrupt(void); +void vcd_response_handler(void); +u8 vcd_get_num_of_clients(void); +u32 vcd_get_ion_status(void); +struct ion_client *vcd_get_ion_client(void); +#endif diff --git a/include/media/msm/vcd_property.h b/include/media/msm/vcd_property.h new file mode 100644 index 0000000000000000000000000000000000000000..9b09b1d1aa2c1a3b5aea81c7872c220fc4134c8e --- /dev/null +++ b/include/media/msm/vcd_property.h @@ -0,0 +1,372 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _VCD_DRIVER_PROPERTY_H_ +#define _VCD_DRIVER_PROPERTY_H_ + +#define VCD_START_BASE 0x0 +#define VCD_I_LIVE (VCD_START_BASE + 0x1) +#define VCD_I_CODEC (VCD_START_BASE + 0x2) +#define VCD_I_FRAME_SIZE (VCD_START_BASE + 0x3) +#define VCD_I_METADATA_ENABLE (VCD_START_BASE + 0x4) +#define VCD_I_METADATA_HEADER (VCD_START_BASE + 0x5) +#define VCD_I_PROFILE (VCD_START_BASE + 0x6) +#define VCD_I_LEVEL (VCD_START_BASE + 0x7) +#define VCD_I_BUFFER_FORMAT (VCD_START_BASE + 0x8) +#define VCD_I_FRAME_RATE (VCD_START_BASE + 0x9) +#define VCD_I_TARGET_BITRATE (VCD_START_BASE + 0xA) +#define VCD_I_MULTI_SLICE (VCD_START_BASE + 0xB) +#define VCD_I_ENTROPY_CTRL (VCD_START_BASE + 0xC) +#define VCD_I_DEBLOCKING (VCD_START_BASE + 0xD) +#define VCD_I_RATE_CONTROL (VCD_START_BASE + 0xE) +#define VCD_I_QP_RANGE (VCD_START_BASE + 0xF) +#define VCD_I_SESSION_QP (VCD_START_BASE + 0x10) +#define VCD_I_INTRA_PERIOD (VCD_START_BASE + 0x11) +#define VCD_I_VOP_TIMING (VCD_START_BASE + 0x12) +#define VCD_I_SHORT_HEADER (VCD_START_BASE + 0x13) +#define VCD_I_SEQ_HEADER (VCD_START_BASE + 0x14) +#define VCD_I_HEADER_EXTENSION (VCD_START_BASE + 0x15) +#define VCD_I_INTRA_REFRESH (VCD_START_BASE + 0x16) +#define VCD_I_POST_FILTER (VCD_START_BASE + 0x17) +#define VCD_I_PROGRESSIVE_ONLY (VCD_START_BASE + 0x18) +#define VCD_I_OUTPUT_ORDER (VCD_START_BASE + 0x19) +#define VCD_I_RECON_BUFFERS (VCD_START_BASE + 0x1A) +#define VCD_I_FREE_RECON_BUFFERS (VCD_START_BASE + 0x1B) +#define VCD_I_GET_RECON_BUFFER_SIZE (VCD_START_BASE + 0x1C) +#define VCD_I_H264_MV_BUFFER (VCD_START_BASE + 0x1D) +#define VCD_I_FREE_H264_MV_BUFFER (VCD_START_BASE + 0x1E) +#define VCD_I_GET_H264_MV_SIZE (VCD_START_BASE + 0x1F) +#define VCD_I_DEC_PICTYPE (VCD_START_BASE + 0x20) +#define VCD_I_CONT_ON_RECONFIG (VCD_START_BASE + 0x21) +#define VCD_I_META_BUFFER_MODE (VCD_START_BASE + 0x22) +#define VCD_I_DISABLE_DMX (VCD_START_BASE + 0x23) +#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_I_VOP_TIMING_CONSTANT_DELTA (VCD_START_BASE + 0x28) + +#define VCD_START_REQ (VCD_START_BASE + 0x1000) +#define VCD_I_REQ_IFRAME (VCD_START_REQ + 0x1) + +#define VCD_I_RESERVED_BASE (VCD_START_BASE + 0x10000) + +struct vcd_property_hdr { + u32 prop_id; + size_t sz; +}; + +struct vcd_property_live { + u32 live; +}; + +enum vcd_codec { + VCD_CODEC_H264 = 0x1, + VCD_CODEC_H263 = 0x2, + VCD_CODEC_MPEG1 = 0x3, + VCD_CODEC_MPEG2 = 0x4, + VCD_CODEC_MPEG4 = 0x5, + VCD_CODEC_DIVX_3 = 0x6, + VCD_CODEC_DIVX_4 = 0x7, + VCD_CODEC_DIVX_5 = 0x8, + VCD_CODEC_DIVX_6 = 0x9, + VCD_CODEC_XVID = 0xA, + VCD_CODEC_VC1 = 0xB, + VCD_CODEC_VC1_RCV = 0xC +}; + +struct vcd_property_codec { + enum vcd_codec codec; +}; + +struct vcd_property_frame_size { + u32 width; + u32 height; + u32 stride; + u32 scan_lines; +}; + +enum vcd_perf_level { + VCD_PERF_LEVEL0, + VCD_PERF_LEVEL1, + VCD_PERF_LEVEL2, + VCD_PERF_LEVEL_TURBO, +}; + +#define VCD_METADATA_DATANONE 0x001 +#define VCD_METADATA_QCOMFILLER 0x002 +#define VCD_METADATA_QPARRAY 0x004 +#define VCD_METADATA_CONCEALMB 0x008 +#define VCD_METADATA_SEI 0x010 +#define VCD_METADATA_VUI 0x020 +#define VCD_METADATA_VC1 0x040 +#define VCD_METADATA_PASSTHROUGH 0x080 +#define VCD_METADATA_ENC_SLICE 0x100 + +struct vcd_property_meta_data_enable { + u32 meta_data_enable_flag; +}; + +struct vcd_property_metadata_hdr { + u32 meta_data_id; + u32 version; + u32 port_index; + u32 type; +}; + +struct vcd_property_frame_rate { + u32 fps_denominator; + u32 fps_numerator; +}; + +struct vcd_property_target_bitrate { + u32 target_bitrate; +}; + +struct vcd_property_perf_level { + enum vcd_perf_level level; +}; + +enum vcd_yuv_buffer_format { + VCD_BUFFER_FORMAT_NV12 = 0x1, + VCD_BUFFER_FORMAT_TILE_4x2 = 0x2, + VCD_BUFFER_FORMAT_NV12_16M2KA = 0x3, + VCD_BUFFER_FORMAT_TILE_1x1 = 0x4 +}; + +struct vcd_property_buffer_format { + enum vcd_yuv_buffer_format buffer_format; +}; + +struct vcd_property_post_filter { + u32 post_filter; +}; + +enum vcd_codec_profile { + VCD_PROFILE_UNKNOWN = 0x0, + VCD_PROFILE_MPEG4_SP = 0x1, + VCD_PROFILE_MPEG4_ASP = 0x2, + VCD_PROFILE_H264_BASELINE = 0x3, + VCD_PROFILE_H264_MAIN = 0x4, + VCD_PROFILE_H264_HIGH = 0x5, + VCD_PROFILE_H263_BASELINE = 0x6, + VCD_PROFILE_VC1_SIMPLE = 0x7, + VCD_PROFILE_VC1_MAIN = 0x8, + VCD_PROFILE_VC1_ADVANCE = 0x9, + VCD_PROFILE_MPEG2_MAIN = 0xA, + VCD_PROFILE_MPEG2_SIMPLE = 0xB +}; + +struct vcd_property_profile { + enum vcd_codec_profile profile; +}; + +enum vcd_codec_level { + VCD_LEVEL_UNKNOWN = 0x0, + VCD_LEVEL_MPEG4_0 = 0x1, + VCD_LEVEL_MPEG4_0b = 0x2, + VCD_LEVEL_MPEG4_1 = 0x3, + VCD_LEVEL_MPEG4_2 = 0x4, + VCD_LEVEL_MPEG4_3 = 0x5, + VCD_LEVEL_MPEG4_3b = 0x6, + VCD_LEVEL_MPEG4_4 = 0x7, + VCD_LEVEL_MPEG4_4a = 0x8, + VCD_LEVEL_MPEG4_5 = 0x9, + VCD_LEVEL_MPEG4_6 = 0xA, + VCD_LEVEL_MPEG4_7 = 0xB, + VCD_LEVEL_MPEG4_X = 0xC, + VCD_LEVEL_H264_1 = 0x10, + VCD_LEVEL_H264_1b = 0x11, + VCD_LEVEL_H264_1p1 = 0x12, + VCD_LEVEL_H264_1p2 = 0x13, + VCD_LEVEL_H264_1p3 = 0x14, + VCD_LEVEL_H264_2 = 0x15, + VCD_LEVEL_H264_2p1 = 0x16, + VCD_LEVEL_H264_2p2 = 0x17, + VCD_LEVEL_H264_3 = 0x18, + VCD_LEVEL_H264_3p1 = 0x19, + VCD_LEVEL_H264_3p2 = 0x1A, + VCD_LEVEL_H264_4 = 0x1B, + VCD_LEVEL_H264_4p1 = 0x1C, + VCD_LEVEL_H264_4p2 = 0x1D, + VCD_LEVEL_H264_5 = 0x1E, + VCD_LEVEL_H264_5p1 = 0x1F, + VCD_LEVEL_H263_10 = 0x20, + VCD_LEVEL_H263_20 = 0x21, + VCD_LEVEL_H263_30 = 0x22, + VCD_LEVEL_H263_40 = 0x23, + VCD_LEVEL_H263_45 = 0x24, + VCD_LEVEL_H263_50 = 0x25, + VCD_LEVEL_H263_60 = 0x26, + VCD_LEVEL_H263_70 = 0x27, + VCD_LEVEL_H263_X = 0x28, + VCD_LEVEL_MPEG2_LOW = 0x30, + VCD_LEVEL_MPEG2_MAIN = 0x31, + VCD_LEVEL_MPEG2_HIGH_14 = 0x32, + VCD_LEVEL_MPEG2_HIGH = 0x33, + VCD_LEVEL_MPEG2_X = 0x34, + VCD_LEVEL_VC1_S_LOW = 0x40, + VCD_LEVEL_VC1_S_MEDIUM = 0x41, + VCD_LEVEL_VC1_M_LOW = 0x42, + VCD_LEVEL_VC1_M_MEDIUM = 0x43, + VCD_LEVEL_VC1_M_HIGH = 0x44, + VCD_LEVEL_VC1_A_0 = 0x45, + VCD_LEVEL_VC1_A_1 = 0x46, + VCD_LEVEL_VC1_A_2 = 0x47, + VCD_LEVEL_VC1_A_3 = 0x48, + VCD_LEVEL_VC1_A_4 = 0x49, + VCD_LEVEL_VC1_X = 0x4A +}; + +struct vcd_property_level { + enum vcd_codec_level level; +}; + +enum vcd_m_slice_sel { + VCD_MSLICE_OFF = 0x1, + VCD_MSLICE_BY_MB_COUNT = 0x2, + VCD_MSLICE_BY_BYTE_COUNT = 0x3, + VCD_MSLICE_BY_GOB = 0x4 +}; + +struct vcd_property_multi_slice { + enum vcd_m_slice_sel m_slice_sel; + u32 m_slice_size; +}; + +enum vcd_entropy_sel { + VCD_ENTROPY_SEL_CAVLC = 0x1, + VCD_ENTROPY_SEL_CABAC = 0x2 +}; + +enum vcd_cabac_model { + VCD_CABAC_MODEL_NUMBER_0 = 0x1, + VCD_CABAC_MODEL_NUMBER_1 = 0x2, + VCD_CABAC_MODEL_NUMBER_2 = 0x3 +}; + +struct vcd_property_entropy_control { + enum vcd_entropy_sel entropy_sel; + enum vcd_cabac_model cabac_model; +}; + +enum vcd_db_config { + VCD_DB_ALL_BLOCKING_BOUNDARY = 0x1, + VCD_DB_DISABLE = 0x2, + VCD_DB_SKIP_SLICE_BOUNDARY = 0x3 +}; +struct vcd_property_db_config { + enum vcd_db_config db_config; + u32 slice_alpha_offset; + u32 slice_beta_offset; +}; + +enum vcd_rate_control { + VCD_RATE_CONTROL_OFF = 0x1, + VCD_RATE_CONTROL_VBR_VFR = 0x2, + VCD_RATE_CONTROL_VBR_CFR = 0x3, + VCD_RATE_CONTROL_CBR_VFR = 0x4, + VCD_RATE_CONTROL_CBR_CFR = 0x5 +}; + +struct vcd_property_rate_control { + enum vcd_rate_control rate_control; +}; + +struct vcd_property_qp_range { + u32 max_qp; + u32 min_qp; +}; + +struct vcd_property_session_qp { + u32 i_frame_qp; + u32 p_frame_qp; + u32 b_frame_qp; +}; + +struct vcd_property_i_period { + u32 p_frames; + u32 b_frames; +}; + +struct vcd_property_vop_timing { + u32 vop_time_resolution; +}; + +struct vcd_property_vop_timing_constant_delta { + u32 constant_delta; /*In usecs */ +}; + +struct vcd_property_short_header { + u32 short_header; +}; + +struct vcd_property_intra_refresh_mb_number { + u32 cir_mb_number; +}; + +struct vcd_property_req_i_frame { + u32 req_i_frame; +}; + +struct vcd_frame_rect { + u32 left; + u32 top; + u32 right; + u32 bottom; +}; + +struct vcd_property_dec_output_buffer { + struct vcd_frame_rect disp_frm; + struct vcd_property_frame_size frm_size; +}; + +enum vcd_output_order { + VCD_DEC_ORDER_DISPLAY = 0x0, + VCD_DEC_ORDER_DECODE = 0x1 +}; + +struct vcd_property_enc_recon_buffer { + u8 *user_virtual_addr; + u8 *kernel_virtual_addr; + u8 *physical_addr; + u8 *dev_addr; + u32 buffer_size; + u32 ysize; + int pmem_fd; + u32 offset; + void *client_data; +}; + +struct vcd_property_h264_mv_buffer { + u8 *kernel_virtual_addr; + u8 *physical_addr; + u32 size; + u32 count; + int pmem_fd; + u32 offset; + u8 *dev_addr; + void *client_data; +}; + +struct vcd_property_buffer_size { + int width; + int height; + int size; + int alignment; +}; + +struct vcd_property_sps_pps_for_idr_enable { + u32 sps_pps_for_idr_enable_flag; +}; + +#endif diff --git a/include/media/msm/vcd_status.h b/include/media/msm/vcd_status.h new file mode 100644 index 0000000000000000000000000000000000000000..9b67ed0e34653770d8fa396deb7ab715f0544b39 --- /dev/null +++ b/include/media/msm/vcd_status.h @@ -0,0 +1,61 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _VCD_ERR_STATUS_H_ +#define _VCD_ERR_STATUS_H_ + +#define VCD_EVT_RESP_BASE 0x1000 +#define VCD_EVT_RESP_OPEN (VCD_EVT_RESP_BASE + 0x1) +#define VCD_EVT_RESP_START (VCD_EVT_RESP_BASE + 0x2) +#define VCD_EVT_RESP_STOP (VCD_EVT_RESP_BASE + 0x3) +#define VCD_EVT_RESP_PAUSE (VCD_EVT_RESP_BASE + 0x4) +#define VCD_EVT_RESP_FLUSH_INPUT_DONE (VCD_EVT_RESP_BASE + 0x5) +#define VCD_EVT_RESP_FLUSH_OUTPUT_DONE (VCD_EVT_RESP_BASE + 0x6) +#define VCD_EVT_RESP_INPUT_FLUSHED (VCD_EVT_RESP_BASE + 0x7) +#define VCD_EVT_RESP_OUTPUT_FLUSHED (VCD_EVT_RESP_BASE + 0x8) +#define VCD_EVT_RESP_INPUT_DONE (VCD_EVT_RESP_BASE + 0x9) +#define VCD_EVT_RESP_OUTPUT_DONE (VCD_EVT_RESP_BASE + 0xa) + +#define VCD_EVT_IND_BASE 0x2000 +#define VCD_EVT_IND_INPUT_RECONFIG (VCD_EVT_IND_BASE + 0x1) +#define VCD_EVT_IND_OUTPUT_RECONFIG (VCD_EVT_IND_BASE + 0x2) +#define VCD_EVT_IND_HWERRFATAL (VCD_EVT_IND_BASE + 0x3) +#define VCD_EVT_IND_RESOURCES_LOST (VCD_EVT_IND_BASE + 0x4) +#define VCD_EVT_IND_INFO_OUTPUT_RECONFIG (VCD_EVT_IND_BASE + 0x5) +#define VCD_EVT_IND_INFO_FIELD_DROPPED (VCD_EVT_IND_BASE + 0x6) + +#define VCD_S_SUCCESS 0x0 + +#define VCD_S_ERR_BASE 0x80000000 +#define VCD_ERR_FAIL (VCD_S_ERR_BASE + 0x01) +#define VCD_ERR_ALLOC_FAIL (VCD_S_ERR_BASE + 0x02) +#define VCD_ERR_ILLEGAL_OP (VCD_S_ERR_BASE + 0x03) +#define VCD_ERR_ILLEGAL_PARM (VCD_S_ERR_BASE + 0x04) +#define VCD_ERR_BAD_POINTER (VCD_S_ERR_BASE + 0x05) +#define VCD_ERR_BAD_HANDLE (VCD_S_ERR_BASE + 0x06) +#define VCD_ERR_NOT_SUPPORTED (VCD_S_ERR_BASE + 0x07) +#define VCD_ERR_BAD_STATE (VCD_S_ERR_BASE + 0x08) +#define VCD_ERR_BUSY (VCD_S_ERR_BASE + 0x09) +#define VCD_ERR_MAX_CLIENT (VCD_S_ERR_BASE + 0x0a) +#define VCD_ERR_IFRAME_EXPECTED (VCD_S_ERR_BASE + 0x0b) +#define VCD_ERR_INTRLCD_FIELD_DROP (VCD_S_ERR_BASE + 0x0c) +#define VCD_ERR_HW_FATAL (VCD_S_ERR_BASE + 0x0d) +#define VCD_ERR_BITSTREAM_ERR (VCD_S_ERR_BASE + 0x0e) +#define VCD_ERR_QEMPTY (VCD_S_ERR_BASE + 0x0f) +#define VCD_ERR_SEQHDR_PARSE_FAIL (VCD_S_ERR_BASE + 0x10) +#define VCD_ERR_INPUT_NOT_PROCESSED (VCD_S_ERR_BASE + 0x11) +#define VCD_ERR_INDEX_NOMORE (VCD_S_ERR_BASE + 0x12) + +#define VCD_FAILED(rc) ((rc > VCD_S_ERR_BASE) ? true : false) + +#endif diff --git a/include/media/msm/vidc_init.h b/include/media/msm/vidc_init.h new file mode 100644 index 0000000000000000000000000000000000000000..48bc9263b4a4f7e8fd9b31f25c6dd0eb8e40b92f --- /dev/null +++ b/include/media/msm/vidc_init.h @@ -0,0 +1,100 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef VIDC_INIT_H +#define VIDC_INIT_H +#include +#include +#include + +#define VIDC_MAX_NUM_CLIENTS 4 +#define MAX_VIDEO_NUM_OF_BUFF 100 + +enum buffer_dir { + BUFFER_TYPE_INPUT, + BUFFER_TYPE_OUTPUT +}; + +struct buf_addr_table { + unsigned long user_vaddr; + unsigned long kernel_vaddr; + unsigned long phy_addr; + unsigned long buff_ion_flag; + struct ion_handle *buff_ion_handle; + int pmem_fd; + struct file *file; + unsigned long dev_addr; + void *client_data; +}; + +struct video_client_ctx { + void *vcd_handle; + u32 num_of_input_buffers; + u32 num_of_output_buffers; + struct buf_addr_table input_buf_addr_table[MAX_VIDEO_NUM_OF_BUFF]; + struct buf_addr_table output_buf_addr_table[MAX_VIDEO_NUM_OF_BUFF]; + struct list_head msg_queue; + struct mutex msg_queue_lock; + struct mutex enrty_queue_lock; + wait_queue_head_t msg_wait; + struct completion event; + struct vcd_property_h264_mv_buffer vcd_h264_mv_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; + 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]; + u32 dmx_disable; +}; + +void __iomem *vidc_get_ioaddr(void); +int vidc_load_firmware(void); +void vidc_release_firmware(void); +u32 vidc_get_fd_info(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, int pmem_fd, + unsigned long kvaddr, int index, + struct ion_handle **buff_handle); +u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, u32 search_with_user_vaddr, + unsigned long *user_vaddr, unsigned long *kernel_vaddr, + unsigned long *phy_addr, int *pmem_fd, struct file **file, + s32 *buffer_index); +u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, unsigned long user_vaddr, + unsigned long *kernel_vaddr, int pmem_fd, + unsigned long buffer_addr_offset, + unsigned int max_num_buffers, unsigned long length); +u32 vidc_insert_addr_table_kernel(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, unsigned long user_vaddr, + unsigned long kernel_vaddr, unsigned long phys_addr, + unsigned int max_num_buffers, + unsigned long length); +u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, unsigned long user_vaddr, + unsigned long *kernel_vaddr); +void vidc_cleanup_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer); + +u32 vidc_timer_create(void (*timer_handler)(void *), + void *user_data, void **timer_handle); +void vidc_timer_release(void *timer_handle); +void vidc_timer_start(void *timer_handle, u32 time_out); +void vidc_timer_stop(void *timer_handle); + + +#endif diff --git a/include/media/msm/vidc_type.h b/include/media/msm/vidc_type.h new file mode 100644 index 0000000000000000000000000000000000000000..04d28b260884f78b3d8e546a11ca828a0cd8946c --- /dev/null +++ b/include/media/msm/vidc_type.h @@ -0,0 +1,30 @@ +/* Copyright (c) 2010-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef VIDC_TYPE_H +#define VIDC_TYPE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG 0 +#define VIDC_ENABLE_DBGFS + +#define USE_RES_TRACKER +#endif diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h new file mode 100644 index 0000000000000000000000000000000000000000..c91bdfc07c207997df42b78e950ffffdf7dfbc9b --- /dev/null +++ b/include/media/msm_camera.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2009-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __LINUX_MSM_CAMERA_H +#define __LINUX_MSM_CAMERA_H + +#include +#include + +#endif /* __LINUX_MSM_CAMERA_H */ diff --git a/include/media/msm_v4l2_overlay.h b/include/media/msm_v4l2_overlay.h new file mode 100644 index 0000000000000000000000000000000000000000..c83cfb7b19169b2924b244b9e0fffe9ac20faded --- /dev/null +++ b/include/media/msm_v4l2_overlay.h @@ -0,0 +1,9 @@ +#ifndef LINUX_MSM_V4L2_OVERLAY +#define LINUX_MSM_V4L2_OVERLAY + +#include + +#define VIDIOC_MSM_USERPTR_QBUF \ +_IOWR('V', BASE_VIDIOC_PRIVATE, struct v4l2_buffer) + +#endif diff --git a/include/uapi/Kbuild b/include/uapi/Kbuild index 81d2106287fef98433387e5a62afe628a9192950..3098462d692ceaf2c34e21f66b2547a194a8ec10 100644 --- a/include/uapi/Kbuild +++ b/include/uapi/Kbuild @@ -12,3 +12,4 @@ header-y += video/ header-y += drm/ header-y += xen/ header-y += scsi/ +header-y += media/ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 707cc39a47a14519cb33aedcc750761a9141e621..bac2a91cdb2cee6eeef21092333b574b32b07a84 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -251,6 +251,7 @@ header-y += mroute.h header-y += mroute6.h header-y += msdos_fs.h header-y += msg.h +header-y += msm_mdp.h header-y += mtio.h header-y += n_r3964.h header-y += nbd.h diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h new file mode 100644 index 0000000000000000000000000000000000000000..cab9e7714d341bed5245b6dd0cf6de31ff34a9f0 --- /dev/null +++ b/include/uapi/linux/msm_mdp.h @@ -0,0 +1,480 @@ +#ifndef _UAPI_MSM_MDP_H_ +#define _UAPI_MSM_MDP_H_ + +#include +#include + +#define MSMFB_IOCTL_MAGIC 'm' +#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int) +#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int) +#define MSMFB_SUSPEND_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 128, unsigned int) +#define MSMFB_RESUME_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 129, unsigned int) +#define MSMFB_CURSOR _IOW(MSMFB_IOCTL_MAGIC, 130, struct fb_cursor) +#define MSMFB_SET_LUT _IOW(MSMFB_IOCTL_MAGIC, 131, struct fb_cmap) +#define MSMFB_HISTOGRAM _IOWR(MSMFB_IOCTL_MAGIC, 132, struct mdp_histogram_data) +/* new ioctls's for set/get ccs matrix */ +#define MSMFB_GET_CCS_MATRIX _IOWR(MSMFB_IOCTL_MAGIC, 133, struct mdp_ccs) +#define MSMFB_SET_CCS_MATRIX _IOW(MSMFB_IOCTL_MAGIC, 134, struct mdp_ccs) +#define MSMFB_OVERLAY_SET _IOWR(MSMFB_IOCTL_MAGIC, 135, \ + struct mdp_overlay) +#define MSMFB_OVERLAY_UNSET _IOW(MSMFB_IOCTL_MAGIC, 136, unsigned int) +#define MSMFB_OVERLAY_PLAY _IOW(MSMFB_IOCTL_MAGIC, 137, \ + struct msmfb_overlay_data) +#define MSMFB_GET_PAGE_PROTECTION _IOR(MSMFB_IOCTL_MAGIC, 138, \ + struct mdp_page_protection) +#define MSMFB_SET_PAGE_PROTECTION _IOW(MSMFB_IOCTL_MAGIC, 139, \ + struct mdp_page_protection) +#define MSMFB_OVERLAY_GET _IOR(MSMFB_IOCTL_MAGIC, 140, \ + struct mdp_overlay) +#define MSMFB_OVERLAY_PLAY_ENABLE _IOW(MSMFB_IOCTL_MAGIC, 141, unsigned int) +#define MSMFB_OVERLAY_BLT _IOWR(MSMFB_IOCTL_MAGIC, 142, \ + struct msmfb_overlay_blt) +#define MSMFB_OVERLAY_BLT_OFFSET _IOW(MSMFB_IOCTL_MAGIC, 143, unsigned int) +#define MSMFB_HISTOGRAM_START _IOR(MSMFB_IOCTL_MAGIC, 144, \ + struct mdp_histogram_start_req) +#define MSMFB_HISTOGRAM_STOP _IOR(MSMFB_IOCTL_MAGIC, 145, unsigned int) +#define MSMFB_NOTIFY_UPDATE _IOW(MSMFB_IOCTL_MAGIC, 146, unsigned int) + +#define MSMFB_OVERLAY_3D _IOWR(MSMFB_IOCTL_MAGIC, 147, \ + struct msmfb_overlay_3d) + +#define MSMFB_MIXER_INFO _IOWR(MSMFB_IOCTL_MAGIC, 148, \ + struct msmfb_mixer_info_req) +#define MSMFB_OVERLAY_PLAY_WAIT _IOWR(MSMFB_IOCTL_MAGIC, 149, \ + struct msmfb_overlay_data) +#define MSMFB_WRITEBACK_INIT _IO(MSMFB_IOCTL_MAGIC, 150) +#define MSMFB_WRITEBACK_START _IO(MSMFB_IOCTL_MAGIC, 151) +#define MSMFB_WRITEBACK_STOP _IO(MSMFB_IOCTL_MAGIC, 152) +#define MSMFB_WRITEBACK_QUEUE_BUFFER _IOW(MSMFB_IOCTL_MAGIC, 153, \ + struct msmfb_data) +#define MSMFB_WRITEBACK_DEQUEUE_BUFFER _IOW(MSMFB_IOCTL_MAGIC, 154, \ + struct msmfb_data) +#define MSMFB_WRITEBACK_TERMINATE _IO(MSMFB_IOCTL_MAGIC, 155) +#define MSMFB_MDP_PP _IOWR(MSMFB_IOCTL_MAGIC, 156, struct msmfb_mdp_pp) + +#define FB_TYPE_3D_PANEL 0x10101010 +#define MDP_IMGTYPE2_START 0x10000 +#define MSMFB_DRIVER_VERSION 0xF9E8D701 + +enum { + NOTIFY_UPDATE_START, + NOTIFY_UPDATE_STOP, +}; + +enum { + MDP_RGB_565, /* RGB 565 planer */ + MDP_XRGB_8888, /* RGB 888 padded */ + MDP_Y_CBCR_H2V2, /* Y and CbCr, pseudo planer w/ Cb is in MSB */ + MDP_Y_CBCR_H2V2_ADRENO, + MDP_ARGB_8888, /* ARGB 888 */ + MDP_RGB_888, /* RGB 888 planer */ + MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planer w/ Cr is in MSB */ + MDP_YCRYCB_H2V1, /* YCrYCb interleave */ + MDP_Y_CRCB_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */ + MDP_Y_CBCR_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */ + MDP_RGBA_8888, /* ARGB 888 */ + MDP_BGRA_8888, /* ABGR 888 */ + MDP_RGBX_8888, /* RGBX 888 */ + MDP_Y_CRCB_H2V2_TILE, /* Y and CrCb, pseudo planer tile */ + MDP_Y_CBCR_H2V2_TILE, /* Y and CbCr, pseudo planer tile */ + MDP_Y_CR_CB_H2V2, /* Y, Cr and Cb, planar */ + MDP_Y_CR_CB_GH2V2, /* Y, Cr and Cb, planar aligned to Android YV12 */ + MDP_Y_CB_CR_H2V2, /* Y, Cb and Cr, planar */ + MDP_Y_CRCB_H1V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */ + MDP_Y_CBCR_H1V1, /* Y and CbCr, pseduo planer w/ Cb is in MSB */ + MDP_YCRCB_H1V1, /* YCrCb interleave */ + MDP_YCBCR_H1V1, /* YCbCr interleave */ + MDP_IMGTYPE_LIMIT, + MDP_RGB_BORDERFILL, /* border fill pipe */ + MDP_BGR_565 = MDP_IMGTYPE2_START, /* BGR 565 planer */ + MDP_FB_FORMAT, /* framebuffer format */ + MDP_IMGTYPE_LIMIT2 /* Non valid image type after this enum */ +}; + +enum { + PMEM_IMG, + FB_IMG, +}; + +enum { + HSIC_HUE = 0, + HSIC_SAT, + HSIC_INT, + HSIC_CON, + NUM_HSIC_PARAM, +}; + +/* mdp_blit_req flag values */ +#define MDP_ROT_NOP 0 +#define MDP_FLIP_LR 0x1 +#define MDP_FLIP_UD 0x2 +#define MDP_ROT_90 0x4 +#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR) +#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR) +#define MDP_DITHER 0x8 +#define MDP_BLUR 0x10 +#define MDP_BLEND_FG_PREMULT 0x20000 +#define MDP_DEINTERLACE 0x80000000 +#define MDP_SHARPENING 0x40000000 +#define MDP_NO_DMA_BARRIER_START 0x20000000 +#define MDP_NO_DMA_BARRIER_END 0x10000000 +#define MDP_NO_BLIT 0x08000000 +#define MDP_BLIT_WITH_DMA_BARRIERS 0x000 +#define MDP_BLIT_WITH_NO_DMA_BARRIERS \ + (MDP_NO_DMA_BARRIER_START | MDP_NO_DMA_BARRIER_END) +#define MDP_BLIT_SRC_GEM 0x04000000 +#define MDP_BLIT_DST_GEM 0x02000000 +#define MDP_BLIT_NON_CACHED 0x01000000 +#define MDP_OV_PIPE_SHARE 0x00800000 +#define MDP_DEINTERLACE_ODD 0x00400000 +#define MDP_OV_PLAY_NOWAIT 0x00200000 +#define MDP_SOURCE_ROTATED_90 0x00100000 +#define MDP_DPP_HSIC 0x00080000 +#define MDP_BACKEND_COMPOSITION 0x00040000 +#define MDP_BORDERFILL_SUPPORTED 0x00010000 +#define MDP_SECURE_OVERLAY_SESSION 0x00008000 +#define MDP_MEMORY_ID_TYPE_FB 0x00001000 + +#define MDP_TRANSP_NOP 0xffffffff +#define MDP_ALPHA_NOP 0xff + +#define MDP_FB_PAGE_PROTECTION_NONCACHED (0) +#define MDP_FB_PAGE_PROTECTION_WRITECOMBINE (1) +#define MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE (2) +#define MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE (3) +#define MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE (4) +/* Sentinel: Don't use! */ +#define MDP_FB_PAGE_PROTECTION_INVALID (5) +/* Count of the number of MDP_FB_PAGE_PROTECTION_... values. */ +#define MDP_NUM_FB_PAGE_PROTECTION_VALUES (5) + +struct mdp_rect { + uint32_t x; + uint32_t y; + uint32_t w; + uint32_t h; +}; + +struct mdp_img { + uint32_t width; + uint32_t height; + uint32_t format; + uint32_t offset; + int memory_id; /* the file descriptor */ + uint32_t priv; +}; + +/* + * {3x3} + {3} ccs matrix + */ + +#define MDP_CCS_RGB2YUV 0 +#define MDP_CCS_YUV2RGB 1 + +#define MDP_CCS_SIZE 9 +#define MDP_BV_SIZE 3 + +struct mdp_ccs { + int direction; /* MDP_CCS_RGB2YUV or YUV2RGB */ + uint16_t ccs[MDP_CCS_SIZE]; /* 3x3 color coefficients */ + uint16_t bv[MDP_BV_SIZE]; /* 1x3 bias vector */ +}; + +struct mdp_csc { + int id; + uint32_t csc_mv[9]; + uint32_t csc_pre_bv[3]; + uint32_t csc_post_bv[3]; + uint32_t csc_pre_lv[6]; + uint32_t csc_post_lv[6]; +}; + +/* The version of the mdp_blit_req structure so that + * user applications can selectively decide which functionality + * to include + */ + +#define MDP_BLIT_REQ_VERSION 2 + +struct mdp_blit_req { + struct mdp_img src; + struct mdp_img dst; + struct mdp_rect src_rect; + struct mdp_rect dst_rect; + uint32_t alpha; + uint32_t transp_mask; + uint32_t flags; + int sharpening_strength; /* -127 <--> 127, default 64 */ +}; + +struct mdp_blit_req_list { + uint32_t count; + struct mdp_blit_req req[]; +}; + +#define MSMFB_DATA_VERSION 2 + +struct msmfb_data { + uint32_t offset; + int memory_id; + int id; + uint32_t flags; + uint32_t priv; + uint32_t iova; +}; + +#define MSMFB_NEW_REQUEST -1 + +struct msmfb_overlay_data { + uint32_t id; + struct msmfb_data data; + uint32_t version_key; + struct msmfb_data plane1_data; + struct msmfb_data plane2_data; +}; + +struct msmfb_img { + uint32_t width; + uint32_t height; + uint32_t format; +}; + +#define MSMFB_WRITEBACK_DEQUEUE_BLOCKING 0x1 +struct msmfb_writeback_data { + struct msmfb_data buf_info; + struct msmfb_img img; +}; + +struct dpp_ctrl { + /* + *'sharp_strength' has inputs = -128 <-> 127 + * Increasingly positive values correlate with increasingly sharper + * picture. Increasingly negative values correlate with increasingly + * smoothed picture. + */ + int8_t sharp_strength; + int8_t hsic_params[NUM_HSIC_PARAM]; +}; + +struct mdp_overlay { + struct msmfb_img src; + struct mdp_rect src_rect; + struct mdp_rect dst_rect; + uint32_t z_order; /* stage number */ + uint32_t is_fg; /* control alpha & transp */ + uint32_t alpha; + uint32_t transp_mask; + uint32_t flags; + uint32_t id; + uint32_t user_data[8]; + struct dpp_ctrl dpp; +}; + +struct msmfb_overlay_3d { + uint32_t is_3d; + uint32_t width; + uint32_t height; +}; + + +struct msmfb_overlay_blt { + uint32_t enable; + uint32_t offset; + uint32_t width; + uint32_t height; + uint32_t bpp; +}; + +struct mdp_histogram { + uint32_t frame_cnt; + uint32_t bin_cnt; + uint32_t *r; + uint32_t *g; + uint32_t *b; +}; + + +/* + + mdp_block_type defines the identifiers for each of pipes in MDP 4.3 + + MDP_BLOCK_RESERVED is provided for backward compatibility and is + deprecated. It corresponds to DMA_P. So MDP_BLOCK_DMA_P should be used + instead. + +*/ + +enum { + MDP_BLOCK_RESERVED = 0, + MDP_BLOCK_OVERLAY_0, + MDP_BLOCK_OVERLAY_1, + MDP_BLOCK_VG_1, + MDP_BLOCK_VG_2, + MDP_BLOCK_RGB_1, + MDP_BLOCK_RGB_2, + MDP_BLOCK_DMA_P, + MDP_BLOCK_DMA_S, + MDP_BLOCK_DMA_E, + MDP_BLOCK_OVERLAY_2, + MDP_BLOCK_MAX, +}; + +/* + * mdp_histogram_start_req is used to provide the parameters for + * histogram start request + */ + +struct mdp_histogram_start_req { + uint32_t block; + uint8_t frame_cnt; + uint8_t bit_mask; + uint8_t num_bins; +}; + +/* + * mdp_histogram_data is used to return the histogram data, once + * the histogram is done/stopped/cance + */ + +struct mdp_histogram_data { + uint32_t block; + uint8_t bin_cnt; + uint32_t *c0; + uint32_t *c1; + uint32_t *c2; + uint32_t *extra_info; +}; + +struct mdp_pcc_coeff { + uint32_t c, r, g, b, rr, gg, bb, rg, gb, rb, rgb_0, rgb_1; +}; + +struct mdp_pcc_cfg_data { + uint32_t block; + uint32_t ops; + struct mdp_pcc_coeff r, g, b; +}; + +#define MDP_CSC_FLAG_ENABLE 0x1 +#define MDP_CSC_FLAG_YUV_IN 0x2 +#define MDP_CSC_FLAG_YUV_OUT 0x4 + +struct mdp_csc_cfg { + /* flags for enable CSC, toggling RGB,YUV input/output */ + uint32_t flags; + uint32_t csc_mv[9]; + uint32_t csc_pre_bv[3]; + uint32_t csc_post_bv[3]; + uint32_t csc_pre_lv[6]; + uint32_t csc_post_lv[6]; +}; + +struct mdp_csc_cfg_data { + uint32_t block; + struct mdp_csc_cfg csc_data; +}; + +enum { + mdp_lut_igc, + mdp_lut_pgc, + mdp_lut_hist, + mdp_lut_max, +}; + + +struct mdp_igc_lut_data { + uint32_t block; + uint32_t len, ops; + uint32_t *c0_c1_data; + uint32_t *c2_data; +}; + +struct mdp_ar_gc_lut_data { + uint32_t x_start; + uint32_t slope; + uint32_t offset; +}; + +struct mdp_pgc_lut_data { + uint32_t block; + uint32_t flags; + uint8_t num_r_stages; + uint8_t num_g_stages; + uint8_t num_b_stages; + struct mdp_ar_gc_lut_data *r_data; + struct mdp_ar_gc_lut_data *g_data; + struct mdp_ar_gc_lut_data *b_data; +}; + + +struct mdp_hist_lut_data { + uint32_t block; + uint32_t ops; + uint32_t len; + uint32_t *data; +}; + + +struct mdp_lut_cfg_data { + uint32_t lut_type; + union { + struct mdp_igc_lut_data igc_lut_data; + struct mdp_pgc_lut_data pgc_lut_data; + struct mdp_hist_lut_data hist_lut_data; + } data; +}; + +struct mdp_qseed_cfg_data { + uint32_t block; + uint32_t table_num; + uint32_t ops; + uint32_t len; + uint32_t *data; +}; + + +enum { + mdp_op_pcc_cfg, + mdp_op_csc_cfg, + mdp_op_lut_cfg, + mdp_op_qseed_cfg, + mdp_op_max, +}; + +struct msmfb_mdp_pp { + uint32_t op; + union { + struct mdp_pcc_cfg_data pcc_cfg_data; + struct mdp_csc_cfg_data csc_cfg_data; + struct mdp_lut_cfg_data lut_cfg_data; + struct mdp_qseed_cfg_data qseed_cfg_data; + } data; +}; + + +struct mdp_page_protection { + uint32_t page_protection; +}; + + +struct mdp_mixer_info { + int pndx; + int pnum; + int ptype; + int mixer_num; + int z_order; +}; + +#define MAX_PIPE_PER_MIXER 4 + +struct msmfb_mixer_info_req { + int mixer_num; + int cnt; + struct mdp_mixer_info info[MAX_PIPE_PER_MIXER]; +}; + +enum { + DISPLAY_SUBSYSTEM_ID, + ROTATOR_SUBSYSTEM_ID, +}; +#endif /*_UAPI_MSM_MDP_H_*/ diff --git a/include/uapi/media/Kbuild b/include/uapi/media/Kbuild new file mode 100644 index 0000000000000000000000000000000000000000..75a11b286a61cecdcbee697314c299acb37b50f2 --- /dev/null +++ b/include/uapi/media/Kbuild @@ -0,0 +1 @@ +header-y += msm_camera.h diff --git a/include/uapi/media/msm_camera.h b/include/uapi/media/msm_camera.h new file mode 100644 index 0000000000000000000000000000000000000000..be9e04671897a2ee6e4a093416da78ffb303e9ca --- /dev/null +++ b/include/uapi/media/msm_camera.h @@ -0,0 +1,2266 @@ +/* Copyright (c) 2009-2012, 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __UAPI_MSM_CAMERA_H +#define __UAPI_MSM_CAMERA_H + +#ifdef MSM_CAMERA_BIONIC +#include +#endif +#include +#include +#include +#ifdef MSM_CAMERA_GCC +#include +#else +#include +#endif + +#include + +#define BIT(nr) (1UL << (nr)) + +#define MSM_CAM_IOCTL_MAGIC 'm' + +#define MAX_SERVER_PAYLOAD_LENGTH 8192 + +#define MSM_CAM_IOCTL_GET_SENSOR_INFO \ + _IOR(MSM_CAM_IOCTL_MAGIC, 1, struct msm_camsensor_info *) + +#define MSM_CAM_IOCTL_REGISTER_PMEM \ + _IOW(MSM_CAM_IOCTL_MAGIC, 2, struct msm_pmem_info *) + +#define MSM_CAM_IOCTL_UNREGISTER_PMEM \ + _IOW(MSM_CAM_IOCTL_MAGIC, 3, unsigned) + +#define MSM_CAM_IOCTL_CTRL_COMMAND \ + _IOW(MSM_CAM_IOCTL_MAGIC, 4, struct msm_ctrl_cmd *) + +#define MSM_CAM_IOCTL_CONFIG_VFE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 5, struct msm_camera_vfe_cfg_cmd *) + +#define MSM_CAM_IOCTL_GET_STATS \ + _IOR(MSM_CAM_IOCTL_MAGIC, 6, struct msm_camera_stats_event_ctrl *) + +#define MSM_CAM_IOCTL_GETFRAME \ + _IOR(MSM_CAM_IOCTL_MAGIC, 7, struct msm_camera_get_frame *) + +#define MSM_CAM_IOCTL_ENABLE_VFE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 8, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_CTRL_CMD_DONE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 9, struct camera_cmd *) + +#define MSM_CAM_IOCTL_CONFIG_CMD \ + _IOW(MSM_CAM_IOCTL_MAGIC, 10, struct camera_cmd *) + +#define MSM_CAM_IOCTL_DISABLE_VFE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 11, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_PAD_REG_RESET2 \ + _IOW(MSM_CAM_IOCTL_MAGIC, 12, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_VFE_APPS_RESET \ + _IOW(MSM_CAM_IOCTL_MAGIC, 13, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER \ + _IOW(MSM_CAM_IOCTL_MAGIC, 14, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_RELEASE_STATS_BUFFER \ + _IOW(MSM_CAM_IOCTL_MAGIC, 15, struct msm_stats_buf *) + +#define MSM_CAM_IOCTL_AXI_CONFIG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 16, struct msm_camera_vfe_cfg_cmd *) + +#define MSM_CAM_IOCTL_GET_PICTURE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 17, struct msm_frame *) + +#define MSM_CAM_IOCTL_SET_CROP \ + _IOW(MSM_CAM_IOCTL_MAGIC, 18, struct crop_info *) + +#define MSM_CAM_IOCTL_PICT_PP \ + _IOW(MSM_CAM_IOCTL_MAGIC, 19, uint8_t *) + +#define MSM_CAM_IOCTL_PICT_PP_DONE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 20, struct msm_snapshot_pp_status *) + +#define MSM_CAM_IOCTL_SENSOR_IO_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 21, struct sensor_cfg_data *) + +#define MSM_CAM_IOCTL_FLASH_LED_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 22, unsigned *) + +#define MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME \ + _IO(MSM_CAM_IOCTL_MAGIC, 23) + +#define MSM_CAM_IOCTL_CTRL_COMMAND_2 \ + _IOW(MSM_CAM_IOCTL_MAGIC, 24, struct msm_ctrl_cmd *) + +#define MSM_CAM_IOCTL_AF_CTRL \ + _IOR(MSM_CAM_IOCTL_MAGIC, 25, struct msm_ctrl_cmt_t *) + +#define MSM_CAM_IOCTL_AF_CTRL_DONE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 26, struct msm_ctrl_cmt_t *) + +#define MSM_CAM_IOCTL_CONFIG_VPE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 27, struct msm_camera_vpe_cfg_cmd *) + +#define MSM_CAM_IOCTL_AXI_VPE_CONFIG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 28, struct msm_camera_vpe_cfg_cmd *) + +#define MSM_CAM_IOCTL_STROBE_FLASH_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 29, uint32_t *) + +#define MSM_CAM_IOCTL_STROBE_FLASH_CHARGE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 30, uint32_t *) + +#define MSM_CAM_IOCTL_STROBE_FLASH_RELEASE \ + _IO(MSM_CAM_IOCTL_MAGIC, 31) + +#define MSM_CAM_IOCTL_FLASH_CTRL \ + _IOW(MSM_CAM_IOCTL_MAGIC, 32, struct flash_ctrl_data *) + +#define MSM_CAM_IOCTL_ERROR_CONFIG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 33, uint32_t *) + +#define MSM_CAM_IOCTL_ABORT_CAPTURE \ + _IO(MSM_CAM_IOCTL_MAGIC, 34) + +#define MSM_CAM_IOCTL_SET_FD_ROI \ + _IOW(MSM_CAM_IOCTL_MAGIC, 35, struct fd_roi_info *) + +#define MSM_CAM_IOCTL_GET_CAMERA_INFO \ + _IOR(MSM_CAM_IOCTL_MAGIC, 36, struct msm_camera_info *) + +#define MSM_CAM_IOCTL_UNBLOCK_POLL_PIC_FRAME \ + _IO(MSM_CAM_IOCTL_MAGIC, 37) + +#define MSM_CAM_IOCTL_RELEASE_PIC_BUFFER \ + _IOW(MSM_CAM_IOCTL_MAGIC, 38, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_PUT_ST_FRAME \ + _IOW(MSM_CAM_IOCTL_MAGIC, 39, struct msm_camera_st_frame *) + +#define MSM_CAM_IOCTL_V4L2_EVT_NOTIFY \ + _IOW(MSM_CAM_IOCTL_MAGIC, 40, struct v4l2_event_and_payload) + +#define MSM_CAM_IOCTL_SET_MEM_MAP_INFO \ + _IOR(MSM_CAM_IOCTL_MAGIC, 41, struct msm_mem_map_info *) + +#define MSM_CAM_IOCTL_ACTUATOR_IO_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 42, struct msm_actuator_cfg_data *) + +#define MSM_CAM_IOCTL_MCTL_POST_PROC \ + _IOW(MSM_CAM_IOCTL_MAGIC, 43, struct msm_mctl_post_proc_cmd *) + +#define MSM_CAM_IOCTL_RESERVE_FREE_FRAME \ + _IOW(MSM_CAM_IOCTL_MAGIC, 44, struct msm_cam_evt_divert_frame *) + +#define MSM_CAM_IOCTL_RELEASE_FREE_FRAME \ + _IOR(MSM_CAM_IOCTL_MAGIC, 45, struct msm_cam_evt_divert_frame *) + +#define MSM_CAM_IOCTL_PICT_PP_DIVERT_DONE \ + _IOR(MSM_CAM_IOCTL_MAGIC, 46, struct msm_pp_frame *) + +#define MSM_CAM_IOCTL_SENSOR_V4l2_S_CTRL \ + _IOR(MSM_CAM_IOCTL_MAGIC, 47, struct v4l2_control) + +#define MSM_CAM_IOCTL_SENSOR_V4l2_QUERY_CTRL \ + _IOR(MSM_CAM_IOCTL_MAGIC, 48, struct v4l2_queryctrl) + +#define MSM_CAM_IOCTL_GET_KERNEL_SYSTEM_TIME \ + _IOW(MSM_CAM_IOCTL_MAGIC, 49, struct timeval *) + +#define MSM_CAM_IOCTL_SET_VFE_OUTPUT_TYPE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 50, uint32_t *) + +#define MSM_CAM_IOCTL_MCTL_DIVERT_DONE \ + _IOR(MSM_CAM_IOCTL_MAGIC, 51, struct msm_cam_evt_divert_frame *) + +#define MSM_CAM_IOCTL_GET_ACTUATOR_INFO \ + _IOW(MSM_CAM_IOCTL_MAGIC, 52, struct msm_actuator_cfg_data *) + +#define MSM_CAM_IOCTL_EEPROM_IO_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 53, struct msm_eeprom_cfg_data *) + +#define MSM_CAM_IOCTL_ISPIF_IO_CFG \ + _IOR(MSM_CAM_IOCTL_MAGIC, 54, struct ispif_cfg_data *) + +#define MSM_CAM_IOCTL_STATS_REQBUF \ + _IOR(MSM_CAM_IOCTL_MAGIC, 55, struct msm_stats_reqbuf *) + +#define MSM_CAM_IOCTL_STATS_ENQUEUEBUF \ + _IOR(MSM_CAM_IOCTL_MAGIC, 56, struct msm_stats_buf_info *) + +#define MSM_CAM_IOCTL_STATS_FLUSH_BUFQ \ + _IOR(MSM_CAM_IOCTL_MAGIC, 57, struct msm_stats_flush_bufq *) + +#define MSM_CAM_IOCTL_SET_MCTL_SDEV \ + _IOW(MSM_CAM_IOCTL_MAGIC, 58, struct msm_mctl_set_sdev_data *) + +#define MSM_CAM_IOCTL_UNSET_MCTL_SDEV \ + _IOW(MSM_CAM_IOCTL_MAGIC, 59, struct msm_mctl_set_sdev_data *) + +#define MSM_CAM_IOCTL_GET_INST_HANDLE \ + _IOR(MSM_CAM_IOCTL_MAGIC, 60, uint32_t *) + +#define MSM_CAM_IOCTL_STATS_UNREG_BUF \ + _IOR(MSM_CAM_IOCTL_MAGIC, 61, struct msm_stats_flush_bufq *) + +#define MSM_CAM_IOCTL_CSIC_IO_CFG \ + _IOWR(MSM_CAM_IOCTL_MAGIC, 62, struct csic_cfg_data *) + +#define MSM_CAM_IOCTL_CSID_IO_CFG \ + _IOWR(MSM_CAM_IOCTL_MAGIC, 63, struct csid_cfg_data *) + +#define MSM_CAM_IOCTL_CSIPHY_IO_CFG \ + _IOR(MSM_CAM_IOCTL_MAGIC, 64, struct csiphy_cfg_data *) + +#define MSM_CAM_IOCTL_OEM \ + _IOW(MSM_CAM_IOCTL_MAGIC, 65, struct sensor_cfg_data *) + +#define MSM_CAM_IOCTL_AXI_INIT \ + _IOWR(MSM_CAM_IOCTL_MAGIC, 66, uint8_t *) + +#define MSM_CAM_IOCTL_AXI_RELEASE \ + _IO(MSM_CAM_IOCTL_MAGIC, 67) + +struct v4l2_event_and_payload { + struct v4l2_event evt; + uint32_t payload_length; + uint32_t transaction_id; + void *payload; +}; + +struct msm_stats_reqbuf { + int num_buf; /* how many buffers requested */ + int stats_type; /* stats type */ +}; + +struct msm_stats_flush_bufq { + int stats_type; /* enum msm_stats_enum_type */ +}; + +struct msm_mctl_pp_cmd { + int32_t id; + uint16_t length; + void *value; +}; + +struct msm_mctl_post_proc_cmd { + int32_t type; + struct msm_mctl_pp_cmd cmd; +}; + +#define MSM_CAMERA_LED_OFF 0 +#define MSM_CAMERA_LED_LOW 1 +#define MSM_CAMERA_LED_HIGH 2 +#define MSM_CAMERA_LED_INIT 3 +#define MSM_CAMERA_LED_RELEASE 4 + +#define MSM_CAMERA_STROBE_FLASH_NONE 0 +#define MSM_CAMERA_STROBE_FLASH_XENON 1 + +#define MSM_MAX_CAMERA_SENSORS 5 +#define MAX_SENSOR_NAME 32 +#define MAX_CAM_NAME_SIZE 32 +#define MAX_ACT_MOD_NAME_SIZE 32 +#define MAX_ACT_NAME_SIZE 32 +#define NUM_ACTUATOR_DIR 2 +#define MAX_ACTUATOR_SCENARIO 8 +#define MAX_ACTUATOR_REGION 5 +#define MAX_ACTUATOR_INIT_SET 12 +#define MAX_ACTUATOR_TYPE_SIZE 32 +#define MAX_ACTUATOR_REG_TBL_SIZE 8 + + +#define MSM_MAX_CAMERA_CONFIGS 2 + +#define PP_SNAP 0x01 +#define PP_RAW_SNAP ((0x01)<<1) +#define PP_PREV ((0x01)<<2) +#define PP_THUMB ((0x01)<<3) +#define PP_MASK (PP_SNAP|PP_RAW_SNAP|PP_PREV|PP_THUMB) + +#define MSM_CAM_CTRL_CMD_DONE 0 +#define MSM_CAM_SENSOR_VFE_CMD 1 + +/* Should be same as VIDEO_MAX_PLANES in videodev2.h */ +#define MAX_PLANES 8 + +/***************************************************** + * structure + *****************************************************/ + +/* define five type of structures for userspace <==> kernel + * space communication: + * command 1 - 2 are from userspace ==> kernel + * command 3 - 4 are from kernel ==> userspace + * + * 1. control command: control command(from control thread), + * control status (from config thread); + */ +struct msm_ctrl_cmd { + uint16_t type; + uint16_t length; + void *value; + uint16_t status; + uint32_t timeout_ms; + int resp_fd; /* FIXME: to be used by the kernel, pass-through for now */ + int vnode_id; /* video dev id. Can we overload resp_fd? */ + int queue_idx; + uint32_t evt_id; + uint32_t stream_type; /* used to pass value to qcamera server */ + int config_ident; /*used as identifier for config node*/ +}; + +struct msm_cam_evt_msg { + unsigned short type; /* 1 == event (RPC), 0 == message (adsp) */ + unsigned short msg_id; + unsigned int len; /* size in, number of bytes out */ + uint32_t frame_id; + void *data; + struct timespec timestamp; +}; + +struct msm_pp_frame_sp { + /* phy addr of the buffer */ + unsigned long phy_addr; + uint32_t y_off; + uint32_t cbcr_off; + /* buffer length */ + uint32_t length; + int32_t fd; + uint32_t addr_offset; + /* mapped addr */ + unsigned long vaddr; +}; + +struct msm_pp_frame_mp { + /* phy addr of the plane */ + unsigned long phy_addr; + /* offset of plane data */ + uint32_t data_offset; + /* plane length */ + uint32_t length; + int32_t fd; + uint32_t addr_offset; + /* mapped addr */ + unsigned long vaddr; +}; + +struct msm_pp_frame { + uint32_t handle; /* stores vb cookie */ + uint32_t frame_id; + unsigned short buf_idx; + int path; + unsigned short image_type; + unsigned short num_planes; /* 1 for sp */ + struct timeval timestamp; + union { + struct msm_pp_frame_sp sp; + struct msm_pp_frame_mp mp[MAX_PLANES]; + }; + int node_type; + uint32_t inst_handle; +}; + +struct msm_pp_crop { + uint32_t src_x; + uint32_t src_y; + uint32_t src_w; + uint32_t src_h; + uint32_t dst_x; + uint32_t dst_y; + uint32_t dst_w; + uint32_t dst_h; + uint8_t update_flag; +}; + +struct msm_mctl_pp_frame_cmd { + uint32_t cookie; + uint8_t vpe_output_action; + struct msm_pp_frame src_frame; + struct msm_pp_frame dest_frame; + struct msm_pp_crop crop; + int path; +}; + +struct msm_cam_evt_divert_frame { + unsigned short image_mode; + unsigned short op_mode; + unsigned short inst_idx; + unsigned short node_idx; + struct msm_pp_frame frame; + int do_pp; +}; + +struct msm_mctl_pp_cmd_ack_event { + uint32_t cmd; /* VPE_CMD_ZOOM? */ + int status; /* 0 done, < 0 err */ + uint32_t cookie; /* daemon's cookie */ +}; + +struct msm_mctl_pp_event_info { + int32_t event; + union { + struct msm_mctl_pp_cmd_ack_event ack; + }; +}; + +struct msm_isp_event_ctrl { + unsigned short resptype; + union { + struct msm_cam_evt_msg isp_msg; + struct msm_ctrl_cmd ctrl; + struct msm_cam_evt_divert_frame div_frame; + struct msm_mctl_pp_event_info pp_event_info; + } isp_data; +}; + +#define MSM_CAM_RESP_CTRL 0 +#define MSM_CAM_RESP_STAT_EVT_MSG 1 +#define MSM_CAM_RESP_STEREO_OP_1 2 +#define MSM_CAM_RESP_STEREO_OP_2 3 +#define MSM_CAM_RESP_V4L2 4 +#define MSM_CAM_RESP_DIV_FRAME_EVT_MSG 5 +#define MSM_CAM_RESP_DONE_EVENT 6 +#define MSM_CAM_RESP_MCTL_PP_EVENT 7 +#define MSM_CAM_RESP_MAX 8 + +#define MSM_CAM_APP_NOTIFY_EVENT 0 +#define MSM_CAM_APP_NOTIFY_ERROR_EVENT 1 + +/* this one is used to send ctrl/status up to config thread */ + +struct msm_stats_event_ctrl { + /* 0 - ctrl_cmd from control thread, + * 1 - stats/event kernel, + * 2 - V4L control or read request */ + int resptype; + int timeout_ms; + struct msm_ctrl_cmd ctrl_cmd; + /* struct vfe_event_t stats_event; */ + struct msm_cam_evt_msg stats_event; +}; + +/* 2. config command: config command(from config thread); */ +struct msm_camera_cfg_cmd { + /* what to config: + * 1 - sensor config, 2 - vfe config */ + uint16_t cfg_type; + + /* sensor config type */ + uint16_t cmd_type; + uint16_t queue; + uint16_t length; + void *value; +}; + +#define CMD_GENERAL 0 +#define CMD_AXI_CFG_OUT1 1 +#define CMD_AXI_CFG_SNAP_O1_AND_O2 2 +#define CMD_AXI_CFG_OUT2 3 +#define CMD_PICT_T_AXI_CFG 4 +#define CMD_PICT_M_AXI_CFG 5 +#define CMD_RAW_PICT_AXI_CFG 6 + +#define CMD_FRAME_BUF_RELEASE 7 +#define CMD_PREV_BUF_CFG 8 +#define CMD_SNAP_BUF_RELEASE 9 +#define CMD_SNAP_BUF_CFG 10 +#define CMD_STATS_DISABLE 11 +#define CMD_STATS_AEC_AWB_ENABLE 12 +#define CMD_STATS_AF_ENABLE 13 +#define CMD_STATS_AEC_ENABLE 14 +#define CMD_STATS_AWB_ENABLE 15 +#define CMD_STATS_ENABLE 16 + +#define CMD_STATS_AXI_CFG 17 +#define CMD_STATS_AEC_AXI_CFG 18 +#define CMD_STATS_AF_AXI_CFG 19 +#define CMD_STATS_AWB_AXI_CFG 20 +#define CMD_STATS_RS_AXI_CFG 21 +#define CMD_STATS_CS_AXI_CFG 22 +#define CMD_STATS_IHIST_AXI_CFG 23 +#define CMD_STATS_SKIN_AXI_CFG 24 + +#define CMD_STATS_BUF_RELEASE 25 +#define CMD_STATS_AEC_BUF_RELEASE 26 +#define CMD_STATS_AF_BUF_RELEASE 27 +#define CMD_STATS_AWB_BUF_RELEASE 28 +#define CMD_STATS_RS_BUF_RELEASE 29 +#define CMD_STATS_CS_BUF_RELEASE 30 +#define CMD_STATS_IHIST_BUF_RELEASE 31 +#define CMD_STATS_SKIN_BUF_RELEASE 32 + +#define UPDATE_STATS_INVALID 33 +#define CMD_AXI_CFG_SNAP_GEMINI 34 +#define CMD_AXI_CFG_SNAP 35 +#define CMD_AXI_CFG_PREVIEW 36 +#define CMD_AXI_CFG_VIDEO 37 + +#define CMD_STATS_IHIST_ENABLE 38 +#define CMD_STATS_RS_ENABLE 39 +#define CMD_STATS_CS_ENABLE 40 +#define CMD_VPE 41 +#define CMD_AXI_CFG_VPE 42 +#define CMD_AXI_CFG_ZSL 43 +#define CMD_AXI_CFG_SNAP_VPE 44 +#define CMD_AXI_CFG_SNAP_THUMB_VPE 45 + +#define CMD_CONFIG_PING_ADDR 46 +#define CMD_CONFIG_PONG_ADDR 47 +#define CMD_CONFIG_FREE_BUF_ADDR 48 +#define CMD_AXI_CFG_ZSL_ALL_CHNLS 49 +#define CMD_AXI_CFG_VIDEO_ALL_CHNLS 50 +#define CMD_VFE_BUFFER_RELEASE 51 +#define CMD_VFE_PROCESS_IRQ 52 +#define CMD_STATS_BG_ENABLE 53 +#define CMD_STATS_BF_ENABLE 54 +#define CMD_STATS_BHIST_ENABLE 55 +#define CMD_STATS_BG_BUF_RELEASE 56 +#define CMD_STATS_BF_BUF_RELEASE 57 +#define CMD_STATS_BHIST_BUF_RELEASE 58 +#define CMD_VFE_PIX_SOF_COUNT_UPDATE 59 +#define CMD_VFE_COUNT_PIX_SOF_ENABLE 60 +#define CMD_STATS_BE_ENABLE 61 +#define CMD_STATS_BE_BUF_RELEASE 62 + +#define CMD_AXI_CFG_PRIM BIT(8) +#define CMD_AXI_CFG_PRIM_ALL_CHNLS BIT(9) +#define CMD_AXI_CFG_SEC BIT(10) +#define CMD_AXI_CFG_SEC_ALL_CHNLS BIT(11) +#define CMD_AXI_CFG_TERT1 BIT(12) +#define CMD_AXI_CFG_TERT2 BIT(13) + +#define CMD_AXI_START 0xE1 +#define CMD_AXI_STOP 0xE2 +#define CMD_AXI_RESET 0xE3 +#define CMD_AXI_ABORT 0xE4 + + + +#define AXI_CMD_PREVIEW BIT(0) +#define AXI_CMD_CAPTURE BIT(1) +#define AXI_CMD_RECORD BIT(2) +#define AXI_CMD_ZSL BIT(3) +#define AXI_CMD_RAW_CAPTURE BIT(4) +#define AXI_CMD_LIVESHOT BIT(5) + +/* vfe config command: config command(from config thread)*/ +struct msm_vfe_cfg_cmd { + int cmd_type; + uint16_t length; + void *value; +}; + +struct msm_vpe_cfg_cmd { + int cmd_type; + uint16_t length; + void *value; +}; + +#define MAX_CAMERA_ENABLE_NAME_LEN 32 +struct camera_enable_cmd { + char name[MAX_CAMERA_ENABLE_NAME_LEN]; +}; + +#define MSM_PMEM_OUTPUT1 0 +#define MSM_PMEM_OUTPUT2 1 +#define MSM_PMEM_OUTPUT1_OUTPUT2 2 +#define MSM_PMEM_THUMBNAIL 3 +#define MSM_PMEM_MAINIMG 4 +#define MSM_PMEM_RAW_MAINIMG 5 +#define MSM_PMEM_AEC_AWB 6 +#define MSM_PMEM_AF 7 +#define MSM_PMEM_AEC 8 +#define MSM_PMEM_AWB 9 +#define MSM_PMEM_RS 10 +#define MSM_PMEM_CS 11 +#define MSM_PMEM_IHIST 12 +#define MSM_PMEM_SKIN 13 +#define MSM_PMEM_VIDEO 14 +#define MSM_PMEM_PREVIEW 15 +#define MSM_PMEM_VIDEO_VPE 16 +#define MSM_PMEM_C2D 17 +#define MSM_PMEM_MAINIMG_VPE 18 +#define MSM_PMEM_THUMBNAIL_VPE 19 +#define MSM_PMEM_BAYER_GRID 20 +#define MSM_PMEM_BAYER_FOCUS 21 +#define MSM_PMEM_BAYER_HIST 22 +#define MSM_PMEM_BAYER_EXPOSURE 23 +#define MSM_PMEM_MAX 24 + +#define STAT_AEAW 0 +#define STAT_AEC 1 +#define STAT_AF 2 +#define STAT_AWB 3 +#define STAT_RS 4 +#define STAT_CS 5 +#define STAT_IHIST 6 +#define STAT_SKIN 7 +#define STAT_BG 8 +#define STAT_BF 9 +#define STAT_BE 10 +#define STAT_BHIST 11 +#define STAT_MAX 12 + +#define FRAME_PREVIEW_OUTPUT1 0 +#define FRAME_PREVIEW_OUTPUT2 1 +#define FRAME_SNAPSHOT 2 +#define FRAME_THUMBNAIL 3 +#define FRAME_RAW_SNAPSHOT 4 +#define FRAME_MAX 5 + +enum msm_stats_enum_type { + MSM_STATS_TYPE_AEC, /* legacy based AEC */ + MSM_STATS_TYPE_AF, /* legacy based AF */ + MSM_STATS_TYPE_AWB, /* legacy based AWB */ + MSM_STATS_TYPE_RS, /* legacy based RS */ + MSM_STATS_TYPE_CS, /* legacy based CS */ + MSM_STATS_TYPE_IHIST, /* legacy based HIST */ + MSM_STATS_TYPE_SKIN, /* legacy based SKIN */ + MSM_STATS_TYPE_BG, /* Bayer Grids */ + MSM_STATS_TYPE_BF, /* Bayer Focus */ + MSM_STATS_TYPE_BE, /* Bayer Exposure*/ + MSM_STATS_TYPE_BHIST, /* Bayer Hist */ + MSM_STATS_TYPE_AE_AW, /* legacy stats for vfe 2.x*/ + MSM_STATS_TYPE_COMP, /* Composite stats */ + MSM_STATS_TYPE_MAX /* MAX */ +}; + +struct msm_stats_buf_info { + int type; /* msm_stats_enum_type */ + int fd; + void *vaddr; + uint32_t offset; + uint32_t len; + uint32_t y_off; + uint32_t cbcr_off; + uint32_t planar0_off; + uint32_t planar1_off; + uint32_t planar2_off; + uint8_t active; + int buf_idx; +}; + +struct msm_pmem_info { + int type; + int fd; + void *vaddr; + uint32_t offset; + uint32_t len; + uint32_t y_off; + uint32_t cbcr_off; + uint32_t planar0_off; + uint32_t planar1_off; + uint32_t planar2_off; + uint8_t active; +}; + +struct outputCfg { + uint32_t height; + uint32_t width; + + uint32_t window_height_firstline; + uint32_t window_height_lastline; +}; + +#define VIDEO_NODE 0 +#define MCTL_NODE 1 + +#define OUTPUT_1 0 +#define OUTPUT_2 1 +#define OUTPUT_1_AND_2 2 /* snapshot only */ +#define OUTPUT_1_AND_3 3 /* video */ +#define CAMIF_TO_AXI_VIA_OUTPUT_2 4 +#define OUTPUT_1_AND_CAMIF_TO_AXI_VIA_OUTPUT_2 5 +#define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6 +#define OUTPUT_1_2_AND_3 7 +#define OUTPUT_ALL_CHNLS 8 +#define OUTPUT_VIDEO_ALL_CHNLS 9 +#define OUTPUT_ZSL_ALL_CHNLS 10 +#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_ZSL_ALL_CHNLS + +#define OUTPUT_PRIM BIT(8) +#define OUTPUT_PRIM_ALL_CHNLS BIT(9) +#define OUTPUT_SEC BIT(10) +#define OUTPUT_SEC_ALL_CHNLS BIT(11) +#define OUTPUT_TERT1 BIT(12) +#define OUTPUT_TERT2 BIT(13) + + + +#define MSM_FRAME_PREV_1 0 +#define MSM_FRAME_PREV_2 1 +#define MSM_FRAME_ENC 2 + +#define OUTPUT_TYPE_P BIT(0) +#define OUTPUT_TYPE_T BIT(1) +#define OUTPUT_TYPE_S BIT(2) +#define OUTPUT_TYPE_V BIT(3) +#define OUTPUT_TYPE_L BIT(4) +#define OUTPUT_TYPE_ST_L BIT(5) +#define OUTPUT_TYPE_ST_R BIT(6) +#define OUTPUT_TYPE_ST_D BIT(7) +#define OUTPUT_TYPE_R BIT(8) +#define OUTPUT_TYPE_R1 BIT(9) +#define OUTPUT_TYPE_SAEC BIT(10) +#define OUTPUT_TYPE_SAFC BIT(11) +#define OUTPUT_TYPE_SAWB BIT(12) +#define OUTPUT_TYPE_IHST BIT(13) +#define OUTPUT_TYPE_CSTA BIT(14) + +struct fd_roi_info { + void *info; + int info_len; +}; + +struct msm_mem_map_info { + uint32_t cookie; + uint32_t length; + uint32_t mem_type; +}; + +#define MSM_MEM_MMAP 0 +#define MSM_MEM_USERPTR 1 +#define MSM_PLANE_MAX 8 +#define MSM_PLANE_Y 0 +#define MSM_PLANE_UV 1 + +struct msm_frame { + struct timespec ts; + int path; + int type; + unsigned long buffer; + uint32_t phy_offset; + uint32_t y_off; + uint32_t cbcr_off; + uint32_t planar0_off; + uint32_t planar1_off; + uint32_t planar2_off; + int fd; + + void *cropinfo; + int croplen; + uint32_t error_code; + struct fd_roi_info roi_info; + uint32_t frame_id; + int stcam_quality_ind; + uint32_t stcam_conv_value; + + struct ion_allocation_data ion_alloc; + struct ion_fd_data fd_data; + int ion_dev_fd; +}; + +enum msm_st_frame_packing { + SIDE_BY_SIDE_HALF, + SIDE_BY_SIDE_FULL, + TOP_DOWN_HALF, + TOP_DOWN_FULL, +}; + +struct msm_st_crop { + uint32_t in_w; + uint32_t in_h; + uint32_t out_w; + uint32_t out_h; +}; + +struct msm_st_half { + uint32_t buf_p0_off; + uint32_t buf_p1_off; + uint32_t buf_p0_stride; + uint32_t buf_p1_stride; + uint32_t pix_x_off; + uint32_t pix_y_off; + struct msm_st_crop stCropInfo; +}; + +struct msm_st_frame { + struct msm_frame buf_info; + int type; + enum msm_st_frame_packing packing; + struct msm_st_half L; + struct msm_st_half R; + int frame_id; +}; + +#define MSM_CAMERA_ERR_MASK (0xFFFFFFFF & 1) + +struct stats_buff { + unsigned long buff; + int fd; +}; + +struct msm_stats_buf { + uint8_t awb_ymin; + struct stats_buff aec; + struct stats_buff awb; + struct stats_buff af; + struct stats_buff be; + struct stats_buff ihist; + struct stats_buff rs; + struct stats_buff cs; + struct stats_buff skin; + int type; + uint32_t status_bits; + unsigned long buffer; + int fd; + int length; + struct ion_handle *handle; + uint32_t frame_id; + int buf_idx; +}; +#define MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT 0 +/* video capture mode in VIDIOC_S_PARM */ +#define MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+1) +/* extendedmode for video recording in VIDIOC_S_PARM */ +#define MSM_V4L2_EXT_CAPTURE_MODE_VIDEO \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+2) +/* extendedmode for the full size main image in VIDIOC_S_PARM */ +#define MSM_V4L2_EXT_CAPTURE_MODE_MAIN (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+3) +/* extendedmode for the thumb nail image in VIDIOC_S_PARM */ +#define MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+4) +/* ISP_PIX_OUTPUT1: no pp, directly send output1 buf to user */ +#define MSM_V4L2_EXT_CAPTURE_MODE_ISP_PIX_OUTPUT1 \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+5) +/* ISP_PIX_OUTPUT2: no pp, directly send output2 buf to user */ +#define MSM_V4L2_EXT_CAPTURE_MODE_ISP_PIX_OUTPUT2 \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+6) +/* raw image type */ +#define MSM_V4L2_EXT_CAPTURE_MODE_RAW \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+7) +/* RDI dump */ +#define MSM_V4L2_EXT_CAPTURE_MODE_RDI \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+8) +/* RDI dump 1 */ +#define MSM_V4L2_EXT_CAPTURE_MODE_RDI1 \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+9) +/* RDI dump 2 */ +#define MSM_V4L2_EXT_CAPTURE_MODE_RDI2 \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+10) +#define MSM_V4L2_EXT_CAPTURE_MODE_AEC \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+11) +#define MSM_V4L2_EXT_CAPTURE_MODE_AWB \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+12) +#define MSM_V4L2_EXT_CAPTURE_MODE_AF \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+13) +#define MSM_V4L2_EXT_CAPTURE_MODE_IHIST \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+14) +#define MSM_V4L2_EXT_CAPTURE_MODE_CS \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+15) +#define MSM_V4L2_EXT_CAPTURE_MODE_RS \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+16) +#define MSM_V4L2_EXT_CAPTURE_MODE_CSTA \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+17) +#define MSM_V4L2_EXT_CAPTURE_MODE_V2X_LIVESHOT \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+18) +#define MSM_V4L2_EXT_CAPTURE_MODE_MAX (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+19) + + +#define MSM_V4L2_PID_MOTION_ISO V4L2_CID_PRIVATE_BASE +#define MSM_V4L2_PID_EFFECT (V4L2_CID_PRIVATE_BASE+1) +#define MSM_V4L2_PID_HJR (V4L2_CID_PRIVATE_BASE+2) +#define MSM_V4L2_PID_LED_MODE (V4L2_CID_PRIVATE_BASE+3) +#define MSM_V4L2_PID_PREP_SNAPSHOT (V4L2_CID_PRIVATE_BASE+4) +#define MSM_V4L2_PID_EXP_METERING (V4L2_CID_PRIVATE_BASE+5) +#define MSM_V4L2_PID_ISO (V4L2_CID_PRIVATE_BASE+6) +#define MSM_V4L2_PID_CAM_MODE (V4L2_CID_PRIVATE_BASE+7) +#define MSM_V4L2_PID_LUMA_ADAPTATION (V4L2_CID_PRIVATE_BASE+8) +#define MSM_V4L2_PID_BEST_SHOT (V4L2_CID_PRIVATE_BASE+9) +#define MSM_V4L2_PID_FOCUS_MODE (V4L2_CID_PRIVATE_BASE+10) +#define MSM_V4L2_PID_BL_DETECTION (V4L2_CID_PRIVATE_BASE+11) +#define MSM_V4L2_PID_SNOW_DETECTION (V4L2_CID_PRIVATE_BASE+12) +#define MSM_V4L2_PID_CTRL_CMD (V4L2_CID_PRIVATE_BASE+13) +#define MSM_V4L2_PID_EVT_SUB_INFO (V4L2_CID_PRIVATE_BASE+14) +#define MSM_V4L2_PID_STROBE_FLASH (V4L2_CID_PRIVATE_BASE+15) +#define MSM_V4L2_PID_INST_HANDLE (V4L2_CID_PRIVATE_BASE+16) +#define MSM_V4L2_PID_MMAP_INST (V4L2_CID_PRIVATE_BASE+17) +#define MSM_V4L2_PID_PP_PLANE_INFO (V4L2_CID_PRIVATE_BASE+18) +#define MSM_V4L2_PID_MAX MSM_V4L2_PID_PP_PLANE_INFO + +/* camera operation mode for video recording - two frame output queues */ +#define MSM_V4L2_CAM_OP_DEFAULT 0 +/* camera operation mode for video recording - two frame output queues */ +#define MSM_V4L2_CAM_OP_PREVIEW (MSM_V4L2_CAM_OP_DEFAULT+1) +/* camera operation mode for video recording - two frame output queues */ +#define MSM_V4L2_CAM_OP_VIDEO (MSM_V4L2_CAM_OP_DEFAULT+2) +/* camera operation mode for standard shapshot - two frame output queues */ +#define MSM_V4L2_CAM_OP_CAPTURE (MSM_V4L2_CAM_OP_DEFAULT+3) +/* camera operation mode for zsl shapshot - three output queues */ +#define MSM_V4L2_CAM_OP_ZSL (MSM_V4L2_CAM_OP_DEFAULT+4) +/* camera operation mode for raw snapshot - one frame output queue */ +#define MSM_V4L2_CAM_OP_RAW (MSM_V4L2_CAM_OP_DEFAULT+5) +/* camera operation mode for jpeg snapshot - one frame output queue */ +#define MSM_V4L2_CAM_OP_JPEG_CAPTURE (MSM_V4L2_CAM_OP_DEFAULT+6) + + +#define MSM_V4L2_VID_CAP_TYPE 0 +#define MSM_V4L2_STREAM_ON 1 +#define MSM_V4L2_STREAM_OFF 2 +#define MSM_V4L2_SNAPSHOT 3 +#define MSM_V4L2_QUERY_CTRL 4 +#define MSM_V4L2_GET_CTRL 5 +#define MSM_V4L2_SET_CTRL 6 +#define MSM_V4L2_QUERY 7 +#define MSM_V4L2_GET_CROP 8 +#define MSM_V4L2_SET_CROP 9 +#define MSM_V4L2_OPEN 10 +#define MSM_V4L2_CLOSE 11 +#define MSM_V4L2_SET_CTRL_CMD 12 +#define MSM_V4L2_EVT_SUB_MASK 13 +#define MSM_V4L2_PRIVATE_CMD 14 +#define MSM_V4L2_MAX 15 +#define V4L2_CAMERA_EXIT 43 + +struct crop_info { + void *info; + int len; +}; + +struct msm_postproc { + int ftnum; + struct msm_frame fthumnail; + int fmnum; + struct msm_frame fmain; +}; + +struct msm_snapshot_pp_status { + void *status; +}; + +#define CFG_SET_MODE 0 +#define CFG_SET_EFFECT 1 +#define CFG_START 2 +#define CFG_PWR_UP 3 +#define CFG_PWR_DOWN 4 +#define CFG_WRITE_EXPOSURE_GAIN 5 +#define CFG_SET_DEFAULT_FOCUS 6 +#define CFG_MOVE_FOCUS 7 +#define CFG_REGISTER_TO_REAL_GAIN 8 +#define CFG_REAL_TO_REGISTER_GAIN 9 +#define CFG_SET_FPS 10 +#define CFG_SET_PICT_FPS 11 +#define CFG_SET_BRIGHTNESS 12 +#define CFG_SET_CONTRAST 13 +#define CFG_SET_ZOOM 14 +#define CFG_SET_EXPOSURE_MODE 15 +#define CFG_SET_WB 16 +#define CFG_SET_ANTIBANDING 17 +#define CFG_SET_EXP_GAIN 18 +#define CFG_SET_PICT_EXP_GAIN 19 +#define CFG_SET_LENS_SHADING 20 +#define CFG_GET_PICT_FPS 21 +#define CFG_GET_PREV_L_PF 22 +#define CFG_GET_PREV_P_PL 23 +#define CFG_GET_PICT_L_PF 24 +#define CFG_GET_PICT_P_PL 25 +#define CFG_GET_AF_MAX_STEPS 26 +#define CFG_GET_PICT_MAX_EXP_LC 27 +#define CFG_SEND_WB_INFO 28 +#define CFG_SENSOR_INIT 29 +#define CFG_GET_3D_CALI_DATA 30 +#define CFG_GET_CALIB_DATA 31 +#define CFG_GET_OUTPUT_INFO 32 +#define CFG_GET_EEPROM_INFO 33 +#define CFG_GET_EEPROM_DATA 34 +#define CFG_SET_ACTUATOR_INFO 35 +#define CFG_GET_ACTUATOR_INFO 36 +/* TBD: QRD */ +#define CFG_SET_SATURATION 37 +#define CFG_SET_SHARPNESS 38 +#define CFG_SET_TOUCHAEC 39 +#define CFG_SET_AUTO_FOCUS 40 +#define CFG_SET_AUTOFLASH 41 +#define CFG_SET_EXPOSURE_COMPENSATION 42 +#define CFG_SET_ISO 43 +#define CFG_START_STREAM 44 +#define CFG_STOP_STREAM 45 +#define CFG_GET_CSI_PARAMS 46 +#define CFG_POWER_UP 47 +#define CFG_POWER_DOWN 48 +#define CFG_WRITE_I2C_ARRAY 49 +#define CFG_READ_I2C_ARRAY 50 +#define CFG_PCLK_CHANGE 51 +#define CFG_CONFIG_VREG_ARRAY 52 +#define CFG_CONFIG_CLK_ARRAY 53 +#define CFG_GPIO_OP 54 +#define CFG_MAX 55 + + +#define MOVE_NEAR 0 +#define MOVE_FAR 1 + +#define SENSOR_PREVIEW_MODE 0 +#define SENSOR_SNAPSHOT_MODE 1 +#define SENSOR_RAW_SNAPSHOT_MODE 2 +#define SENSOR_HFR_60FPS_MODE 3 +#define SENSOR_HFR_90FPS_MODE 4 +#define SENSOR_HFR_120FPS_MODE 5 + +#define SENSOR_QTR_SIZE 0 +#define SENSOR_FULL_SIZE 1 +#define SENSOR_QVGA_SIZE 2 +#define SENSOR_INVALID_SIZE 3 + +#define CAMERA_EFFECT_OFF 0 +#define CAMERA_EFFECT_MONO 1 +#define CAMERA_EFFECT_NEGATIVE 2 +#define CAMERA_EFFECT_SOLARIZE 3 +#define CAMERA_EFFECT_SEPIA 4 +#define CAMERA_EFFECT_POSTERIZE 5 +#define CAMERA_EFFECT_WHITEBOARD 6 +#define CAMERA_EFFECT_BLACKBOARD 7 +#define CAMERA_EFFECT_AQUA 8 +#define CAMERA_EFFECT_EMBOSS 9 +#define CAMERA_EFFECT_SKETCH 10 +#define CAMERA_EFFECT_NEON 11 +#define CAMERA_EFFECT_FADED 12 +#define CAMERA_EFFECT_VINTAGECOOL 13 +#define CAMERA_EFFECT_VINTAGEWARM 14 +#define CAMERA_EFFECT_ACCENT_BLUE 15 +#define CAMERA_EFFECT_ACCENT_GREEN 16 +#define CAMERA_EFFECT_ACCENT_ORANGE 17 +#define CAMERA_EFFECT_MAX 18 + +/* QRD */ +#define CAMERA_EFFECT_BW 10 +#define CAMERA_EFFECT_BLUISH 12 +#define CAMERA_EFFECT_REDDISH 13 +#define CAMERA_EFFECT_GREENISH 14 + +/* QRD */ +#define CAMERA_ANTIBANDING_OFF 0 +#define CAMERA_ANTIBANDING_50HZ 2 +#define CAMERA_ANTIBANDING_60HZ 1 +#define CAMERA_ANTIBANDING_AUTO 3 + +#define CAMERA_CONTRAST_LV0 0 +#define CAMERA_CONTRAST_LV1 1 +#define CAMERA_CONTRAST_LV2 2 +#define CAMERA_CONTRAST_LV3 3 +#define CAMERA_CONTRAST_LV4 4 +#define CAMERA_CONTRAST_LV5 5 +#define CAMERA_CONTRAST_LV6 6 +#define CAMERA_CONTRAST_LV7 7 +#define CAMERA_CONTRAST_LV8 8 +#define CAMERA_CONTRAST_LV9 9 + +#define CAMERA_BRIGHTNESS_LV0 0 +#define CAMERA_BRIGHTNESS_LV1 1 +#define CAMERA_BRIGHTNESS_LV2 2 +#define CAMERA_BRIGHTNESS_LV3 3 +#define CAMERA_BRIGHTNESS_LV4 4 +#define CAMERA_BRIGHTNESS_LV5 5 +#define CAMERA_BRIGHTNESS_LV6 6 +#define CAMERA_BRIGHTNESS_LV7 7 +#define CAMERA_BRIGHTNESS_LV8 8 + + +#define CAMERA_SATURATION_LV0 0 +#define CAMERA_SATURATION_LV1 1 +#define CAMERA_SATURATION_LV2 2 +#define CAMERA_SATURATION_LV3 3 +#define CAMERA_SATURATION_LV4 4 +#define CAMERA_SATURATION_LV5 5 +#define CAMERA_SATURATION_LV6 6 +#define CAMERA_SATURATION_LV7 7 +#define CAMERA_SATURATION_LV8 8 + +#define CAMERA_SHARPNESS_LV0 0 +#define CAMERA_SHARPNESS_LV1 3 +#define CAMERA_SHARPNESS_LV2 6 +#define CAMERA_SHARPNESS_LV3 9 +#define CAMERA_SHARPNESS_LV4 12 +#define CAMERA_SHARPNESS_LV5 15 +#define CAMERA_SHARPNESS_LV6 18 +#define CAMERA_SHARPNESS_LV7 21 +#define CAMERA_SHARPNESS_LV8 24 +#define CAMERA_SHARPNESS_LV9 27 +#define CAMERA_SHARPNESS_LV10 30 + +#define CAMERA_SETAE_AVERAGE 0 +#define CAMERA_SETAE_CENWEIGHT 1 + +#define CAMERA_WB_AUTO 1 /* This list must match aeecamera.h */ +#define CAMERA_WB_CUSTOM 2 +#define CAMERA_WB_INCANDESCENT 3 +#define CAMERA_WB_FLUORESCENT 4 +#define CAMERA_WB_DAYLIGHT 5 +#define CAMERA_WB_CLOUDY_DAYLIGHT 6 +#define CAMERA_WB_TWILIGHT 7 +#define CAMERA_WB_SHADE 8 + +#define CAMERA_EXPOSURE_COMPENSATION_LV0 12 +#define CAMERA_EXPOSURE_COMPENSATION_LV1 6 +#define CAMERA_EXPOSURE_COMPENSATION_LV2 0 +#define CAMERA_EXPOSURE_COMPENSATION_LV3 -6 +#define CAMERA_EXPOSURE_COMPENSATION_LV4 -12 + +enum msm_v4l2_saturation_level { + MSM_V4L2_SATURATION_L0, + MSM_V4L2_SATURATION_L1, + MSM_V4L2_SATURATION_L2, + MSM_V4L2_SATURATION_L3, + MSM_V4L2_SATURATION_L4, + MSM_V4L2_SATURATION_L5, + MSM_V4L2_SATURATION_L6, + MSM_V4L2_SATURATION_L7, + MSM_V4L2_SATURATION_L8, + MSM_V4L2_SATURATION_L9, + MSM_V4L2_SATURATION_L10, +}; + +enum msm_v4l2_contrast_level { + MSM_V4L2_CONTRAST_L0, + MSM_V4L2_CONTRAST_L1, + MSM_V4L2_CONTRAST_L2, + MSM_V4L2_CONTRAST_L3, + MSM_V4L2_CONTRAST_L4, + MSM_V4L2_CONTRAST_L5, + MSM_V4L2_CONTRAST_L6, + MSM_V4L2_CONTRAST_L7, + MSM_V4L2_CONTRAST_L8, + MSM_V4L2_CONTRAST_L9, + MSM_V4L2_CONTRAST_L10, +}; + + +enum msm_v4l2_exposure_level { + MSM_V4L2_EXPOSURE_N2, + MSM_V4L2_EXPOSURE_N1, + MSM_V4L2_EXPOSURE_D, + MSM_V4L2_EXPOSURE_P1, + MSM_V4L2_EXPOSURE_P2, +}; + +enum msm_v4l2_sharpness_level { + MSM_V4L2_SHARPNESS_L0, + MSM_V4L2_SHARPNESS_L1, + MSM_V4L2_SHARPNESS_L2, + MSM_V4L2_SHARPNESS_L3, + MSM_V4L2_SHARPNESS_L4, + MSM_V4L2_SHARPNESS_L5, + MSM_V4L2_SHARPNESS_L6, +}; + +enum msm_v4l2_expo_metering_mode { + MSM_V4L2_EXP_FRAME_AVERAGE, + MSM_V4L2_EXP_CENTER_WEIGHTED, + MSM_V4L2_EXP_SPOT_METERING, +}; + +enum msm_v4l2_iso_mode { + MSM_V4L2_ISO_AUTO = 0, + MSM_V4L2_ISO_DEBLUR, + MSM_V4L2_ISO_100, + MSM_V4L2_ISO_200, + MSM_V4L2_ISO_400, + MSM_V4L2_ISO_800, + MSM_V4L2_ISO_1600, +}; + +enum msm_v4l2_wb_mode { + MSM_V4L2_WB_OFF, + MSM_V4L2_WB_AUTO , + MSM_V4L2_WB_CUSTOM, + MSM_V4L2_WB_INCANDESCENT, + MSM_V4L2_WB_FLUORESCENT, + MSM_V4L2_WB_DAYLIGHT, + MSM_V4L2_WB_CLOUDY_DAYLIGHT, +}; + +enum msm_v4l2_special_effect { + MSM_V4L2_EFFECT_OFF, + MSM_V4L2_EFFECT_MONO, + MSM_V4L2_EFFECT_NEGATIVE, + MSM_V4L2_EFFECT_SOLARIZE, + MSM_V4L2_EFFECT_SEPIA, + MSM_V4L2_EFFECT_POSTERAIZE, + MSM_V4L2_EFFECT_WHITEBOARD, + MSM_V4L2_EFFECT_BLACKBOARD, + MSM_V4L2_EFFECT_AQUA, + MSM_V4L2_EFFECT_EMBOSS, + MSM_V4L2_EFFECT_SKETCH, + MSM_V4L2_EFFECT_NEON, + MSM_V4L2_EFFECT_MAX, +}; + +enum msm_v4l2_power_line_frequency { + MSM_V4L2_POWER_LINE_OFF, + MSM_V4L2_POWER_LINE_60HZ, + MSM_V4L2_POWER_LINE_50HZ, + MSM_V4L2_POWER_LINE_AUTO, +}; + +#define CAMERA_ISO_TYPE_AUTO 0 +#define CAMEAR_ISO_TYPE_HJR 1 +#define CAMEAR_ISO_TYPE_100 2 +#define CAMERA_ISO_TYPE_200 3 +#define CAMERA_ISO_TYPE_400 4 +#define CAMEAR_ISO_TYPE_800 5 +#define CAMERA_ISO_TYPE_1600 6 + +struct sensor_pict_fps { + uint16_t prevfps; + uint16_t pictfps; +}; + +struct exp_gain_cfg { + uint16_t gain; + uint32_t line; +}; + +struct focus_cfg { + int32_t steps; + int dir; +}; + +struct fps_cfg { + uint16_t f_mult; + uint16_t fps_div; + uint32_t pict_fps_div; +}; +struct wb_info_cfg { + uint16_t red_gain; + uint16_t green_gain; + uint16_t blue_gain; +}; +struct sensor_3d_exp_cfg { + uint16_t gain; + uint32_t line; + uint16_t r_gain; + uint16_t b_gain; + uint16_t gr_gain; + uint16_t gb_gain; + uint16_t gain_adjust; +}; +struct sensor_3d_cali_data_t{ + unsigned char left_p_matrix[3][4][8]; + unsigned char right_p_matrix[3][4][8]; + unsigned char square_len[8]; + unsigned char focal_len[8]; + unsigned char pixel_pitch[8]; + uint16_t left_r; + uint16_t left_b; + uint16_t left_gb; + uint16_t left_af_far; + uint16_t left_af_mid; + uint16_t left_af_short; + uint16_t left_af_5um; + uint16_t left_af_50up; + uint16_t left_af_50down; + uint16_t right_r; + uint16_t right_b; + uint16_t right_gb; + uint16_t right_af_far; + uint16_t right_af_mid; + uint16_t right_af_short; + uint16_t right_af_5um; + uint16_t right_af_50up; + uint16_t right_af_50down; +}; +struct sensor_init_cfg { + uint8_t prev_res; + uint8_t pict_res; +}; + +struct sensor_calib_data { + /* Color Related Measurements */ + uint16_t r_over_g; + uint16_t b_over_g; + uint16_t gr_over_gb; + + /* Lens Related Measurements */ + uint16_t macro_2_inf; + uint16_t inf_2_macro; + uint16_t stroke_amt; + uint16_t af_pos_1m; + uint16_t af_pos_inf; +}; + +enum msm_sensor_resolution_t { + MSM_SENSOR_RES_FULL, + MSM_SENSOR_RES_QTR, + MSM_SENSOR_RES_2, + MSM_SENSOR_RES_3, + MSM_SENSOR_RES_4, + MSM_SENSOR_RES_5, + MSM_SENSOR_RES_6, + MSM_SENSOR_RES_7, + MSM_SENSOR_INVALID_RES, +}; + +struct msm_sensor_output_info_t { + uint16_t x_output; + uint16_t y_output; + uint16_t line_length_pclk; + uint16_t frame_length_lines; + uint32_t vt_pixel_clk; + uint32_t op_pixel_clk; + uint16_t binning_factor; +}; + +struct sensor_output_info_t { + struct msm_sensor_output_info_t *output_info; + uint16_t num_info; +}; + +struct msm_sensor_exp_gain_info_t { + uint16_t coarse_int_time_addr; + uint16_t global_gain_addr; + uint16_t vert_offset; +}; + +struct msm_sensor_output_reg_addr_t { + uint16_t x_output; + uint16_t y_output; + uint16_t line_length_pclk; + uint16_t frame_length_lines; +}; + +struct sensor_driver_params_type { + struct msm_camera_i2c_reg_setting *init_settings; + uint16_t init_settings_size; + struct msm_camera_i2c_reg_setting *mode_settings; + uint16_t mode_settings_size; + struct msm_sensor_output_reg_addr_t *sensor_output_reg_addr; + struct msm_camera_i2c_reg_setting *start_settings; + struct msm_camera_i2c_reg_setting *stop_settings; + struct msm_camera_i2c_reg_setting *groupon_settings; + struct msm_camera_i2c_reg_setting *groupoff_settings; + struct msm_sensor_exp_gain_info_t *sensor_exp_gain_info; + struct msm_sensor_output_info_t *output_info; +}; + +struct mirror_flip { + int32_t x_mirror; + int32_t y_flip; +}; + +struct cord { + uint32_t x; + uint32_t y; +}; + +struct msm_eeprom_data_t { + void *eeprom_data; + uint16_t index; +}; + +struct msm_camera_csid_vc_cfg { + uint8_t cid; + uint8_t dt; + uint8_t decode_format; +}; + +struct csi_lane_params_t { + uint16_t csi_lane_assign; + uint8_t csi_lane_mask; + uint8_t csi_if; + uint8_t csid_core[2]; + uint8_t csi_phy_sel; +}; + +struct msm_camera_csid_lut_params { + uint8_t num_cid; + struct msm_camera_csid_vc_cfg *vc_cfg; +}; + +struct msm_camera_csid_params { + uint8_t lane_cnt; + uint16_t lane_assign; + uint8_t phy_sel; + struct msm_camera_csid_lut_params lut_params; +}; + +struct msm_camera_csiphy_params { + uint8_t lane_cnt; + uint8_t settle_cnt; + uint16_t lane_mask; + uint8_t combo_mode; +}; + +struct msm_camera_csi2_params { + struct msm_camera_csid_params csid_params; + struct msm_camera_csiphy_params csiphy_params; +}; + +enum msm_camera_csi_data_format { + CSI_8BIT, + CSI_10BIT, + CSI_12BIT, +}; + +struct msm_camera_csi_params { + enum msm_camera_csi_data_format data_format; + uint8_t lane_cnt; + uint8_t lane_assign; + uint8_t settle_cnt; + uint8_t dpcm_scheme; +}; + +enum csic_cfg_type_t { + CSIC_INIT, + CSIC_CFG, +}; + +struct csic_cfg_data { + enum csic_cfg_type_t cfgtype; + struct msm_camera_csi_params *csic_params; +}; + +enum csid_cfg_type_t { + CSID_INIT, + CSID_CFG, +}; + +struct csid_cfg_data { + enum csid_cfg_type_t cfgtype; + union { + uint32_t csid_version; + struct msm_camera_csid_params *csid_params; + } cfg; +}; + +enum csiphy_cfg_type_t { + CSIPHY_INIT, + CSIPHY_CFG, +}; + +struct csiphy_cfg_data { + enum csiphy_cfg_type_t cfgtype; + struct msm_camera_csiphy_params *csiphy_params; +}; + +#define CSI_EMBED_DATA 0x12 +#define CSI_RESERVED_DATA_0 0x13 +#define CSI_YUV422_8 0x1E +#define CSI_RAW8 0x2A +#define CSI_RAW10 0x2B +#define CSI_RAW12 0x2C + +#define CSI_DECODE_6BIT 0 +#define CSI_DECODE_8BIT 1 +#define CSI_DECODE_10BIT 2 +#define CSI_DECODE_DPCM_10_8_10 5 + +#define ISPIF_STREAM(intf, action, vfe) (((intf)<> 24) : 0xFF) + +#define CLR_IMG_MODE(handle) (handle &= 0xFF00FFFF) +#define SET_IMG_MODE(handle, data) \ + (handle |= ((0x1 << 23) | ((data & 0x7F) << 16))) +#define GET_IMG_MODE(handle) \ + ((handle & 0x800000) ? ((handle & 0x7F0000) >> 16) : 0xFF) + +#define CLR_MCTLPP_INST_IDX(handle) (handle &= 0xFFFF00FF) +#define SET_MCTLPP_INST_IDX(handle, data) \ + (handle |= ((0x1 << 15) | ((data & 0x7F) << 8))) +#define GET_MCTLPP_INST_IDX(handle) \ + ((handle & 0x8000) ? ((handle & 0x7F00) >> 8) : 0xFF) + +#define CLR_VIDEO_INST_IDX(handle) (handle &= 0xFFFFFF00) +#define GET_VIDEO_INST_IDX(handle) \ + ((handle & 0x80) ? (handle & 0x7F) : 0xFF) +#define SET_VIDEO_INST_IDX(handle, data) \ + (handle |= (0x1 << 7) | (data & 0x7F)) + +#endif /* __UAPI_MSM_CAMERA_H */