msm: vidc: Amend DCVS condition
Amend DCVS condition as follows
- Enable it for 1 encoder and 1 decoder concurent sessions.
- Remove low power dependency for encoder.
- Extra buffer count based on DCVS.
Also derive clock based on encoder load.
This change also reverts change @ commit b0b1581fc1
("msm: vidc: Use Dcvs only when there is no resolution change")
CRs-Fixed: 1050357
Change-Id: I3a15f830e52ee89ea81d0e450b68ef13970d0363
Signed-off-by: Praneeth Paladugu <ppaladug@codeaurora.org>
This commit is contained in:
parent
c605e110ab
commit
2b52593cea
6 changed files with 130 additions and 164 deletions
|
@ -2331,6 +2331,8 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
|
||||||
rc = -ENOTSUPP;
|
rc = -ENOTSUPP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msm_dcvs_try_enable(inst);
|
||||||
msm_comm_scale_clocks_and_bus(inst);
|
msm_comm_scale_clocks_and_bus(inst);
|
||||||
break;
|
break;
|
||||||
case V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_INPUT:
|
case V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_INPUT:
|
||||||
|
|
|
@ -1665,7 +1665,6 @@ static inline int msm_venc_power_save_mode_enable(struct msm_vidc_inst *inst)
|
||||||
goto fail_power_mode_set;
|
goto fail_power_mode_set;
|
||||||
}
|
}
|
||||||
inst->flags |= VIDC_LOW_POWER;
|
inst->flags |= VIDC_LOW_POWER;
|
||||||
msm_dcvs_enc_set_power_save_mode(inst, true);
|
|
||||||
dprintk(VIDC_INFO, "Power Save Mode set for inst: %pK\n", inst);
|
dprintk(VIDC_INFO, "Power Save Mode set for inst: %pK\n", inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2940,6 +2939,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msm_dcvs_try_enable(inst);
|
||||||
msm_comm_scale_clocks_and_bus(inst);
|
msm_comm_scale_clocks_and_bus(inst);
|
||||||
break;
|
break;
|
||||||
case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_BITSTREAM_RESTRICT:
|
case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_BITSTREAM_RESTRICT:
|
||||||
|
@ -3053,8 +3053,6 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
|
||||||
}
|
}
|
||||||
pdata = &venc_mode;
|
pdata = &venc_mode;
|
||||||
|
|
||||||
msm_dcvs_enc_set_power_save_mode(inst,
|
|
||||||
ctrl->val == V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE);
|
|
||||||
break;
|
break;
|
||||||
case V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS:
|
case V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS:
|
||||||
if (inst->fmts[CAPTURE_PORT]->fourcc != V4L2_PIX_FMT_HEVC) {
|
if (inst->fmts[CAPTURE_PORT]->fourcc != V4L2_PIX_FMT_HEVC) {
|
||||||
|
|
|
@ -1237,8 +1237,6 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
|
||||||
inst->prop.width[OUTPUT_PORT] = event_notify->width;
|
inst->prop.width[OUTPUT_PORT] = event_notify->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
inst->seqchanged_count++;
|
|
||||||
|
|
||||||
if (inst->session_type == MSM_VIDC_DECODER)
|
if (inst->session_type == MSM_VIDC_DECODER)
|
||||||
msm_dcvs_init_load(inst);
|
msm_dcvs_init_load(inst);
|
||||||
|
|
||||||
|
@ -2225,11 +2223,32 @@ void handle_cmd_response(enum hal_command_response cmd, void *data)
|
||||||
|
|
||||||
int msm_comm_scale_clocks(struct msm_vidc_core *core)
|
int msm_comm_scale_clocks(struct msm_vidc_core *core)
|
||||||
{
|
{
|
||||||
int num_mbs_per_sec =
|
int num_mbs_per_sec, enc_mbs_per_sec, dec_mbs_per_sec;
|
||||||
msm_comm_get_load(core, MSM_VIDC_ENCODER, LOAD_CALC_NO_QUIRKS) +
|
|
||||||
|
enc_mbs_per_sec =
|
||||||
|
msm_comm_get_load(core, MSM_VIDC_ENCODER, LOAD_CALC_NO_QUIRKS);
|
||||||
|
dec_mbs_per_sec =
|
||||||
msm_comm_get_load(core, MSM_VIDC_DECODER, LOAD_CALC_NO_QUIRKS);
|
msm_comm_get_load(core, MSM_VIDC_DECODER, LOAD_CALC_NO_QUIRKS);
|
||||||
|
|
||||||
|
if (enc_mbs_per_sec >= dec_mbs_per_sec) {
|
||||||
|
/*
|
||||||
|
* If Encoder load is higher, use that load. Encoder votes for higher
|
||||||
|
* clock. Since Encoder and Deocder run on parallel cores, this clock
|
||||||
|
* should suffice decoder usecases.
|
||||||
|
*/
|
||||||
|
num_mbs_per_sec = enc_mbs_per_sec;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* If Decoder load is higher, it's tricky to decide clock. Decoder
|
||||||
|
* higher load might results less clocks than Encoder smaller load.
|
||||||
|
* At this point driver doesn't know which clock to vote. Hence use
|
||||||
|
* total load.
|
||||||
|
*/
|
||||||
|
num_mbs_per_sec = enc_mbs_per_sec + dec_mbs_per_sec;
|
||||||
|
}
|
||||||
|
|
||||||
return msm_comm_scale_clocks_load(core, num_mbs_per_sec,
|
return msm_comm_scale_clocks_load(core, num_mbs_per_sec,
|
||||||
LOAD_CALC_NO_QUIRKS);
|
LOAD_CALC_NO_QUIRKS);
|
||||||
}
|
}
|
||||||
|
|
||||||
int msm_comm_scale_clocks_load(struct msm_vidc_core *core,
|
int msm_comm_scale_clocks_load(struct msm_vidc_core *core,
|
||||||
|
@ -4894,6 +4913,9 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!rc)
|
||||||
|
msm_dcvs_try_enable(inst);
|
||||||
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
if (inst->prop.width[CAPTURE_PORT] < capability->width.min ||
|
if (inst->prop.width[CAPTURE_PORT] < capability->width.min ||
|
||||||
inst->prop.height[CAPTURE_PORT] <
|
inst->prop.height[CAPTURE_PORT] <
|
||||||
|
@ -5203,6 +5225,7 @@ int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
|
||||||
msm_dcvs_init_load(inst);
|
msm_dcvs_init_load(inst);
|
||||||
}
|
}
|
||||||
msm_comm_scale_clocks_and_bus(inst);
|
msm_comm_scale_clocks_and_bus(inst);
|
||||||
|
msm_dcvs_try_enable(inst);
|
||||||
}
|
}
|
||||||
exit:
|
exit:
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -20,10 +20,19 @@
|
||||||
((__cur_mbpf) >= (__min_mbpf))
|
((__cur_mbpf) >= (__min_mbpf))
|
||||||
|
|
||||||
static bool msm_dcvs_check_supported(struct msm_vidc_inst *inst);
|
static bool msm_dcvs_check_supported(struct msm_vidc_inst *inst);
|
||||||
static bool msm_dcvs_enc_check(struct msm_vidc_inst *inst);
|
|
||||||
static int msm_dcvs_enc_scale_clocks(struct msm_vidc_inst *inst);
|
static int msm_dcvs_enc_scale_clocks(struct msm_vidc_inst *inst);
|
||||||
static int msm_dcvs_dec_scale_clocks(struct msm_vidc_inst *inst, bool fbd);
|
static int msm_dcvs_dec_scale_clocks(struct msm_vidc_inst *inst, bool fbd);
|
||||||
|
|
||||||
|
int msm_dcvs_try_enable(struct msm_vidc_inst *inst)
|
||||||
|
{
|
||||||
|
if (!inst) {
|
||||||
|
dprintk(VIDC_ERR, "%s: Invalid args: %p\n", __func__, inst);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
inst->dcvs_mode = msm_dcvs_check_supported(inst);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int msm_dcvs_get_mbs_per_frame(struct msm_vidc_inst *inst)
|
static inline int msm_dcvs_get_mbs_per_frame(struct msm_vidc_inst *inst)
|
||||||
{
|
{
|
||||||
int height, width;
|
int height, width;
|
||||||
|
@ -41,20 +50,27 @@ static inline int msm_dcvs_get_mbs_per_frame(struct msm_vidc_inst *inst)
|
||||||
return NUM_MBS_PER_FRAME(height, width);
|
return NUM_MBS_PER_FRAME(height, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int msm_dcvs_count_active_instances(struct msm_vidc_core *core)
|
static inline int msm_dcvs_count_active_instances(struct msm_vidc_core *core,
|
||||||
|
enum session_type session_type)
|
||||||
{
|
{
|
||||||
int active_instances = 0;
|
int active_instances = 0;
|
||||||
struct msm_vidc_inst *inst = NULL;
|
struct msm_vidc_inst *temp = NULL;
|
||||||
|
|
||||||
if (!core) {
|
if (!core) {
|
||||||
dprintk(VIDC_ERR, "%s: Invalid args: %pK\n", __func__, core);
|
dprintk(VIDC_ERR, "%s: Invalid args: %pK\n", __func__, core);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* DCVS condition is as following
|
||||||
|
* Decoder DCVS : Only for ONE decoder session.
|
||||||
|
* Encoder DCVS : Only for ONE encoder session + ONE decoder session
|
||||||
|
*/
|
||||||
mutex_lock(&core->lock);
|
mutex_lock(&core->lock);
|
||||||
list_for_each_entry(inst, &core->instances, list) {
|
list_for_each_entry(temp, &core->instances, list) {
|
||||||
if (inst->state >= MSM_VIDC_OPEN_DONE &&
|
if (temp->state >= MSM_VIDC_OPEN_DONE &&
|
||||||
inst->state < MSM_VIDC_STOP_DONE)
|
temp->state < MSM_VIDC_STOP_DONE &&
|
||||||
|
(temp->session_type == session_type ||
|
||||||
|
temp->session_type == MSM_VIDC_ENCODER))
|
||||||
active_instances++;
|
active_instances++;
|
||||||
}
|
}
|
||||||
mutex_unlock(&core->lock);
|
mutex_unlock(&core->lock);
|
||||||
|
@ -112,17 +128,12 @@ static void msm_dcvs_enc_check_and_scale_clocks(struct msm_vidc_inst *inst)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (inst->session_type == MSM_VIDC_ENCODER && msm_vidc_enc_dcvs_mode) {
|
if (inst->session_type == MSM_VIDC_ENCODER &&
|
||||||
inst->dcvs_mode = msm_dcvs_check_supported(inst);
|
msm_vidc_enc_dcvs_mode) {
|
||||||
dprintk(VIDC_DBG, "%s: session DCVS %s supported\n",
|
rc = msm_dcvs_enc_scale_clocks(inst);
|
||||||
__func__, inst->dcvs_mode ? "" : "not");
|
if (rc) {
|
||||||
|
dprintk(VIDC_DBG,
|
||||||
if (inst->dcvs_mode) {
|
|
||||||
rc = msm_dcvs_enc_scale_clocks(inst);
|
|
||||||
if (rc) {
|
|
||||||
dprintk(VIDC_DBG,
|
|
||||||
"ENC_DCVS: error while scaling clocks\n");
|
"ENC_DCVS: error while scaling clocks\n");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,28 +142,14 @@ static void msm_dcvs_dec_check_and_scale_clocks(struct msm_vidc_inst *inst)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (inst->session_type != MSM_VIDC_DECODER || !msm_vidc_dec_dcvs_mode)
|
if (inst->session_type == MSM_VIDC_DECODER &&
|
||||||
return;
|
msm_vidc_dec_dcvs_mode) {
|
||||||
|
|
||||||
if (msm_dcvs_check_supported(inst)) {
|
|
||||||
inst->dcvs_mode = true;
|
|
||||||
dprintk(VIDC_DBG,
|
|
||||||
"%s: session DCVS supported, decode_dcvs_mode = %d\n",
|
|
||||||
__func__, inst->dcvs_mode);
|
|
||||||
} else {
|
|
||||||
inst->dcvs_mode = false;
|
|
||||||
dprintk(VIDC_DBG,
|
|
||||||
"%s: session DCVS not supported, decode_dcvs_mode = %d\n",
|
|
||||||
__func__, inst->dcvs_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msm_vidc_dec_dcvs_mode && inst->dcvs_mode) {
|
|
||||||
msm_dcvs_monitor_buffer(inst);
|
msm_dcvs_monitor_buffer(inst);
|
||||||
rc = msm_dcvs_dec_scale_clocks(inst, false);
|
rc = msm_dcvs_dec_scale_clocks(inst, false);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
dprintk(VIDC_ERR,
|
dprintk(VIDC_ERR,
|
||||||
"%s: Failed to scale clocks in DCVS: %d\n",
|
"%s: Failed to scale clocks in DCVS: %d\n",
|
||||||
__func__, rc);
|
__func__, rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,6 +160,11 @@ void msm_dcvs_check_and_scale_clocks(struct msm_vidc_inst *inst, bool is_etb)
|
||||||
dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
|
dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
msm_dcvs_try_enable(inst);
|
||||||
|
if (!inst->dcvs_mode) {
|
||||||
|
dprintk(VIDC_DBG, "DCVS is not enabled\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_etb)
|
if (is_etb)
|
||||||
msm_dcvs_enc_check_and_scale_clocks(inst);
|
msm_dcvs_enc_check_and_scale_clocks(inst);
|
||||||
|
@ -531,48 +533,6 @@ static int msm_dcvs_dec_scale_clocks(struct msm_vidc_inst *inst, bool fbd)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool msm_dcvs_enc_check(struct msm_vidc_inst *inst)
|
|
||||||
{
|
|
||||||
int num_mbs_per_frame = 0;
|
|
||||||
long int instance_load = 0;
|
|
||||||
long int dcvs_limit = 0;
|
|
||||||
bool dcvs_check_passed = false, is_codec_supported = false;
|
|
||||||
struct msm_vidc_platform_resources *res = NULL;
|
|
||||||
|
|
||||||
if (!inst || !inst->core) {
|
|
||||||
dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
|
|
||||||
return dcvs_check_passed;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = &inst->core->resources;
|
|
||||||
if (!res->dcvs_limit) {
|
|
||||||
dprintk(VIDC_ERR,
|
|
||||||
"%s Dcvs limit table uninitialized\n", __func__);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
is_codec_supported =
|
|
||||||
msm_dcvs_check_codec_supported(
|
|
||||||
inst->fmts[CAPTURE_PORT]->fourcc,
|
|
||||||
inst->dcvs.supported_codecs,
|
|
||||||
inst->session_type);
|
|
||||||
|
|
||||||
num_mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
|
|
||||||
instance_load = msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS);
|
|
||||||
dcvs_limit =
|
|
||||||
(long int)res->dcvs_limit[inst->session_type].min_mbpf *
|
|
||||||
res->dcvs_limit[inst->session_type].fps;
|
|
||||||
|
|
||||||
if (msm_vidc_enc_dcvs_mode && is_codec_supported &&
|
|
||||||
inst->dcvs.is_power_save_mode &&
|
|
||||||
IS_VALID_DCVS_SESSION(num_mbs_per_frame,
|
|
||||||
res->dcvs_limit[inst->session_type].min_mbpf) &&
|
|
||||||
IS_VALID_DCVS_SESSION(instance_load, dcvs_limit)) {
|
|
||||||
dcvs_check_passed = true;
|
|
||||||
}
|
|
||||||
return dcvs_check_passed;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool msm_dcvs_check_supported(struct msm_vidc_inst *inst)
|
static bool msm_dcvs_check_supported(struct msm_vidc_inst *inst)
|
||||||
{
|
{
|
||||||
int num_mbs_per_frame = 0, instance_count = 0;
|
int num_mbs_per_frame = 0, instance_count = 0;
|
||||||
|
@ -583,6 +543,7 @@ static bool msm_dcvs_check_supported(struct msm_vidc_inst *inst)
|
||||||
struct hal_buffer_requirements *output_buf_req;
|
struct hal_buffer_requirements *output_buf_req;
|
||||||
struct dcvs_stats *dcvs;
|
struct dcvs_stats *dcvs;
|
||||||
bool is_codec_supported = false;
|
bool is_codec_supported = false;
|
||||||
|
bool is_dcvs_supported = true;
|
||||||
struct msm_vidc_platform_resources *res = NULL;
|
struct msm_vidc_platform_resources *res = NULL;
|
||||||
|
|
||||||
if (!inst || !inst->core || !inst->core->device) {
|
if (!inst || !inst->core || !inst->core->device) {
|
||||||
|
@ -599,104 +560,88 @@ static bool msm_dcvs_check_supported(struct msm_vidc_inst *inst)
|
||||||
"%s: dcvs limit table not found\n", __func__);
|
"%s: dcvs limit table not found\n", __func__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
instance_count = msm_dcvs_count_active_instances(core);
|
instance_count = msm_dcvs_count_active_instances(core,
|
||||||
|
inst->session_type);
|
||||||
|
num_mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
|
||||||
|
instance_load = msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS);
|
||||||
|
dcvs_limit =
|
||||||
|
(long int)res->dcvs_limit[inst->session_type].min_mbpf *
|
||||||
|
res->dcvs_limit[inst->session_type].fps;
|
||||||
|
inst->dcvs.extra_buffer_count = 0;
|
||||||
|
|
||||||
if (instance_count == 1 && inst->session_type == MSM_VIDC_DECODER &&
|
if (!IS_VALID_DCVS_SESSION(num_mbs_per_frame,
|
||||||
!msm_comm_turbo_session(inst)) {
|
res->dcvs_limit[inst->session_type].min_mbpf)) {
|
||||||
num_mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
|
inst->dcvs.extra_buffer_count = 0;
|
||||||
instance_load = msm_comm_get_inst_load(inst,
|
is_dcvs_supported = false;
|
||||||
LOAD_CALC_NO_QUIRKS);
|
goto dcvs_decision_done;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst->session_type == MSM_VIDC_DECODER) {
|
||||||
|
inst->dcvs.extra_buffer_count = DCVS_DEC_EXTRA_OUTPUT_BUFFERS;
|
||||||
output_buf_req = get_buff_req_buffer(inst,
|
output_buf_req = get_buff_req_buffer(inst,
|
||||||
msm_comm_get_hal_output_buffer(inst));
|
msm_comm_get_hal_output_buffer(inst));
|
||||||
dcvs_limit =
|
|
||||||
(long int)res->dcvs_limit[inst->session_type].min_mbpf *
|
|
||||||
res->dcvs_limit[inst->session_type].fps;
|
|
||||||
is_codec_supported =
|
|
||||||
msm_dcvs_check_codec_supported(
|
|
||||||
inst->fmts[OUTPUT_PORT]->fourcc,
|
|
||||||
inst->dcvs.supported_codecs,
|
|
||||||
inst->session_type);
|
|
||||||
if (!is_codec_supported ||
|
|
||||||
!IS_VALID_DCVS_SESSION(num_mbs_per_frame,
|
|
||||||
res->dcvs_limit[inst->session_type].min_mbpf) ||
|
|
||||||
!IS_VALID_DCVS_SESSION(instance_load, dcvs_limit) ||
|
|
||||||
inst->seqchanged_count > 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!output_buf_req) {
|
if (!output_buf_req) {
|
||||||
dprintk(VIDC_ERR,
|
dprintk(VIDC_ERR,
|
||||||
"%s: No buffer requirement for buffer type %x\n",
|
"%s: No buffer requirement for buffer type %x\n",
|
||||||
__func__, HAL_BUFFER_OUTPUT);
|
__func__, HAL_BUFFER_OUTPUT);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (instance_count == 1 &&
|
is_codec_supported =
|
||||||
inst->session_type == MSM_VIDC_ENCODER &&
|
msm_dcvs_check_codec_supported(
|
||||||
!msm_comm_turbo_session(inst)) {
|
inst->fmts[OUTPUT_PORT]->fourcc,
|
||||||
if (!msm_dcvs_enc_check(inst))
|
inst->dcvs.supported_codecs,
|
||||||
return false;
|
inst->session_type);
|
||||||
} else {
|
if (!is_codec_supported ||
|
||||||
/*
|
!msm_vidc_dec_dcvs_mode) {
|
||||||
* For multiple instance use case with 4K, clocks will be scaled
|
inst->dcvs.extra_buffer_count = 0;
|
||||||
* as per load in streamon, but the clocks may be scaled
|
is_dcvs_supported = false;
|
||||||
* down as DCVS is running for first playback instance
|
goto dcvs_decision_done;
|
||||||
* Rescaling the core clock for multiple instance use case
|
|
||||||
*/
|
|
||||||
if (!dcvs->is_clock_scaled) {
|
|
||||||
if (!msm_comm_scale_clocks(core)) {
|
|
||||||
dcvs->is_clock_scaled = true;
|
|
||||||
dprintk(VIDC_DBG,
|
|
||||||
"%s: Scaled clocks = %d\n",
|
|
||||||
__func__, dcvs->is_clock_scaled);
|
|
||||||
} else {
|
|
||||||
dprintk(VIDC_DBG,
|
|
||||||
"%s: Failed to Scale clocks. Perf might be impacted\n",
|
|
||||||
__func__);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*
|
if (msm_comm_turbo_session(inst) ||
|
||||||
* For multiple instance use case turn OFF DCVS algorithm
|
!IS_VALID_DCVS_SESSION(instance_load, dcvs_limit ||
|
||||||
* immediately
|
instance_count > 1))
|
||||||
*/
|
is_dcvs_supported = false;
|
||||||
|
}
|
||||||
|
if (inst->session_type == MSM_VIDC_ENCODER) {
|
||||||
|
inst->dcvs.extra_buffer_count = DCVS_ENC_EXTRA_OUTPUT_BUFFERS;
|
||||||
|
is_codec_supported =
|
||||||
|
msm_dcvs_check_codec_supported(
|
||||||
|
inst->fmts[CAPTURE_PORT]->fourcc,
|
||||||
|
inst->dcvs.supported_codecs,
|
||||||
|
inst->session_type);
|
||||||
|
if (!is_codec_supported ||
|
||||||
|
!msm_vidc_enc_dcvs_mode) {
|
||||||
|
inst->dcvs.extra_buffer_count = 0;
|
||||||
|
is_dcvs_supported = false;
|
||||||
|
goto dcvs_decision_done;
|
||||||
|
}
|
||||||
|
if (msm_comm_turbo_session(inst) ||
|
||||||
|
!IS_VALID_DCVS_SESSION(instance_load, dcvs_limit ||
|
||||||
|
instance_count > 1))
|
||||||
|
is_dcvs_supported = false;
|
||||||
|
}
|
||||||
|
dcvs_decision_done:
|
||||||
|
if (!is_dcvs_supported) {
|
||||||
|
msm_comm_scale_clocks(core);
|
||||||
if (instance_count > 1) {
|
if (instance_count > 1) {
|
||||||
mutex_lock(&core->lock);
|
mutex_lock(&core->lock);
|
||||||
list_for_each_entry(temp, &core->instances, list)
|
list_for_each_entry(temp, &core->instances, list)
|
||||||
temp->dcvs_mode = false;
|
temp->dcvs_mode = false;
|
||||||
mutex_unlock(&core->lock);
|
mutex_unlock(&core->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return is_dcvs_supported;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int msm_dcvs_get_extra_buff_count(struct msm_vidc_inst *inst)
|
int msm_dcvs_get_extra_buff_count(struct msm_vidc_inst *inst)
|
||||||
{
|
{
|
||||||
int extra_buffer = 0;
|
|
||||||
|
|
||||||
if (!inst) {
|
if (!inst) {
|
||||||
dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
|
dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst->session_type == MSM_VIDC_ENCODER) {
|
return inst->dcvs.extra_buffer_count;
|
||||||
if (msm_dcvs_enc_check(inst))
|
|
||||||
extra_buffer = DCVS_ENC_EXTRA_OUTPUT_BUFFERS;
|
|
||||||
} else if (inst->session_type == MSM_VIDC_DECODER) {
|
|
||||||
if (msm_dcvs_check_supported(inst))
|
|
||||||
extra_buffer = DCVS_DEC_EXTRA_OUTPUT_BUFFERS;
|
|
||||||
}
|
|
||||||
return extra_buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void msm_dcvs_enc_set_power_save_mode(struct msm_vidc_inst *inst,
|
|
||||||
bool is_power_save_mode)
|
|
||||||
{
|
|
||||||
if (!inst) {
|
|
||||||
dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
inst->dcvs.is_power_save_mode = is_power_save_mode;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -36,6 +36,5 @@ void msm_dcvs_init_load(struct msm_vidc_inst *inst);
|
||||||
void msm_dcvs_monitor_buffer(struct msm_vidc_inst *inst);
|
void msm_dcvs_monitor_buffer(struct msm_vidc_inst *inst);
|
||||||
void msm_dcvs_check_and_scale_clocks(struct msm_vidc_inst *inst, bool is_etb);
|
void msm_dcvs_check_and_scale_clocks(struct msm_vidc_inst *inst, bool is_etb);
|
||||||
int msm_dcvs_get_extra_buff_count(struct msm_vidc_inst *inst);
|
int msm_dcvs_get_extra_buff_count(struct msm_vidc_inst *inst);
|
||||||
void msm_dcvs_enc_set_power_save_mode(struct msm_vidc_inst *inst,
|
int msm_dcvs_try_enable(struct msm_vidc_inst *inst);
|
||||||
bool is_power_save_mode);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -204,9 +204,9 @@ struct dcvs_stats {
|
||||||
int load_high;
|
int load_high;
|
||||||
int min_threshold;
|
int min_threshold;
|
||||||
int max_threshold;
|
int max_threshold;
|
||||||
bool is_clock_scaled;
|
|
||||||
int etb_counter;
|
int etb_counter;
|
||||||
bool is_power_save_mode;
|
bool is_power_save_mode;
|
||||||
|
unsigned int extra_buffer_count;
|
||||||
u32 supported_codecs;
|
u32 supported_codecs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -279,7 +279,6 @@ struct msm_vidc_inst {
|
||||||
bool in_reconfig;
|
bool in_reconfig;
|
||||||
u32 reconfig_width;
|
u32 reconfig_width;
|
||||||
u32 reconfig_height;
|
u32 reconfig_height;
|
||||||
u32 seqchanged_count;
|
|
||||||
struct dentry *debugfs_root;
|
struct dentry *debugfs_root;
|
||||||
void *priv;
|
void *priv;
|
||||||
struct msm_vidc_debug debug;
|
struct msm_vidc_debug debug;
|
||||||
|
|
Loading…
Add table
Reference in a new issue