waipio: driver: Add support for work mode and route
Iris2 specific calculations for Work Mode and Route. Also add quality mode support. Change-Id: I7a1e2fa27236aa749978d146d85fd0af6177084c Signed-off-by: Chinmay Sawarkar <chinmays@codeaurora.org>
This commit is contained in:
@@ -17,7 +17,6 @@
|
||||
#include "msm_vidc_buffer.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
|
||||
|
||||
#define VBIF_BASE_OFFS_IRIS2 0x00080000
|
||||
#define CPU_BASE_OFFS_IRIS2 0x000A0000
|
||||
#define AON_BASE_OFFS 0x000E0000
|
||||
@@ -484,6 +483,170 @@ static int __boot_firmware_iris2(struct msm_vidc_core *vidc_core)
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool res_is_greater_than(u32 width, u32 height,
|
||||
u32 ref_width, u32 ref_height)
|
||||
{
|
||||
u32 num_mbs = NUM_MBS_PER_FRAME(height, width);
|
||||
u32 max_side = max(ref_width, ref_height);
|
||||
|
||||
if (num_mbs > NUM_MBS_PER_FRAME(ref_height, ref_width) ||
|
||||
width > max_side ||
|
||||
height > max_side)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool res_is_less_than_or_equal_to(u32 width, u32 height,
|
||||
u32 ref_width, u32 ref_height)
|
||||
{
|
||||
u32 num_mbs = NUM_MBS_PER_FRAME(height, width);
|
||||
u32 max_side = max(ref_width, ref_height);
|
||||
|
||||
if (num_mbs <= NUM_MBS_PER_FRAME(ref_height, ref_width) &&
|
||||
width <= max_side &&
|
||||
height <= max_side)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst* inst)
|
||||
{
|
||||
u32 work_mode;
|
||||
struct v4l2_format* out_f;
|
||||
struct v4l2_format* inp_f;
|
||||
u32 width, height;
|
||||
bool res_ok = false;
|
||||
bool lowlatency = false;
|
||||
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
work_mode = MSM_VIDC_STAGE_2;
|
||||
out_f = &inst->fmts[OUTPUT_PORT];
|
||||
inp_f = &inst->fmts[INPUT_PORT];
|
||||
|
||||
if (is_decode_session(inst)) {
|
||||
height = out_f->fmt.pix_mp.height;
|
||||
width = out_f->fmt.pix_mp.width;
|
||||
res_ok = res_is_less_than_or_equal_to(width, height, 1280, 720);
|
||||
if (inst->capabilities->cap[CODED_FRAMES].value ==
|
||||
CODED_FRAMES_ADAPTIVE_FIELDS ||
|
||||
inst->capabilities->cap[LOWLATENCY_MODE].value ||
|
||||
res_ok) {
|
||||
work_mode = MSM_VIDC_STAGE_1;
|
||||
}
|
||||
} else if (is_encode_session(inst)) {
|
||||
height = inp_f->fmt.pix_mp.height;
|
||||
width = inp_f->fmt.pix_mp.width;
|
||||
res_ok = !res_is_greater_than(width, height, 4096, 2160);
|
||||
if (res_ok &&
|
||||
(inst->capabilities->cap[LOWLATENCY_MODE].value)) {
|
||||
work_mode = MSM_VIDC_STAGE_1;
|
||||
/* For WORK_MODE_1, set Low Latency mode by default */
|
||||
lowlatency = true;
|
||||
}
|
||||
if (inst->capabilities->cap[LOSSLESS].value) {
|
||||
/*TODO Set 2 stage in case of ALL INTRA */
|
||||
work_mode = MSM_VIDC_STAGE_2;
|
||||
lowlatency = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
d_vpr_e("%s: invalid session type\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s_vpr_h(inst->sid, "Configuring work mode = %u low latency = %u",
|
||||
work_mode, lowlatency);
|
||||
inst->capabilities->cap[STAGE].value = work_mode;
|
||||
|
||||
/* TODO If Encode then Set Low Latency (Enable/Disable)
|
||||
* and Update internal cap struct
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst* inst)
|
||||
{
|
||||
u32 work_route;
|
||||
struct msm_vidc_core* core;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core = inst->core;
|
||||
work_route = core->capabilities[NUM_VPP_PIPE].value;
|
||||
|
||||
if (is_decode_session(inst)) {
|
||||
if (inst->capabilities->cap[CODED_FRAMES].value ==
|
||||
CODED_FRAMES_ADAPTIVE_FIELDS)
|
||||
work_route = MSM_VIDC_PIPE_1;
|
||||
} else if (is_encode_session(inst)) {
|
||||
u32 slice_mode, width, height;
|
||||
struct v4l2_format* f;
|
||||
|
||||
f = &inst->fmts[INPUT_PORT];
|
||||
height = f->fmt.pix_mp.height;
|
||||
width = f->fmt.pix_mp.width;
|
||||
slice_mode = inst->capabilities->cap[SLICE_MODE].value;
|
||||
|
||||
/*TODO Pipe=1 for legacy CBR*/
|
||||
if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES)
|
||||
work_route = MSM_VIDC_PIPE_1;
|
||||
|
||||
} else {
|
||||
d_vpr_e("%s: invalid session type\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s_vpr_h(inst->sid, "Configuring work route = %u", work_route);
|
||||
inst->capabilities->cap[PIPE].value = work_route;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_decide_quality_mode_iris2(struct msm_vidc_inst* inst)
|
||||
{
|
||||
struct msm_vidc_inst_capability* capability = inst->capabilities;
|
||||
struct msm_vidc_core *core;
|
||||
u32 mbpf, mbps, max_hq_mbpf, max_hq_mbps;
|
||||
u32 mode;
|
||||
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!is_encode_session(inst))
|
||||
return 0;
|
||||
|
||||
mode = MSM_VIDC_POWER_SAVE_MODE;
|
||||
mbpf = msm_vidc_get_mbs_per_frame(inst);
|
||||
mbps = mbpf * msm_vidc_get_fps(inst);
|
||||
core = inst->core;
|
||||
max_hq_mbpf = core->capabilities[MAX_MBPF_HQ].value;;
|
||||
max_hq_mbps = core->capabilities[MAX_MBPS_HQ].value;;
|
||||
|
||||
/* Power saving always disabled for CQ and LOSSLESS RC modes. */
|
||||
if (inst->capabilities->cap[LOSSLESS].value ||
|
||||
(mbpf <= max_hq_mbpf && mbps <= max_hq_mbps))
|
||||
mode = MSM_VIDC_MAX_QUALITY_MODE;
|
||||
|
||||
inst->flags = mode == MSM_VIDC_POWER_SAVE_MODE ?
|
||||
inst->flags | VIDC_LOW_POWER :
|
||||
inst->flags & ~VIDC_LOW_POWER;
|
||||
capability->cap[QUALITY_MODE].value = mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct msm_vidc_venus_ops iris2_ops = {
|
||||
.boot_firmware = __boot_firmware_iris2,
|
||||
.interrupt_init = __interrupt_init_iris2,
|
||||
@@ -504,9 +667,9 @@ static struct msm_vidc_session_ops msm_session_ops = {
|
||||
.extra_count = msm_buffer_extra_count_iris2,
|
||||
.calc_freq = msm_vidc_calc_freq_iris2,
|
||||
.calc_bw = msm_vidc_calc_bw_iris2,
|
||||
.decide_work_route = NULL,
|
||||
.decide_work_mode = NULL,
|
||||
.decide_core_and_power_mode = NULL,
|
||||
.decide_work_route = msm_vidc_decide_work_route_iris2,
|
||||
.decide_work_mode = msm_vidc_decide_work_mode_iris2,
|
||||
.decide_quality_mode = msm_vidc_decide_quality_mode_iris2,
|
||||
};
|
||||
|
||||
int msm_vidc_init_iris2(struct msm_vidc_core *core)
|
||||
|
Reference in New Issue
Block a user