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:
@@ -959,7 +959,7 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
|||||||
{QUALITY_MODE, ENC, CODECS_ALL,
|
{QUALITY_MODE, ENC, CODECS_ALL,
|
||||||
MSM_VIDC_MAX_QUALITY_MODE,
|
MSM_VIDC_MAX_QUALITY_MODE,
|
||||||
MSM_VIDC_POWER_SAVE_MODE, 1,
|
MSM_VIDC_POWER_SAVE_MODE, 1,
|
||||||
MSM_VIDC_MAX_QUALITY_MODE},
|
MSM_VIDC_POWER_SAVE_MODE},
|
||||||
|
|
||||||
{CODED_FRAMES, DEC, CODECS_ALL,
|
{CODED_FRAMES, DEC, CODECS_ALL,
|
||||||
CODED_FRAMES_MBS_ONLY, CODED_FRAMES_ADAPTIVE_FIELDS,
|
CODED_FRAMES_MBS_ONLY, CODED_FRAMES_ADAPTIVE_FIELDS,
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
#include "msm_vidc_buffer.h"
|
#include "msm_vidc_buffer.h"
|
||||||
#include "msm_vidc_debug.h"
|
#include "msm_vidc_debug.h"
|
||||||
|
|
||||||
|
|
||||||
#define VBIF_BASE_OFFS_IRIS2 0x00080000
|
#define VBIF_BASE_OFFS_IRIS2 0x00080000
|
||||||
#define CPU_BASE_OFFS_IRIS2 0x000A0000
|
#define CPU_BASE_OFFS_IRIS2 0x000A0000
|
||||||
#define AON_BASE_OFFS 0x000E0000
|
#define AON_BASE_OFFS 0x000E0000
|
||||||
@@ -484,6 +483,170 @@ static int __boot_firmware_iris2(struct msm_vidc_core *vidc_core)
|
|||||||
return rc;
|
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 = {
|
static struct msm_vidc_venus_ops iris2_ops = {
|
||||||
.boot_firmware = __boot_firmware_iris2,
|
.boot_firmware = __boot_firmware_iris2,
|
||||||
.interrupt_init = __interrupt_init_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,
|
.extra_count = msm_buffer_extra_count_iris2,
|
||||||
.calc_freq = msm_vidc_calc_freq_iris2,
|
.calc_freq = msm_vidc_calc_freq_iris2,
|
||||||
.calc_bw = msm_vidc_calc_bw_iris2,
|
.calc_bw = msm_vidc_calc_bw_iris2,
|
||||||
.decide_work_route = NULL,
|
.decide_work_route = msm_vidc_decide_work_route_iris2,
|
||||||
.decide_work_mode = NULL,
|
.decide_work_mode = msm_vidc_decide_work_mode_iris2,
|
||||||
.decide_core_and_power_mode = NULL,
|
.decide_quality_mode = msm_vidc_decide_quality_mode_iris2,
|
||||||
};
|
};
|
||||||
|
|
||||||
int msm_vidc_init_iris2(struct msm_vidc_core *core)
|
int msm_vidc_init_iris2(struct msm_vidc_core *core)
|
||||||
|
@@ -21,7 +21,7 @@ struct msm_vidc_session_ops {
|
|||||||
struct vidc_bus_vote_data* vote_data);
|
struct vidc_bus_vote_data* vote_data);
|
||||||
int (*decide_work_route)(struct msm_vidc_inst *inst);
|
int (*decide_work_route)(struct msm_vidc_inst *inst);
|
||||||
int (*decide_work_mode)(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 (*decide_quality_mode)(struct msm_vidc_inst *inst);
|
||||||
int (*buffer_size)(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type type);
|
int (*buffer_size)(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type type);
|
||||||
int (*min_count)(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type type);
|
int (*min_count)(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type type);
|
||||||
int (*extra_count)(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type type);
|
int (*extra_count)(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type type);
|
||||||
|
@@ -327,9 +327,17 @@ static int msm_venc_set_pipe(struct msm_vidc_inst *inst)
|
|||||||
static int msm_venc_set_quality_mode(struct msm_vidc_inst *inst)
|
static int msm_venc_set_quality_mode(struct msm_vidc_inst *inst)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
struct msm_vidc_core* core = inst->core;
|
||||||
struct msm_vidc_inst_capability *capability = inst->capabilities;
|
struct msm_vidc_inst_capability *capability = inst->capabilities;
|
||||||
u32 mode;
|
u32 mode;
|
||||||
|
|
||||||
|
rc = call_session_op(core, decide_quality_mode, inst);
|
||||||
|
if (rc) {
|
||||||
|
s_vpr_e(inst->sid, "%s: decide_work_route failed\n",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
mode = capability->cap[QUALITY_MODE].value;
|
mode = capability->cap[QUALITY_MODE].value;
|
||||||
s_vpr_h(inst->sid, "%s: quality_mode: %u\n", __func__, mode);
|
s_vpr_h(inst->sid, "%s: quality_mode: %u\n", __func__, mode);
|
||||||
rc = venus_hfi_session_property(inst,
|
rc = venus_hfi_session_property(inst,
|
||||||
|
Reference in New Issue
Block a user