/* Copyright (c) 2014-2016, 2018 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include "msm_vidc_common.h"
#include "vidc_hfi_api.h"
#include "msm_vidc_debug.h"
#include "msm_vidc_dcvs.h"

#define IS_VALID_DCVS_SESSION(__cur_mbpf, __min_mbpf) \
		((__cur_mbpf) >= (__min_mbpf))

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_dec_scale_clocks(struct msm_vidc_inst *inst, bool fbd);

static inline int msm_dcvs_get_mbs_per_frame(struct msm_vidc_inst *inst)
{
	int height, width;

	if (!inst->in_reconfig) {
		height = max(inst->prop.height[CAPTURE_PORT],
				inst->prop.height[OUTPUT_PORT]);
		width = max(inst->prop.width[CAPTURE_PORT],
				inst->prop.width[OUTPUT_PORT]);
	} else {
		height = inst->reconfig_height;
		width = inst->reconfig_width;
	}

	return NUM_MBS_PER_FRAME(height, width);
}

static inline int msm_dcvs_count_active_instances(struct msm_vidc_core *core)
{
	int active_instances = 0;
	struct msm_vidc_inst *inst = NULL;

	if (!core) {
		dprintk(VIDC_ERR, "%s: Invalid args: %pK\n", __func__, core);
		return -EINVAL;
	}

	mutex_lock(&core->lock);
	list_for_each_entry(inst, &core->instances, list) {
		if (inst->state >= MSM_VIDC_OPEN_DONE &&
			inst->state < MSM_VIDC_STOP_DONE)
			active_instances++;
	}
	mutex_unlock(&core->lock);
	return active_instances;
}

static bool msm_dcvs_check_codec_supported(int fourcc,
		unsigned long codecs_supported, enum session_type type)
{
	int codec_bit, session_type_bit;
	bool codec_type, session_type;
	unsigned long session;

	session = VIDC_VOTE_DATA_SESSION_VAL(get_hal_codec(fourcc),
		get_hal_domain(type));

	if (!codecs_supported || !session)
		return false;

	/* ffs returns a 1 indexed, test_bit takes a 0 indexed...index */
	codec_bit = ffs(session) - 1;
	session_type_bit = codec_bit + 1;

	codec_type =
		test_bit(codec_bit, &codecs_supported) ==
		test_bit(codec_bit, &session);
	session_type =
		test_bit(session_type_bit, &codecs_supported) ==
		test_bit(session_type_bit, &session);

	return codec_type && session_type;
}

static void msm_dcvs_update_dcvs_params(int idx, struct msm_vidc_inst *inst)
{
	struct dcvs_stats *dcvs = NULL;
	struct msm_vidc_platform_resources *res = NULL;
	struct dcvs_table *table = NULL;

	if (!inst || !inst->core) {
		dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
		return;
	}

	dcvs = &inst->dcvs;
	res = &inst->core->resources;
	table = res->dcvs_tbl;

	dcvs->load_low = table[idx].load_low;
	dcvs->load_high = table[idx].load_high;
	dcvs->supported_codecs = table[idx].supported_codecs;
}

static void msm_dcvs_enc_check_and_scale_clocks(struct msm_vidc_inst *inst)
{
	int rc = 0;

	if (inst->session_type == MSM_VIDC_ENCODER && msm_vidc_enc_dcvs_mode) {
		inst->dcvs_mode = msm_dcvs_check_supported(inst);
		dprintk(VIDC_DBG, "%s: session DCVS %s supported\n",
				__func__, inst->dcvs_mode ? "" : "not");

		if (inst->dcvs_mode) {
			rc = msm_dcvs_enc_scale_clocks(inst);
			if (rc) {
				dprintk(VIDC_DBG,
				"ENC_DCVS: error while scaling clocks\n");
			}
		}
	}
}

static void msm_dcvs_dec_check_and_scale_clocks(struct msm_vidc_inst *inst)
{
	int rc = 0;

	if (inst->session_type != MSM_VIDC_DECODER || !msm_vidc_dec_dcvs_mode)
		return;

	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);
		rc = msm_dcvs_dec_scale_clocks(inst, false);
		if (rc) {
			dprintk(VIDC_ERR,
				"%s: Failed to scale clocks in DCVS: %d\n",
				__func__, rc);
		}
	}
}

void msm_dcvs_check_and_scale_clocks(struct msm_vidc_inst *inst, bool is_etb)
{
	if (!inst) {
		dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
		return;
	}

	if (is_etb)
		msm_dcvs_enc_check_and_scale_clocks(inst);
	else
		msm_dcvs_dec_check_and_scale_clocks(inst);
}

static inline int get_pending_bufs_fw(struct msm_vidc_inst *inst)
{
	int fw_out_qsize = 0, buffers_in_driver = 0;

	if (!inst) {
		dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
		return -EINVAL;
	}

	if (inst->state >= MSM_VIDC_OPEN_DONE &&
		inst->state < MSM_VIDC_STOP_DONE) {
		fw_out_qsize = inst->count.ftb - inst->count.fbd;
		buffers_in_driver = inst->buffers_held_in_driver;
	}

	return fw_out_qsize + buffers_in_driver;
}

static inline void msm_dcvs_print_dcvs_stats(struct dcvs_stats *dcvs)
{
	dprintk(VIDC_DBG,
		"DCVS: Load_Low %d, Load High %d\n",
		dcvs->load_low,
		dcvs->load_high);

	dprintk(VIDC_DBG,
		"DCVS: ThrDispBufLow %d, ThrDispBufHigh %d\n",
		dcvs->threshold_disp_buf_low,
		dcvs->threshold_disp_buf_high);

	dprintk(VIDC_DBG,
		"DCVS: min_threshold %d, max_threshold %d\n",
		dcvs->min_threshold, dcvs->max_threshold);
}

void msm_dcvs_init_load(struct msm_vidc_inst *inst)
{
	struct msm_vidc_core *core;
	struct hal_buffer_requirements *output_buf_req;
	struct dcvs_stats *dcvs;
	struct dcvs_table *table;
	struct msm_vidc_platform_resources *res = NULL;
	int i, num_rows, fourcc;

	dprintk(VIDC_DBG, "Init DCVS Load\n");

	if (!inst || !inst->core) {
		dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
		return;
	}

	core = inst->core;
	dcvs = &inst->dcvs;
	res = &core->resources;
	dcvs->load = msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS);

	num_rows = res->dcvs_tbl_size;
	table = res->dcvs_tbl;

	if (!num_rows || !table) {
		dprintk(VIDC_ERR,
				"%s: Dcvs table entry not found.\n", __func__);
		return;
	}

	fourcc = inst->session_type == MSM_VIDC_DECODER ?
				inst->fmts[OUTPUT_PORT].fourcc :
				inst->fmts[CAPTURE_PORT].fourcc;

	for (i = 0; i < num_rows; i++) {
		bool matches = msm_dcvs_check_codec_supported(
					fourcc,
					table[i].supported_codecs,
					inst->session_type);
		if (!matches)
			continue;

		if (dcvs->load > table[i].load) {
			msm_dcvs_update_dcvs_params(i, inst);
			break;
		}
	}

	if (inst->session_type == MSM_VIDC_ENCODER)
		goto print_stats;

	output_buf_req = get_buff_req_buffer(inst,
		msm_comm_get_hal_output_buffer(inst));

	if (!output_buf_req) {
		dprintk(VIDC_ERR,
			"%s: No buffer requirement for buffer type %x\n",
			__func__, HAL_BUFFER_OUTPUT);
		return;
	}

	dcvs->transition_turbo = false;

	/* calculating the min and max threshold */
	if (output_buf_req->buffer_count_actual) {
		dcvs->min_threshold = output_buf_req->buffer_count_actual -
			output_buf_req->buffer_count_min -
			msm_dcvs_get_extra_buff_count(inst) + 1;
		dcvs->max_threshold = output_buf_req->buffer_count_actual;
		if (dcvs->max_threshold <= dcvs->min_threshold)
			dcvs->max_threshold =
				dcvs->min_threshold + DCVS_BUFFER_SAFEGUARD;
		dcvs->threshold_disp_buf_low = dcvs->min_threshold;
		dcvs->threshold_disp_buf_high = dcvs->max_threshold;
	}

print_stats:
	msm_dcvs_print_dcvs_stats(dcvs);
}

void msm_dcvs_init(struct msm_vidc_inst *inst)
{
	dprintk(VIDC_DBG, "Init DCVS Struct\n");

	if (!inst) {
		dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
		return;
	}

	inst->dcvs = (struct dcvs_stats){ {0} };
	inst->dcvs.threshold_disp_buf_high = DCVS_NOMINAL_THRESHOLD;
	inst->dcvs.threshold_disp_buf_low = DCVS_TURBO_THRESHOLD;
}

void msm_dcvs_monitor_buffer(struct msm_vidc_inst *inst)
{
	int new_ftb, i, prev_buf_count;
	int fw_pending_bufs, total_output_buf, buffers_outside_fw;
	struct dcvs_stats *dcvs;
	struct hal_buffer_requirements *output_buf_req;

	if (!inst) {
		dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
		return;
	}
	dcvs = &inst->dcvs;

	mutex_lock(&inst->lock);
	output_buf_req = get_buff_req_buffer(inst,
				msm_comm_get_hal_output_buffer(inst));
	if (!output_buf_req) {
		dprintk(VIDC_ERR, "%s : Get output buffer req failed %pK\n",
			__func__, inst);
		mutex_unlock(&inst->lock);
		return;
	}

	total_output_buf = output_buf_req->buffer_count_actual;
	fw_pending_bufs = get_pending_bufs_fw(inst);
	mutex_unlock(&inst->lock);

	buffers_outside_fw = total_output_buf - fw_pending_bufs;
	dcvs->num_ftb[dcvs->ftb_index] = buffers_outside_fw;
	dcvs->ftb_index = (dcvs->ftb_index + 1) % DCVS_FTB_WINDOW;

	if (dcvs->ftb_counter < DCVS_FTB_WINDOW)
		dcvs->ftb_counter++;

	dprintk(VIDC_PROF,
		"DCVS: ftb_counter %d\n", dcvs->ftb_counter);

	if (dcvs->ftb_counter == DCVS_FTB_WINDOW) {
		new_ftb = 0;
		for (i = 0; i < dcvs->ftb_counter; i++) {
			if (dcvs->num_ftb[i] > new_ftb)
				new_ftb = dcvs->num_ftb[i];
		}

		dcvs->threshold_disp_buf_high = new_ftb;
		if (dcvs->threshold_disp_buf_high <=
			dcvs->threshold_disp_buf_low +
			DCVS_BUFFER_SAFEGUARD) {
			dcvs->threshold_disp_buf_high =
				dcvs->threshold_disp_buf_low +
				DCVS_BUFFER_SAFEGUARD
				+ (DCVS_BUFFER_SAFEGUARD == 0);
		}

		dcvs->threshold_disp_buf_high =
			clamp(dcvs->threshold_disp_buf_high,
				dcvs->min_threshold,
				dcvs->max_threshold);
	}

	if (dcvs->ftb_counter == DCVS_FTB_WINDOW &&
			dcvs->load == dcvs->load_low) {
		prev_buf_count =
			dcvs->num_ftb[((dcvs->ftb_index - 2 +
				DCVS_FTB_WINDOW) % DCVS_FTB_WINDOW)];
		if (prev_buf_count == dcvs->threshold_disp_buf_low &&
			buffers_outside_fw <= dcvs->threshold_disp_buf_low) {
			dcvs->transition_turbo = true;
		} else if (buffers_outside_fw > dcvs->threshold_disp_buf_low &&
			(buffers_outside_fw -
			 (prev_buf_count - buffers_outside_fw))
			< dcvs->threshold_disp_buf_low){
			dcvs->transition_turbo = true;
		}
	}

	dprintk(VIDC_PROF,
		"DCVS: total_output_buf %d buffers_outside_fw %d load %d transition_turbo %d\n",
		total_output_buf, buffers_outside_fw, dcvs->load_low,
		dcvs->transition_turbo);
}

static int msm_dcvs_enc_scale_clocks(struct msm_vidc_inst *inst)
{
	int rc = 0, fw_pending_bufs = 0, total_input_buf = 0;
	struct msm_vidc_core *core;
	struct dcvs_stats *dcvs;

	if (!inst || !inst->core || !inst->core->device) {
		dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
		return -EINVAL;
	}

	core = inst->core;
	dcvs = &inst->dcvs;

	mutex_lock(&inst->lock);
	total_input_buf = inst->buff_req.buffer[0].buffer_count_actual;
	fw_pending_bufs = (inst->count.etb - inst->count.ebd);
	mutex_unlock(&inst->lock);

	dprintk(VIDC_PROF,
		"DCVS: total_input_buf %d, fw_pending_bufs %d\n",
		total_input_buf, fw_pending_bufs);

	if (dcvs->etb_counter < total_input_buf) {
		dcvs->etb_counter++;
		if (dcvs->etb_counter != total_input_buf)
			return rc;
	}

	dprintk(VIDC_PROF,
		"DCVS: total_input_buf %d, fw_pending_bufs %d etb_counter %d  dcvs->load %d\n",
		total_input_buf, fw_pending_bufs,
		dcvs->etb_counter, dcvs->load);

	if (fw_pending_bufs <= DCVS_ENC_LOW_THR &&
		dcvs->load > dcvs->load_low) {
		dcvs->load = dcvs->load_low;
		dcvs->prev_freq_lowered = true;
	} else {
		dcvs->prev_freq_lowered = false;
	}

	if (fw_pending_bufs >= DCVS_ENC_HIGH_THR &&
		dcvs->load <= dcvs->load_low) {
		dcvs->load = dcvs->load_high;
		dcvs->prev_freq_increased = true;
	} else {
		dcvs->prev_freq_increased = false;
	}

	if (dcvs->prev_freq_lowered || dcvs->prev_freq_increased) {
		dprintk(VIDC_PROF,
			"DCVS: (Scaling Clock %s)  etb clock set = %d total_input_buf = %d fw_pending_bufs %d\n",
			dcvs->prev_freq_lowered ? "Lower" : "Higher",
			dcvs->load, total_input_buf, fw_pending_bufs);

		rc = msm_comm_scale_clocks_load(core, dcvs->load,
				LOAD_CALC_NO_QUIRKS);
		if (rc) {
			dprintk(VIDC_PROF,
				"Failed to set clock rate in FBD: %d\n", rc);
		}
	} else {
		dprintk(VIDC_PROF,
			"DCVS: etb clock load_old = %d total_input_buf = %d fw_pending_bufs %d\n",
			dcvs->load, total_input_buf, fw_pending_bufs);
	}

	return rc;
}


/*
 * In DCVS scale_clocks will be done both in qbuf and FBD
 * 1 indicates call made from fbd that lowers clock
 * 0 indicates call made from qbuf that increases clock
 * based on DCVS algorithm
 */

static int msm_dcvs_dec_scale_clocks(struct msm_vidc_inst *inst, bool fbd)
{
	int rc = 0;
	int fw_pending_bufs = 0;
	int total_output_buf = 0;
	int buffers_outside_fw = 0;
	struct msm_vidc_core *core;
	struct hal_buffer_requirements *output_buf_req;
	struct dcvs_stats *dcvs;

	if (!inst || !inst->core || !inst->core->device) {
		dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
		return -EINVAL;
	}
	core = inst->core;
	dcvs = &inst->dcvs;
	mutex_lock(&inst->lock);
	fw_pending_bufs = get_pending_bufs_fw(inst);

	output_buf_req = get_buff_req_buffer(inst,
		msm_comm_get_hal_output_buffer(inst));
	mutex_unlock(&inst->lock);
	if (!output_buf_req) {
		dprintk(VIDC_ERR,
			"%s: No buffer requirement for buffer type %x\n",
			__func__, HAL_BUFFER_OUTPUT);
		return -EINVAL;
	}

	/* Total number of output buffers */
	total_output_buf = output_buf_req->buffer_count_actual;

	/* Buffers outside FW are with display */
	buffers_outside_fw = total_output_buf - fw_pending_bufs;

	if (buffers_outside_fw >= dcvs->threshold_disp_buf_high &&
		!dcvs->prev_freq_increased &&
		dcvs->load > dcvs->load_low) {
		dcvs->load = dcvs->load_low;
		dcvs->prev_freq_lowered = true;
		dcvs->prev_freq_increased = false;
	} else if (dcvs->transition_turbo && dcvs->load == dcvs->load_low) {
		dcvs->load = dcvs->load_high;
		dcvs->prev_freq_increased = true;
		dcvs->prev_freq_lowered = false;
		dcvs->transition_turbo = false;
	} else {
		dcvs->prev_freq_increased = false;
		dcvs->prev_freq_lowered = false;
	}

	if (dcvs->prev_freq_lowered || dcvs->prev_freq_increased) {
		dprintk(VIDC_PROF,
			"DCVS: clock set = %d tot_output_buf = %d buffers_outside_fw %d threshold_high %d transition_turbo %d\n",
			dcvs->load, total_output_buf, buffers_outside_fw,
			dcvs->threshold_disp_buf_high, dcvs->transition_turbo);

		rc = msm_comm_scale_clocks_load(core, dcvs->load,
				LOAD_CALC_NO_QUIRKS);
		if (rc) {
			dprintk(VIDC_ERR,
				"Failed to set clock rate in FBD: %d\n", rc);
		}
	} else {
		dprintk(VIDC_PROF,
			"DCVS: clock old = %d tot_output_buf = %d buffers_outside_fw %d threshold_high %d transition_turbo %d\n",
			dcvs->load, total_output_buf, buffers_outside_fw,
			dcvs->threshold_disp_buf_high, dcvs->transition_turbo);
	}
	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)
{
	int num_mbs_per_frame = 0, instance_count = 0;
	long int instance_load = 0;
	long int dcvs_limit = 0;
	struct msm_vidc_inst *temp = NULL;
	struct msm_vidc_core *core;
	struct hal_buffer_requirements *output_buf_req;
	struct dcvs_stats *dcvs;
	bool is_codec_supported = false;
	struct msm_vidc_platform_resources *res = NULL;

	if (!inst || !inst->core || !inst->core->device) {
		dprintk(VIDC_WARN, "%s: Invalid parameter\n", __func__);
		return -EINVAL;
	}

	core = inst->core;
	dcvs = &inst->dcvs;
	res = &core->resources;

	if (!res->dcvs_limit) {
		dprintk(VIDC_WARN,
				"%s: dcvs limit table not found\n", __func__);
		return false;
	}
	instance_count = msm_dcvs_count_active_instances(core);

	if (instance_count == 1 && inst->session_type == MSM_VIDC_DECODER &&
		!msm_comm_turbo_session(inst)) {
		num_mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
		instance_load = msm_comm_get_inst_load(inst,
			LOAD_CALC_NO_QUIRKS);
		output_buf_req = get_buff_req_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) {
			dprintk(VIDC_ERR,
				"%s: No buffer requirement for buffer type %x\n",
				__func__, HAL_BUFFER_OUTPUT);
			return false;
		}
	} else if (instance_count == 1 &&
			inst->session_type == MSM_VIDC_ENCODER &&
			!msm_comm_turbo_session(inst)) {
		if (!msm_dcvs_enc_check(inst))
			return false;
	} else {
		/*
		 * For multiple instance use case with 4K, clocks will be scaled
		 * as per load in streamon, but the clocks may be scaled
		 * down as DCVS is running for first playback instance
		 * 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__);
			}
		}
		/*
		 * For multiple instance use case turn OFF DCVS algorithm
		 * immediately
		 */
		if (instance_count > 1) {
			mutex_lock(&core->lock);
			list_for_each_entry(temp, &core->instances, list)
				temp->dcvs_mode = false;
			mutex_unlock(&core->lock);
		}

		return false;
	}

	return true;
}

int msm_dcvs_get_extra_buff_count(struct msm_vidc_inst *inst)
{
	int extra_buffer = 0;

	if (!inst) {
		dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
		return 0;
	}

	if (inst->session_type == MSM_VIDC_ENCODER) {
		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;
}
