[PATCH] media: iris: add FPS calculation and VPP FW overhead in frequency formula
From: Vishnu Reddy
Date: Wed Mar 04 2026 - 04:20:30 EST
The driver was using a fixed default FPS value when calculating the VPU
frequency. This caused wrong frequency requests for high‑frame‑rate
streams, for example 4K at 240 FPS. Because of this, the hardware was
running at a lower frequency than needed.
Add the FPS measurement based on the decoder input buffer arrival rate.
The measured FPS is stored per instance and used in frequency calculation
instead of the fixed default FPS. The value is clamped so that it does
not exceed platform limits. Add a VPP firmware overhead when running in
STAGE_2.
Signed-off-by: Vishnu Reddy <busanna.reddy@xxxxxxxxxxxxxxxx>
---
drivers/media/platform/qcom/iris/iris_instance.h | 2 ++
drivers/media/platform/qcom/iris/iris_vdec.c | 21 +++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_vpu_common.c | 6 +++++-
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h
index 16965150f427..180cba36a7f2 100644
--- a/drivers/media/platform/qcom/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -109,6 +109,8 @@ struct iris_inst {
u32 metadata_idx;
u32 codec;
bool last_buffer_dequeued;
+ u64 last_buf_recv_time_ns;
+ u32 frame_count;
u32 frame_rate;
u32 operating_rate;
u32 hfi_rc_type;
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c
index 719217399a30..88820060e22a 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -369,6 +369,8 @@ int iris_vdec_streamon_input(struct iris_inst *inst)
if (ret)
return ret;
+ inst->frame_count = 0;
+
return iris_process_streamon_input(inst);
}
@@ -411,6 +413,7 @@ int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
{
struct iris_buffer *buf = to_iris_buffer(vbuf);
struct vb2_buffer *vb2 = &vbuf->vb2_buf;
+ u64 cur_buf_recv_time_ns, time_delta_ns;
struct vb2_queue *q;
int ret;
@@ -427,6 +430,24 @@ int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
return 0;
}
+ if (buf->type == BUF_INPUT) {
+ cur_buf_recv_time_ns = ktime_get_ns();
+
+ if (inst->frame_count == 0) {
+ inst->last_buf_recv_time_ns = cur_buf_recv_time_ns;
+ inst->frame_rate = MAXIMUM_FPS;
+ }
+ time_delta_ns = cur_buf_recv_time_ns - inst->last_buf_recv_time_ns;
+
+ if (time_delta_ns >= NSEC_PER_SEC) {
+ inst->frame_rate = clamp_t(u32, inst->frame_count, DEFAULT_FPS,
+ MAXIMUM_FPS);
+ inst->last_buf_recv_time_ns = cur_buf_recv_time_ns;
+ inst->frame_count = 0;
+ }
+ inst->frame_count++;
+ }
+
iris_scale_power(inst);
return iris_queue_buffer(inst, buf);
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
index 548e5f1727fd..3ccc8feff678 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
@@ -416,7 +416,7 @@ u64 iris_vpu3x_vpu4x_calculate_frequency(struct iris_inst *inst, size_t data_siz
u32 height, width, mbs_per_second, mbpf;
u64 fw_cycles, fw_vpp_cycles;
u64 vsp_cycles, vpp_cycles;
- u32 fps = DEFAULT_FPS;
+ u32 fps = inst->frame_rate;
width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
@@ -435,6 +435,10 @@ u64 iris_vpu3x_vpu4x_calculate_frequency(struct iris_inst *inst, size_t data_siz
if (inst->fw_caps[PIPE].value > 1)
vpp_cycles += div_u64(vpp_cycles * 59, 1000);
+ /* 1.050 is VPP FW overhead */
+ if (inst->fw_caps[STAGE].value == STAGE_2)
+ vpp_cycles += div_u64(vpp_cycles * 50, 1000);
+
vsp_cycles = fps * data_size * 8;
vsp_cycles = div_u64(vsp_cycles, 2);
/* VSP FW overhead 1.05 */
---
base-commit: f505e978d1a0442adbbde48aed38c084ddea6d6e
change-id: 20260304-update_fps_calculation-98ee7f7507b1
Best regards,
--
Vishnu Reddy <busanna.reddy@xxxxxxxxxxxxxxxx>