mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 23:24:22 -04:00
msm: vidc: refine bus bw voting
- Avoid redundant memory alloc/free at frame level. - Only calculate bus bw for current session. - Skip bus bw voting if change is less than 50MBps. Change-Id: I944670c6ac0bf663cb43f47a06b8e828ccdb28cc Signed-off-by: Qiwei Liu <qiweil@codeaurora.org>
This commit is contained in:
parent
1b9472cc6f
commit
1ec1845dab
10 changed files with 179 additions and 227 deletions
|
|
@ -69,13 +69,16 @@ struct tzbsp_video_set_state_req {
|
|||
};
|
||||
|
||||
const struct msm_vidc_bus_data DEFAULT_BUS_VOTE = {
|
||||
.data = NULL,
|
||||
.data_count = 0,
|
||||
.total_bw_ddr = 0,
|
||||
.total_bw_llcc = 0,
|
||||
.calc_bw = NULL,
|
||||
};
|
||||
|
||||
/* Less than 50MBps is treated as trivial BW change */
|
||||
#define TRIVIAL_BW_THRESHOLD 50000
|
||||
#define TRIVIAL_BW_CHANGE(a, b) \
|
||||
((a) > (b) ? (a) - (b) < TRIVIAL_BW_THRESHOLD : \
|
||||
(b) - (a) < TRIVIAL_BW_THRESHOLD)
|
||||
|
||||
const int max_packets = 1000;
|
||||
|
||||
static void venus_hfi_pm_handler(struct work_struct *work);
|
||||
|
|
@ -1001,9 +1004,7 @@ int __unvote_buses(struct venus_hfi_device *device)
|
|||
int rc = 0;
|
||||
struct bus_info *bus = NULL;
|
||||
|
||||
kfree(device->bus_vote.data);
|
||||
device->bus_vote.data = NULL;
|
||||
device->bus_vote.data_count = 0;
|
||||
device->bus_vote = DEFAULT_BUS_VOTE;
|
||||
|
||||
venus_hfi_for_each_bus(device, bus) {
|
||||
rc = __vote_bandwidth(bus, 0);
|
||||
|
|
@ -1016,63 +1017,56 @@ err_unknown_device:
|
|||
}
|
||||
|
||||
static int __vote_buses(struct venus_hfi_device *device,
|
||||
struct vidc_bus_vote_data *data, int num_data)
|
||||
unsigned long bw_ddr, unsigned long bw_llcc)
|
||||
{
|
||||
int rc = 0;
|
||||
struct bus_info *bus = NULL;
|
||||
struct vidc_bus_vote_data *new_data = NULL;
|
||||
unsigned long bw_kbps = 0;
|
||||
unsigned long bw_kbps = 0, bw_prev = 0;
|
||||
enum vidc_bus_type type;
|
||||
|
||||
if (!num_data) {
|
||||
dprintk(VIDC_LOW, "No vote data available\n");
|
||||
goto no_data_count;
|
||||
} else if (!data) {
|
||||
dprintk(VIDC_ERR, "Invalid voting data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
new_data = kmemdup(data, num_data * sizeof(*new_data), GFP_KERNEL);
|
||||
if (!new_data) {
|
||||
dprintk(VIDC_ERR, "Can't alloc memory to cache bus votes\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_no_mem;
|
||||
}
|
||||
|
||||
no_data_count:
|
||||
kfree(device->bus_vote.data);
|
||||
device->bus_vote.data = new_data;
|
||||
device->bus_vote.data_count = num_data;
|
||||
|
||||
if (device->bus_vote.calc_bw)
|
||||
device->bus_vote.calc_bw(&device->bus_vote);
|
||||
|
||||
venus_hfi_for_each_bus(device, bus) {
|
||||
if (bus && bus->client) {
|
||||
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
|
||||
if (type == DDR) {
|
||||
bw_kbps = bw_ddr;
|
||||
bw_prev = device->bus_vote.total_bw_ddr;
|
||||
} else if (type == LLCC) {
|
||||
bw_kbps = bw_llcc;
|
||||
bw_prev = device->bus_vote.total_bw_llcc;
|
||||
} else {
|
||||
bw_kbps = bus->range[1];
|
||||
bw_prev = device->bus_vote.total_bw_ddr ?
|
||||
bw_kbps : 0;
|
||||
}
|
||||
|
||||
/* ensure freq is within limits */
|
||||
bw_kbps = clamp_t(typeof(bw_kbps), bw_kbps,
|
||||
bus->range[0], bus->range[1]);
|
||||
|
||||
if (TRIVIAL_BW_CHANGE(bw_kbps, bw_prev) && bw_prev) {
|
||||
dprintk(VIDC_PERF,
|
||||
"Skip voting bus %s to %llu bps",
|
||||
bus->name, bw_kbps * 1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = __vote_bandwidth(bus, bw_kbps);
|
||||
|
||||
if (type == DDR)
|
||||
device->bus_vote.total_bw_ddr = bw_kbps;
|
||||
else if (type == LLCC)
|
||||
device->bus_vote.total_bw_llcc = bw_kbps;
|
||||
} else {
|
||||
dprintk(VIDC_ERR, "No BUS to Vote\n");
|
||||
}
|
||||
}
|
||||
|
||||
err_no_mem:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int venus_hfi_vote_buses(void *dev, struct vidc_bus_vote_data *d, int n)
|
||||
static int venus_hfi_vote_buses(void *dev, unsigned long bw_ddr,
|
||||
unsigned long bw_llcc)
|
||||
{
|
||||
int rc = 0;
|
||||
struct venus_hfi_device *device = dev;
|
||||
|
|
@ -1081,11 +1075,10 @@ static int venus_hfi_vote_buses(void *dev, struct vidc_bus_vote_data *d, int n)
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&device->lock);
|
||||
rc = __vote_buses(device, d, n);
|
||||
rc = __vote_buses(device, bw_ddr, bw_llcc);
|
||||
mutex_unlock(&device->lock);
|
||||
|
||||
return rc;
|
||||
|
||||
}
|
||||
static int __core_set_resource(struct venus_hfi_device *device,
|
||||
struct vidc_resource_hdr *resource_hdr, void *resource_value)
|
||||
|
|
@ -2055,16 +2048,7 @@ static int venus_hfi_core_init(void *device)
|
|||
|
||||
mutex_lock(&dev->lock);
|
||||
|
||||
dev->bus_vote.data =
|
||||
kzalloc(sizeof(struct vidc_bus_vote_data), GFP_KERNEL);
|
||||
if (!dev->bus_vote.data) {
|
||||
dprintk(VIDC_ERR, "Bus vote data memory is not allocated\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_no_mem;
|
||||
}
|
||||
|
||||
dev->bus_vote.data_count = 1;
|
||||
dev->bus_vote.data->power_mode = VIDC_POWER_TURBO;
|
||||
dev->bus_vote = DEFAULT_BUS_VOTE;
|
||||
|
||||
rc = __load_fw(dev);
|
||||
if (rc) {
|
||||
|
|
@ -2131,7 +2115,6 @@ err_core_init:
|
|||
__set_state(dev, VENUS_STATE_DEINIT);
|
||||
__unload_fw(dev);
|
||||
err_load_fw:
|
||||
err_no_mem:
|
||||
dprintk(VIDC_ERR, "Core init failed\n");
|
||||
mutex_unlock(&dev->lock);
|
||||
return rc;
|
||||
|
|
@ -3924,7 +3907,6 @@ static void __deinit_bus(struct venus_hfi_device *device)
|
|||
if (!device)
|
||||
return;
|
||||
|
||||
kfree(device->bus_vote.data);
|
||||
device->bus_vote = DEFAULT_BUS_VOTE;
|
||||
|
||||
venus_hfi_for_each_bus_reverse(device, bus) {
|
||||
|
|
@ -3962,11 +3944,6 @@ static int __init_bus(struct venus_hfi_device *device)
|
|||
}
|
||||
}
|
||||
|
||||
if (device->res->vpu_ver == VPU_VERSION_IRIS1)
|
||||
device->bus_vote.calc_bw = calc_bw_iris1;
|
||||
else
|
||||
device->bus_vote.calc_bw = calc_bw_iris2;
|
||||
|
||||
return 0;
|
||||
|
||||
err_add_dev:
|
||||
|
|
@ -4508,8 +4485,7 @@ static int __venus_power_on(struct venus_hfi_device *device)
|
|||
|
||||
device->power_enabled = true;
|
||||
/* Vote for all hardware resources */
|
||||
rc = __vote_buses(device, device->bus_vote.data,
|
||||
device->bus_vote.data_count);
|
||||
rc = __vote_buses(device, INT_MAX, INT_MAX);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to vote buses, err: %d\n", rc);
|
||||
goto fail_vote_buses;
|
||||
|
|
@ -4774,7 +4750,6 @@ static void __unload_fw(struct venus_hfi_device *device)
|
|||
if (device->state != VENUS_STATE_DEINIT)
|
||||
flush_workqueue(device->venus_pm_workq);
|
||||
|
||||
__vote_buses(device, NULL, 0);
|
||||
subsystem_put(device->resources.fw.cookie);
|
||||
__interface_queues_release(device);
|
||||
call_venus_op(device, power_off, device);
|
||||
|
|
|
|||
|
|
@ -255,8 +255,6 @@ struct venus_hfi_device {
|
|||
u32 device_id;
|
||||
u32 clk_freq;
|
||||
u32 last_packet_type;
|
||||
unsigned long clk_bitrate;
|
||||
unsigned long scaled_rate;
|
||||
struct msm_vidc_bus_data bus_vote;
|
||||
bool power_enabled;
|
||||
struct mutex lock;
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ static int msm_cvp_scale_clocks_and_bus(struct msm_vidc_inst *inst)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
rc = msm_comm_vote_bus(inst->core);
|
||||
rc = msm_comm_vote_bus(inst);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: failed vote_bus for inst %pK (%#x)\n",
|
||||
|
|
|
|||
|
|
@ -213,40 +213,14 @@ struct dump {
|
|||
size_t val;
|
||||
};
|
||||
|
||||
struct vidc_bus_vote_data {
|
||||
enum hal_domain domain;
|
||||
enum hal_video_codec codec;
|
||||
enum hal_uncompressed_format color_formats[2];
|
||||
int num_formats; /* 1 = DPB-OPB unified; 2 = split */
|
||||
int input_height, input_width, bitrate;
|
||||
int output_height, output_width;
|
||||
int rotation;
|
||||
int compression_ratio;
|
||||
int complexity_factor;
|
||||
int input_cr;
|
||||
u32 ddr_bw;
|
||||
u32 sys_cache_bw;
|
||||
unsigned int lcu_size;
|
||||
unsigned int fps;
|
||||
enum msm_vidc_power_mode power_mode;
|
||||
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 total_bw_ddr;
|
||||
unsigned long total_bw_llcc;
|
||||
int (*calc_bw)(struct msm_vidc_bus_data *data);
|
||||
};
|
||||
|
||||
int calc_bw_iris1(struct msm_vidc_bus_data *vidc_data);
|
||||
int calc_bw_iris1(struct vidc_bus_vote_data *vidc_data);
|
||||
|
||||
int calc_bw_iris2(struct msm_vidc_bus_data *vidc_data);
|
||||
int calc_bw_iris2(struct vidc_bus_vote_data *vidc_data);
|
||||
|
||||
struct lut const *__lut(int width, int height, int fps);
|
||||
fp_t __compression_ratio(struct lut const *entry, int bpp);
|
||||
|
|
|
|||
|
|
@ -75,12 +75,7 @@ static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d)
|
|||
|
||||
static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d)
|
||||
{
|
||||
unsigned long ret = 0;
|
||||
|
||||
d->calc_bw_ddr = d->ddr_bw;
|
||||
d->calc_bw_llcc = d->sys_cache_bw;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d)
|
||||
|
|
@ -641,31 +636,15 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d)
|
|||
return value;
|
||||
}
|
||||
|
||||
int calc_bw_iris1(struct msm_vidc_bus_data *vidc_data)
|
||||
int calc_bw_iris1(struct vidc_bus_vote_data *vidc_data)
|
||||
{
|
||||
int ret = 0, c = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!vidc_data || !vidc_data->data_count || !vidc_data->data)
|
||||
goto exit;
|
||||
if (!vidc_data)
|
||||
return ret;
|
||||
|
||||
vidc_data->total_bw_ddr = 0;
|
||||
vidc_data->total_bw_llcc = 0;
|
||||
ret = __calculate(vidc_data);
|
||||
|
||||
for (c = 0; c < vidc_data->data_count; ++c) {
|
||||
if (vidc_data->data->power_mode == VIDC_POWER_TURBO) {
|
||||
vidc_data->total_bw_ddr = INT_MAX;
|
||||
vidc_data->total_bw_llcc = INT_MAX;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,12 +13,7 @@ static unsigned long __calculate_vpe(struct vidc_bus_vote_data *d)
|
|||
|
||||
static unsigned long __calculate_cvp(struct vidc_bus_vote_data *d)
|
||||
{
|
||||
unsigned long ret = 0;
|
||||
|
||||
d->calc_bw_ddr = d->ddr_bw;
|
||||
d->calc_bw_llcc = d->sys_cache_bw;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long __calculate_decoder(struct vidc_bus_vote_data *d)
|
||||
|
|
@ -545,30 +540,14 @@ static unsigned long __calculate(struct vidc_bus_vote_data *d)
|
|||
return value;
|
||||
}
|
||||
|
||||
int calc_bw_iris2(struct msm_vidc_bus_data *vidc_data)
|
||||
int calc_bw_iris2(struct vidc_bus_vote_data *vidc_data)
|
||||
{
|
||||
int ret = 0, c = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!vidc_data || !vidc_data->data_count || !vidc_data->data)
|
||||
goto exit;
|
||||
if (!vidc_data)
|
||||
return ret;
|
||||
|
||||
vidc_data->total_bw_ddr = 0;
|
||||
vidc_data->total_bw_llcc = 0;
|
||||
ret = __calculate(vidc_data);
|
||||
|
||||
for (c = 0; c < vidc_data->data_count; ++c) {
|
||||
if (vidc_data->data->power_mode == VIDC_POWER_TURBO) {
|
||||
vidc_data->total_bw_ddr = INT_MAX;
|
||||
vidc_data->total_bw_llcc = INT_MAX;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ struct msm_vidc_core_ops core_ops_ar50 = {
|
|||
.decide_work_route = NULL,
|
||||
.decide_work_mode = msm_vidc_decide_work_mode_ar50,
|
||||
.decide_core_and_power_mode = NULL,
|
||||
.calc_bw = NULL,
|
||||
};
|
||||
|
||||
struct msm_vidc_core_ops core_ops_iris1 = {
|
||||
|
|
@ -36,6 +37,7 @@ struct msm_vidc_core_ops core_ops_iris1 = {
|
|||
.decide_work_route = msm_vidc_decide_work_route_iris1,
|
||||
.decide_work_mode = msm_vidc_decide_work_mode_iris1,
|
||||
.decide_core_and_power_mode = msm_vidc_decide_core_and_power_mode_iris1,
|
||||
.calc_bw = calc_bw_iris1,
|
||||
};
|
||||
|
||||
struct msm_vidc_core_ops core_ops_iris2 = {
|
||||
|
|
@ -43,6 +45,7 @@ struct msm_vidc_core_ops core_ops_iris2 = {
|
|||
.decide_work_route = msm_vidc_decide_work_route_iris2,
|
||||
.decide_work_mode = msm_vidc_decide_work_mode_iris2,
|
||||
.decide_core_and_power_mode = msm_vidc_decide_core_and_power_mode_iris2,
|
||||
.calc_bw = calc_bw_iris2,
|
||||
};
|
||||
|
||||
static inline void msm_dcvs_print_dcvs_stats(struct clock_data *dcvs)
|
||||
|
|
@ -256,15 +259,12 @@ static int fill_dynamic_stats(struct msm_vidc_inst *inst,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int msm_comm_vote_bus(struct msm_vidc_core *core)
|
||||
int msm_comm_set_buses(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0, vote_data_count = 0, i = 0;
|
||||
struct hfi_device *hdev;
|
||||
int rc = 0;
|
||||
struct msm_vidc_inst *inst = NULL;
|
||||
struct vidc_bus_vote_data *vote_data = NULL;
|
||||
bool is_turbo = false;
|
||||
struct v4l2_format *out_f;
|
||||
struct v4l2_format *inp_f;
|
||||
struct hfi_device *hdev;
|
||||
unsigned long total_bw_ddr = 0, total_bw_llcc = 0;
|
||||
|
||||
if (!core || !core->device) {
|
||||
dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core);
|
||||
|
|
@ -272,23 +272,8 @@ int msm_comm_vote_bus(struct msm_vidc_core *core)
|
|||
}
|
||||
hdev = core->device;
|
||||
|
||||
vote_data = kzalloc(sizeof(struct vidc_bus_vote_data) *
|
||||
MAX_SUPPORTED_INSTANCES, GFP_ATOMIC);
|
||||
if (!vote_data) {
|
||||
dprintk(VIDC_LOW,
|
||||
"vote_data allocation with GFP_ATOMIC failed\n");
|
||||
vote_data = kzalloc(sizeof(struct vidc_bus_vote_data) *
|
||||
MAX_SUPPORTED_INSTANCES, GFP_KERNEL);
|
||||
if (!vote_data) {
|
||||
dprintk(VIDC_ERR,
|
||||
"vote_data allocation failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
list_for_each_entry(inst, &core->instances, list) {
|
||||
int codec = 0;
|
||||
struct msm_vidc_buffer *temp, *next;
|
||||
u32 filled_len = 0;
|
||||
u32 device_addr = 0;
|
||||
|
|
@ -301,11 +286,6 @@ int msm_comm_vote_bus(struct msm_vidc_core *core)
|
|||
temp->vvb.vb2_buf.planes[0].bytesused);
|
||||
device_addr = temp->smem[0].device_addr;
|
||||
}
|
||||
if (inst->session_type == MSM_VIDC_ENCODER &&
|
||||
(temp->vvb.flags &
|
||||
V4L2_BUF_FLAG_PERF_MODE)) {
|
||||
is_turbo = true;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&inst->registeredbufs.lock);
|
||||
|
||||
|
|
@ -316,8 +296,75 @@ int msm_comm_vote_bus(struct msm_vidc_core *core)
|
|||
continue;
|
||||
}
|
||||
|
||||
++vote_data_count;
|
||||
if (inst->bus_data.power_mode == VIDC_POWER_TURBO) {
|
||||
total_bw_ddr = total_bw_llcc = INT_MAX;
|
||||
break;
|
||||
}
|
||||
total_bw_ddr += inst->bus_data.calc_bw_ddr;
|
||||
total_bw_llcc += inst->bus_data.calc_bw_llcc;
|
||||
}
|
||||
mutex_unlock(&core->lock);
|
||||
|
||||
rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data,
|
||||
total_bw_ddr, total_bw_llcc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_comm_vote_bus(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_core *core;
|
||||
struct vidc_bus_vote_data *vote_data = NULL;
|
||||
bool is_turbo = false;
|
||||
struct v4l2_format *out_f;
|
||||
struct v4l2_format *inp_f;
|
||||
struct msm_vidc_buffer *temp, *next;
|
||||
u32 filled_len = 0;
|
||||
u32 device_addr = 0;
|
||||
int codec = 0;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
|
||||
return -EINVAL;
|
||||
}
|
||||
core = inst->core;
|
||||
vote_data = &inst->bus_data;
|
||||
|
||||
mutex_lock(&inst->registeredbufs.lock);
|
||||
list_for_each_entry_safe(temp, next,
|
||||
&inst->registeredbufs.list, list) {
|
||||
if (temp->vvb.vb2_buf.type == INPUT_MPLANE) {
|
||||
filled_len = max(filled_len,
|
||||
temp->vvb.vb2_buf.planes[0].bytesused);
|
||||
device_addr = temp->smem[0].device_addr;
|
||||
}
|
||||
if (inst->session_type == MSM_VIDC_ENCODER &&
|
||||
(temp->vvb.flags & V4L2_BUF_FLAG_PERF_MODE)) {
|
||||
is_turbo = true;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&inst->registeredbufs.lock);
|
||||
|
||||
if ((!filled_len || !device_addr) &&
|
||||
(inst->session_type != MSM_VIDC_CVP)) {
|
||||
dprintk(VIDC_LOW, "%s: no input for session %x\n",
|
||||
__func__, hash32_ptr(inst->session));
|
||||
return 0;
|
||||
}
|
||||
|
||||
vote_data->domain = get_hal_domain(inst->session_type);
|
||||
vote_data->power_mode = 0;
|
||||
if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW &&
|
||||
inst->session_type != MSM_VIDC_CVP)
|
||||
vote_data->power_mode = VIDC_POWER_TURBO;
|
||||
if (msm_vidc_clock_voting || is_turbo)
|
||||
vote_data->power_mode = VIDC_POWER_TURBO;
|
||||
|
||||
if (inst->session_type == MSM_VIDC_CVP) {
|
||||
vote_data->calc_bw_ddr= inst->clk_data.ddr_bw;
|
||||
vote_data->calc_bw_llcc= inst->clk_data.sys_cache_bw;
|
||||
} else if (vote_data->power_mode != VIDC_POWER_TURBO) {
|
||||
out_f = &inst->fmts[OUTPUT_PORT].v4l2_fmt;
|
||||
inp_f = &inst->fmts[INPUT_PORT].v4l2_fmt;
|
||||
switch (inst->session_type) {
|
||||
|
|
@ -336,81 +383,60 @@ int msm_comm_vote_bus(struct msm_vidc_core *core)
|
|||
break;
|
||||
}
|
||||
|
||||
memset(&(vote_data[i]), 0x0, sizeof(struct vidc_bus_vote_data));
|
||||
|
||||
vote_data[i].domain = get_hal_domain(inst->session_type);
|
||||
vote_data[i].codec = get_hal_codec(codec);
|
||||
vote_data[i].input_width = inp_f->fmt.pix_mp.width;
|
||||
vote_data[i].input_height = inp_f->fmt.pix_mp.height;
|
||||
vote_data[i].output_width = out_f->fmt.pix_mp.width;
|
||||
vote_data[i].output_height = out_f->fmt.pix_mp.height;
|
||||
vote_data[i].lcu_size = (codec == V4L2_PIX_FMT_HEVC ||
|
||||
vote_data->codec = get_hal_codec(codec);
|
||||
vote_data->input_width = inp_f->fmt.pix_mp.width;
|
||||
vote_data->input_height = inp_f->fmt.pix_mp.height;
|
||||
vote_data->output_width = out_f->fmt.pix_mp.width;
|
||||
vote_data->output_height = out_f->fmt.pix_mp.height;
|
||||
vote_data->lcu_size = (codec == V4L2_PIX_FMT_HEVC ||
|
||||
codec == V4L2_PIX_FMT_VP9) ? 32 : 16;
|
||||
|
||||
vote_data[i].fps = msm_vidc_get_fps(inst);
|
||||
vote_data->fps = msm_vidc_get_fps(inst);
|
||||
if (inst->session_type == MSM_VIDC_ENCODER) {
|
||||
vote_data[i].bitrate = inst->clk_data.bitrate;
|
||||
vote_data[i].rotation =
|
||||
vote_data->bitrate = inst->clk_data.bitrate;
|
||||
vote_data->rotation =
|
||||
msm_comm_g_ctrl_for_id(inst, V4L2_CID_ROTATE);
|
||||
vote_data[i].b_frames_enabled =
|
||||
vote_data->b_frames_enabled =
|
||||
msm_comm_g_ctrl_for_id(inst,
|
||||
V4L2_CID_MPEG_VIDEO_B_FRAMES) != 0;
|
||||
/* scale bitrate if operating rate is larger than fps */
|
||||
if (vote_data[i].fps > (inst->clk_data.frame_rate >> 16)
|
||||
if (vote_data->fps > (inst->clk_data.frame_rate >> 16)
|
||||
&& (inst->clk_data.frame_rate >> 16)) {
|
||||
vote_data[i].bitrate = vote_data[i].bitrate /
|
||||
vote_data->bitrate = vote_data->bitrate /
|
||||
(inst->clk_data.frame_rate >> 16) *
|
||||
vote_data[i].fps;
|
||||
vote_data->fps;
|
||||
}
|
||||
} else if (inst->session_type == MSM_VIDC_DECODER) {
|
||||
vote_data[i].bitrate =
|
||||
filled_len * vote_data[i].fps * 8;
|
||||
vote_data->bitrate =
|
||||
filled_len * vote_data->fps * 8;
|
||||
}
|
||||
|
||||
vote_data[i].power_mode = 0;
|
||||
if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW &&
|
||||
inst->session_type != MSM_VIDC_CVP)
|
||||
vote_data[i].power_mode = VIDC_POWER_TURBO;
|
||||
if (msm_vidc_clock_voting || is_turbo)
|
||||
vote_data[i].power_mode = VIDC_POWER_TURBO;
|
||||
|
||||
if (msm_comm_get_stream_output_mode(inst) ==
|
||||
HAL_VIDEO_DECODER_PRIMARY) {
|
||||
vote_data[i].color_formats[0] =
|
||||
vote_data->color_formats[0] =
|
||||
msm_comm_get_hal_uncompressed(
|
||||
inst->clk_data.opb_fourcc);
|
||||
vote_data[i].num_formats = 1;
|
||||
vote_data->num_formats = 1;
|
||||
} else {
|
||||
vote_data[i].color_formats[0] =
|
||||
vote_data->color_formats[0] =
|
||||
msm_comm_get_hal_uncompressed(
|
||||
inst->clk_data.dpb_fourcc);
|
||||
vote_data[i].color_formats[1] =
|
||||
vote_data->color_formats[1] =
|
||||
msm_comm_get_hal_uncompressed(
|
||||
inst->clk_data.opb_fourcc);
|
||||
vote_data[i].num_formats = 2;
|
||||
vote_data->num_formats = 2;
|
||||
}
|
||||
vote_data[i].work_mode = inst->clk_data.work_mode;
|
||||
fill_dynamic_stats(inst, &vote_data[i]);
|
||||
vote_data->work_mode = inst->clk_data.work_mode;
|
||||
fill_dynamic_stats(inst, vote_data);
|
||||
|
||||
if (core->resources.sys_cache_res_set)
|
||||
vote_data[i].use_sys_cache = true;
|
||||
vote_data->use_sys_cache = true;
|
||||
|
||||
if (inst->session_type == MSM_VIDC_CVP) {
|
||||
vote_data[i].domain =
|
||||
get_hal_domain(inst->session_type);
|
||||
vote_data[i].ddr_bw = inst->clk_data.ddr_bw;
|
||||
vote_data[i].sys_cache_bw =
|
||||
inst->clk_data.sys_cache_bw;
|
||||
}
|
||||
|
||||
i++;
|
||||
call_core_op(core, calc_bw, vote_data);
|
||||
}
|
||||
mutex_unlock(&core->lock);
|
||||
if (vote_data_count)
|
||||
rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data,
|
||||
vote_data, vote_data_count);
|
||||
|
||||
kfree(vote_data);
|
||||
rc = msm_comm_set_buses(core);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1058,7 +1084,7 @@ int msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst, bool do_bw_calc)
|
|||
}
|
||||
|
||||
if (do_bw_calc) {
|
||||
if (msm_comm_vote_bus(core)) {
|
||||
if (msm_comm_vote_bus(inst)) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to scale DDR bus. May impact perf\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
void msm_clock_data_reset(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_set_clocks(struct msm_vidc_core *core);
|
||||
int msm_comm_vote_bus(struct msm_vidc_core *core);
|
||||
int msm_comm_vote_bus(struct msm_vidc_inst *inst);
|
||||
int msm_dcvs_try_enable(struct msm_vidc_inst *inst);
|
||||
bool res_is_less_than(u32 width, u32 height, u32 ref_width, u32 ref_height);
|
||||
bool res_is_greater_than(u32 width, u32 height, u32 ref_width, u32 ref_height);
|
||||
|
|
|
|||
|
|
@ -423,6 +423,27 @@ struct clock_data {
|
|||
u32 frame_rate;
|
||||
};
|
||||
|
||||
struct vidc_bus_vote_data {
|
||||
enum hal_domain domain;
|
||||
enum hal_video_codec codec;
|
||||
enum hal_uncompressed_format color_formats[2];
|
||||
int num_formats; /* 1 = DPB-OPB unified; 2 = split */
|
||||
int input_height, input_width, bitrate;
|
||||
int output_height, output_width;
|
||||
int rotation;
|
||||
int compression_ratio;
|
||||
int complexity_factor;
|
||||
int input_cr;
|
||||
unsigned int lcu_size;
|
||||
unsigned int fps;
|
||||
enum msm_vidc_power_mode power_mode;
|
||||
u32 work_mode;
|
||||
bool use_sys_cache;
|
||||
bool b_frames_enabled;
|
||||
unsigned long calc_bw_ddr;
|
||||
unsigned long calc_bw_llcc;
|
||||
};
|
||||
|
||||
struct profile_data {
|
||||
int start;
|
||||
int stop;
|
||||
|
|
@ -450,6 +471,7 @@ struct msm_vidc_core_ops {
|
|||
int (*decide_work_route)(struct msm_vidc_inst *inst);
|
||||
int (*decide_work_mode)(struct msm_vidc_inst *inst);
|
||||
int (*decide_core_and_power_mode)(struct msm_vidc_inst *inst);
|
||||
int (*calc_bw)(struct vidc_bus_vote_data *vidc_data);
|
||||
};
|
||||
|
||||
struct msm_vidc_core {
|
||||
|
|
@ -524,6 +546,7 @@ struct msm_vidc_inst {
|
|||
struct msm_vidc_debug debug;
|
||||
struct buf_count count;
|
||||
struct clock_data clk_data;
|
||||
struct vidc_bus_vote_data bus_data;
|
||||
enum msm_vidc_modes flags;
|
||||
struct msm_vidc_capability capability;
|
||||
u32 buffer_size_limit;
|
||||
|
|
|
|||
|
|
@ -58,8 +58,6 @@
|
|||
/* 16 video sessions */
|
||||
#define VIDC_MAX_SESSIONS 16
|
||||
|
||||
struct vidc_bus_vote_data;
|
||||
|
||||
enum vidc_status {
|
||||
VIDC_ERR_NONE = 0x0,
|
||||
VIDC_ERR_FAIL = 0x80000000,
|
||||
|
|
@ -721,8 +719,8 @@ struct hfi_device {
|
|||
int (*session_pause)(void *sess);
|
||||
int (*session_resume)(void *sess);
|
||||
int (*scale_clocks)(void *dev, u32 freq);
|
||||
int (*vote_bus)(void *dev, struct vidc_bus_vote_data *data,
|
||||
int num_data);
|
||||
int (*vote_bus)(void *dev, unsigned long bw_ddr,
|
||||
unsigned long bw_llcc);
|
||||
int (*get_fw_info)(void *dev, struct hal_fw_info *fw_info);
|
||||
int (*session_clean)(void *sess);
|
||||
int (*get_core_capabilities)(void *dev);
|
||||
|
|
|
|||
Loading…
Reference in a new issue