Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e788af49 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Add support for runtime input CR"

parents b227c6d8 7722b4e0
Loading
Loading
Loading
Loading
+105 −138
Original line number Diff line number Diff line
@@ -565,32 +565,21 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d,
	 */
	/* Encoder Parameters */

	enum hal_video_codec standard;
	int width, height, fps;
	enum hal_uncompressed_format dpb_color_format;
	enum hal_uncompressed_format original_color_format;
	int width, height, fps, dpb_bpp, lcu_per_frame, lcu_size,
		vertical_tile_width, colocated_bytes_per_lcu, bitrate,
		ref_overlap_bw_factor;
	enum hal_uncompressed_format dpb_color_format, original_color_format;
	bool dpb_compression_enabled, original_compression_enabled,
		two_stage_encoding, low_power, rotation, cropping_or_scaling;
		work_mode_1, low_power, rotation, cropping_or_scaling,
		b_frames_enabled = false;
	fp_t dpb_compression_factor, original_compression_factor,
		qsmmu_bw_overhead_factor;
	bool b_frames_enabled;

	/* Derived Parameters */
	int lcu_size;
	enum gop {
		GOP_IBBP,
		GOP_IPPP,
	} gop;
	unsigned long bitrate;
	fp_t bins_to_bit_factor, chroma_luma_factor_dpb, one_frame_bw_dpb,
		 chroma_luma_factor_original, one_frame_bw_original,
		 line_buffer_size_per_lcu, line_buffer_size, line_buffer_bw,
		 bw_increase_p, bw_increase_b;
	int collocated_mv_per_lcu, max_transaction_size,
		search_window_size_vertical_p, search_window_factor_p,
		search_window_factor_bw_p,
		search_window_size_vertical_b, search_window_factor_b,
		search_window_factor_bw_b;
		input_compression_factor, qsmmu_bw_overhead_factor,
		ref_y_bw_factor, ref_cb_cr_bw_factor, ten_bpc_bpp_factor,
		bw_for_1x_8bpc, dpb_bw_for_1x, ref_cb_cr_read,
		bins_to_bit_factor, ref_y_read,	ten_bpc_packing_factor,
		dpb_write_factor, ref_overlap_bw;
	fp_t integer_part, frac_part;
	unsigned long ret = 0;

	/* Output paramaters */
	struct {
@@ -599,27 +588,41 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d,
			original_write, dpb_read, dpb_write, total;
	} ddr = {0};

	unsigned long ret = 0;
	fp_t integer_part, frac_part;

	/* Encoder Parameters setup */
	ten_bpc_packing_factor = FP(1, 67, 1000);
	ten_bpc_bpp_factor = FP(1, 1, 4);
	rotation = false;
	cropping_or_scaling = false;
	vertical_tile_width = 960;
	ref_y_bw_factor = FP(1, 30, 100);
	ref_cb_cr_bw_factor = FP(1, 50, 100);
	dpb_write_factor = FP(1, 8, 100);

	standard = d->codec;

	/* Derived Parameters */
	lcu_size = d->lcu_size;
	fps = d->fps;
	b_frames_enabled = d->b_frames_enabled;
	width = max(d->input_width, BASELINE_DIMENSIONS.width);
	height = max(d->input_height, BASELINE_DIMENSIONS.height);
	bitrate = __lut(width, height, fps)->bitrate;
	lcu_per_frame = DIV_ROUND_UP(width, lcu_size) *
		DIV_ROUND_UP(height, lcu_size);

	dpb_color_format = HAL_COLOR_FORMAT_NV12_UBWC;
	original_color_format = d->num_formats >= 1 ?
		d->color_formats[0] : HAL_UNUSED_COLOR;

	fps = d->fps;
	dpb_bpp = d->num_formats >= 1 ? __bpp(d->color_formats[0]) : INT_MAX;

	dpb_compression_enabled = __ubwc(dpb_color_format);
	original_compression_enabled = __ubwc(original_color_format);

	two_stage_encoding = false;
	work_mode_1 = d->work_mode == VIDC_WORK_MODE_1;
	low_power = d->power_mode == VIDC_POWER_LOW;
	b_frames_enabled = false;
	bins_to_bit_factor = work_mode_1 ?
		FP_INT(0) : FP_INT(4);

	/*
	 * Convert Q16 number into Integer and Fractional part upto 2 places.
@@ -636,96 +639,84 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d,

	dpb_compression_factor = FP(integer_part, frac_part, 100);

	original_compression_factor = dpb_compression_factor;
	integer_part = d->input_cr >> 16;
	frac_part =
		((d->input_cr - (integer_part * 65536)) * 100) >> 16;

	rotation = false;
	cropping_or_scaling = false;
	input_compression_factor = FP(integer_part, frac_part, 100);

	/* Derived Parameters */
	lcu_size = 16;
	gop = b_frames_enabled ? GOP_IBBP : GOP_IPPP;
	bitrate = __lut(width, height, fps)->bitrate;
	bins_to_bit_factor = FP(1, 6, 10);
	original_compression_factor =
		original_compression_enabled ? d->use_dpb_read ?
			dpb_compression_factor : input_compression_factor :
		FP_ONE;

	/*
	 * FIXME: Minor color format related hack: a lot of the derived params
	 * depend on the YUV bitdepth as a variable.  However, we don't have
	 * appropriate enums defined yet (hence no support).  As a result omit
	 * a lot of the checks (which should look like the snippet below) in
	 * favour of hardcoding.
	 *      dpb_color_format == YUV420 ? 0.5 :
	 *      dpb_color_format == YUV422 ? 1.0 : 2.0
	 * Similar hacks are annotated inline in code with the string "CF hack"
	 * for documentation purposes.
	 */
	chroma_luma_factor_dpb = FP(0, 1, 2);
	one_frame_bw_dpb = fp_mult(FP_ONE + chroma_luma_factor_dpb,
			fp_div(FP_INT(width * height * fps),
				FP_INT(1000 * 1000)));

	chroma_luma_factor_original = FP(0, 1, 2); /* XXX: CF hack */
	one_frame_bw_original = fp_mult(FP_ONE + chroma_luma_factor_original,
			fp_div(FP_INT(width * height * fps),
				FP_INT(1000 * 1000)));

	line_buffer_size_per_lcu = FP_ZERO;
	if (lcu_size == 16)
		line_buffer_size_per_lcu = FP_INT(128) + fp_mult(FP_INT(256),
					FP_ONE /*XXX: CF hack */);
	else
		line_buffer_size_per_lcu = FP_INT(192) + fp_mult(FP_INT(512),
					FP_ONE /*XXX: CF hack */);

	line_buffer_size = fp_div(
			fp_mult(FP_INT(width / lcu_size),
				line_buffer_size_per_lcu),
			FP_INT(1024));
	line_buffer_bw = fp_mult(line_buffer_size,
			fp_div(FP_INT((height / lcu_size /
				(two_stage_encoding ? 2 : 1) - 1) * fps),
				FP_INT(1000)));

	collocated_mv_per_lcu = lcu_size == 16 ? 16 : 64;
	max_transaction_size = 256;

	search_window_size_vertical_p = low_power ? 32 :
					b_frames_enabled ? 80 :
					width > 2048 ? 64 : 48;
	search_window_factor_p = search_window_size_vertical_p * 2 / lcu_size;
	search_window_factor_bw_p = !two_stage_encoding ?
		search_window_size_vertical_p * 2 / lcu_size + 1 :
		(search_window_size_vertical_p * 2 / lcu_size + 2) / 2;
	bw_increase_p = fp_mult(one_frame_bw_dpb,
			FP_INT(search_window_factor_bw_p - 1) / 3);

	search_window_size_vertical_b = 48;
	search_window_factor_b = search_window_size_vertical_b * 2 / lcu_size;
	search_window_factor_bw_b = !two_stage_encoding ?
		search_window_size_vertical_b * 2 / lcu_size + 1 :
		(search_window_size_vertical_b * 2 / lcu_size + 2) / 2;
	bw_increase_b = fp_mult(one_frame_bw_dpb,
			FP_INT((search_window_factor_bw_b - 1) / 3));

	/* Output parameters for DDR */
	ddr.vsp_read = fp_mult(fp_div(FP_INT(bitrate), FP_INT(8)),
			bins_to_bit_factor);
	ddr.vsp_write = ddr.vsp_read + fp_div(FP_INT(bitrate), FP_INT(8));

	ddr.collocated_read = fp_div(FP_INT(DIV_ROUND_UP(width, lcu_size) *
			DIV_ROUND_UP(height, lcu_size) *
			collocated_mv_per_lcu * fps), FP_INT(1000 * 1000));
	colocated_bytes_per_lcu = lcu_size == 16 ? 16 :
				lcu_size == 32 ? 64 : 256;

	ddr.collocated_read = FP_INT(lcu_per_frame *
			colocated_bytes_per_lcu * fps / bps(1));

	ddr.collocated_write = ddr.collocated_read;

	ddr.line_buffer_read = FP_INT(16 * lcu_per_frame * fps / bps(1));

	ddr.line_buffer_write = ddr.line_buffer_read;

	ddr.original_read = fp_div(one_frame_bw_original,
			original_compression_factor);
	bw_for_1x_8bpc = fp_div(FP_INT(width * height), FP_INT(32 * 8));

	bw_for_1x_8bpc = fp_mult(bw_for_1x_8bpc,
		fp_div(FP_INT(256 * 30), FP_INT(1000 * 1000)));

	dpb_bw_for_1x = dpb_bpp == 8 ? bw_for_1x_8bpc :
		fp_mult(bw_for_1x_8bpc, fp_mult(ten_bpc_packing_factor,
			ten_bpc_bpp_factor));

	ddr.original_read = fp_div(fp_mult(FP(1, 50, 100), dpb_bw_for_1x),
		input_compression_factor);

	ddr.original_write = FP_ZERO;

	ddr.dpb_read = FP_ZERO;
	ref_y_bw_factor =
		width == vertical_tile_width ? FP_INT(1) : ref_y_bw_factor;

	ref_y_read = fp_mult(ref_y_bw_factor, dpb_bw_for_1x);

	ddr.dpb_read = fp_div(ddr.dpb_read, dpb_compression_factor);
	ddr.dpb_write = fp_div(one_frame_bw_dpb, dpb_compression_factor);
	ref_y_read = fp_div(ref_y_read, dpb_compression_factor);

	ref_y_read =
		b_frames_enabled ? fp_mult(ref_y_read, FP_INT(2)) : ref_y_read;

	ref_cb_cr_read = fp_mult(ref_cb_cr_bw_factor, dpb_bw_for_1x);

	ref_cb_cr_read = fp_div(ref_cb_cr_read, dpb_compression_factor);

	ref_cb_cr_read =
		b_frames_enabled ? fp_mult(ref_cb_cr_read, FP_INT(2)) :
					ref_cb_cr_read;

	ref_cb_cr_read = fp_div(ref_cb_cr_read, FP_INT(2));

	ddr.dpb_write = fp_mult(dpb_write_factor, dpb_bw_for_1x);

	ddr.dpb_write = fp_mult(ddr.dpb_write, FP(1, 50, 100));

	ddr.dpb_write = fp_div(ddr.dpb_write, input_compression_factor);

	ref_overlap_bw_factor =
		width <= vertical_tile_width ? FP_INT(0) : FP_INT(1);

	ref_overlap_bw = fp_mult(ddr.dpb_write, ref_overlap_bw_factor);

	ref_overlap_bw = fp_div(ref_overlap_bw, dpb_write_factor);

	ref_overlap_bw = fp_mult(ref_overlap_bw,
		(dpb_write_factor - FP_INT(1)));

	ddr.dpb_read = ref_y_read + ref_cb_cr_read + ref_overlap_bw;

	ddr.total = ddr.vsp_read + ddr.vsp_write +
		ddr.collocated_read + ddr.collocated_write +
@@ -739,7 +730,6 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d,
	if (debug) {
		struct dump dump[] = {
		{"ENCODER PARAMETERS", "", DUMP_HEADER_MAGIC},
		{"standard", "%#x", standard},
		{"width", "%d", width},
		{"height", "%d", height},
		{"DPB format", "%#x", dpb_color_format},
@@ -748,8 +738,8 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d,
		{"DPB compression enable", "%d", dpb_compression_enabled},
		{"original compression enable", "%d",
			original_compression_enabled},
		{"two stage encoding", "%d", two_stage_encoding},
		{"low power mode", "%d", low_power},
		{"Work Mode", "%d", work_mode_1},
		{"DPB compression factor", DUMP_FP_FMT,
			dpb_compression_factor},
		{"original compression factor", DUMP_FP_FMT,
@@ -759,44 +749,21 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d,

		{"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC},
		{"LCU size", "%d", lcu_size},
		{"GOB pattern", "%d", gop},
		{"bitrate (Mbit/sec)", "%lu", bitrate},
		{"bins to bit factor", DUMP_FP_FMT, bins_to_bit_factor},
		{"B-frames enabled", "%d", b_frames_enabled},
		{"search window size vertical (B)", "%d",
			search_window_size_vertical_b},
		{"search window factor (B)", "%d", search_window_factor_b},
		{"search window factor BW (B)", "%d",
			search_window_factor_bw_b},
		{"bw increase (MB/s) (B)", DUMP_FP_FMT, bw_increase_b},
		{"search window size vertical (P)", "%d",
			search_window_size_vertical_p},
		{"search window factor (P)", "%d", search_window_factor_p},
		{"search window factor BW (P)", "%d",
			search_window_factor_bw_p},
		{"bw increase (MB/s) (P)", DUMP_FP_FMT, bw_increase_p},
		{"chroma/luma factor DPB", DUMP_FP_FMT,
			chroma_luma_factor_dpb},
		{"one frame BW DPB (MB/s)", DUMP_FP_FMT, one_frame_bw_dpb},
		{"chroma/Luma factor original", DUMP_FP_FMT,
			chroma_luma_factor_original},
		{"one frame BW original (MB/s)", DUMP_FP_FMT,
			one_frame_bw_original},
		{"line buffer size per LCU", DUMP_FP_FMT,
			line_buffer_size_per_lcu},
		{"line buffer size (KB)", DUMP_FP_FMT, line_buffer_size},
		{"line buffer BW (MB/s)", DUMP_FP_FMT, line_buffer_bw},
		{"collocated MVs per LCU", "%d", collocated_mv_per_lcu},

		{"INTERMEDIATE B/W DDR", "", DUMP_HEADER_MAGIC},
		{"ref_y_read", DUMP_FP_FMT, ref_y_read},
		{"ref_cb_cr_read", DUMP_FP_FMT, ref_cb_cr_read},
		{"ref_overlap_bw", DUMP_FP_FMT, ref_overlap_bw},
		{"VSP read", DUMP_FP_FMT, ddr.vsp_read},
		{"VSP read", DUMP_FP_FMT, ddr.vsp_write},
		{"VSP write", DUMP_FP_FMT, ddr.vsp_write},
		{"collocated read", DUMP_FP_FMT, ddr.collocated_read},
		{"collocated read", DUMP_FP_FMT, ddr.collocated_write},
		{"collocated write", DUMP_FP_FMT, ddr.collocated_write},
		{"line buffer read", DUMP_FP_FMT, ddr.line_buffer_read},
		{"line buffer read", DUMP_FP_FMT, ddr.line_buffer_write},
		{"line buffer write", DUMP_FP_FMT, ddr.line_buffer_write},
		{"original read", DUMP_FP_FMT, ddr.original_read},
		{"original read", DUMP_FP_FMT, ddr.original_write},
		{"original write", DUMP_FP_FMT, ddr.original_write},
		{"DPB read", DUMP_FP_FMT, ddr.dpb_read},
		{"DPB write", DUMP_FP_FMT, ddr.dpb_write},
		};
+6 −0
Original line number Diff line number Diff line
@@ -1140,6 +1140,12 @@ static void hfi_process_sess_get_prop_buf_req(
			buffreq->buffer[10].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_BUFFER_INTERNAL_RECON;
			break;
		default:
			dprintk(VIDC_ERR,
			"hal_process_sess_get_prop_buf_req: bad_buffer_type: %d\n",
+1 −0
Original line number Diff line number Diff line
@@ -2362,6 +2362,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
			rc = -EINVAL;
			goto exit;
		}
		inst->clk_data.opb_fourcc = f->fmt.pix_mp.pixelformat;
		memcpy(&inst->fmts[fmt->type], fmt,
				sizeof(struct msm_vidc_format));

+16 −1
Original line number Diff line number Diff line
@@ -442,6 +442,7 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
	struct msm_vidc_inst *inst = instance;
	int rc = 0, i = 0;
	struct buf_queue *q = NULL;
	u32 cr = 0;

	if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) {
		dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n",
@@ -453,8 +454,16 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
		b->m.planes[i].m.fd = b->m.planes[i].reserved[0];
		b->m.planes[i].data_offset = b->m.planes[i].reserved[1];
	}

	msm_comm_qbuf_cache_operations(inst, b);

	/* Compression ratio is valid only for Encoder YUV buffers. */
	if (inst->session_type == MSM_VIDC_ENCODER &&
			b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		cr = b->m.planes[0].reserved[2];
		msm_comm_update_input_cr(inst, b->index, cr);
	}

	q = msm_comm_get_vb2q(inst, b->type);
	if (!q) {
		dprintk(VIDC_ERR,
@@ -712,7 +721,6 @@ static int msm_vidc_queue_setup(struct vb2_queue *q,
		rc = set_buffer_count(inst, bufreq->buffer_count_min_host,
			bufreq->buffer_count_actual, HAL_BUFFER_INPUT);
		}

		break;
	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: {
		buffer_type = msm_comm_get_hal_output_buffer(inst);
@@ -1494,6 +1502,7 @@ void *msm_vidc_open(int core_id, int session_type)

	INIT_MSM_VIDC_LIST(&inst->scratchbufs);
	INIT_MSM_VIDC_LIST(&inst->freqs);
	INIT_MSM_VIDC_LIST(&inst->input_crs);
	INIT_MSM_VIDC_LIST(&inst->persistbufs);
	INIT_MSM_VIDC_LIST(&inst->pending_getpropq);
	INIT_MSM_VIDC_LIST(&inst->outputbufs);
@@ -1605,6 +1614,8 @@ void *msm_vidc_open(int core_id, int session_type)
	DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
	DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
	DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
	DEINIT_MSM_VIDC_LIST(&inst->freqs);
	DEINIT_MSM_VIDC_LIST(&inst->input_crs);

	kfree(inst);
	inst = NULL;
@@ -1634,6 +1645,8 @@ static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst)

	msm_comm_free_freq_table(inst);

	msm_comm_free_input_cr_table(inst);

	if (msm_comm_release_scratch_buffers(inst, false))
		dprintk(VIDC_ERR,
			"Failed to release scratch buffers\n");
@@ -1699,6 +1712,8 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst)
	DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
	DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
	DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
	DEINIT_MSM_VIDC_LIST(&inst->freqs);
	DEINIT_MSM_VIDC_LIST(&inst->input_crs);

	mutex_destroy(&inst->sync_lock);
	mutex_destroy(&inst->bufq[CAPTURE_PORT].lock);
+85 −12
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@
#define MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR (1 << 16)
#define MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR (4 << 16)

#define MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO (1 << 16)
#define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (5 << 16)

static inline unsigned long int get_ubwc_compression_ratio(
	struct ubwc_cr_stats_info_type ubwc_stats_info)
{
@@ -90,36 +93,56 @@ void update_recon_stats(struct msm_vidc_inst *inst,
	mutex_unlock(&inst->reconbufs.lock);
}

static int fill_recon_stats(struct msm_vidc_inst *inst,
static int fill_dynamic_stats(struct msm_vidc_inst *inst,
	struct vidc_bus_vote_data *vote_data)
{
	struct recon_buf *binfo;
	u32 CR = 0, min_cf = MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR,
		max_cf = MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR;
	struct recon_buf *binfo, *nextb;
	struct vidc_input_cr_data *temp, *next;
	u32 min_cf = 0, max_cf = 0;
	u32 min_input_cr = 0, max_input_cr = 0, min_cr = 0, max_cr = 0;

	mutex_lock(&inst->reconbufs.lock);
	list_for_each_entry(binfo, &inst->reconbufs.list, list) {
		CR = max(CR, binfo->CR);
	list_for_each_entry_safe(binfo, nextb, &inst->reconbufs.list, list) {
		min_cr = min(min_cr, binfo->CR);
		max_cr = max(max_cr, binfo->CR);
		min_cf = min(min_cf, binfo->CF);
		max_cf = max(max_cf, binfo->CF);
	}
	mutex_unlock(&inst->reconbufs.lock);

	mutex_lock(&inst->input_crs.lock);
	list_for_each_entry_safe(temp, next, &inst->input_crs.list, list) {
		min_input_cr = min(min_input_cr, temp->input_cr);
		max_input_cr = max(max_input_cr, temp->input_cr);
	}
	mutex_unlock(&inst->input_crs.lock);

	/* Sanitize CF values from HW . */
	max_cf = min_t(u32, max_cf, MSM_VIDC_MAX_UBWC_COMPLEXITY_FACTOR);
	min_cf = max_t(u32, min_cf, MSM_VIDC_MIN_UBWC_COMPLEXITY_FACTOR);

	vote_data->compression_ratio = CR;
	max_cr = min_t(u32, max_cr, MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO);
	min_cr = max_t(u32, min_cr, MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO);
	max_input_cr = min_t(u32,
		max_input_cr, MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO);
	min_input_cr = max_t(u32,
		min_input_cr, MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO);

	vote_data->compression_ratio = min_cr;
	vote_data->complexity_factor = max_cf;
	vote_data->input_cr = min_input_cr;
	vote_data->use_dpb_read = false;

	/* Check if driver can vote for lower bus BW */
	if (inst->clk_data.load <= inst->clk_data.load_norm) {
		vote_data->compression_ratio = max_cr;
		vote_data->complexity_factor = min_cf;
		vote_data->input_cr = max_input_cr;
		vote_data->use_dpb_read = true;
	}

	dprintk(VIDC_DBG,
		"Compression Ratio = %d Complexity Factor = %d\n",
			vote_data->compression_ratio,
	dprintk(VIDC_PROF,
		"Input CR = %d Recon CR = %d Complexity Factor = %d\n",
			vote_data->input_cr, vote_data->compression_ratio,
			vote_data->complexity_factor);

	return 0;
@@ -198,6 +221,9 @@ int msm_comm_vote_bus(struct msm_vidc_core *core)
				max(inst->prop.height[CAPTURE_PORT],
				inst->prop.height[OUTPUT_PORT]);
		vote_data[i].lcu_size = codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
		vote_data[i].b_frames_enabled =
			msm_comm_g_ctrl_for_id(inst,
				V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES) != 0;

		if (inst->clk_data.operating_rate)
			vote_data[i].fps =
@@ -227,7 +253,7 @@ int msm_comm_vote_bus(struct msm_vidc_core *core)
			vote_data[i].num_formats = 2;
		}
		vote_data[i].work_mode = inst->clk_data.work_mode;
		fill_recon_stats(inst, &vote_data[i]);
		fill_dynamic_stats(inst, &vote_data[i]);

		if (core->resources.sys_cache_res_set)
			vote_data[i].use_sys_cache = true;
@@ -356,10 +382,15 @@ static void msm_vidc_update_freq_entry(struct msm_vidc_inst *inst,

	if (!found) {
		temp = kzalloc(sizeof(*temp), GFP_KERNEL);
		if (!temp) {
			dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__);
			goto exit;
		}
		temp->freq = freq;
		temp->device_addr = device_addr;
		list_add_tail(&temp->list, &inst->freqs.list);
	}
exit:
	mutex_unlock(&inst->freqs.lock);
}

@@ -415,6 +446,48 @@ void msm_comm_free_freq_table(struct msm_vidc_inst *inst)
	mutex_unlock(&inst->freqs.lock);
}

void msm_comm_free_input_cr_table(struct msm_vidc_inst *inst)
{
	struct vidc_input_cr_data *temp, *next;

	mutex_lock(&inst->input_crs.lock);
	list_for_each_entry_safe(temp, next, &inst->input_crs.list, list) {
		list_del(&temp->list);
		kfree(temp);
	}
	INIT_LIST_HEAD(&inst->input_crs.list);
	mutex_unlock(&inst->input_crs.lock);
}

void msm_comm_update_input_cr(struct msm_vidc_inst *inst,
	u32 index, u32 cr)
{
	struct vidc_input_cr_data *temp, *next;
	bool found = false;

	mutex_lock(&inst->input_crs.lock);
	list_for_each_entry_safe(temp, next, &inst->input_crs.list, list) {
		if (temp->index == index) {
			temp->input_cr = cr;
			found = true;
			break;
		}
	}

	if (!found) {
		temp = kzalloc(sizeof(*temp), GFP_KERNEL);
		if (!temp)  {
			dprintk(VIDC_WARN, "%s: malloc failure.\n", __func__);
			goto exit;
		}
		temp->index = index;
		temp->input_cr = cr;
		list_add_tail(&temp->list, &inst->input_crs.list);
	}
exit:
	mutex_unlock(&inst->input_crs.lock);
}

static unsigned long msm_vidc_max_freq(struct msm_vidc_core *core)
{
	struct allowed_clock_rates_table *allowed_clks_tbl = NULL;
Loading