From 2bbf35063f88be09595ee9e3a0ab281f7d1eae2e Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Thu, 8 Oct 2020 14:32:12 -0700 Subject: [PATCH] video: driver: fixes for streamoff/streamon Changes to fix streamon/streamoff functionality. Change-Id: Ibefa04c5812e0f5a42c578e72eea7650e37c18b0 Signed-off-by: Akshata Sahukar --- driver/platform/waipio/src/msm_vidc_waipio.c | 4 +- .../variant/iris2/inc/msm_vidc_buffer_iris2.h | 15 +- .../variant/iris2/src/msm_vidc_buffer_iris2.c | 175 +++++++++++++- driver/variant/iris2/src/msm_vidc_iris2.c | 157 +----------- driver/vidc/inc/hfi_command.h | 21 +- driver/vidc/inc/msm_vidc_driver.h | 13 +- driver/vidc/inc/msm_vidc_inst.h | 27 ++- driver/vidc/inc/msm_vidc_internal.h | 14 +- driver/vidc/inc/venus_hfi.h | 6 + driver/vidc/src/hfi_packet.c | 34 ++- driver/vidc/src/msm_vdec.c | 226 ++++++++---------- driver/vidc/src/msm_vidc.c | 31 +-- driver/vidc/src/msm_vidc_driver.c | 124 +++++++--- driver/vidc/src/msm_vidc_probe.c | 15 +- driver/vidc/src/msm_vidc_vb2.c | 43 ++++ driver/vidc/src/venus_hfi.c | 124 ++++++++-- driver/vidc/src/venus_hfi_response.c | 137 ++++++++--- 17 files changed, 704 insertions(+), 462 deletions(-) diff --git a/driver/platform/waipio/src/msm_vidc_waipio.c b/driver/platform/waipio/src/msm_vidc_waipio.c index 7de13f1e0f..b3217228df 100644 --- a/driver/platform/waipio/src/msm_vidc_waipio.c +++ b/driver/platform/waipio/src/msm_vidc_waipio.c @@ -59,11 +59,11 @@ static struct msm_platform_core_capability core_data_waipio[] = { {MAX_MBPF_B_FRAME, 32640}, /* 3840x2176/256 */ {MAX_MBPS_B_FRAME, 1958400}, /* 3840x2176/256 MBs@60fps */ {NUM_VPP_PIPE, 4}, - {SW_PC, 1}, + {SW_PC, 0}, {SW_PC_DELAY, 1500}, /* 1500 ms */ {FW_UNLOAD, 0}, {FW_UNLOAD_DELAY, 1000}, /* 1000 ms */ - {HW_RESPONSE_TIMEOUT, 1000}, /* 1000 ms */ + {HW_RESPONSE_TIMEOUT, 3000}, /* 1000 ms */ {DEBUG_TIMEOUT, 0}, {PREFIX_BUF_COUNT_PIX, 18}, {PREFIX_BUF_SIZE_PIX, 13434880}, /* Calculated by VENUS_BUFFER_SIZE for 4096x2160 UBWC */ diff --git a/driver/variant/iris2/inc/msm_vidc_buffer_iris2.h b/driver/variant/iris2/inc/msm_vidc_buffer_iris2.h index ba29d574ff..e3a319c415 100644 --- a/driver/variant/iris2/inc/msm_vidc_buffer_iris2.h +++ b/driver/variant/iris2/inc/msm_vidc_buffer_iris2.h @@ -8,13 +8,10 @@ #include "msm_vidc_inst.h" -u32 msm_vidc_decoder_scratch_size_iris2(struct msm_vidc_inst *inst); -u32 msm_vidc_decoder_scratch_1_size_iris2(struct msm_vidc_inst *inst); -u32 msm_vidc_decoder_persist_1_size_iris2(struct msm_vidc_inst *inst); - -u32 msm_vidc_encoder_scratch_size_iris2(struct msm_vidc_inst *inst); -u32 msm_vidc_encoder_scratch_1_size_iris2(struct msm_vidc_inst *inst); -u32 msm_vidc_encoder_scratch_2_size_iris2(struct msm_vidc_inst *inst); -u32 msm_vidc_encoder_persist_size_iris2(struct msm_vidc_inst *inst); - +int msm_buffer_size_iris2(struct msm_vidc_inst *inst, + enum msm_vidc_buffer_type buffer_type); +int msm_buffer_min_count_iris2(struct msm_vidc_inst *inst, + enum msm_vidc_buffer_type buffer_type); +int msm_buffer_extra_count_iris2(struct msm_vidc_inst *inst, + enum msm_vidc_buffer_type buffer_type); #endif // __H_MSM_VIDC_BUFFER_IRIS2_H__ diff --git a/driver/variant/iris2/src/msm_vidc_buffer_iris2.c b/driver/variant/iris2/src/msm_vidc_buffer_iris2.c index 427f2184b7..13563c2c1a 100644 --- a/driver/variant/iris2/src/msm_vidc_buffer_iris2.c +++ b/driver/variant/iris2/src/msm_vidc_buffer_iris2.c @@ -1003,7 +1003,7 @@ static u32 calculate_mpeg2d_persist1_size(void) } /* decoder internal buffers */ -u32 msm_vidc_decoder_scratch_size_iris2(struct msm_vidc_inst *inst) +static u32 msm_vidc_decoder_bin_size_iris2(struct msm_vidc_inst *inst) { struct msm_vidc_core *core; u32 size = 0; @@ -1050,7 +1050,7 @@ u32 msm_vidc_decoder_scratch_size_iris2(struct msm_vidc_inst *inst) return size; } -u32 msm_vidc_decoder_scratch_1_size_iris2(struct msm_vidc_inst *inst) +static u32 msm_vidc_decoder_scratch_1_size_iris2(struct msm_vidc_inst *inst) { struct msm_vidc_core *core; u32 size = 0; @@ -1101,7 +1101,7 @@ u32 msm_vidc_decoder_scratch_1_size_iris2(struct msm_vidc_inst *inst) return size; } -u32 msm_vidc_decoder_persist_1_size_iris2(struct msm_vidc_inst *inst) +static u32 msm_vidc_decoder_persist_size_iris2(struct msm_vidc_inst *inst) { u32 size = 0; @@ -1125,7 +1125,7 @@ u32 msm_vidc_decoder_persist_1_size_iris2(struct msm_vidc_inst *inst) } /* encoder internal buffers */ -u32 msm_vidc_encoder_scratch_size_iris2(struct msm_vidc_inst *inst) +static u32 msm_vidc_encoder_bin_size_iris2(struct msm_vidc_inst *inst) { struct msm_vidc_core *core; u32 size = 0; @@ -1161,7 +1161,7 @@ u32 msm_vidc_encoder_scratch_size_iris2(struct msm_vidc_inst *inst) return size; } -u32 msm_vidc_encoder_scratch_1_size_iris2(struct msm_vidc_inst *inst) +static u32 msm_vidc_encoder_scratch_1_size_iris2(struct msm_vidc_inst *inst) { struct msm_vidc_core *core; u32 size = 0; @@ -1198,7 +1198,7 @@ u32 msm_vidc_encoder_scratch_1_size_iris2(struct msm_vidc_inst *inst) return size; } -u32 msm_vidc_encoder_scratch_2_size_iris2(struct msm_vidc_inst *inst) +static u32 msm_vidc_encoder_dpb_size_iris2(struct msm_vidc_inst *inst) { u32 width, height, num_ref; bool is_tenbit = false; @@ -1212,14 +1212,171 @@ u32 msm_vidc_encoder_scratch_2_size_iris2(struct msm_vidc_inst *inst) f = &inst->fmts[OUTPUT_PORT]; width = f->fmt.pix_mp.width; height = f->fmt.pix_mp.height; - num_ref = 4; //msm_vidc_get_num_ref_frames(inst); - is_tenbit = false; //(inst->bit_depth == MSM_VIDC_BIT_DEPTH_10); + num_ref = 4; // TODO: msm_vidc_get_num_ref_frames(inst); + is_tenbit = false; // TODO: (inst->bit_depth == MSM_VIDC_BIT_DEPTH_10); return calculate_enc_scratch2_size(inst, width, height, num_ref, is_tenbit); } -u32 msm_vidc_encoder_persist_size_iris2(struct msm_vidc_inst *inst) +static u32 msm_vidc_encoder_persist_size_iris2(struct msm_vidc_inst *inst) { return calculate_enc_persist_size(); } + +int msm_buffer_size_iris2(struct msm_vidc_inst *inst, + enum msm_vidc_buffer_type buffer_type) +{ + int size = 0; + + if (!inst) { + d_vpr_e("%s: invalid params\n", __func__); + return size; + } + + if (is_decode_session(inst)) { + switch (buffer_type) { + case MSM_VIDC_BUF_INPUT: + size = msm_vidc_decoder_input_size(inst); + break; + case MSM_VIDC_BUF_OUTPUT: + size = msm_vidc_decoder_output_size(inst); + break; + case MSM_VIDC_BUF_INPUT_META: + size = msm_vidc_decoder_input_meta_size(inst); + break; + case MSM_VIDC_BUF_OUTPUT_META: + size = msm_vidc_decoder_output_meta_size(inst); + break; + case MSM_VIDC_BUF_BIN: + size = msm_vidc_decoder_bin_size_iris2(inst); + break; + case MSM_VIDC_BUF_COMV: + case MSM_VIDC_BUF_NON_COMV: + case MSM_VIDC_BUF_LINE: + size = msm_vidc_decoder_scratch_1_size_iris2(inst); + break; + case MSM_VIDC_BUF_PERSIST: + //size = msm_vidc_decoder_persist_1_size_iris2(inst); + size = msm_vidc_decoder_persist_size_iris2(inst); + break; + default: + break; + } + } else if (is_encode_session(inst)) { + switch (buffer_type) { + case MSM_VIDC_BUF_INPUT: + size = msm_vidc_encoder_input_size(inst); + break; + case MSM_VIDC_BUF_OUTPUT: + size = msm_vidc_encoder_output_size(inst); + break; + case MSM_VIDC_BUF_INPUT_META: + size = msm_vidc_encoder_input_meta_size(inst); + break; + case MSM_VIDC_BUF_OUTPUT_META: + size = msm_vidc_encoder_output_meta_size(inst); + break; + case MSM_VIDC_BUF_BIN: + size = msm_vidc_encoder_bin_size_iris2(inst); + break; + case MSM_VIDC_BUF_COMV: + case MSM_VIDC_BUF_NON_COMV: + case MSM_VIDC_BUF_LINE: + size = msm_vidc_encoder_scratch_1_size_iris2(inst); + break; + case MSM_VIDC_BUF_DPB: + size = msm_vidc_encoder_dpb_size_iris2(inst); + break; + case MSM_VIDC_BUF_PERSIST: + size = msm_vidc_encoder_persist_size_iris2(inst); + break; + default: + break; + } + } + + return size; +} + +int msm_buffer_min_count_iris2(struct msm_vidc_inst *inst, + enum msm_vidc_buffer_type buffer_type) +{ + int count = 0; + + if (!inst) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + if (is_decode_session(inst)) { + switch (buffer_type) { + case MSM_VIDC_BUF_INPUT: + case MSM_VIDC_BUF_INPUT_META: + count = msm_vidc_input_min_count(inst); + break; + case MSM_VIDC_BUF_OUTPUT: + case MSM_VIDC_BUF_OUTPUT_META: + count = msm_vidc_output_min_count(inst); + break; + case MSM_VIDC_BUF_BIN: + case MSM_VIDC_BUF_COMV: + case MSM_VIDC_BUF_NON_COMV: + case MSM_VIDC_BUF_LINE: + case MSM_VIDC_BUF_PERSIST: + count = 1; + break; + default: + break; + } + } else if (is_encode_session(inst)) { + switch (buffer_type) { + case MSM_VIDC_BUF_INPUT: + case MSM_VIDC_BUF_INPUT_META: + count = msm_vidc_input_min_count(inst); + break; + case MSM_VIDC_BUF_OUTPUT: + case MSM_VIDC_BUF_OUTPUT_META: + count = msm_vidc_output_min_count(inst); + break; + case MSM_VIDC_BUF_BIN: + case MSM_VIDC_BUF_COMV: + case MSM_VIDC_BUF_NON_COMV: + case MSM_VIDC_BUF_LINE: + case MSM_VIDC_BUF_DPB: + case MSM_VIDC_BUF_PERSIST: + count = 1; + break; + default: + break; + } + } + + return count; +} + +int msm_buffer_extra_count_iris2(struct msm_vidc_inst *inst, + enum msm_vidc_buffer_type buffer_type) +{ + int count = 0; + + if (!inst) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + switch (buffer_type) { + case MSM_VIDC_BUF_INPUT: + case MSM_VIDC_BUF_INPUT_META: + count = msm_vidc_input_extra_count(inst); + break; + case MSM_VIDC_BUF_OUTPUT: + case MSM_VIDC_BUF_OUTPUT_META: + count = msm_vidc_output_extra_count(inst); + break; + default: + break; + } + + return count; +} diff --git a/driver/variant/iris2/src/msm_vidc_iris2.c b/driver/variant/iris2/src/msm_vidc_iris2.c index 75a7ed998d..20e8b3c8ee 100644 --- a/driver/variant/iris2/src/msm_vidc_iris2.c +++ b/driver/variant/iris2/src/msm_vidc_iris2.c @@ -495,161 +495,10 @@ static struct msm_vidc_venus_ops iris2_ops = { .noc_error_info = __noc_error_info_iris2, }; -static int msm_vidc_buffer_size_iris2(struct msm_vidc_inst *inst, - enum msm_vidc_buffer_type buffer_type) -{ - int size = 0; - - d_vpr_h("%s()\n", __func__); - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return size; - } - - if (is_decode_session(inst)) { - switch (buffer_type) { - case MSM_VIDC_BUF_INPUT: - size = msm_vidc_decoder_input_size(inst); - break; - case MSM_VIDC_BUF_OUTPUT: - size = msm_vidc_decoder_output_size(inst); - break; - case MSM_VIDC_BUF_INPUT_META: - size = msm_vidc_decoder_input_meta_size(inst); - break; - case MSM_VIDC_BUF_OUTPUT_META: - size = msm_vidc_decoder_output_meta_size(inst); - break; - case MSM_VIDC_BUF_SCRATCH: - size = msm_vidc_decoder_scratch_size_iris2(inst); - break; - case MSM_VIDC_BUF_SCRATCH_1: - size = msm_vidc_decoder_scratch_1_size_iris2(inst); - break; - case MSM_VIDC_BUF_PERSIST_1: - size = msm_vidc_decoder_persist_1_size_iris2(inst); - break; - default: - break; - } - } else if (is_encode_session(inst)) { - switch (buffer_type) { - case MSM_VIDC_BUF_INPUT: - size = msm_vidc_encoder_input_size(inst); - break; - case MSM_VIDC_BUF_OUTPUT: - size = msm_vidc_encoder_output_size(inst); - break; - case MSM_VIDC_BUF_INPUT_META: - size = msm_vidc_encoder_input_meta_size(inst); - break; - case MSM_VIDC_BUF_OUTPUT_META: - size = msm_vidc_encoder_output_meta_size(inst); - break; - case MSM_VIDC_BUF_SCRATCH: - size = msm_vidc_encoder_scratch_size_iris2(inst); - break; - case MSM_VIDC_BUF_SCRATCH_1: - size = msm_vidc_encoder_scratch_1_size_iris2(inst); - break; - case MSM_VIDC_BUF_SCRATCH_2: - size = msm_vidc_encoder_scratch_2_size_iris2(inst); - break; - case MSM_VIDC_BUF_PERSIST: - size = msm_vidc_encoder_persist_size_iris2(inst); - break; - default: - break; - } - } - - return size; -} - -static int msm_vidc_min_count_iris2(struct msm_vidc_inst *inst, - enum msm_vidc_buffer_type buffer_type) -{ - int count = 0; - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - d_vpr_h("%s()\n", __func__); - - if (is_decode_session(inst)) { - switch (buffer_type) { - case MSM_VIDC_BUF_INPUT: - case MSM_VIDC_BUF_INPUT_META: - count = msm_vidc_input_min_count(inst); - break; - case MSM_VIDC_BUF_OUTPUT: - case MSM_VIDC_BUF_OUTPUT_META: - count = msm_vidc_output_min_count(inst); - break; - case MSM_VIDC_BUF_SCRATCH: - case MSM_VIDC_BUF_SCRATCH_1: - case MSM_VIDC_BUF_PERSIST_1: - count = 1; - break; - default: - break; - } - } else if (is_encode_session(inst)) { - switch (buffer_type) { - case MSM_VIDC_BUF_INPUT: - case MSM_VIDC_BUF_INPUT_META: - count = msm_vidc_input_min_count(inst); - break; - case MSM_VIDC_BUF_OUTPUT: - case MSM_VIDC_BUF_OUTPUT_META: - count = msm_vidc_output_min_count(inst); - break; - case MSM_VIDC_BUF_SCRATCH: - case MSM_VIDC_BUF_SCRATCH_1: - case MSM_VIDC_BUF_SCRATCH_2: - case MSM_VIDC_BUF_PERSIST: - count = 1; - break; - default: - break; - } - } - - return count; -} - -static int msm_vidc_extra_count_iris2(struct msm_vidc_inst *inst, - enum msm_vidc_buffer_type buffer_type) -{ - int count = 0; - - if (!inst) { - d_vpr_e("%s: invalid params\n", __func__); - return -EINVAL; - } - d_vpr_h("%s()\n", __func__); - - switch (buffer_type) { - case MSM_VIDC_BUF_INPUT: - case MSM_VIDC_BUF_INPUT_META: - count = msm_vidc_input_extra_count(inst); - break; - case MSM_VIDC_BUF_OUTPUT: - case MSM_VIDC_BUF_OUTPUT_META: - count = msm_vidc_output_extra_count(inst); - break; - default: - break; - } - - return count; -} - static struct msm_vidc_session_ops msm_session_ops = { - .buffer_size = msm_vidc_buffer_size_iris2, - .min_count = msm_vidc_min_count_iris2, - .extra_count = msm_vidc_extra_count_iris2, + .buffer_size = msm_buffer_size_iris2, + .min_count = msm_buffer_min_count_iris2, + .extra_count = msm_buffer_extra_count_iris2, .calc_freq = NULL, .calc_bw = NULL, .decide_work_route = NULL, diff --git a/driver/vidc/inc/hfi_command.h b/driver/vidc/inc/hfi_command.h index 3eb5621572..058819bff3 100644 --- a/driver/vidc/inc/hfi_command.h +++ b/driver/vidc/inc/hfi_command.h @@ -6,6 +6,9 @@ #ifndef __H_HFI_COMMAND_H__ #define __H_HFI_COMMAND_H__ +#include +#include + #define HFI_VIDEO_ARCH_OX 0x1 struct hfi_header { @@ -34,8 +37,8 @@ struct hfi_buffer { u32 buffer_size; u32 data_offset; u32 data_size; - u32 flags; u64 timestamp; + u32 flags; u32 reserved[5]; }; @@ -81,13 +84,15 @@ enum hfi_buffer_type { HFI_BUFFER_BITSTREAM = 0x00000001, HFI_BUFFER_RAW = 0x00000002, HFI_BUFFER_METADATA = 0x00000003, - HFI_BUFFER_SCRATCH = 0x00000010, - HFI_BUFFER_SCRATCH_1 = 0x00000011, - HFI_BUFFER_SCRATCH_2 = 0x00000012, - HFI_BUFFER_PERSIST = 0x00000013, - HFI_BUFFER_PERSIST_1 = 0x00000014, - HFI_BUFFER_SUBCACHE = 0x00000020, - HFI_BUFFER_SFR = 0x00000021, + HFI_BUFFER_DPB = 0x00000004, + HFI_BUFFER_BIN = 0x00000005, + HFI_BUFFER_LINE = 0x00000006, + HFI_BUFFER_ARP = 0x00000007, + HFI_BUFFER_COMV = 0x00000008, + HFI_BUFFER_NON_COMV = 0x00000009, + HFI_BUFFER_PERSIST = 0x0000000A, + HFI_BUFFER_SUBCACHE = 0x0000000B, + HFI_BUFFER_SFR = 0x0000000C, }; enum hfi_buffer_host_flags { diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index e950655c0e..9b562d6223 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -49,11 +49,12 @@ static inline is_output_meta_buffer(enum msm_vidc_buffer_type buffer_type) static inline is_internal_buffer(enum msm_vidc_buffer_type buffer_type) { - return buffer_type == MSM_VIDC_BUF_SCRATCH || - buffer_type == MSM_VIDC_BUF_SCRATCH_1 || - buffer_type == MSM_VIDC_BUF_SCRATCH_2 || - buffer_type == MSM_VIDC_BUF_PERSIST || - buffer_type == MSM_VIDC_BUF_PERSIST_1; + return buffer_type == MSM_VIDC_BUF_BIN || + buffer_type == MSM_VIDC_BUF_COMV || + buffer_type == MSM_VIDC_BUF_NON_COMV || + buffer_type == MSM_VIDC_BUF_LINE || + buffer_type == MSM_VIDC_BUF_DPB || + buffer_type == MSM_VIDC_BUF_PERSIST; } static inline bool is_secondary_output_mode(struct msm_vidc_inst *inst) @@ -96,6 +97,8 @@ int msm_vidc_remove_session(struct msm_vidc_inst *inst); int msm_vidc_add_session(struct msm_vidc_inst *inst); int msm_vidc_session_open(struct msm_vidc_inst *inst); int msm_vidc_session_set_codec(struct msm_vidc_inst *inst); +int msm_vidc_session_stop(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port); int msm_vidc_session_close(struct msm_vidc_inst *inst); int msm_vidc_get_inst_capability(struct msm_vidc_inst *inst); int msm_vidc_core_init(struct msm_vidc_core *core); diff --git a/driver/vidc/inc/msm_vidc_inst.h b/driver/vidc/inc/msm_vidc_inst.h index 4294bfc9f1..1045100f48 100644 --- a/driver/vidc/inc/msm_vidc_inst.h +++ b/driver/vidc/inc/msm_vidc_inst.h @@ -26,11 +26,12 @@ struct msm_vidc_session_ops { }; struct msm_vidc_allocations_info { - struct msm_vidc_allocations scratch; - struct msm_vidc_allocations scratch_1; - struct msm_vidc_allocations scratch_2; + struct msm_vidc_allocations bin; + struct msm_vidc_allocations comv; + struct msm_vidc_allocations non_comv; + struct msm_vidc_allocations line; + struct msm_vidc_allocations dpb; struct msm_vidc_allocations persist; - struct msm_vidc_allocations persist_1; }; struct msm_vidc_mappings_info { @@ -38,11 +39,12 @@ struct msm_vidc_mappings_info { struct msm_vidc_mappings output; struct msm_vidc_mappings input_meta; struct msm_vidc_mappings output_meta; - struct msm_vidc_mappings scratch; - struct msm_vidc_mappings scratch_1; - struct msm_vidc_mappings scratch_2; + struct msm_vidc_mappings bin; + struct msm_vidc_mappings comv; + struct msm_vidc_mappings non_comv; + struct msm_vidc_mappings line; + struct msm_vidc_mappings dpb; struct msm_vidc_mappings persist; - struct msm_vidc_mappings persist_1; }; struct msm_vidc_buffers_info { @@ -50,11 +52,12 @@ struct msm_vidc_buffers_info { struct msm_vidc_buffers output; struct msm_vidc_buffers input_meta; struct msm_vidc_buffers output_meta; - struct msm_vidc_buffers scratch; - struct msm_vidc_buffers scratch_1; - struct msm_vidc_buffers scratch_2; + struct msm_vidc_buffers bin; + struct msm_vidc_buffers comv; + struct msm_vidc_buffers non_comv; + struct msm_vidc_buffers line; + struct msm_vidc_buffers dpb; struct msm_vidc_buffers persist; - struct msm_vidc_buffers persist_1; }; enum msm_vidc_inst_state { diff --git a/driver/vidc/inc/msm_vidc_internal.h b/driver/vidc/inc/msm_vidc_internal.h index 88788dbe48..987cdb12b8 100644 --- a/driver/vidc/inc/msm_vidc_internal.h +++ b/driver/vidc/inc/msm_vidc_internal.h @@ -109,11 +109,12 @@ enum msm_vidc_buffer_type { MSM_VIDC_BUF_INPUT_META, MSM_VIDC_BUF_OUTPUT_META, MSM_VIDC_BUF_QUEUE, - MSM_VIDC_BUF_SCRATCH, - MSM_VIDC_BUF_SCRATCH_1, - MSM_VIDC_BUF_SCRATCH_2, + MSM_VIDC_BUF_BIN, + MSM_VIDC_BUF_COMV, + MSM_VIDC_BUF_NON_COMV, + MSM_VIDC_BUF_LINE, + MSM_VIDC_BUF_DPB, MSM_VIDC_BUF_PERSIST, - MSM_VIDC_BUF_PERSIST_1, }; /* always match with v4l2 flags V4L2_BUF_FLAG_* */ @@ -144,7 +145,7 @@ enum msm_vidc_buffer_region { }; enum msm_vidc_port_type { - INPUT_PORT, + INPUT_PORT = 0, OUTPUT_PORT, INPUT_META_PORT, OUTPUT_META_PORT, @@ -339,7 +340,8 @@ enum profiling_points { }; enum signal_session_response { - SIGNAL_CMD_STOP = 0, + SIGNAL_CMD_STOP_INPUT = 0, + SIGNAL_CMD_STOP_OUTPUT, SIGNAL_CMD_CLOSE, MAX_SIGNAL, }; diff --git a/driver/vidc/inc/venus_hfi.h b/driver/vidc/inc/venus_hfi.h index 97eda798f9..686f12e275 100644 --- a/driver/vidc/inc/venus_hfi.h +++ b/driver/vidc/inc/venus_hfi.h @@ -6,6 +6,8 @@ #ifndef _VENUS_HFI_H_ #define _VENUS_HFI_H_ +#include + #include "msm_vidc_internal.h" #include "msm_vidc_inst.h" #include "msm_vidc_core.h" @@ -49,6 +51,9 @@ struct hfi_resource_syscache_info_type { int venus_hfi_session_property(struct msm_vidc_inst *inst, u32 pkt_type, u32 flags, u32 port, u32 payload_type, void *payload, u32 payload_size); +int venus_hfi_session_command(struct msm_vidc_inst *inst, + u32 cmd, enum msm_vidc_port_type port, u32 payload_type, + void *payload, u32 payload_size); int venus_hfi_queue_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *buffer, struct msm_vidc_buffer *metabuf); int venus_hfi_release_buffer(struct msm_vidc_inst *inst, @@ -63,6 +68,7 @@ int venus_hfi_core_release(struct msm_vidc_core *core); int venus_hfi_suspend(struct msm_vidc_core *core); void venus_hfi_work_handler(struct work_struct *work); void venus_hfi_pm_work_handler(struct work_struct *work); +irqreturn_t venus_hfi_isr(int irq, void *data); void __write_register(struct msm_vidc_core *core, u32 reg, u32 value); diff --git a/driver/vidc/src/hfi_packet.c b/driver/vidc/src/hfi_packet.c index eb0c20a05d..021d43759e 100644 --- a/driver/vidc/src/hfi_packet.c +++ b/driver/vidc/src/hfi_packet.c @@ -62,8 +62,16 @@ u32 get_hfi_port_from_buffer_type(struct msm_vidc_inst *inst, switch(buffer_type) { case MSM_VIDC_BUF_INPUT: case MSM_VIDC_BUF_INPUT_META: + case MSM_VIDC_BUF_BIN: + case MSM_VIDC_BUF_COMV: + case MSM_VIDC_BUF_NON_COMV: + case MSM_VIDC_BUF_LINE: + case MSM_VIDC_BUF_DPB: hfi_port = HFI_PORT_BITSTREAM; break; + case MSM_VIDC_BUF_PERSIST: + hfi_port = HFI_PORT_BITSTREAM | HFI_PORT_RAW; + break; case MSM_VIDC_BUF_OUTPUT: case MSM_VIDC_BUF_OUTPUT_META: hfi_port = HFI_PORT_RAW; @@ -77,8 +85,16 @@ u32 get_hfi_port_from_buffer_type(struct msm_vidc_inst *inst, switch (buffer_type) { case MSM_VIDC_BUF_INPUT: case MSM_VIDC_BUF_INPUT_META: + case MSM_VIDC_BUF_BIN: + case MSM_VIDC_BUF_COMV: + case MSM_VIDC_BUF_NON_COMV: + case MSM_VIDC_BUF_LINE: + case MSM_VIDC_BUF_DPB: hfi_port = HFI_PORT_RAW; break; + case MSM_VIDC_BUF_PERSIST: + hfi_port = HFI_PORT_BITSTREAM | HFI_PORT_RAW; + break; case MSM_VIDC_BUF_OUTPUT: case MSM_VIDC_BUF_OUTPUT_META: hfi_port = HFI_PORT_BITSTREAM; @@ -113,16 +129,18 @@ u32 get_hfi_buffer_type(enum msm_vidc_domain_type domain, case MSM_VIDC_BUF_INPUT_META: case MSM_VIDC_BUF_OUTPUT_META: return HFI_BUFFER_METADATA; - case MSM_VIDC_BUF_SCRATCH: - return HFI_BUFFER_SCRATCH; - case MSM_VIDC_BUF_SCRATCH_1: - return HFI_BUFFER_SCRATCH_1; - case MSM_VIDC_BUF_SCRATCH_2: - return HFI_BUFFER_SCRATCH_2; + case MSM_VIDC_BUF_BIN: + return HFI_BUFFER_BIN; + case MSM_VIDC_BUF_COMV: + return HFI_BUFFER_COMV; + case MSM_VIDC_BUF_NON_COMV: + return HFI_BUFFER_NON_COMV; + case MSM_VIDC_BUF_LINE: + return HFI_BUFFER_LINE; + case MSM_VIDC_BUF_DPB: + return HFI_BUFFER_DPB; case MSM_VIDC_BUF_PERSIST: return HFI_BUFFER_PERSIST; - case MSM_VIDC_BUF_PERSIST_1: - return HFI_BUFFER_PERSIST_1; default: d_vpr_e("invalid buffer type %d\n", buffer_type); diff --git a/driver/vidc/src/msm_vdec.c b/driver/vidc/src/msm_vdec.c index 00851bf514..a6d80be430 100644 --- a/driver/vidc/src/msm_vdec.c +++ b/driver/vidc/src/msm_vdec.c @@ -33,7 +33,7 @@ u32 msm_vdec_subscribe_for_properties[] = { }; u32 msm_vdec_subscribe_for_metadata[] = { - HFI_PROP_TAG_NOT_PROPAGATED_TO_OUTPUT, + HFI_PROP_BUFFER_TAG, }; u32 msm_vdec_deliver_as_metadata[] = { @@ -496,30 +496,44 @@ static int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst) } core = inst->core; - inst->buffers.scratch.size = call_session_op(core, buffer_size, - inst, MSM_VIDC_BUF_SCRATCH); - inst->buffers.scratch_1.size = call_session_op(core, buffer_size, - inst, MSM_VIDC_BUF_SCRATCH_1); - inst->buffers.persist_1.size = call_session_op(core, buffer_size, - inst, MSM_VIDC_BUF_PERSIST_1); + inst->buffers.bin.size = call_session_op(core, buffer_size, + inst, MSM_VIDC_BUF_BIN); + inst->buffers.comv.size = call_session_op(core, buffer_size, + inst, MSM_VIDC_BUF_COMV); + inst->buffers.non_comv.size = call_session_op(core, buffer_size, + inst, MSM_VIDC_BUF_NON_COMV); + inst->buffers.line.size = call_session_op(core, buffer_size, + inst, MSM_VIDC_BUF_LINE); + inst->buffers.persist.size = call_session_op(core, buffer_size, + inst, MSM_VIDC_BUF_PERSIST); - inst->buffers.scratch.min_count = call_session_op(core, min_count, - inst, MSM_VIDC_BUF_SCRATCH); - inst->buffers.scratch_1.min_count = call_session_op(core, min_count, - inst, MSM_VIDC_BUF_SCRATCH_1); - inst->buffers.persist_1.min_count = call_session_op(core, min_count, - inst, MSM_VIDC_BUF_PERSIST_1); + inst->buffers.bin.min_count = call_session_op(core, min_count, + inst, MSM_VIDC_BUF_BIN); + inst->buffers.comv.min_count = call_session_op(core, min_count, + inst, MSM_VIDC_BUF_COMV); + inst->buffers.non_comv.min_count = call_session_op(core, min_count, + inst, MSM_VIDC_BUF_NON_COMV); + inst->buffers.line.min_count = call_session_op(core, min_count, + inst, MSM_VIDC_BUF_LINE); + inst->buffers.persist.min_count = call_session_op(core, min_count, + inst, MSM_VIDC_BUF_PERSIST); s_vpr_h(inst->sid, "internal buffer: min size\n"); - s_vpr_h(inst->sid, "scratch buffer: %d %d\n", - inst->buffers.scratch.min_count, - inst->buffers.scratch.size); - s_vpr_h(inst->sid, "scratch1 buffer: %d %d\n", - inst->buffers.scratch_1.min_count, - inst->buffers.scratch_1.size); - s_vpr_h(inst->sid, "persist1 buffer: %d %d\n", - inst->buffers.persist_1.min_count, - inst->buffers.persist_1.size); + s_vpr_h(inst->sid, "bin buffer: %d %d\n", + inst->buffers.bin.min_count, + inst->buffers.bin.size); + s_vpr_h(inst->sid, "comv buffer: %d %d\n", + inst->buffers.comv.min_count, + inst->buffers.comv.size); + s_vpr_h(inst->sid, "non_comv buffer: %d %d\n", + inst->buffers.non_comv.min_count, + inst->buffers.non_comv.size); + s_vpr_h(inst->sid, "line buffer: %d %d\n", + inst->buffers.line.min_count, + inst->buffers.line.size); + s_vpr_h(inst->sid, "persist buffer: %d %d\n", + inst->buffers.persist.min_count, + inst->buffers.persist.size); return rc; } @@ -534,13 +548,19 @@ static int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst) return -EINVAL; } - rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_SCRATCH); + rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_BIN); if (rc) return rc; - rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_SCRATCH_1); + rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_COMV); if (rc) return rc; - rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_PERSIST_1); + rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_NON_COMV); + if (rc) + return rc; + rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_LINE); + if (rc) + return rc; + rc = msm_vidc_create_internal_buffers(inst, MSM_VIDC_BUF_PERSIST); if (rc) return rc; @@ -557,18 +577,25 @@ static int msm_vdec_queue_input_internal_buffers(struct msm_vidc_inst *inst) return -EINVAL; } - rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_SCRATCH); + rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_BIN); if (rc) return rc; - rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_SCRATCH_1); + rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_COMV); if (rc) return rc; - rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_PERSIST_1); + rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_NON_COMV); + if (rc) + return rc; + rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_LINE); + if (rc) + return rc; + rc = msm_vidc_queue_internal_buffers(inst, MSM_VIDC_BUF_PERSIST); if (rc) return rc; return 0; } + /* static int msm_vdec_release_input_internal_buffers(struct msm_vidc_inst *inst) { @@ -614,24 +641,13 @@ static int msm_vdec_port_settings_subscription(struct msm_vidc_inst *inst, i++) payload[i + 1] = msm_vdec_subscribe_for_port_settings_change[i]; - rc = hfi_create_header(inst->packet, inst->packet_size, - inst->session_id, - core->header_id++); - if (rc) - return rc; - - rc = hfi_create_packet(inst->packet, inst->packet_size, - HFI_CMD_SUBSCRIBE_MODE, - (HFI_HOST_FLAGS_RESPONSE_REQUIRED | - HFI_HOST_FLAGS_INTR_REQUIRED), - HFI_PAYLOAD_U32_ARRAY, - get_hfi_port(inst, port), - core->packet_id++, - &payload[0], - (ARRAY_SIZE(msm_vdec_subscribe_for_port_settings_change) + 1) * - sizeof(u32)); - if (rc) - return rc; + rc = venus_hfi_session_command(inst, + HFI_CMD_SUBSCRIBE_MODE, + port, + HFI_PAYLOAD_U32_ARRAY, + &payload[0], + (ARRAY_SIZE(msm_vdec_subscribe_for_port_settings_change) + 1) * + sizeof(u32)); return rc; } @@ -655,24 +671,13 @@ static int msm_vdec_property_subscription(struct msm_vidc_inst *inst, for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_properties); i++) payload[i + 1] = msm_vdec_subscribe_for_properties[i]; - rc = hfi_create_header(inst->packet, inst->packet_size, - inst->session_id, - core->header_id++); - if (rc) - return rc; - - rc = hfi_create_packet(inst->packet, inst->packet_size, + rc = venus_hfi_session_command(inst, HFI_CMD_SUBSCRIBE_MODE, - (HFI_HOST_FLAGS_RESPONSE_REQUIRED | - HFI_HOST_FLAGS_INTR_REQUIRED), + port, HFI_PAYLOAD_U32_ARRAY, - get_hfi_port(inst, port), - core->packet_id++, &payload[0], (ARRAY_SIZE(msm_vdec_subscribe_for_properties) + 1) * sizeof(u32)); - if (rc) - return rc; return rc; } @@ -696,24 +701,13 @@ static int msm_vdec_metadata_subscription(struct msm_vidc_inst *inst, for (i = 0; i < ARRAY_SIZE(msm_vdec_subscribe_for_metadata); i++) payload[i + 1] = msm_vdec_subscribe_for_metadata[i]; - rc = hfi_create_header(inst->packet, inst->packet_size, - inst->session_id, - core->header_id++); - if (rc) - return rc; - - rc = hfi_create_packet(inst->packet, inst->packet_size, + rc = venus_hfi_session_command(inst, HFI_CMD_SUBSCRIBE_MODE, - (HFI_HOST_FLAGS_RESPONSE_REQUIRED | - HFI_HOST_FLAGS_INTR_REQUIRED), + port, HFI_PAYLOAD_U32_ARRAY, - get_hfi_port(inst, port), - core->packet_id++, &payload[0], (ARRAY_SIZE(msm_vdec_subscribe_for_metadata) + 1) * sizeof(u32)); - if (rc) - return rc; return rc; } @@ -737,53 +731,13 @@ static int msm_vdec_metadata_delivery(struct msm_vidc_inst *inst, for (i = 0; i < ARRAY_SIZE(msm_vdec_deliver_as_metadata); i++) payload[i + 1] = msm_vdec_deliver_as_metadata[i]; - rc = hfi_create_header(inst->packet, inst->packet_size, - inst->session_id, - core->header_id++); - if (rc) - return rc; - - rc = hfi_create_packet(inst->packet, inst->packet_size, - HFI_CMD_DELIVERY_MODE, - (HFI_HOST_FLAGS_RESPONSE_REQUIRED | - HFI_HOST_FLAGS_INTR_REQUIRED), - HFI_PAYLOAD_U32_ARRAY, - get_hfi_port(inst, port), - core->packet_id++, - &payload[0], - (ARRAY_SIZE(msm_vdec_deliver_as_metadata) + 1) * sizeof(u32)); - if (rc) - return rc; - - return rc; -} - -static int msm_vdec_subscription(struct msm_vidc_inst *inst, - enum msm_vidc_port_type port) -{ - int rc = 0; - - rc = msm_vdec_port_settings_subscription(inst, port); - if (rc) - return rc; - rc = msm_vdec_property_subscription(inst, port); - if (rc) - return rc; - rc = msm_vdec_metadata_subscription(inst, port); - if (rc) - return rc; - - return rc; -} - -static int msm_vdec_deliveries(struct msm_vidc_inst *inst, - enum msm_vidc_port_type port) -{ - int rc = 0; - - rc = msm_vdec_metadata_delivery(inst, port); - if (rc) - return rc; + rc = venus_hfi_session_command(inst, + HFI_CMD_DELIVERY_MODE, + port, + HFI_PAYLOAD_U32_ARRAY, + &payload[0], + (ARRAY_SIZE(msm_vdec_deliver_as_metadata) + 1) * + sizeof(u32)); return rc; } @@ -796,9 +750,12 @@ int msm_vdec_stop_input(struct msm_vidc_inst *inst) d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } - d_vpr_h("%s()\n", __func__); - return rc; + rc = msm_vidc_session_stop(inst, INPUT_PORT); + if (rc) + return rc; + + return 0; } int msm_vdec_start_input(struct msm_vidc_inst *inst) @@ -848,13 +805,17 @@ int msm_vdec_start_input(struct msm_vidc_inst *inst) if (rc) goto error; - rc = msm_vdec_subscription(inst, INPUT_PORT); + rc = msm_vdec_port_settings_subscription(inst, INPUT_PORT); if (rc) - goto error; + return rc; - rc = msm_vdec_deliveries(inst, INPUT_PORT); + rc = msm_vdec_property_subscription(inst, INPUT_PORT); if (rc) - goto error; + return rc; + + rc = msm_vdec_metadata_delivery(inst, INPUT_PORT); + if (rc) + return rc; rc = venus_hfi_start(inst, INPUT_PORT); if (rc) @@ -873,13 +834,16 @@ int msm_vdec_stop_output(struct msm_vidc_inst *inst) { int rc = 0; - d_vpr_h("%s()\n", __func__); if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } - return rc; + rc = msm_vidc_session_stop(inst, OUTPUT_PORT); + if (rc) + return rc; + + return 0; } int msm_vdec_start_output(struct msm_vidc_inst *inst) @@ -896,13 +860,13 @@ int msm_vdec_start_output(struct msm_vidc_inst *inst) if (rc) goto error; - rc = msm_vdec_subscription(inst, OUTPUT_PORT); + rc = msm_vdec_port_settings_subscription(inst, OUTPUT_PORT); if (rc) - goto error; + return rc; - rc = msm_vdec_deliveries(inst, OUTPUT_PORT); + rc = msm_vdec_metadata_subscription(inst, OUTPUT_PORT); if (rc) - goto error; + return rc; rc = venus_hfi_start(inst, OUTPUT_PORT); if (rc) diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index 3e2af014a4..d45151234e 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -444,7 +444,7 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type) { int rc = 0; struct msm_vidc_inst *inst = instance; - enum msm_vidc_inst_state new_state = 0; + enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR; int port; if (!inst) { @@ -523,7 +523,7 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type) { int rc = 0; struct msm_vidc_inst *inst = instance; - enum msm_vidc_inst_state new_state = 0; + enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR; int port; if (!inst) { @@ -759,25 +759,28 @@ void *msm_vidc_open(void *vidc_core, u32 session_type) INIT_LIST_HEAD(&inst->buffers.input_meta.list); INIT_LIST_HEAD(&inst->buffers.output.list); INIT_LIST_HEAD(&inst->buffers.output_meta.list); - INIT_LIST_HEAD(&inst->buffers.scratch.list); - INIT_LIST_HEAD(&inst->buffers.scratch_1.list); - INIT_LIST_HEAD(&inst->buffers.scratch_2.list); + INIT_LIST_HEAD(&inst->buffers.bin.list); + INIT_LIST_HEAD(&inst->buffers.comv.list); + INIT_LIST_HEAD(&inst->buffers.non_comv.list); + INIT_LIST_HEAD(&inst->buffers.line.list); + INIT_LIST_HEAD(&inst->buffers.dpb.list); INIT_LIST_HEAD(&inst->buffers.persist.list); - INIT_LIST_HEAD(&inst->buffers.persist_1.list); - INIT_LIST_HEAD(&inst->allocations.scratch.list); - INIT_LIST_HEAD(&inst->allocations.scratch_1.list); - INIT_LIST_HEAD(&inst->allocations.scratch_2.list); + INIT_LIST_HEAD(&inst->allocations.bin.list); + INIT_LIST_HEAD(&inst->allocations.comv.list); + INIT_LIST_HEAD(&inst->allocations.non_comv.list); + INIT_LIST_HEAD(&inst->allocations.line.list); + INIT_LIST_HEAD(&inst->allocations.dpb.list); INIT_LIST_HEAD(&inst->allocations.persist.list); - INIT_LIST_HEAD(&inst->allocations.persist_1.list); INIT_LIST_HEAD(&inst->mappings.input.list); INIT_LIST_HEAD(&inst->mappings.input_meta.list); INIT_LIST_HEAD(&inst->mappings.output.list); INIT_LIST_HEAD(&inst->mappings.output_meta.list); - INIT_LIST_HEAD(&inst->mappings.scratch.list); - INIT_LIST_HEAD(&inst->mappings.scratch_1.list); - INIT_LIST_HEAD(&inst->mappings.scratch_2.list); + INIT_LIST_HEAD(&inst->mappings.bin.list); + INIT_LIST_HEAD(&inst->mappings.comv.list); + INIT_LIST_HEAD(&inst->mappings.non_comv.list); + INIT_LIST_HEAD(&inst->mappings.line.list); + INIT_LIST_HEAD(&inst->mappings.dpb.list); INIT_LIST_HEAD(&inst->mappings.persist.list); - INIT_LIST_HEAD(&inst->mappings.persist_1.list); INIT_LIST_HEAD(&inst->children.list); INIT_LIST_HEAD(&inst->firmware.list); inst->domain = session_type; diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index 0c87adb603..6c4e9f8c75 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -296,22 +296,18 @@ u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst, case MSM_VIDC_BUF_OUTPUT_META: region = MSM_VIDC_NON_SECURE; break; - case MSM_VIDC_BUF_SCRATCH: + case MSM_VIDC_BUF_BIN: region = MSM_VIDC_SECURE_BITSTREAM; break; - case MSM_VIDC_BUF_SCRATCH_1: + case MSM_VIDC_BUF_COMV: + case MSM_VIDC_BUF_NON_COMV: + case MSM_VIDC_BUF_LINE: region = MSM_VIDC_SECURE_NONPIXEL; break; - case MSM_VIDC_BUF_SCRATCH_2: + case MSM_VIDC_BUF_DPB: region = MSM_VIDC_SECURE_PIXEL; break; case MSM_VIDC_BUF_PERSIST: - if (is_encode_session(inst)) - region = MSM_VIDC_SECURE_NONPIXEL; - else - region = MSM_VIDC_SECURE_BITSTREAM; - break; - case MSM_VIDC_BUF_PERSIST_1: region = MSM_VIDC_SECURE_NONPIXEL; break; default: @@ -334,16 +330,18 @@ struct msm_vidc_buffers *msm_vidc_get_buffers( return &inst->buffers.output; case MSM_VIDC_BUF_OUTPUT_META: return &inst->buffers.output_meta; - case MSM_VIDC_BUF_SCRATCH: - return &inst->buffers.scratch; - case MSM_VIDC_BUF_SCRATCH_1: - return &inst->buffers.scratch_1; - case MSM_VIDC_BUF_SCRATCH_2: - return &inst->buffers.scratch_2; + case MSM_VIDC_BUF_BIN: + return &inst->buffers.bin; + case MSM_VIDC_BUF_COMV: + return &inst->buffers.comv; + case MSM_VIDC_BUF_NON_COMV: + return &inst->buffers.non_comv; + case MSM_VIDC_BUF_LINE: + return &inst->buffers.line; + case MSM_VIDC_BUF_DPB: + return &inst->buffers.dpb; case MSM_VIDC_BUF_PERSIST: return &inst->buffers.persist; - case MSM_VIDC_BUF_PERSIST_1: - return &inst->buffers.persist_1; default: s_vpr_e(inst->sid, "%s: invalid driver buffer type %d\n", func, buffer_type); @@ -364,16 +362,18 @@ struct msm_vidc_mappings *msm_vidc_get_mappings( return &inst->mappings.output; case MSM_VIDC_BUF_OUTPUT_META: return &inst->mappings.output_meta; - case MSM_VIDC_BUF_SCRATCH: - return &inst->mappings.scratch; - case MSM_VIDC_BUF_SCRATCH_1: - return &inst->mappings.scratch_1; - case MSM_VIDC_BUF_SCRATCH_2: - return &inst->mappings.scratch_2; + case MSM_VIDC_BUF_BIN: + return &inst->mappings.bin; + case MSM_VIDC_BUF_COMV: + return &inst->mappings.comv; + case MSM_VIDC_BUF_NON_COMV: + return &inst->mappings.non_comv; + case MSM_VIDC_BUF_LINE: + return &inst->mappings.line; + case MSM_VIDC_BUF_DPB: + return &inst->mappings.dpb; case MSM_VIDC_BUF_PERSIST: return &inst->mappings.persist; - case MSM_VIDC_BUF_PERSIST_1: - return &inst->mappings.persist_1; default: s_vpr_e(inst->sid, "%s: invalid driver buffer type %d\n", func, buffer_type); @@ -386,16 +386,18 @@ struct msm_vidc_allocations *msm_vidc_get_allocations( const char *func) { switch (buffer_type) { - case MSM_VIDC_BUF_SCRATCH: - return &inst->allocations.scratch; - case MSM_VIDC_BUF_SCRATCH_1: - return &inst->allocations.scratch_1; - case MSM_VIDC_BUF_SCRATCH_2: - return &inst->allocations.scratch_2; + case MSM_VIDC_BUF_BIN: + return &inst->allocations.bin; + case MSM_VIDC_BUF_COMV: + return &inst->allocations.comv; + case MSM_VIDC_BUF_NON_COMV: + return &inst->allocations.non_comv; + case MSM_VIDC_BUF_LINE: + return &inst->allocations.line; + case MSM_VIDC_BUF_DPB: + return &inst->allocations.dpb; case MSM_VIDC_BUF_PERSIST: return &inst->allocations.persist; - case MSM_VIDC_BUF_PERSIST_1: - return &inst->allocations.persist_1; default: s_vpr_e(inst->sid, "%s: invalid driver buffer type %d\n", func, buffer_type); @@ -410,6 +412,7 @@ int msm_vidc_change_inst_state(struct msm_vidc_inst *inst, d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } + if (!request_state) { s_vpr_e(inst->sid, "%s: invalid request state\n", func); return -EINVAL; @@ -541,6 +544,8 @@ int msm_vidc_put_driver_buf(struct msm_vidc_inst *inst, if (rc) return rc; + msm_vidc_memory_put_dmabuf(buf->dmabuf); + /* delete the buffer from buffers->list */ list_del(&buf->list); kfree(buf); @@ -628,7 +633,6 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst, dmabuf = msm_vidc_memory_get_dmabuf(vb2->planes[0].m.fd); if (!dmabuf) return NULL; - msm_vidc_memory_put_dmabuf(dmabuf); /* check if it is an existing buffer */ list_for_each_entry(buf, &buffers->list, list) { @@ -679,6 +683,7 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst, return buf; error: + msm_vidc_memory_put_dmabuf(dmabuf); if (!found) kfree(buf); return NULL; @@ -1171,6 +1176,54 @@ int msm_vidc_session_set_codec(struct msm_vidc_inst *inst) return 0; } +int msm_vidc_session_stop(struct msm_vidc_inst *inst, + enum msm_vidc_port_type port) +{ + int rc = 0; + struct msm_vidc_core *core; + enum signal_session_response signal_type; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + if (port == INPUT_PORT) { + signal_type = SIGNAL_CMD_STOP_INPUT; + } else if (port == OUTPUT_PORT) { + signal_type = SIGNAL_CMD_STOP_OUTPUT; + } else { + s_vpr_e(inst->sid, "%s: invalid port: %d\n", __func__, port); + return -EINVAL; + } + + rc = venus_hfi_stop(inst, port); + if (rc) + return rc; + + core = inst->core; + mutex_unlock(&inst->lock); + s_vpr_h(inst->sid, "%s: wait on port: %d for time: %d ms\n", + __func__, port, core->capabilities[HW_RESPONSE_TIMEOUT].value); + rc = wait_for_completion_timeout( + &inst->completions[signal_type], + msecs_to_jiffies( + core->capabilities[HW_RESPONSE_TIMEOUT].value)); + mutex_lock(&inst->lock); + if (!rc) { + s_vpr_e(inst->sid, "%s: session stop timed out for port: %d\n", + __func__, port); + //msm_comm_kill_session(inst); + rc = -EIO; + } else { + rc = 0; + s_vpr_h(inst->sid, "%s: stop successful on port: %d\n", + __func__, port); + } + + return rc; +} + int msm_vidc_session_close(struct msm_vidc_inst *inst) { int rc = 0; @@ -1186,6 +1239,8 @@ int msm_vidc_session_close(struct msm_vidc_inst *inst) return rc; core = inst->core; + s_vpr_h(inst->sid, "%s: wait on close for time: %d ms\n", + __func__, core->capabilities[HW_RESPONSE_TIMEOUT].value); rc = wait_for_completion_timeout( &inst->completions[SIGNAL_CMD_CLOSE], msecs_to_jiffies( @@ -1196,6 +1251,7 @@ int msm_vidc_session_close(struct msm_vidc_inst *inst) rc = -EIO; } else { rc = 0; + s_vpr_h(inst->sid, "%s: close successful\n", __func__); } return rc; diff --git a/driver/vidc/src/msm_vidc_probe.c b/driver/vidc/src/msm_vidc_probe.c index 31090a1154..b70d596669 100644 --- a/driver/vidc/src/msm_vidc_probe.c +++ b/driver/vidc/src/msm_vidc_probe.c @@ -9,7 +9,6 @@ #include #include #include -#include #include "msm_vidc_internal.h" #include "msm_vidc_debug.h" @@ -21,18 +20,6 @@ #define BASE_DEVICE_NUMBER 32 -static irqreturn_t msm_vidc_isr(int irq, void *data) -{ - struct msm_vidc_core *core = data; - - d_vpr_e("%s()\n", __func__); - - disable_irq_nosync(irq); - queue_work(core->device_workq, &core->device_work); - - return IRQ_HANDLED; -} - static int msm_vidc_init_irq(struct msm_vidc_core *core) { int rc = 0; @@ -54,7 +41,7 @@ static int msm_vidc_init_irq(struct msm_vidc_core *core) goto exit; } - rc = request_irq(dt->irq, msm_vidc_isr, IRQF_TRIGGER_HIGH, + rc = request_irq(dt->irq, venus_hfi_isr, IRQF_TRIGGER_HIGH, "msm_vidc", core); if (unlikely(rc)) { d_vpr_e("%s: request_irq failed\n", __func__); diff --git a/driver/vidc/src/msm_vidc_vb2.c b/driver/vidc/src/msm_vidc_vb2.c index 6e714e052c..d746d570cb 100644 --- a/driver/vidc/src/msm_vidc_vb2.c +++ b/driver/vidc/src/msm_vidc_vb2.c @@ -188,6 +188,49 @@ int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count) void msm_vidc_stop_streaming(struct vb2_queue *q) { + int rc = 0; + struct msm_vidc_inst *inst; + + if (!q || !q->drv_priv) { + d_vpr_e("%s: invalid input, q = %pK\n", q); + return; + } + inst = q->drv_priv; + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params\n", __func__); + return; + } + if (q->type == INPUT_META_PLANE || q->type == OUTPUT_META_PLANE) { + s_vpr_h(inst->sid, "%s: nothing to stop on meta port %d\n", + __func__, q->type); + return; + } + if (!is_decode_session(inst) && !is_encode_session(inst)) { + s_vpr_e(inst->sid, "%s: invalid session %d\n", + __func__, inst->domain); + return; + } + s_vpr_h(inst->sid, "Streamoff: %d\n", q->type); + + if (q->type == INPUT_MPLANE) { + if (is_decode_session(inst)) + rc = msm_vdec_stop_input(inst); + //else if (is_encode_session(inst)) + // rc = msm_venc_start_input(inst); + } else if (q->type == OUTPUT_MPLANE) { + if (is_decode_session(inst)) + rc = msm_vdec_stop_output(inst); + //else if (is_encode_session(inst)) + // rc = msm_venc_start_output(inst); + } else { + s_vpr_e(inst->sid, "%s: invalid type %d\n", __func__, q->type); + } + + if (rc) + s_vpr_e(inst->sid, "%s: stop failed for qtype: %d\n", + __func__, q->type); + + return; } void msm_vidc_buf_queue(struct vb2_buffer *vb2) diff --git a/driver/vidc/src/venus_hfi.c b/driver/vidc/src/venus_hfi.c index 5efb7d8031..ba6ceeeb86 100644 --- a/driver/vidc/src/venus_hfi.c +++ b/driver/vidc/src/venus_hfi.c @@ -594,8 +594,8 @@ static int __write_queue(struct msm_vidc_iface_q_info *qinfo, u8 *packet, } // TODO: handle writing packet - d_vpr_e("skip writing packet\n"); - return 0; + //d_vpr_e("skip writing packet\n"); + //return 0; packet_size_in_words = (*(u32 *)packet) >> 2; if (!packet_size_in_words || packet_size_in_words > @@ -915,18 +915,36 @@ dbg_error_null: return rc; } -/*TODO:darshana needs discussion*/ -static void __flush_debug_queue(struct msm_vidc_core *core, u8 *header) +// TODO: revisit once firmware updated to latest interface headers +struct hfi_packet_header { + u32 size; + u32 packet_type; +}; + +struct hfi_msg_sys_debug_packet { + u32 size; + u32 packet_type; + u32 msg_type; + u32 msg_size; + u32 time_stamp_hi; + u32 time_stamp_lo; + u8 rg_msg_data[1]; +}; + +static void __flush_debug_queue(struct msm_vidc_core *core, u8 *packet) { bool local_packet = false; enum vidc_msg_prio log_level = msm_vidc_debug; - struct hfi_packet *pkt; - u32 payload = 0; - if (!header) { - header = kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_KERNEL); - if (!header) { - d_vpr_e("%s: Fail to allocate mem\n", __func__); + if (!core) { + d_vpr_e("%s: invalid params\n", __func__); + return; + } + + if (!packet) { + packet = kzalloc(VIDC_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_KERNEL); + if (!packet) { + d_vpr_e("%s: fail to allocate\n", __func__); return; } @@ -950,20 +968,21 @@ static void __flush_debug_queue(struct msm_vidc_core *core, u8 *header) } \ }) - while (!__iface_dbgq_read(core, header)) { - struct hfi_header *hdr = - (struct hfi_header *) header; + while (!__iface_dbgq_read(core, packet)) { + struct hfi_packet_header *pkt = + (struct hfi_packet_header *) packet; - if (validate_packet((u8 *)pkt, core->response_packet, - core->packet_size, __func__)) - return; + if (pkt->size < sizeof(struct hfi_packet_header)) { + d_vpr_e("Invalid pkt size - %s\n", __func__); + continue; + } + + if (1) { + struct hfi_msg_sys_debug_packet *pkt = + (struct hfi_msg_sys_debug_packet *) packet; - pkt = (struct hfi_packet *)(hdr + sizeof(struct hfi_header)); - if (pkt->type == HFI_PROP_DEBUG_LOG_LEVEL) { SKIP_INVALID_PKT(pkt->size, - sizeof(u32), sizeof(*pkt)); - - payload = (u32) *((u8 *)pkt + sizeof(struct hfi_packet)); + pkt->msg_size, sizeof(*pkt)); /* * All fw messages starts with new line character. This @@ -972,14 +991,14 @@ static void __flush_debug_queue(struct msm_vidc_core *core, u8 *header) * from the message fixes this to print it in a single * line. */ - //pkt->rg_msg_data[sizeof(u32)-1] = '\0'; - dprintk_firmware(log_level, "%s", &payload); + pkt->rg_msg_data[pkt->msg_size-1] = '\0'; + dprintk_firmware(log_level, "%s", &pkt->rg_msg_data[1]); } } #undef SKIP_INVALID_PKT if (local_packet) - kfree(header); + kfree(packet); } static int __sys_set_debug(struct msm_vidc_core *core, u32 debug) @@ -2318,6 +2337,18 @@ static int __response_handler(struct msm_vidc_core *core) return rc; } +irqreturn_t venus_hfi_isr(int irq, void *data) +{ + struct msm_vidc_core *core = data; + + d_vpr_e("%s()\n", __func__); + + disable_irq_nosync(irq); + queue_work(core->device_workq, &core->device_work); + + return IRQ_HANDLED; +} + void venus_hfi_work_handler(struct work_struct *work) { struct msm_vidc_core *core; @@ -2561,7 +2592,7 @@ int venus_hfi_session_set_codec(struct msm_vidc_inst *inst) HFI_PROP_CODEC, HFI_HOST_FLAGS_NONE, HFI_PORT_NONE, - HFI_PAYLOAD_U32, + HFI_PAYLOAD_U32_ENUM, &codec, sizeof(u32)); if (rc) @@ -2702,6 +2733,49 @@ int venus_hfi_stop(struct msm_vidc_inst *inst, enum msm_vidc_port_type port) return rc; } +int venus_hfi_session_command(struct msm_vidc_inst *inst, + u32 cmd, enum msm_vidc_port_type port, u32 payload_type, + void *payload, u32 payload_size) +{ + int rc = 0; + struct msm_vidc_core *core; + + if (!inst || !inst->packet || !inst->core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + + rc = hfi_create_header(inst->packet, inst->packet_size, + inst->session_id, + core->header_id++); + if (rc) + return rc; + + rc = hfi_create_packet(inst->packet, inst->packet_size, + cmd, + (HFI_HOST_FLAGS_RESPONSE_REQUIRED | + HFI_HOST_FLAGS_INTR_REQUIRED), + payload_type, + get_hfi_port(inst, port), + core->packet_id++, + payload, + payload_size); + + if (rc) + goto err_cmd; + + s_vpr_h(inst->sid, "Command packet 0x%x created\n", cmd); + __iface_cmdq_write(inst->core, inst->packet); + + return rc; + +err_cmd: + s_vpr_e(inst->sid, "%s: create packet failed for cmd: %d\n", + __func__, cmd); + return rc; +} + int venus_hfi_queue_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *buffer, struct msm_vidc_buffer *metabuf) { diff --git a/driver/vidc/src/venus_hfi_response.c b/driver/vidc/src/venus_hfi_response.c index d4c1473144..b31bbd7a29 100644 --- a/driver/vidc/src/venus_hfi_response.c +++ b/driver/vidc/src/venus_hfi_response.c @@ -34,7 +34,13 @@ bool is_valid_hfi_buffer_type(struct msm_vidc_inst *inst, if (buffer_type != HFI_BUFFER_BITSTREAM && buffer_type != HFI_BUFFER_RAW && - buffer_type != HFI_BUFFER_METADATA) { + buffer_type != HFI_BUFFER_METADATA && + buffer_type != HFI_BUFFER_BIN && + buffer_type != HFI_BUFFER_COMV && + buffer_type != HFI_BUFFER_NON_COMV && + buffer_type != HFI_BUFFER_LINE && + buffer_type != HFI_BUFFER_DPB && + buffer_type != HFI_BUFFER_PERSIST) { s_vpr_e(inst->sid, "%s: invalid buffer type %#x\n", func, buffer_type); return false; @@ -185,6 +191,8 @@ static int handle_session_start(struct msm_vidc_inst *inst, static int handle_session_stop(struct msm_vidc_inst *inst, struct hfi_packet *pkt) { + int signal_type = -1; + if (pkt->flags & HFI_FW_FLAGS_SESSION_ERROR) { s_vpr_e(inst->sid, "%s: received session error\n", __func__); msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__); @@ -193,7 +201,34 @@ static int handle_session_stop(struct msm_vidc_inst *inst, if (pkt->flags & HFI_FW_FLAGS_SUCCESS) s_vpr_h(inst->sid, "%s: successful for port %d\n", __func__, pkt->port); - signal_session_msg_receipt(inst, SIGNAL_CMD_STOP); + + if (is_encode_session(inst)) { + if (pkt->port == HFI_PORT_RAW) { + signal_type = SIGNAL_CMD_STOP_INPUT; + } else if (pkt->port == HFI_PORT_BITSTREAM) { + signal_type = SIGNAL_CMD_STOP_OUTPUT; + } else { + s_vpr_e(inst->sid, "%s: invalid port: %d\n", + __func__, pkt->port); + return -EINVAL; + } + } else if (is_decode_session(inst)) { + if (pkt->port == HFI_PORT_RAW) { + signal_type = SIGNAL_CMD_STOP_OUTPUT; + } else if (pkt->port == HFI_PORT_BITSTREAM) { + signal_type = SIGNAL_CMD_STOP_INPUT; + } else { + s_vpr_e(inst->sid, "%s: invalid port: %d\n", + __func__, pkt->port); + return -EINVAL; + } + } else { + s_vpr_e(inst->sid, "%s: invalid session\n", __func__); + return -EINVAL; + } + + if (signal_type != -1) + signal_session_msg_receipt(inst, signal_type); return 0; } @@ -441,6 +476,32 @@ static int handle_port_settings_change(struct msm_vidc_inst *inst, return 0; } +static int handle_session_subscribe_mode(struct msm_vidc_inst *inst, + struct hfi_packet *pkt) +{ + if (pkt->flags & HFI_FW_FLAGS_SESSION_ERROR) { + s_vpr_e(inst->sid, "%s: received session error\n", __func__); + msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__); + } + + if (pkt->flags & HFI_FW_FLAGS_SUCCESS) + s_vpr_h(inst->sid, "%s: successful\n", __func__); + return 0; +} + +static int handle_session_delivery_mode(struct msm_vidc_inst *inst, + struct hfi_packet *pkt) +{ + if (pkt->flags & HFI_FW_FLAGS_SESSION_ERROR) { + s_vpr_e(inst->sid, "%s: received session error\n", __func__); + msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__); + } + + if (pkt->flags & HFI_FW_FLAGS_SUCCESS) + s_vpr_h(inst->sid, "%s: successful\n", __func__); + return 0; +} + static int handle_session_command(struct msm_vidc_inst *inst, struct hfi_packet *pkt) { @@ -459,6 +520,10 @@ static int handle_session_command(struct msm_vidc_inst *inst, return handle_session_buffer(inst, pkt); case HFI_CMD_SETTINGS_CHANGE: return handle_port_settings_change(inst, pkt); + case HFI_CMD_SUBSCRIBE_MODE: + return handle_session_subscribe_mode(inst, pkt); + case HFI_CMD_DELIVERY_MODE: + return handle_session_delivery_mode(inst, pkt); default: s_vpr_e(inst->sid, "%s: Unsupported command type: %#x\n", __func__, pkt->type); @@ -531,39 +596,47 @@ static int handle_system_response(struct msm_vidc_core *core, struct hfi_header *hdr) { int rc = 0; - struct hfi_packet *pkt; + struct hfi_packet *packet; + u8 *pkt; int i; - pkt = (struct hfi_packet *)((u8 *)hdr + sizeof(struct hfi_header)); + pkt = (u8 *)((u8 *)hdr + sizeof(struct hfi_header)); for (i = 0; i < hdr->num_packets; i++) { if (validate_packet((u8 *)pkt, core->response_packet, - core->packet_size, __func__)) - return -EINVAL; - if (pkt->type == HFI_CMD_INIT) { - rc = handle_system_init(core, pkt); - } else if (pkt->type > HFI_SYSTEM_ERROR_BEGIN && - pkt->type < HFI_SYSTEM_ERROR_END) { - rc = handle_system_error(core, pkt); - } else if (pkt->type > HFI_PROP_BEGIN && - pkt->type < HFI_PROP_CODEC) { - rc = handle_system_property(core, pkt); + core->packet_size, __func__)) { + rc = -EINVAL; + goto exit; + } + packet = (struct hfi_packet *)pkt; + if (packet->type == HFI_CMD_INIT) { + rc = handle_system_init(core, packet); + } else if (packet->type > HFI_SYSTEM_ERROR_BEGIN && + packet->type < HFI_SYSTEM_ERROR_END) { + rc = handle_system_error(core, packet); + } else if (packet->type > HFI_PROP_BEGIN && + packet->type < HFI_PROP_CODEC) { + rc = handle_system_property(core, packet); } else { d_vpr_e("%s: Unknown packet type: %#x\n", - __func__, pkt->type); - return -EINVAL; + __func__, packet->type); + rc = -EINVAL; + goto exit; } - pkt += pkt->size; + pkt += packet->size; } +exit: return rc; } static int handle_session_response(struct msm_vidc_core *core, struct hfi_header *hdr) { - struct hfi_packet *pkt; + int rc = 0; struct msm_vidc_inst *inst; - int i, rc = 0; + struct hfi_packet *packet; + u8 *pkt; + int i; inst = get_inst(core, hdr->session_id); if (!inst) { @@ -572,29 +645,31 @@ static int handle_session_response(struct msm_vidc_core *core, } mutex_lock(&inst->lock); - pkt = (struct hfi_packet *)((u8 *)hdr + sizeof(struct hfi_header)); + pkt = (u8 *)((u8 *)hdr + sizeof(struct hfi_header)); for (i = 0; i < hdr->num_packets; i++) { - if (validate_packet((u8 *)pkt, core->response_packet, + if (validate_packet(pkt, core->response_packet, core->packet_size, __func__)) { rc = -EINVAL; goto exit; } - if (pkt->type < HFI_CMD_END && pkt->type > HFI_CMD_BEGIN) { - rc = handle_session_command(inst, pkt); - } else if (pkt->type > HFI_PROP_BEGIN && - pkt->type < HFI_PROP_END) { - rc = handle_session_property(inst, pkt); - } else if (pkt->type > HFI_SESSION_ERROR_BEGIN && - pkt->type < HFI_SESSION_ERROR_END) { - rc = handle_session_error(inst, pkt); + packet = (struct hfi_packet *)pkt; + if (packet->type < HFI_CMD_END && + packet->type > HFI_CMD_BEGIN) { + rc = handle_session_command(inst, packet); + } else if (packet->type > HFI_PROP_BEGIN && + packet->type < HFI_PROP_END) { + rc = handle_session_property(inst, packet); + } else if (packet->type > HFI_SESSION_ERROR_BEGIN && + packet->type < HFI_SESSION_ERROR_END) { + rc = handle_session_error(inst, packet); } else { s_vpr_e(inst->sid, "%s: Unknown packet type: %#x\n", - __func__, pkt->type); + __func__, packet->type); rc = -EINVAL; goto exit; } - pkt += pkt->size; + pkt += packet->size; } exit: mutex_unlock(&inst->lock);