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

Commit c5b079d2 authored by Chinmay Sawarkar's avatar Chinmay Sawarkar
Browse files

msm: vidc: Optimize bw calculations



Calculate DDR and LLCC bw simulteneously to avoid
redundant calculations. This reduces number of calculations
required by 50% and hence reduces cpu load.

CRs-Fixed: 2487664
Change-Id: I6e1768cd63d9b6651fbaf4a8ed8d5706929d7743
Signed-off-by: default avatarChinmay Sawarkar <chinmays@codeaurora.org>
parent ac0ba4c8
Loading
Loading
Loading
Loading
+16 −10
Original line number Diff line number Diff line
@@ -977,14 +977,14 @@ static void __set_registers(struct venus_hfi_device *device)
	}
}

static int __vote_bandwidth(struct bus_info *bus, unsigned long freq)
static int __vote_bandwidth(struct bus_info *bus, unsigned long bw_kbps)
{
	int rc = 0;
	uint64_t ab = 0;

	/* Bus Driver expects values in Bps */
	ab = freq * 1000;
	dprintk(VIDC_PERF, "Voting bus %s to ab %llu\n", bus->name, ab);
	ab = bw_kbps * 1000;
	dprintk(VIDC_PERF, "Voting bus %s to ab %llu bps\n", bus->name, ab);
	rc = msm_bus_scale_update_bw(bus->client, ab, 0);
	if (rc)
		dprintk(VIDC_ERR, "Failed voting bus %s to ab %llu, rc=%d\n",
@@ -1018,7 +1018,8 @@ static int __vote_buses(struct venus_hfi_device *device,
	int rc = 0;
	struct bus_info *bus = NULL;
	struct vidc_bus_vote_data *new_data = NULL;
	unsigned long freq = 0;
	unsigned long bw_kbps = 0;
	enum vidc_bus_type type;

	if (!num_data) {
		dprintk(VIDC_LOW, "No vote data available\n");
@@ -1040,19 +1041,24 @@ static int __vote_buses(struct venus_hfi_device *device,
	device->bus_vote.data = new_data;
	device->bus_vote.data_count = num_data;

	device->bus_vote.calc_bw(&device->bus_vote);

	venus_hfi_for_each_bus(device, bus) {
		if (bus && bus->client) {
			if (!bus->is_prfm_mode)
				freq = device->bus_vote.calc_bw
					(bus, &device->bus_vote);
			type = get_type_frm_name(bus->name);

			if (type == DDR)
				bw_kbps = device->bus_vote.total_bw_ddr;
			else if (type == LLCC)
				bw_kbps = device->bus_vote.total_bw_llcc;
			else
				freq = bus->range[1];
				bw_kbps = bus->range[1];

			/* ensure freq is within limits */
			freq = clamp_t(typeof(freq), freq,
			bw_kbps = clamp_t(typeof(bw_kbps), bw_kbps,
				bus->range[0], bus->range[1]);

			rc = __vote_bandwidth(bus, freq);
			rc = __vote_bandwidth(bus, bw_kbps);
		} else {
			dprintk(VIDC_ERR, "No BUS to Vote\n");
		}
+7 −6
Original line number Diff line number Diff line
@@ -232,20 +232,21 @@ struct vidc_bus_vote_data {
	u32 work_mode;
	bool use_sys_cache;
	bool b_frames_enabled;
	unsigned long calc_bw_ddr;
	unsigned long calc_bw_llcc;
};

struct msm_vidc_bus_data {
	struct vidc_bus_vote_data *data;
	u32 data_count;
	unsigned long (*calc_bw)(struct bus_info *bus,
				struct msm_vidc_bus_data *data);
	unsigned long total_bw_ddr;
	unsigned long total_bw_llcc;
	int (*calc_bw)(struct msm_vidc_bus_data *data);
};

unsigned long calc_bw_iris1(struct bus_info *bus,
				struct msm_vidc_bus_data *vidc_data);
int calc_bw_iris1(struct msm_vidc_bus_data *vidc_data);

unsigned long calc_bw_iris2(struct bus_info *bus,
				struct msm_vidc_bus_data *vidc_data);
int calc_bw_iris2(struct msm_vidc_bus_data *vidc_data);

struct lut const *__lut(int width, int height, int fps);
fp_t __compression_ratio(struct lut const *entry, int bpp);
+28 −56
Original line number Diff line number Diff line
@@ -68,34 +68,22 @@ void __dump(struct dump dump[], int len)
	}
}

static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d,
		enum vidc_bus_type type)
static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d)
{
	return 0;
}

static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d,
		enum vidc_bus_type type)
static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d)
{
	unsigned long ret = 0;

	switch (type) {
	case DDR:
		ret = d->ddr_bw;
		break;
	case LLCC:
		ret = d->sys_cache_bw;
		break;
	default:
		dprintk(VIDC_ERR, "%s - Unknown type\n", __func__);
		break;
	}
	d->calc_bw_ddr = d->ddr_bw;
	d->calc_bw_llcc = d->sys_cache_bw;

	return ret;
}

static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d,
		enum vidc_bus_type type)
static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d)
{
	/*
	 * XXX: Don't fool around with any of the hardcoded numbers unless you
@@ -335,22 +323,13 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d,
		__dump(dump, ARRAY_SIZE(dump));
	}

	switch (type) {
	case DDR:
		ret = kbps(fp_round(ddr.total));
		break;
	case LLCC:
		ret = kbps(fp_round(llc.total));
		break;
	default:
		dprintk(VIDC_ERR, "%s - Unknown type\n", __func__);
	}
	d->calc_bw_ddr = kbps(fp_round(ddr.total));
	d->calc_bw_llcc = kbps(fp_round(llc.total));

	return ret;
}

static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d,
		enum vidc_bus_type type)
static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d)
{
	/*
	 * XXX: Don't fool around with any of the hardcoded numbers unless you
@@ -632,37 +611,28 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d,
		__dump(dump, ARRAY_SIZE(dump));
	}

	switch (type) {
	case DDR:
		ret = kbps(fp_round(ddr.total));
		break;
	case LLCC:
		ret = kbps(fp_round(llc.total));
		break;
	default:
		dprintk(VIDC_ERR, "%s - Unknown type\n", __func__);
	}
	d->calc_bw_ddr = kbps(fp_round(ddr.total));
	d->calc_bw_llcc = kbps(fp_round(llc.total));

	return ret;
}

static unsigned long __calculate(struct vidc_bus_vote_data *d,
		enum vidc_bus_type type)
static unsigned long __calculate(struct vidc_bus_vote_data *d)
{
	unsigned long value = 0;

	switch (d->domain) {
	case HAL_VIDEO_DOMAIN_VPE:
		value = __calculate_vpe(d, type);
		value = __calculate_vpe(d);
		break;
	case HAL_VIDEO_DOMAIN_ENCODER:
		value = __calculate_encoder(d, type);
		value = __calculate_encoder(d);
		break;
	case HAL_VIDEO_DOMAIN_DECODER:
		value = __calculate_decoder(d, type);
		value = __calculate_decoder(d);
		break;
	case HAL_VIDEO_DOMAIN_CVP:
		value = __calculate_cvp(d, type);
		value = __calculate_cvp(d);
		break;
	default:
		dprintk(VIDC_ERR, "Unknown Domain");
@@ -671,29 +641,31 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d,
	return value;
}

unsigned long calc_bw_iris1(struct bus_info *bus,
				struct msm_vidc_bus_data *vidc_data)
int calc_bw_iris1(struct msm_vidc_bus_data *vidc_data)
{
	unsigned long ab_kbps = 0, c = 0;
	enum vidc_bus_type type;
	int ret = 0, c = 0;

	if (!vidc_data || !vidc_data->data_count || !vidc_data->data)
		goto exit;

	vidc_data->total_bw_ddr = 0;
	vidc_data->total_bw_llcc = 0;

	for (c = 0; c < vidc_data->data_count; ++c) {
		if (vidc_data->data->power_mode == VIDC_POWER_TURBO) {
			ab_kbps = INT_MAX;
			vidc_data->total_bw_ddr = INT_MAX;
			vidc_data->total_bw_llcc = INT_MAX;
			goto exit;
		}
	}

	type = get_type_frm_name(bus->name);

	for (c = 0; c < vidc_data->data_count; ++c)
		ab_kbps += __calculate(&vidc_data->data[c], type);
	for (c = 0; c < vidc_data->data_count; ++c) {
		__calculate(&vidc_data->data[c]);
		vidc_data->total_bw_ddr += vidc_data->data[c].calc_bw_ddr;
		vidc_data->total_bw_llcc += vidc_data->data[c].calc_bw_llcc;
	}

exit:
	trace_msm_vidc_perf_bus_vote(bus->name, ab_kbps);
	return ab_kbps;
	return ret;
}
+28 −56
Original line number Diff line number Diff line
@@ -6,34 +6,22 @@
#include "msm_vidc_bus.h"
#include "msm_vidc_internal.h"

static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d,
		enum vidc_bus_type type)
static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d)
{
	return 0;
}

static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d,
		enum vidc_bus_type type)
static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d)
{
	unsigned long ret = 0;

	switch (type) {
	case DDR:
		ret = d->ddr_bw;
		break;
	case LLCC:
		ret = d->sys_cache_bw;
		break;
	default:
		dprintk(VIDC_ERR, "%s - Unknown type\n", __func__);
		break;
	}
	d->calc_bw_ddr = d->ddr_bw;
	d->calc_bw_llcc = d->sys_cache_bw;

	return ret;
}

static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d,
		enum vidc_bus_type type)
static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d)
{
	/*
	 * XXX: Don't fool around with any of the hardcoded numbers unless you
@@ -276,22 +264,13 @@ static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d,
		__dump(dump, ARRAY_SIZE(dump));
	}

	switch (type) {
	case DDR:
		ret = kbps(fp_round(ddr.total));
		break;
	case LLCC:
		ret = kbps(fp_round(llc.total));
		break;
	default:
		dprintk(VIDC_ERR, "%s - Unknown type\n", __func__);
	}
	d->calc_bw_ddr = kbps(fp_round(ddr.total));
	d->calc_bw_llcc = kbps(fp_round(llc.total));

	return ret;
}

static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d,
		enum vidc_bus_type type)
static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d)
{
	/*
	 * XXX: Don't fool around with any of the hardcoded numbers unless you
@@ -573,37 +552,28 @@ static unsigned long __calculate_encoder(struct vidc_bus_vote_data *d,
		__dump(dump, ARRAY_SIZE(dump));
	}

	switch (type) {
	case DDR:
		ret = kbps(fp_round(ddr.total));
		break;
	case LLCC:
		ret = kbps(fp_round(llc.total));
		break;
	default:
		dprintk(VIDC_ERR, "%s - Unknown governor\n", __func__);
	}
	d->calc_bw_ddr = kbps(fp_round(ddr.total));
	d->calc_bw_llcc = kbps(fp_round(llc.total));

	return ret;
}

static unsigned long __calculate(struct vidc_bus_vote_data *d,
		enum vidc_bus_type type)
static unsigned long __calculate(struct vidc_bus_vote_data *d)
{
	unsigned long value = 0;

	switch (d->domain) {
	case HAL_VIDEO_DOMAIN_VPE:
		value = __calculate_vpe(d, type);
		value = __calculate_vpe(d);
		break;
	case HAL_VIDEO_DOMAIN_ENCODER:
		value = __calculate_encoder(d, type);
		value = __calculate_encoder(d);
		break;
	case HAL_VIDEO_DOMAIN_DECODER:
		value = __calculate_decoder(d, type);
		value = __calculate_decoder(d);
		break;
	case HAL_VIDEO_DOMAIN_CVP:
		value = __calculate_cvp(d, type);
		value = __calculate_cvp(d);
		break;
	default:
		dprintk(VIDC_ERR, "Unknown Domain");
@@ -612,28 +582,30 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d,
	return value;
}

unsigned long calc_bw_iris2(struct bus_info *bus,
				struct msm_vidc_bus_data *vidc_data)
int calc_bw_iris2(struct msm_vidc_bus_data *vidc_data)
{
	unsigned long ab_kbps = 0, c = 0;
	enum vidc_bus_type type;
	int ret = 0, c = 0;

	if (!vidc_data || !vidc_data->data_count || !vidc_data->data)
		goto exit;

	vidc_data->total_bw_ddr = 0;
	vidc_data->total_bw_llcc = 0;

	for (c = 0; c < vidc_data->data_count; ++c) {
		if (vidc_data->data->power_mode == VIDC_POWER_TURBO) {
			ab_kbps = INT_MAX;
			vidc_data->total_bw_ddr = INT_MAX;
			vidc_data->total_bw_llcc = INT_MAX;
			goto exit;
		}
	}

	type = get_type_frm_name(bus->name);

	for (c = 0; c < vidc_data->data_count; ++c)
		ab_kbps += __calculate(&vidc_data->data[c], type);
	for (c = 0; c < vidc_data->data_count; ++c) {
		__calculate(&vidc_data->data[c]);
		vidc_data->total_bw_ddr += vidc_data->data[c].calc_bw_ddr;
		vidc_data->total_bw_llcc += vidc_data->data[c].calc_bw_llcc;
	}

exit:
	trace_msm_vidc_perf_bus_vote(bus->name, ab_kbps);
	return ab_kbps;
	return ret;
}