On 18.12.2023 12:32, Dikshita Agarwal wrote:
> 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>
> ---
[...]
> +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 */
> +};
can this be calculated at runtime by chance?
Konrad
@@ -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;