diff --git a/msm/vidc/hfi_iris2.c b/msm/vidc/hfi_iris2.c index 4627f8b46871..5ac62b788ea4 100644 --- a/msm/vidc/hfi_iris2.c +++ b/msm/vidc/hfi_iris2.c @@ -243,10 +243,6 @@ skip_aon_mvp_noc: /* HPG 6.1.2 Step 6 */ __disable_unprepare_clks(device); - /* HPG 6.1.2 Step 7 & 8 */ - if (call_venus_op(device, reset_ahb2axi_bridge, device, sid)) - d_vpr_e("%s: Failed to reset ahb2axi\n", __func__); - /* HPG 6.1.2 Step 5 */ if (__disable_regulators(device)) d_vpr_e("%s: Failed to disable regulators\n", __func__); diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index fb778e6cded4..9e65e0462498 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -496,11 +496,21 @@ static int hfi_process_sys_rel_resource_done(u32 device_id, return 0; } +static void copy_hfi_to_hal_buf_req(struct hal_buffer_requirements *dst, + struct hfi_buffer_requirements *src) { + dst->buffer_size = src->buffer_size; + dst->buffer_count_min = (u16)src->buffer_count_min; + dst->buffer_count_min_host = (u16)src->buffer_count_min_host; + dst->buffer_count_actual = (u16)src->buffer_count_actual; + dst->buffer_alignment = (u16)src->buffer_alignment; +} + static void hfi_process_sess_get_prop_buf_req( struct hfi_msg_session_property_info_packet *prop, struct buffer_requirements *buffreq, u32 sid) { struct hfi_buffer_requirements *hfi_buf_req; + struct hal_buffer_requirements *hal_buf_req; u32 req_bytes; if (!prop) { @@ -529,79 +539,70 @@ static void hfi_process_sess_get_prop_buf_req( hfi_buf_req->buffer_type); switch (hfi_buf_req->buffer_type) { case HFI_BUFFER_INPUT: - memcpy(&buffreq->buffer[0], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[0].buffer_type = HAL_BUFFER_INPUT; + hal_buf_req = &buffreq->buffer[0]; + hal_buf_req->buffer_type = HAL_BUFFER_INPUT; break; case HFI_BUFFER_OUTPUT: - memcpy(&buffreq->buffer[1], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[1].buffer_type = HAL_BUFFER_OUTPUT; + hal_buf_req = &buffreq->buffer[1]; + hal_buf_req->buffer_type = HAL_BUFFER_OUTPUT; break; case HFI_BUFFER_OUTPUT2: - memcpy(&buffreq->buffer[2], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[2].buffer_type = HAL_BUFFER_OUTPUT2; + hal_buf_req = &buffreq->buffer[2]; + hal_buf_req->buffer_type = HAL_BUFFER_OUTPUT2; break; case HFI_BUFFER_EXTRADATA_INPUT: - memcpy(&buffreq->buffer[3], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[3].buffer_type = + hal_buf_req = &buffreq->buffer[3]; + hal_buf_req->buffer_type = HAL_BUFFER_EXTRADATA_INPUT; break; case HFI_BUFFER_EXTRADATA_OUTPUT: - memcpy(&buffreq->buffer[4], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[4].buffer_type = + hal_buf_req = &buffreq->buffer[4]; + hal_buf_req->buffer_type = HAL_BUFFER_EXTRADATA_OUTPUT; break; case HFI_BUFFER_EXTRADATA_OUTPUT2: - memcpy(&buffreq->buffer[5], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[5].buffer_type = + hal_buf_req = &buffreq->buffer[5]; + hal_buf_req->buffer_type = HAL_BUFFER_EXTRADATA_OUTPUT2; break; case HFI_BUFFER_COMMON_INTERNAL_SCRATCH: - memcpy(&buffreq->buffer[6], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[6].buffer_type = + hal_buf_req = &buffreq->buffer[6]; + hal_buf_req->buffer_type = HAL_BUFFER_INTERNAL_SCRATCH; break; case HFI_BUFFER_COMMON_INTERNAL_SCRATCH_1: - memcpy(&buffreq->buffer[7], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[7].buffer_type = + hal_buf_req = &buffreq->buffer[7]; + hal_buf_req->buffer_type = HAL_BUFFER_INTERNAL_SCRATCH_1; break; case HFI_BUFFER_COMMON_INTERNAL_SCRATCH_2: - memcpy(&buffreq->buffer[8], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[8].buffer_type = + hal_buf_req = &buffreq->buffer[8]; + hal_buf_req->buffer_type = HAL_BUFFER_INTERNAL_SCRATCH_2; break; case HFI_BUFFER_INTERNAL_PERSIST: - memcpy(&buffreq->buffer[9], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[9].buffer_type = + hal_buf_req = &buffreq->buffer[9]; + hal_buf_req->buffer_type = HAL_BUFFER_INTERNAL_PERSIST; break; case HFI_BUFFER_INTERNAL_PERSIST_1: - memcpy(&buffreq->buffer[10], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[10].buffer_type = + hal_buf_req = &buffreq->buffer[10]; + hal_buf_req->buffer_type = HAL_BUFFER_INTERNAL_PERSIST_1; break; case HFI_BUFFER_COMMON_INTERNAL_RECON: - memcpy(&buffreq->buffer[11], hfi_buf_req, - sizeof(struct hfi_buffer_requirements)); - buffreq->buffer[11].buffer_type = + hal_buf_req = &buffreq->buffer[11]; + hal_buf_req->buffer_type = HAL_BUFFER_INTERNAL_RECON; break; default: + hal_buf_req = NULL; s_vpr_e(sid, "%s: bad_buffer_type: %d\n", __func__, hfi_buf_req->buffer_type); break; } + if (hal_buf_req) + copy_hfi_to_hal_buf_req(hal_buf_req, hfi_buf_req); req_bytes -= sizeof(struct hfi_buffer_requirements); hfi_buf_req++; } diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index c53353abd940..685f56e6c17b 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -17,7 +17,7 @@ #define MIN_NUM_DEC_CAPTURE_BUFFERS 4 /* Y=16(0-9bits), Cb(10-19bits)=Cr(20-29bits)=128, black by default */ #define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8020010 -#define MAX_VP9D_INST_COUNT 6 +#define MAX_VP9D_INST_COUNT 3 static const char *const mpeg_video_h264_profile[] = { "Baseline", @@ -1195,10 +1195,9 @@ int msm_vdec_set_secure_mode(struct msm_vidc_inst *inst) if (ctrl->val) { if (!(codec == V4L2_PIX_FMT_HEVC || codec == V4L2_PIX_FMT_H264 || - codec == V4L2_PIX_FMT_VP9 || - codec == V4L2_PIX_FMT_MPEG2)) { + codec == V4L2_PIX_FMT_VP9)) { s_vpr_e(inst->sid, - "%s: Secure allowed for HEVC/H264/VP9/MPEG2\n", + "%s: Secure allowed for HEVC/H264/VP9\n", __func__); return -EINVAL; } diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 7e4d638319b6..bf3184fe1040 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -32,8 +32,6 @@ #define DEFAULT_QP 0xA #define DEFAULT_QP_PACKED 0xA0A0A #define MIN_CHROMA_QP_OFFSET -12 -#define MAX_CHROMA_QP_OFFSET 0 -#define DEFAULT_CHROMA_QP_OFFSET 0 #define MAX_INTRA_REFRESH_MBS ((7680 * 4320) >> 8) #define MAX_LTR_FRAME_COUNT 10 #define MAX_NUM_B_FRAMES 1 @@ -927,8 +925,8 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .name = "Chroma QP Index Offset", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = MIN_CHROMA_QP_OFFSET, - .maximum = MAX_CHROMA_QP_OFFSET, - .default_value = DEFAULT_CHROMA_QP_OFFSET, + .maximum = INT_MAX, + .default_value = INT_MAX, .step = 1, }, { @@ -2120,6 +2118,7 @@ int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) struct msm_vidc_timestamps *entry, *node, *prev = NULL; int count = 0; int rc = 0; + struct v4l2_ctrl *superframe_ctrl = NULL; if (!inst || !inst->core) { d_vpr_e("%s: invalid parameters\n", __func__); @@ -2172,7 +2171,13 @@ int msm_venc_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) /* if framerate changed and stable for 2 frames, set to firmware */ if (entry->framerate == prev->framerate && entry->framerate != inst->clk_data.frame_rate) { - inst->clk_data.frame_rate = entry->framerate; + superframe_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); + if (superframe_ctrl->val > 1) + inst->clk_data.frame_rate = entry->framerate * superframe_ctrl->val; + else + inst->clk_data.frame_rate = entry->framerate; + s_vpr_l(inst->sid, "%s: updated fps to %u\n", + __func__, (inst->clk_data.frame_rate >> 16)); msm_venc_set_frame_rate(inst); } @@ -2478,8 +2483,9 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst) V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER); codec = get_v4l2_codec(inst); + intra_period.pframes = gop_size->val; + if (!max_layer->val && codec == V4L2_PIX_FMT_H264) { - intra_period.pframes = gop_size->val; /* * At this point we've already made decision on bframe. * Control value gives updated bframe value. @@ -3373,7 +3379,7 @@ int msm_venc_set_chroma_qp_offset(struct msm_vidc_inst *inst) hdev = inst->core->device; chr = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET); - if (chr->val != MIN_CHROMA_QP_OFFSET) + if (chr->val == INT_MAX || (chr->val != 0 && chr->val != -12)) return 0; f = &inst->fmts[INPUT_PORT].v4l2_fmt; @@ -3406,10 +3412,6 @@ int msm_venc_set_chroma_qp_offset(struct msm_vidc_inst *inst) chroma_qp.chroma_offset = (chr->val + 12) << 16 | (chr->val + 12); s_vpr_h(inst->sid, "%s: %x\n", __func__, chroma_qp.chroma_offset); - /* TODO: Remove this check after firmware support added for 8-bit */ - if (inst->bit_depth == MSM_VIDC_BIT_DEPTH_8) - return 0; - rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_HEVC_PPS_CB_CR_OFFSET, &chroma_qp, sizeof(chroma_qp)); @@ -4603,6 +4605,12 @@ int msm_venc_set_cvp_skipratio(struct msm_vidc_inst *inst) d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } + + if (!is_cvp_supported(inst)) { + s_vpr_h(inst->sid, "%s cvp is not supported", __func__); + return rc; + } + if (!msm_vidc_cvp_usage) return 0; diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 3f789a4afe46..7f78071d585d 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -366,7 +366,7 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, int rc = 0; unsigned int i = 0; struct buf_queue *q = NULL; - u64 timestamp_us = 0; + s64 timestamp_us = 0; u32 cr = 0; if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) { @@ -430,14 +430,17 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, && b->type == INPUT_MPLANE) b->flags |= V4L2_BUF_FLAG_PERF_MODE; - timestamp_us = (u64)((b->timestamp.tv_sec * 1000000ULL) + + timestamp_us = (s64)((b->timestamp.tv_sec * 1000000) + b->timestamp.tv_usec); if (is_decode_session(inst) && b->type == INPUT_MPLANE) { if (inst->flush_timestamps) msm_comm_release_timestamps(inst); inst->flush_timestamps = false; - rc = msm_comm_store_timestamp(inst, timestamp_us); + if (!(b->flags & V4L2_BUF_FLAG_CODECCONFIG)) + rc = msm_comm_store_timestamp(inst, timestamp_us, + b->flags & V4L2_BUF_FLAG_EOS); + if (rc) goto unlock; inst->clk_data.frame_rate = msm_comm_get_max_framerate(inst); @@ -508,7 +511,9 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) return -EINVAL; } } - if (is_decode_session(inst) && b->type == OUTPUT_MPLANE) + if (is_decode_session(inst) && + b->type == OUTPUT_MPLANE && + !(b->flags & V4L2_BUF_FLAG_CODECCONFIG)) msm_comm_fetch_ts_framerate(inst, b); return rc; @@ -794,6 +799,11 @@ static bool msm_vidc_set_cvp_metadata(struct msm_vidc_inst *inst) { return false; } + if (!is_cvp_supported(inst)) { + s_vpr_h(inst->sid, "%s cvp is not supported", __func__); + return true; + } + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) value = 0x1; @@ -1403,13 +1413,13 @@ static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst, break; case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: ctrl->val = inst->fmts[OUTPUT_PORT].count_min_host; - s_vpr_h(inst->sid, "g_min: hal_buffer %d min buffers %d\n", - HAL_BUFFER_OUTPUT, ctrl->val); + s_vpr_h(inst->sid, "g_min: OUTPUT_PORT count_min_host %d\n", + ctrl->val); break; case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: ctrl->val = inst->fmts[INPUT_PORT].count_min_host; - s_vpr_h(inst->sid, "g_min: hal_buffer %d min buffers %d\n", - HAL_BUFFER_INPUT, ctrl->val); + s_vpr_h(inst->sid, "g_min: INPUT_PORT count_min_host %d\n", + ctrl->val); break; case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA: ctrl->val = inst->prop.extradata_ctrls; diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 63ed34ed17f8..03079a37ee35 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -790,11 +790,10 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) core = inst->core; /* - * For a non-realtime session, extra buffers are not required. * For thumbnail session, extra buffers are not required as * neither dcvs nor batching will be enabled. */ - if (!is_realtime_session(inst) || is_thumbnail_session(inst)) + if (is_thumbnail_session(inst)) return extra_input_count; if (is_decode_session(inst)) { @@ -1350,13 +1349,15 @@ static inline u32 calculate_vpxd_scratch_size(struct msm_vidc_inst *inst, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) * VPX_DECODER_FRAME_CONCURENCY_LVL * VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_NUM / - VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_DEN, + VPX_DECODER_FRAME_BIN_HDR_BUDGET_RATIO_DEN / + num_vpp_pipes, VENUS_DMA_ALIGNMENT); binbuffer2_size = ALIGN(max_t(u32, size_yuv, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) * VPX_DECODER_FRAME_CONCURENCY_LVL * VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_NUM / - VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_DEN, + VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO_DEN / + num_vpp_pipes, VENUS_DMA_ALIGNMENT); size = binbuffer1_size + binbuffer2_size; size = size * num_vpp_pipes; diff --git a/msm/vidc/msm_vidc_buffer_calculations.h b/msm/vidc/msm_vidc_buffer_calculations.h index dce14310991e..e890db526660 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.h +++ b/msm/vidc/msm_vidc_buffer_calculations.h @@ -6,9 +6,9 @@ #ifndef __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ #define __H_MSM_VIDC_BUFFER_MEM_DEFS_H__ -/* extra o/p buffers in case of dcvs */ +/* extra buffers in case of dcvs */ #define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4 -#define DCVS_ENC_EXTRA_INPUT_BUFFERS DCVS_DEC_EXTRA_OUTPUT_BUFFERS +#define DCVS_ENC_EXTRA_INPUT_BUFFERS 4 struct msm_vidc_dec_buff_size_calculators { u32 (*calculate_scratch_size)(struct msm_vidc_inst *inst, u32 width, diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index c2db722ec8fd..0af709fe2d36 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -120,8 +120,8 @@ bool res_is_less_than_or_equal_to(u32 width, u32 height, u32 num_mbs = NUM_MBS_PER_FRAME(height, width); u32 max_side = max(ref_width, ref_height); - if (num_mbs <= NUM_MBS_PER_FRAME(ref_height, ref_width) || - width <= max_side || + if (num_mbs <= NUM_MBS_PER_FRAME(ref_height, ref_width) && + width <= max_side && height <= max_side) return true; else @@ -999,7 +999,8 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst) inst->clk_data.low_latency_mode || inst->batch.enable || is_turbo_session(inst) || - inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ); + inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ || + is_encode_batching(inst)); s_vpr_hp(inst->sid, "DCVS %s: %pK\n", inst->clk_data.dcvs_mode ? "enabled" : "disabled", inst); @@ -1007,6 +1008,53 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst) return 0; } +void msm_dcvs_reset(struct msm_vidc_inst *inst) +{ + struct msm_vidc_format *fmt; + struct clock_data *dcvs; + + if (!inst) { + d_vpr_e("%s: Invalid params\n", __func__); + return; + } + + dcvs = &inst->clk_data; + if (inst->session_type == MSM_VIDC_ENCODER) { + fmt = &inst->fmts[INPUT_PORT]; + } else if (inst->session_type == MSM_VIDC_DECODER) { + fmt = &inst->fmts[OUTPUT_PORT]; + } else { + s_vpr_e(inst->sid, "%s: invalid session type %#x\n", + __func__, inst->session_type); + return; + } + + dcvs->min_threshold = fmt->count_min; + if (inst->session_type == MSM_VIDC_ENCODER) + dcvs->max_threshold = + min((fmt->count_min + DCVS_ENC_EXTRA_INPUT_BUFFERS), + fmt->count_actual); + else + dcvs->max_threshold = + min((fmt->count_min + DCVS_DEC_EXTRA_OUTPUT_BUFFERS), + fmt->count_actual); + + dcvs->dcvs_window = + dcvs->max_threshold < dcvs->min_threshold ? 0 : + dcvs->max_threshold - dcvs->min_threshold; + dcvs->nom_threshold = dcvs->min_threshold + + (dcvs->dcvs_window ? + (dcvs->dcvs_window / 2) : 0); + + dcvs->dcvs_flags = 0; + + s_vpr_p(inst->sid, "DCVS: Th[%d %d %d] Flag %#x\n", + dcvs->min_threshold, + dcvs->nom_threshold, dcvs->max_threshold, + dcvs->dcvs_flags); + +} + int msm_comm_init_clocks_and_bus_data(struct msm_vidc_inst *inst) { int rc = 0, j = 0; @@ -1047,8 +1095,6 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) struct allowed_clock_rates_table *allowed_clks_tbl = NULL; u64 total_freq = 0, rate = 0, load; int cycles; - struct clock_data *dcvs; - struct msm_vidc_format *fmt; if (!inst || !inst->core || !inst->clk_data.entry) { d_vpr_e("%s: Invalid args: Inst = %pK\n", @@ -1058,35 +1104,14 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst) s_vpr_h(inst->sid, "Init DCVS Load\n"); core = inst->core; - dcvs = &inst->clk_data; load = msm_comm_get_inst_load_per_core(inst, LOAD_POWER); cycles = inst->clk_data.entry->vpp_cycles; allowed_clks_tbl = core->resources.allowed_clks_tbl; - if (inst->session_type == MSM_VIDC_ENCODER) { - cycles = inst->flags & VIDC_LOW_POWER ? - inst->clk_data.entry->low_power_cycles : - cycles; + if (inst->session_type == MSM_VIDC_ENCODER && + inst->flags & VIDC_LOW_POWER) + cycles = inst->clk_data.entry->low_power_cycles; - fmt = &inst->fmts[INPUT_PORT]; - } else if (inst->session_type == MSM_VIDC_DECODER) { - fmt = &inst->fmts[OUTPUT_PORT]; - } else { - s_vpr_e(inst->sid, "%s: invalid session type %#x\n", - __func__, inst->session_type); - return; - } - - dcvs->min_threshold = fmt->count_min; - dcvs->max_threshold = - min((fmt->count_min + DCVS_DEC_EXTRA_OUTPUT_BUFFERS), - fmt->count_actual); - - dcvs->dcvs_window = - dcvs->max_threshold < dcvs->min_threshold ? 0 : - dcvs->max_threshold - dcvs->min_threshold; - dcvs->nom_threshold = dcvs->min_threshold + - (dcvs->dcvs_window ? - (dcvs->dcvs_window / 2) : 0); + msm_dcvs_reset(inst); total_freq = cycles * load; diff --git a/msm/vidc/msm_vidc_clocks.h b/msm/vidc/msm_vidc_clocks.h index f32b370849d6..30a2d40a039f 100644 --- a/msm/vidc/msm_vidc_clocks.h +++ b/msm/vidc/msm_vidc_clocks.h @@ -8,6 +8,7 @@ #include "msm_vidc_internal.h" void msm_clock_data_reset(struct msm_vidc_inst *inst); +void msm_dcvs_reset(struct msm_vidc_inst *inst); int msm_vidc_set_clocks(struct msm_vidc_core *core, u32 sid); int msm_comm_vote_bus(struct msm_vidc_inst *inst); int msm_dcvs_try_enable(struct msm_vidc_inst *inst); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index c5a5f45aa3f0..652334c646c4 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1598,7 +1598,6 @@ static void handle_event_change(enum hal_command_response cmd, void *data) struct hfi_device *hdev; u32 *ptr = NULL; struct msm_vidc_format *fmt; - struct v4l2_format *f; u32 codec; if (!event_notify) { @@ -1650,11 +1649,12 @@ static void handle_event_change(enum hal_command_response cmd, void *data) inst->pic_struct == MSM_VIDC_PIC_STRUCT_MAYBE_INTERLACED)) event_fields_changed = true; - f = &inst->fmts[OUTPUT_PORT].v4l2_fmt; + fmt = &inst->fmts[OUTPUT_PORT]; event_fields_changed |= - (f->fmt.pix_mp.height != event_notify->height); + (fmt->v4l2_fmt.fmt.pix_mp.height != + event_notify->height); event_fields_changed |= - (f->fmt.pix_mp.width != event_notify->width); + (fmt->v4l2_fmt.fmt.pix_mp.width != event_notify->width); if (event_fields_changed) { event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT; @@ -1670,6 +1670,10 @@ static void handle_event_change(enum hal_command_response cmd, void *data) "%s: Failed to decide work mode\n", __func__); } + + fmt->count_min = event_notify->fw_min_cnt; + msm_dcvs_reset(inst); + s_vpr_h(inst->sid, "seq: No parameter change continue session\n"); rc = call_hfi_op(hdev, session_continue, @@ -2809,6 +2813,7 @@ bool is_batching_allowed(struct msm_vidc_inst *inst) { u32 op_pixelformat, fps, maxmbs, maxfps; u32 ignore_flags = VIDC_THUMBNAIL; + u32 enable = 0; if (!inst || !inst->core) return false; @@ -2827,17 +2832,23 @@ bool is_batching_allowed(struct msm_vidc_inst *inst) * as sufficient extra buffers (required for batch mode * on both ports) may not have been updated to client. */ - return (inst->batch.enable && + enable = (inst->batch.enable && inst->core->resources.decode_batching && !is_low_latency_hint(inst) && is_single_session(inst, ignore_flags) && is_decode_session(inst) && !is_thumbnail_session(inst) && + is_realtime_session(inst) && !inst->clk_data.low_latency_mode && (op_pixelformat == V4L2_PIX_FMT_NV12_UBWC || op_pixelformat == V4L2_PIX_FMT_NV12_TP10_UBWC) && fps <= maxfps && msm_vidc_get_mbs_per_frame(inst) <= maxmbs); + + s_vpr_hp(inst->sid, "%s: batching %s\n", + __func__, enable ? "enabled" : "disabled"); + + return enable; } static int msm_comm_session_abort(struct msm_vidc_inst *inst) @@ -4941,7 +4952,10 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst) for (i = 0; i < HAL_BUFFER_MAX; i++) { struct hal_buffer_requirements req = inst->buff_req.buffer[i]; - if (req.buffer_type != HAL_BUFFER_NONE) { + if (req.buffer_type != HAL_BUFFER_NONE && + req.buffer_type != HAL_BUFFER_INPUT && + req.buffer_type != HAL_BUFFER_OUTPUT && + req.buffer_type != HAL_BUFFER_OUTPUT2) { s_vpr_h(inst->sid, "%15s %8d %8d %8d %8d %8d\n", get_buffer_name(req.buffer_type), req.buffer_count_actual, @@ -5319,7 +5333,7 @@ int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) } int msm_comm_set_buffer_count(struct msm_vidc_inst *inst, - int host_count, int act_count, enum hal_buffer type) + int min_count, int act_count, enum hal_buffer type) { int rc = 0; struct v4l2_ctrl *ctrl; @@ -5334,20 +5348,22 @@ int msm_comm_set_buffer_count(struct msm_vidc_inst *inst, buf_count.buffer_type = get_hfi_buffer(type, inst->sid); buf_count.buffer_count_actual = act_count; - buf_count.buffer_count_min_host = host_count; + buf_count.buffer_count_min_host = min_count; /* set total superframe buffers count */ ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); if (ctrl->val) buf_count.buffer_count_actual = act_count * ctrl->val; - s_vpr_h(inst->sid, "%s: hal_buffer %d min_host %d actual %d\n", - __func__, type, host_count, act_count); + s_vpr_h(inst->sid, + "%s: hal_buffer %d min %d actual %d superframe %d\n", + __func__, type, min_count, + buf_count.buffer_count_actual, ctrl->val); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, &buf_count, sizeof(buf_count)); if (rc) s_vpr_e(inst->sid, "Failed to set actual buffer count %d for buffer type %d\n", - act_count, type); + buf_count.buffer_count_actual, type); return rc; } @@ -7584,7 +7600,8 @@ void msm_comm_release_timestamps(struct msm_vidc_inst *inst) mutex_unlock(&inst->timestamps.lock); } -int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) +int msm_comm_store_timestamp(struct msm_vidc_inst *inst, s64 timestamp_us, + bool is_eos) { struct msm_vidc_timestamps *entry, *node, *prev = NULL; struct msm_vidc_timestamps *duplicate; @@ -7602,7 +7619,8 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) duplicate = NULL; list_for_each_entry(node, &inst->timestamps.list, list) { count++; - if (node->timestamp_us == timestamp_us) + if (node->is_valid && node->timestamp_us == timestamp_us && + !node->is_eos) duplicate = node; } @@ -7633,6 +7651,7 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) entry->timestamp_us = duplicate->timestamp_us; entry->framerate = duplicate->framerate; entry->is_valid = true; + entry->is_eos = is_eos; /* add entry next to duplicate */ list_add(&entry->list, &duplicate->list); goto unlock; @@ -7645,7 +7664,8 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) prev = NULL; inserted = false; list_for_each_entry(node, &inst->timestamps.list, list) { - if (entry->timestamp_us < node->timestamp_us) { + if (entry->timestamp_us < node->timestamp_us && + !node->is_eos) { /* * if prev available add entry next to prev else * entry is first so add it at head. @@ -7672,7 +7692,8 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) node->timestamp_us, prev->timestamp_us); break; } - if (node->timestamp_us == entry->timestamp_us) { + if (node->timestamp_us == entry->timestamp_us && + !node->is_eos) { if (prev) node->framerate = msm_comm_calc_framerate(inst, node->timestamp_us, prev->timestamp_us); @@ -7681,6 +7702,12 @@ int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us) prev = node; } + /* mark all entries as eos if is_eos is queued */ + if (is_eos) + list_for_each_entry(node, &inst->timestamps.list, list) { + node->is_eos = true; + } + unlock: mutex_unlock(&inst->timestamps.lock); return rc; @@ -7767,8 +7794,8 @@ int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, if (!(b->flags & V4L2_BUF_FLAG_END_OF_SUBFRAME)) node->is_valid = false; - b->timestamp.tv_sec = node->timestamp_us / 1000000ull; - b->timestamp.tv_usec = node->timestamp_us % 1000000ull; + b->timestamp.tv_sec = node->timestamp_us / 1000000; + b->timestamp.tv_usec = node->timestamp_us % 1000000; b->m.planes[0].reserved[MSM_VIDC_FRAMERATE] = node->framerate; break; } diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 98287b8570e7..e46c5bbd9f62 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -59,6 +59,11 @@ static inline bool is_low_power_session(struct msm_vidc_inst *inst) return !!(inst->flags & VIDC_LOW_POWER); } +static inline bool is_cvp_supported(struct msm_vidc_inst *inst) +{ + return inst->core && !inst->core->resources.no_cvp; +} + static inline struct v4l2_ctrl *get_ctrl(struct msm_vidc_inst *inst, u32 id) { @@ -153,6 +158,17 @@ static inline bool is_encode_session(struct msm_vidc_inst *inst) return inst->session_type == MSM_VIDC_ENCODER; } +static inline bool is_encode_batching(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *ctrl; + + if (inst->session_type != MSM_VIDC_ENCODER) + return false; + + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_SUPERFRAME); + return !!ctrl->val; +} + static inline bool is_primary_output_mode(struct msm_vidc_inst *inst) { return inst->stream_output_mode == HAL_VIDEO_DECODER_PRIMARY; @@ -384,7 +400,8 @@ int msm_comm_set_cvp_skip_ratio(struct msm_vidc_inst *inst, uint32_t capture_rate, uint32_t cvp_rate); int msm_comm_fetch_ts_framerate(struct msm_vidc_inst *inst, struct v4l2_buffer *b); -int msm_comm_store_timestamp(struct msm_vidc_inst *inst, u64 timestamp_us); +int msm_comm_store_timestamp(struct msm_vidc_inst *inst, s64 timestamp_us, + bool is_eos); void msm_comm_release_timestamps(struct msm_vidc_inst *inst); u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst); u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, u64 timestamp_us, diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index cd2f35c46852..e04ac940ace2 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -236,9 +236,10 @@ struct msm_vidc_codec { struct msm_vidc_timestamps { struct list_head list; - u64 timestamp_us; + s64 timestamp_us; u32 framerate; bool is_valid; + bool is_eos; }; enum efuse_purpose { diff --git a/msm/vidc/msm_vidc_platform.c b/msm/vidc/msm_vidc_platform.c index f5ea2f69e633..259c13747682 100644 --- a/msm/vidc/msm_vidc_platform.c +++ b/msm/vidc/msm_vidc_platform.c @@ -72,12 +72,12 @@ static struct msm_vidc_codec_data bengal_codec_data[] = { }; static struct msm_vidc_codec_data shima_codec_data[] = { - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 0, 675, 320), - CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 0, 200, 200), - CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 0, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_ENCODER, 25, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_ENCODER, 25, 675, 320), + CODEC_ENTRY(V4L2_PIX_FMT_MPEG2, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_H264, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_HEVC, MSM_VIDC_DECODER, 25, 200, 200), + CODEC_ENTRY(V4L2_PIX_FMT_VP9, MSM_VIDC_DECODER, 60, 200, 200), }; static struct msm_vidc_codec_data holi_codec_data[] = { @@ -358,6 +358,16 @@ static struct msm_vidc_codec_capability lahaina_capabilities[] = { {CAP_FRAMERATE, DEC, MPEG2, 1, 30, 1, 30}, {CAP_BITRATE, DEC, MPEG2, 1, 40000000, 1, 20000000}, + /* VP9 decoder-specific */ + {CAP_FRAME_WIDTH, DEC, VP9, 96, 4096, 1, 1920}, + {CAP_FRAME_HEIGHT, DEC, VP9, 96, 4096, 1, 1080}, + /* (4096 * 2304) / 256 */ + {CAP_MBS_PER_FRAME, DEC, VP9, 36, 36864, 1, 36864}, + /* ((4096 * 2304) / 256) * 60*/ + {CAP_MBS_PER_SECOND, DEC, VP9, 36, 2211840, 1, 2211840}, + {CAP_FRAMERATE, DEC, VP9, 1, 60, 1, 60}, + {CAP_BITRATE, DEC, VP9, 1, 100000000, 1, 20000000}, + /* Secure usecase specific */ {CAP_SECURE_FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920}, {CAP_SECURE_FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080}, @@ -1398,6 +1408,10 @@ static struct msm_vidc_common_data holi_common_data[] = { .key = "qcom,fw-vpp-cycles", .value = 225975, }, + { + .key = "qcom,no-cvp", + .value = 1, + }, }; static struct msm_vidc_efuse_data shima_efuse_data[] = { @@ -1621,11 +1635,9 @@ void *vidc_get_drv_data(struct device *dev) goto exit; /* Check for sku version */ - if (of_find_property(dev->of_node, "sku-index", NULL)) { - rc = msm_vidc_read_efuse(driver_data, dev); - if (rc) - goto exit; - } + rc = msm_vidc_read_efuse(driver_data, dev); + if (rc) + goto exit; if (!strcmp(match->compatible, "qcom,lahaina-vidc")) { ddr_type = of_fdt_get_ddrtype(); diff --git a/msm/vidc/msm_vidc_res_parse.c b/msm/vidc/msm_vidc_res_parse.c index 0e14602d8f3d..1e17830ff333 100644 --- a/msm/vidc/msm_vidc_res_parse.c +++ b/msm/vidc/msm_vidc_res_parse.c @@ -813,6 +813,8 @@ int read_platform_resources_from_drv_data( "qcom,vpp_delay_supported"); res->enc_auto_dynamic_fps = find_key_value(platform_data, "qcom,enc_auto_dynamic_fps"); + res->no_cvp = find_key_value(platform_data, + "qcom,no-cvp"); res->csc_coeff_data = &platform_data->csc_data; diff --git a/msm/vidc/msm_vidc_resources.h b/msm/vidc/msm_vidc_resources.h index d7c8ee88b887..5add5ec54373 100644 --- a/msm/vidc/msm_vidc_resources.h +++ b/msm/vidc/msm_vidc_resources.h @@ -206,6 +206,7 @@ struct msm_vidc_platform_resources { uint32_t ubwc_stats_in_fbd; uint32_t has_vpp_delay; bool enc_auto_dynamic_fps; + bool no_cvp; }; static inline bool is_iommu_present(struct msm_vidc_platform_resources *res)