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: Chinmay Sawarkar <chinmays@codeaurora.org>
This commit is contained in:
Chinmay Sawarkar 2019-07-05 15:26:09 -07:00
commit c5b079d201
4 changed files with 79 additions and 128 deletions

View file

@ -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 @@ no_data_count:
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");
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}