mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 15:49:17 -04:00
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:
parent
ac0ba4c8f7
commit
c5b079d201
4 changed files with 79 additions and 128 deletions
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue