@@ -799,6 +799,8 @@ int decide_quality_mode(struct iris_inst *inst)
if (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps)
mode = MAX_QUALITY_MODE;
+ inst->cap[QUALITY_MODE].value = mode;
+
return mode;
}
@@ -48,11 +48,16 @@ static int iris_vote_buses(struct iris_inst *inst)
vote_data->height = inp_f->fmt.pix_mp.height;
vote_data->fps = inst->max_rate;
- if (is_linear_colorformat(out_f->fmt.pix_mp.pixelformat)) {
- vote_data->color_formats[0] = V4L2_PIX_FMT_NV12;
- vote_data->color_formats[1] = out_f->fmt.pix_mp.pixelformat;
- } else {
- vote_data->color_formats[0] = out_f->fmt.pix_mp.pixelformat;
+ if (inst->domain == ENCODER) {
+ vote_data->color_formats[0] =
+ v4l2_colorformat_to_driver(inst, inst->fmt_src->fmt.pix_mp.pixelformat);
+ } else if (inst->domain == DECODER) {
+ if (is_linear_colorformat(out_f->fmt.pix_mp.pixelformat)) {
+ vote_data->color_formats[0] = V4L2_PIX_FMT_NV12;
+ vote_data->color_formats[1] = out_f->fmt.pix_mp.pixelformat;
+ } else {
+ vote_data->color_formats[0] = out_f->fmt.pix_mp.pixelformat;
+ }
}
call_session_op(core, calc_bw, inst, vote_data);
@@ -174,6 +174,7 @@ enum plat_inst_cap_type {
INPUT_BUF_HOST_MAX_COUNT,
STAGE,
PIPE,
+ QUALITY_MODE,
POC,
CODED_FRAMES,
BIT_DEPTH,
@@ -279,6 +280,8 @@ struct format_capability {
struct platform_data {
const struct bus_info *bus_tbl;
unsigned int bus_tbl_size;
+ const struct bw_info *bw_tbl_enc;
+ unsigned int bw_tbl_enc_size;
const struct bw_info *bw_tbl_dec;
unsigned int bw_tbl_dec_size;
const char * const *pd_tbl;
@@ -1005,6 +1005,11 @@ static struct plat_inst_cap instance_cap_data_sm8550[] = {
NULL,
set_pipe},
+ {QUALITY_MODE, ENC, CODECS_ALL,
+ MAX_QUALITY_MODE,
+ POWER_SAVE_MODE, 1,
+ POWER_SAVE_MODE},
+
{POC, DEC, H264, 0, 2, 1, 1,
0,
HFI_PROP_PIC_ORDER_CNT_TYPE},
@@ -1051,6 +1056,13 @@ static const char * const sm8550_pd_table[] = { "iris-ctl", "vcodec", NULL };
static const char * const sm8550_opp_pd_table[] = { "mxc", "mmcx", NULL };
+static const struct bw_info sm8550_bw_table_enc[] = {
+ { 1944000, 1491000, 2693000 }, /* 3840x2160@60 */
+ { 972000, 765000, 1366000 }, /* 3840x2160@30 */
+ { 489600, 557000, 780000 }, /* 1920x1080@60 */
+ { 244800, 288000, 399000 }, /* 1920x1080@30 */
+};
+
static const struct bw_info sm8550_bw_table_dec[] = {
{ 2073600, 1608000, 2742000 }, /* 4096x2160@60 */
{ 1036800, 826000, 1393000 }, /* 4096x2160@30 */
@@ -1133,6 +1145,8 @@ struct platform_data sm8550_data = {
.clk_rst_tbl = sm8550_clk_reset_table,
.clk_rst_tbl_size = ARRAY_SIZE(sm8550_clk_reset_table),
+ .bw_tbl_enc = sm8550_bw_table_enc,
+ .bw_tbl_enc_size = ARRAY_SIZE(sm8550_bw_table_enc),
.bw_tbl_dec = sm8550_bw_table_dec,
.bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec),
@@ -11,12 +11,13 @@
u64 iris_calc_freq_iris3(struct iris_inst *inst, u32 data_size)
{
+ u32 operating_rate, vsp_factor_num = 1, vsp_factor_den = 1;
u64 vsp_cycles = 0, vpp_cycles = 0, fw_cycles = 0;
u64 fw_vpp_cycles = 0, bitrate = 0, freq = 0;
+ u32 vpp_cycles_per_mb, mbs_per_second;
u32 base_cycles = 0, fps, mbpf;
u32 height = 0, width = 0;
struct v4l2_format *inp_f;
- u32 mbs_per_second;
inp_f = inst->fmt_src;
width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
@@ -29,32 +30,74 @@ u64 iris_calc_freq_iris3(struct iris_inst *inst, u32 data_size)
fw_cycles = fps * inst->cap[MB_CYCLES_FW].value;
fw_vpp_cycles = fps * inst->cap[MB_CYCLES_FW_VPP].value;
- vpp_cycles = mbs_per_second * inst->cap[MB_CYCLES_VPP].value /
- inst->cap[PIPE].value;
- vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles);
-
- if (inst->cap[PIPE].value > 1)
- vpp_cycles += div_u64(vpp_cycles * 59, 1000);
-
- base_cycles = inst->cap[MB_CYCLES_VSP].value;
- bitrate = fps * data_size * 8;
- vsp_cycles = bitrate;
-
- if (inst->codec == VP9) {
- vsp_cycles = div_u64(vsp_cycles * 170, 100);
- } else if (inst->cap[ENTROPY_MODE].value ==
- V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC) {
- vsp_cycles = div_u64(vsp_cycles * 135, 100);
- } else {
- base_cycles = 0;
- vsp_cycles = div_u64(vsp_cycles, 2);
- }
- vsp_cycles = div_u64(vsp_cycles * 21, 20);
+ if (inst->domain == ENCODER) {
+ vpp_cycles_per_mb =
+ inst->cap[QUALITY_MODE].value == POWER_SAVE_MODE ?
+ inst->cap[MB_CYCLES_LP].value :
+ inst->cap[MB_CYCLES_VPP].value;
+
+ vpp_cycles = mbs_per_second * vpp_cycles_per_mb / inst->cap[PIPE].value;
+
+ if (inst->cap[B_FRAME].value > 1)
+ vpp_cycles += (vpp_cycles / 4) + (vpp_cycles / 8);
+ else if (inst->cap[B_FRAME].value)
+ vpp_cycles += vpp_cycles / 4;
+
+ vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles);
+ if (inst->cap[PIPE].value > 1)
+ vpp_cycles += div_u64(vpp_cycles, 100);
+
+ operating_rate = inst->cap[OPERATING_RATE].value >> 16;
+ if (operating_rate > (inst->cap[FRAME_RATE].value >> 16) &&
+ (inst->cap[FRAME_RATE].value >> 16)) {
+ vsp_factor_num = operating_rate;
+ vsp_factor_den = inst->cap[FRAME_RATE].value >> 16;
+ }
+ vsp_cycles = div_u64(((u64)inst->cap[BIT_RATE].value * vsp_factor_num),
+ vsp_factor_den);
+
+ base_cycles = inst->cap[MB_CYCLES_VSP].value;
+ if (inst->cap[ENTROPY_MODE].value ==
+ V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC) {
+ vsp_cycles = div_u64(vsp_cycles * 135, 100);
+ } else {
+ base_cycles = 0;
+ vsp_cycles = div_u64(vsp_cycles, 2);
+ }
+ vsp_cycles = div_u64(vsp_cycles * 21, 20);
+
+ if (inst->cap[STAGE].value == STAGE_1)
+ vsp_cycles = vsp_cycles * 3;
- if (inst->cap[STAGE].value == STAGE_1)
- vsp_cycles = vsp_cycles * 3;
+ vsp_cycles += mbs_per_second * base_cycles;
+ } else if (inst->domain == DECODER) {
+ vpp_cycles = mbs_per_second * inst->cap[MB_CYCLES_VPP].value /
+ inst->cap[PIPE].value;
+ vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles);
+
+ if (inst->cap[PIPE].value > 1)
+ vpp_cycles += div_u64(vpp_cycles * 59, 1000);
+
+ base_cycles = inst->cap[MB_CYCLES_VSP].value;
+ bitrate = fps * data_size * 8;
+ vsp_cycles = bitrate;
+
+ if (inst->codec == VP9) {
+ vsp_cycles = div_u64(vsp_cycles * 170, 100);
+ } else if (inst->cap[ENTROPY_MODE].value ==
+ V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC) {
+ vsp_cycles = div_u64(vsp_cycles * 135, 100);
+ } else {
+ base_cycles = 0;
+ vsp_cycles = div_u64(vsp_cycles, 2);
+ }
+ vsp_cycles = div_u64(vsp_cycles * 21, 20);
+
+ if (inst->cap[STAGE].value == STAGE_1)
+ vsp_cycles = vsp_cycles * 3;
vsp_cycles += mbs_per_second * base_cycles;
+ }
freq = max3(vpp_cycles, vsp_cycles, fw_cycles);
@@ -78,8 +121,13 @@ int iris_calc_bw_iris3(struct iris_inst *inst, struct bus_vote_data *data)
if (mbps == 0)
return 0;
- bw_tbl = core->platform_data->bw_tbl_dec;
- num_rows = core->platform_data->bw_tbl_dec_size;
+ if (inst->domain == DECODER) {
+ bw_tbl = core->platform_data->bw_tbl_dec;
+ num_rows = core->platform_data->bw_tbl_dec_size;
+ } else if (inst->domain == ENCODER) {
+ bw_tbl = core->platform_data->bw_tbl_enc;
+ num_rows = core->platform_data->bw_tbl_enc_size;
+ }
if (!bw_tbl || num_rows == 0)
return 0;
Hardware specific power sequence include programming specific sequence of registers. Implements this sequence for iris3. Also, implement iris3 Encoder specific calculation for clock and bus bandwidth which depends on hardware configuration, codec format, resolution and frame rate. Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com> --- .../media/platform/qcom/vcodec/iris/iris_ctrls.c | 2 + .../media/platform/qcom/vcodec/iris/iris_power.c | 15 ++-- .../platform/qcom/vcodec/iris/platform_common.h | 3 + .../platform/qcom/vcodec/iris/platform_sm8550.c | 14 +++ .../platform/qcom/vcodec/iris/vpu_iris3_power.c | 100 +++++++++++++++------ 5 files changed, 103 insertions(+), 31 deletions(-)