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

Commit e478c7b7 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm-vidc: update core ops for AR50LT bus calculation"

parents fe49b217 8797296a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ msm-vidc-objs := vidc/msm_v4l2_vidc.o \
                vidc/hfi_packetization.o \
                vidc/vidc_hfi.o \
                vidc/msm_vidc_clocks.o \
                vidc/msm_vidc_bus_ar50lite.o\
                vidc/msm_vidc_bus_iris1.o \
                vidc/msm_vidc_bus_iris2.o \
                vidc/msm_vidc_buffer_calculations.o
+2 −0
Original line number Diff line number Diff line
@@ -218,6 +218,8 @@ struct msm_vidc_bus_data {
	unsigned long total_bw_llcc;
};

int calc_bw_ar50lt(struct vidc_bus_vote_data *vidc_data);

int calc_bw_iris1(struct vidc_bus_vote_data *vidc_data);

int calc_bw_iris2(struct vidc_bus_vote_data *vidc_data);
+295 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
 */

#include "msm_vidc_bus.h"
#include "msm_vidc_internal.h"

static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d)
{
	/* Encoder Parameters */
	int width, height, fps, bitrate, lcu_size;

	/* Derived Parameter */
	int search_range, lcu_per_frame;
	fp_t y_bw;
	bool is_h264_category = true;
	fp_t orig_read_factor, recon_write_factor,
		ref_y_read_factor, ref_c_read_factor, lb_factor,
		rest_factor, total_read_factor, total_write_factor,
		total_factor, overhead_factor;

	/* Output parameters */
	fp_t orig_read, recon_write,
			ref_y_read, ref_c_read,
			lb_read, lb_write,
			bse_read, bse_write,
			total_read, total_write,
			total;

	unsigned long ret = 0;

	/* Encoder Fixed Parameters */
	overhead_factor = FP(1, 3, 100);
	orig_read_factor = FP(1, 50, 100); /* L + C */
	recon_write_factor = FP(1, 50, 100); /* L + C */
	ref_c_read_factor = FP(0, 75, 100); /* 1.5/2  ( 1.5 Cache efficiency )*/
	lb_factor = FP(1, 25, 100); /* Worst case : HEVC 720p = 1.25 */

	fps = d->fps;
	width = max(d->output_width, BASELINE_DIMENSIONS.width);
	height = max(d->output_height, BASELINE_DIMENSIONS.height);
	bitrate = d->bitrate > 0 ? (d->bitrate + 1000000 - 1) / 1000000 :
		__lut(width, height, fps)->bitrate;
	lcu_size = d->lcu_size;

	/* Derived Parameters Setup*/
	lcu_per_frame = DIV_ROUND_UP(width, lcu_size) *
		DIV_ROUND_UP(height, lcu_size);

	if (d->codec == HAL_VIDEO_CODEC_HEVC ||
		d->codec == HAL_VIDEO_CODEC_VP9) {
		/* H264, VP8, MPEG2 use the same settings */
		/* HEVC, VP9 use the same setting */
		is_h264_category = false;
	}

	search_range = 48;

	y_bw = fp_mult(fp_mult(FP_INT(width), FP_INT(height)), FP_INT(fps));
	y_bw = fp_div(y_bw, FP_INT(1000000));

	ref_y_read_factor = fp_div(FP_INT(search_range * 2), FP_INT(lcu_size));
	ref_y_read_factor = ref_y_read_factor + FP_INT(1);

	rest_factor = FP_INT(bitrate) + fp_div(FP_INT(bitrate), FP_INT(8));
	rest_factor = fp_div(rest_factor, y_bw);

	total_read_factor = fp_div(rest_factor, FP_INT(2)) +
		fp_div(lb_factor, FP_INT(2));
	total_read_factor = total_read_factor + orig_read_factor +
		ref_y_read_factor + ref_c_read_factor;

	total_write_factor = fp_div(rest_factor, FP_INT(2)) +
		fp_div(lb_factor, FP_INT(2));
	total_write_factor = total_write_factor + recon_write_factor;

	total_factor = total_read_factor + total_write_factor;

	orig_read = fp_mult(y_bw, orig_read_factor);
	recon_write = fp_mult(y_bw, recon_write_factor);
	ref_y_read = fp_mult(y_bw, ref_y_read_factor);
	ref_c_read = fp_mult(y_bw, ref_c_read_factor);
	lb_read = fp_div(fp_mult(y_bw, lb_factor), FP_INT(2));
	lb_write = lb_read;
	bse_read = fp_mult(y_bw, fp_div(rest_factor, FP_INT(2)));
	bse_write = bse_read;

	total_read = orig_read + ref_y_read + ref_c_read +
		lb_read + bse_read;
	total_write = recon_write + lb_write + bse_write;

	total = total_read + total_write;
	total = fp_mult(total, overhead_factor);

	if (msm_vidc_debug & VIDC_BUS) {
		struct dump dump[] = {
		{"ENCODER PARAMETERS", "", DUMP_HEADER_MAGIC},
		{"width", "%d", width},
		{"height", "%d", height},
		{"fps", "%d", fps},
		{"bitrate (Mbit/sec)", "%lu", bitrate},
		{"lcu size", "%d", lcu_size},

		{"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC},
		{"lcu/frame", "%d", lcu_per_frame},
		{"Y BW", DUMP_FP_FMT, y_bw},
		{"search range", "%d", search_range},
		{"original read factor", DUMP_FP_FMT, orig_read_factor},
		{"recon write factor", DUMP_FP_FMT, recon_write_factor},
		{"ref read Y factor", DUMP_FP_FMT, ref_y_read_factor},
		{"ref read C factor", DUMP_FP_FMT, ref_c_read_factor},
		{"lb factor", DUMP_FP_FMT, lb_factor},
		{"rest factor", DUMP_FP_FMT, rest_factor},
		{"total_read_factor", DUMP_FP_FMT, total_read_factor},
		{"total_write_factor", DUMP_FP_FMT, total_write_factor},
		{"total_factor", DUMP_FP_FMT, total_factor},
		{"overhead_factor", DUMP_FP_FMT, overhead_factor},

		{"INTERMEDIATE B/W DDR", "", DUMP_HEADER_MAGIC},
		{"orig read", DUMP_FP_FMT, orig_read},
		{"recon write", DUMP_FP_FMT, recon_write},
		{"ref read Y", DUMP_FP_FMT, ref_y_read},
		{"ref read C", DUMP_FP_FMT, ref_c_read},
		{"lb read", DUMP_FP_FMT, lb_read},
		{"lb write", DUMP_FP_FMT, lb_write},
		{"bse read", DUMP_FP_FMT, bse_read},
		{"bse write", DUMP_FP_FMT, bse_write},
		{"total read", DUMP_FP_FMT, total_read},
		{"total write", DUMP_FP_FMT, total_write},
		{"total", DUMP_FP_FMT, total},
		};
		__dump(dump, ARRAY_SIZE(dump), d->sid);
	}


	d->calc_bw_ddr = kbps(fp_round(total));

	return ret;
}

static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d)
{
	/* Decoder parameters */
	int width, height, fps, bitrate, lcu_size;

	/* Derived parameters */
	int lcu_per_frame, motion_complexity;
	fp_t y_bw;
	bool is_h264_category = true;
	fp_t recon_write_factor, ref_read_factor, lb_factor,
		rest_factor, opb_factor,
		total_read_factor, total_write_factor,
		total_factor, overhead_factor;

	/* Output parameters */
	fp_t opb_write, recon_write,
			ref_read,
			lb_read, lb_write,
			bse_read, bse_write,
			total_read, total_write,
			total;

	unsigned long ret = 0;

	/* Decoder Fixed Parameters */
	overhead_factor = FP(1, 3, 100);
	recon_write_factor = FP(1, 50, 100); /* L + C */
	opb_factor = FP(1, 50, 100); /* L + C */
	lb_factor = FP(1, 13, 100); /* Worst case : H264 1080p = 1.125 */
	motion_complexity = 5; /* worst case complexity */

	fps = d->fps;
	width = max(d->output_width, BASELINE_DIMENSIONS.width);
	height = max(d->output_height, BASELINE_DIMENSIONS.height);
	bitrate = d->bitrate > 0 ? (d->bitrate + 1000000 - 1) / 1000000 :
		__lut(width, height, fps)->bitrate;
	lcu_size = d->lcu_size;

	/* Derived Parameters Setup*/
	lcu_per_frame = DIV_ROUND_UP(width, lcu_size) *
		DIV_ROUND_UP(height, lcu_size);

	if (d->codec == HAL_VIDEO_CODEC_HEVC ||
		d->codec == HAL_VIDEO_CODEC_VP9) {
		/* H264, VP8, MPEG2 use the same settings */
		/* HEVC, VP9 use the same setting */
		is_h264_category = false;
	}

	y_bw = fp_mult(fp_mult(FP_INT(width), FP_INT(height)), FP_INT(fps));
	y_bw = fp_div(y_bw, FP_INT(1000000));

	ref_read_factor = FP(1, 50, 100); /* L + C */
	ref_read_factor = fp_mult(ref_read_factor, FP_INT(motion_complexity));

	rest_factor = FP_INT(bitrate) + fp_div(FP_INT(bitrate), FP_INT(8));
	rest_factor = fp_div(rest_factor, y_bw);

	total_read_factor = fp_div(rest_factor, FP_INT(2)) +
		fp_div(lb_factor, FP_INT(2));
	total_read_factor = total_read_factor + ref_read_factor;

	total_write_factor = fp_div(rest_factor, FP_INT(2));
	total_write_factor = total_write_factor +
		recon_write_factor + opb_factor;

	total_factor = total_read_factor + total_write_factor;

	recon_write = fp_mult(y_bw, recon_write_factor);
	ref_read = fp_mult(y_bw, ref_read_factor);
	lb_read = fp_div(fp_mult(y_bw, lb_factor), FP_INT(2));
	lb_write = lb_read;
	bse_read = fp_div(fp_mult(y_bw, rest_factor), FP_INT(2));
	bse_write = bse_read;
	opb_write = fp_mult(y_bw, opb_factor);

	total_read = ref_read + lb_read + bse_read;
	total_write = recon_write + lb_write + bse_write + opb_write;

	total = total_read + total_write;
	total = fp_mult(total, overhead_factor);

	if (msm_vidc_debug & VIDC_BUS) {
		struct dump dump[] = {
		{"DECODER PARAMETERS", "", DUMP_HEADER_MAGIC},
		{"width", "%d", width},
		{"height", "%d", height},
		{"fps", "%d", fps},
		{"bitrate (Mbit/sec)", "%lu", bitrate},
		{"lcu size", "%d", lcu_size},

		{"DERIVED PARAMETERS", "", DUMP_HEADER_MAGIC},
		{"lcu/frame", "%d", lcu_per_frame},
		{"Y BW", DUMP_FP_FMT, y_bw},
		{"motion complexity", "%d", motion_complexity},
		{"recon write factor", DUMP_FP_FMT, recon_write_factor},
		{"ref_read_factor", DUMP_FP_FMT, ref_read_factor},
		{"lb factor", DUMP_FP_FMT, lb_factor},
		{"rest factor", DUMP_FP_FMT, rest_factor},
		{"opb factor", DUMP_FP_FMT, opb_factor},
		{"total_read_factor", DUMP_FP_FMT, total_read_factor},
		{"total_write_factor", DUMP_FP_FMT, total_write_factor},
		{"total_factor", DUMP_FP_FMT, total_factor},
		{"overhead_factor", DUMP_FP_FMT, overhead_factor},

		{"INTERMEDIATE B/W DDR", "", DUMP_HEADER_MAGIC},
		{"recon write", DUMP_FP_FMT, recon_write},
		{"ref read", DUMP_FP_FMT, ref_read},
		{"lb read", DUMP_FP_FMT, lb_read},
		{"lb write", DUMP_FP_FMT, lb_write},
		{"bse read", DUMP_FP_FMT, bse_read},
		{"bse write", DUMP_FP_FMT, bse_write},
		{"opb write", DUMP_FP_FMT, opb_write},
		{"total read", DUMP_FP_FMT, total_read},
		{"total write", DUMP_FP_FMT, total_write},
		{"total", DUMP_FP_FMT, total},
		};
		__dump(dump, ARRAY_SIZE(dump), d->sid);
	}

	d->calc_bw_ddr = kbps(fp_round(total));

	return ret;
}

static unsigned long __calculate(struct vidc_bus_vote_data *d)
{
	unsigned long value = 0;

	switch (d->domain) {
	case HAL_VIDEO_DOMAIN_ENCODER:
		value = __calculate_encoder(d);
		break;
	case HAL_VIDEO_DOMAIN_DECODER:
		value = __calculate_decoder(d);
		break;
	default:
		s_vpr_e(d->sid, "Unknown Domain %#x", d->domain);
	}

	return value;
}

int calc_bw_ar50lt(struct vidc_bus_vote_data *vidc_data)
{
	int ret = 0;

	if (!vidc_data)
		return ret;

	ret = __calculate(vidc_data);

	return ret;
}
+11 −1
Original line number Diff line number Diff line
@@ -32,6 +32,14 @@ struct msm_vidc_core_ops core_ops_ar50 = {
	.calc_bw = NULL,
};

struct msm_vidc_core_ops core_ops_ar50lt = {
	.calc_freq = msm_vidc_calc_freq_ar50,
	.decide_work_route = NULL,
	.decide_work_mode = msm_vidc_decide_work_mode_ar50,
	.decide_core_and_power_mode = NULL,
	.calc_bw = calc_bw_ar50lt,
};

struct msm_vidc_core_ops core_ops_iris1 = {
	.calc_freq = msm_vidc_calc_freq_iris1,
	.decide_work_route = msm_vidc_decide_work_route_iris1,
@@ -1709,8 +1717,10 @@ void msm_vidc_init_core_clk_ops(struct msm_vidc_core *core)

	vpu = core->platform_data->vpu_ver;

	if (vpu == VPU_VERSION_AR50 || vpu == VPU_VERSION_AR50_LITE)
	if (vpu == VPU_VERSION_AR50)
		core->core_ops = &core_ops_ar50;
	else if (vpu == VPU_VERSION_AR50_LITE)
		core->core_ops = &core_ops_ar50lt;
	else if (vpu == VPU_VERSION_IRIS1)
		core->core_ops = &core_ops_iris1;
	else