diff --git a/driver/variant/iris3/src/msm_vidc_power_iris3.c b/driver/variant/iris3/src/msm_vidc_power_iris3.c index 1faa08a4ae..18a08c65b0 100644 --- a/driver/variant/iris3/src/msm_vidc_power_iris3.c +++ b/driver/variant/iris3/src/msm_vidc_power_iris3.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "msm_vidc_power_iris3.h" @@ -213,6 +213,11 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size) if (fps >= 960) vsp_cycles += div_u64(vpp_cycles * 25, 100); + /* Add 25 percent extra for HEVC 10bit all intra use case */ + if (inst->iframe && is_hevc_10bit_decode_session(inst)) { + vsp_cycles += div_u64(vsp_cycles * 25, 100); + } + if (inst->codec == MSM_VIDC_VP9 && inst->capabilities->cap[STAGE].value == MSM_VIDC_STAGE_2 && @@ -228,11 +233,14 @@ u64 msm_vidc_calc_freq_iris3(struct msm_vidc_inst *inst, u32 data_size) freq = max(vpp_cycles, vsp_cycles); freq = max(freq, fw_cycles); - if (inst->codec != MSM_VIDC_AV1) { + if (inst->codec == MSM_VIDC_AV1 || + (inst->iframe && is_hevc_10bit_decode_session(inst))) { /* - * for non-AV1 codecs limit the frequency to NOM only - * index 0 is TURBO, index 1 is NOM clock rate + * for AV1 or HEVC 10bit and iframe case only allow TURBO and + * limit to NOM for all other cases */ + } else { + /* limit to NOM, index 0 is TURBO, index 1 is NOM clock rate */ if (core->resource->freq_set.count >= 2 && freq > core->resource->freq_set.freq_tbl[1].freq) freq = core->resource->freq_set.freq_tbl[1].freq; diff --git a/driver/variant/iris33/src/msm_vidc_power_iris33.c b/driver/variant/iris33/src/msm_vidc_power_iris33.c index e133799772..f5a775f151 100644 --- a/driver/variant/iris33/src/msm_vidc_power_iris33.c +++ b/driver/variant/iris33/src/msm_vidc_power_iris33.c @@ -212,6 +212,11 @@ u64 msm_vidc_calc_freq_iris33(struct msm_vidc_inst *inst, u32 data_size) if (fps >= 960) vsp_cycles += div_u64(vpp_cycles * 25, 100); + /* Add 25 percent extra for HEVC 10bit all intra use case */ + if (inst->iframe && is_hevc_10bit_decode_session(inst)) { + vsp_cycles += div_u64(vsp_cycles * 25, 100); + } + if (inst->codec == MSM_VIDC_VP9 && inst->capabilities->cap[STAGE].value == MSM_VIDC_STAGE_2 && @@ -227,11 +232,14 @@ u64 msm_vidc_calc_freq_iris33(struct msm_vidc_inst *inst, u32 data_size) freq = max(vpp_cycles, vsp_cycles); freq = max(freq, fw_cycles); - if (inst->codec != MSM_VIDC_AV1) { + if (inst->codec == MSM_VIDC_AV1 || + (inst->iframe && is_hevc_10bit_decode_session(inst))) { /* - * for non-AV1 codecs limit the frequency to NOM only - * index 0 is TURBO, index 1 is NOM clock rate + * for AV1 or HEVC 10bit and iframe case only allow TURBO and + * limit to NOM for all other cases */ + } else { + /* limit to NOM, index 0 is TURBO, index 1 is NOM clock rate */ if (core->resource->freq_set.count >= 2 && freq > core->resource->freq_set.freq_tbl[1].freq) freq = core->resource->freq_set.freq_tbl[1].freq; diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index d12f909b53..0b93025bde 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2020-2021,, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _MSM_VIDC_DRIVER_H_ @@ -577,6 +578,7 @@ bool res_is_less_than(u32 width, u32 height, u32 ref_width, u32 ref_height); bool res_is_less_than_or_equal_to(u32 width, u32 height, u32 ref_width, u32 ref_height); +bool is_hevc_10bit_decode_session(struct msm_vidc_inst *inst); int signal_session_msg_receipt(struct msm_vidc_inst *inst, enum signal_session_response cmd); int msm_vidc_get_properties(struct msm_vidc_inst *inst); diff --git a/driver/vidc/inc/msm_vidc_inst.h b/driver/vidc/inc/msm_vidc_inst.h index 71d674433e..9da4473236 100644 --- a/driver/vidc/inc/msm_vidc_inst.h +++ b/driver/vidc/inc/msm_vidc_inst.h @@ -181,5 +181,6 @@ struct msm_vidc_inst { bool has_bframe; bool ir_enabled; u32 adjust_priority; + bool iframe; }; #endif // _MSM_VIDC_INST_H_ diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index e4e3c7063e..aa152d55bb 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -901,6 +901,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type) inst->ipsc_properties_set = false; inst->opsc_properties_set = false; inst->has_bframe = false; + inst->iframe = false; inst->auto_framerate = DEFAULT_FPS << 16; inst->initial_time_us = ktime_get_ns() / 1000; kref_init(&inst->kref); diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index cf5bb73af4..15d4a873c7 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -1761,6 +1761,22 @@ bool msm_vidc_allow_psc_last_flag(struct msm_vidc_inst *inst) return false; } +bool is_hevc_10bit_decode_session(struct msm_vidc_inst *inst) +{ + bool is10bit = false; + enum msm_vidc_colorformat_type colorformat; + + colorformat = v4l2_colorformat_to_driver(inst, + inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat, __func__); + + if (colorformat == MSM_VIDC_FMT_TP10C || colorformat == MSM_VIDC_FMT_P010) + is10bit = true; + + return inst->domain == MSM_VIDC_DECODER && + inst->codec == MSM_VIDC_HEVC && + is10bit; +} + int msm_vidc_state_change_streamon(struct msm_vidc_inst *inst, enum msm_vidc_port_type port) { diff --git a/driver/vidc/src/venus_hfi_response.c b/driver/vidc/src/venus_hfi_response.c index c15ba27f2d..63d07918e4 100644 --- a/driver/vidc/src/venus_hfi_response.c +++ b/driver/vidc/src/venus_hfi_response.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1661,6 +1662,10 @@ static int handle_property_with_payload(struct msm_vidc_inst *inst, inst->hfi_frame_info.picture_type = payload_ptr[0]; if (inst->hfi_frame_info.picture_type & HFI_PICTURE_B) inst->has_bframe = true; + if (inst->hfi_frame_info.picture_type & HFI_PICTURE_IDR) + inst->iframe = true; + else + inst->iframe = false; break; case HFI_PROP_SUBFRAME_INPUT: if (port != INPUT_PORT) {