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:
Qiwei Liu 2019-08-09 11:14:47 +08:00 • committed by Gerrit - the friendly Code Review server
commit 1ec1845dab
10 changed files with 179 additions and 227 deletions

View file

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

View file

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

View file

@ -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",

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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