mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 18:21:24 +02:00
media: iris: add FPS calculation and VPP FW overhead in frequency formula
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. Reviewed-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com> Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
This commit is contained in:
parent
d5e3f2b961
commit
5c66647a5c
|
|
@ -70,6 +70,8 @@ struct iris_fmt {
|
||||||
* @metadata_idx: index for metadata buffer
|
* @metadata_idx: index for metadata buffer
|
||||||
* @codec: codec type
|
* @codec: codec type
|
||||||
* @last_buffer_dequeued: a flag to indicate that last buffer is sent by driver
|
* @last_buffer_dequeued: a flag to indicate that last buffer is sent by driver
|
||||||
|
* @last_buf_ns: start time of received input buffer for current one second FPS window
|
||||||
|
* @frame_counter: input buffer counter for current one second FPS window
|
||||||
* @frame_rate: frame rate of current instance
|
* @frame_rate: frame rate of current instance
|
||||||
* @operating_rate: operating rate of current instance
|
* @operating_rate: operating rate of current instance
|
||||||
* @hfi_rc_type: rate control type
|
* @hfi_rc_type: rate control type
|
||||||
|
|
@ -115,6 +117,8 @@ struct iris_inst {
|
||||||
u32 metadata_idx;
|
u32 metadata_idx;
|
||||||
u32 codec;
|
u32 codec;
|
||||||
bool last_buffer_dequeued;
|
bool last_buffer_dequeued;
|
||||||
|
u64 last_buf_ns;
|
||||||
|
u32 frame_counter;
|
||||||
u32 frame_rate;
|
u32 frame_rate;
|
||||||
u32 operating_rate;
|
u32 operating_rate;
|
||||||
u32 hfi_rc_type;
|
u32 hfi_rc_type;
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ int iris_vdec_inst_init(struct iris_inst *inst)
|
||||||
f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
|
f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
|
||||||
inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
|
inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
|
||||||
inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
|
inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
|
||||||
|
inst->frame_rate = MAXIMUM_FPS;
|
||||||
|
|
||||||
memcpy(&inst->fw_caps[0], &core->inst_fw_caps_dec[0],
|
memcpy(&inst->fw_caps[0], &core->inst_fw_caps_dec[0],
|
||||||
INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap));
|
INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap));
|
||||||
|
|
@ -369,6 +370,8 @@ int iris_vdec_streamon_input(struct iris_inst *inst)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
inst->frame_counter = 0;
|
||||||
|
|
||||||
return iris_process_streamon_input(inst);
|
return iris_process_streamon_input(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -411,6 +414,7 @@ int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
|
||||||
{
|
{
|
||||||
struct iris_buffer *buf = to_iris_buffer(vbuf);
|
struct iris_buffer *buf = to_iris_buffer(vbuf);
|
||||||
struct vb2_buffer *vb2 = &vbuf->vb2_buf;
|
struct vb2_buffer *vb2 = &vbuf->vb2_buf;
|
||||||
|
u64 cur_buf_ns, delta_ns;
|
||||||
struct vb2_queue *q;
|
struct vb2_queue *q;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
@ -427,6 +431,22 @@ int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buf->type == BUF_INPUT) {
|
||||||
|
cur_buf_ns = ktime_get_ns();
|
||||||
|
|
||||||
|
if (!inst->frame_counter)
|
||||||
|
inst->last_buf_ns = cur_buf_ns;
|
||||||
|
|
||||||
|
inst->frame_counter++;
|
||||||
|
delta_ns = cur_buf_ns - inst->last_buf_ns;
|
||||||
|
|
||||||
|
if (delta_ns >= NSEC_PER_SEC) {
|
||||||
|
inst->frame_rate = clamp_t(u32, inst->frame_counter, DEFAULT_FPS,
|
||||||
|
MAXIMUM_FPS);
|
||||||
|
inst->frame_counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
iris_scale_power(inst);
|
iris_scale_power(inst);
|
||||||
|
|
||||||
return iris_queue_buffer(inst, buf);
|
return iris_queue_buffer(inst, buf);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size)
|
||||||
struct v4l2_format *inp_f = inst->fmt_src;
|
struct v4l2_format *inp_f = inst->fmt_src;
|
||||||
u32 mbs_per_second, mbpf, height, width;
|
u32 mbs_per_second, mbpf, height, width;
|
||||||
unsigned long vpp_freq, vsp_freq;
|
unsigned long vpp_freq, vsp_freq;
|
||||||
u32 fps = DEFAULT_FPS;
|
u32 fps = inst->frame_rate;
|
||||||
|
|
||||||
width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
|
width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
|
||||||
height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
|
height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
u32 height, width, mbs_per_second, mbpf;
|
||||||
u64 fw_cycles, fw_vpp_cycles;
|
u64 fw_cycles, fw_vpp_cycles;
|
||||||
u64 vsp_cycles, 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);
|
width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
|
||||||
height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
|
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)
|
if (inst->fw_caps[PIPE].value > 1)
|
||||||
vpp_cycles += div_u64(vpp_cycles * 59, 1000);
|
vpp_cycles += div_u64(vpp_cycles * 59, 1000);
|
||||||
|
|
||||||
|
/* 1.05 is VPP FW overhead */
|
||||||
|
if (inst->fw_caps[STAGE].value == STAGE_2)
|
||||||
|
vpp_cycles += mult_frac(vpp_cycles, 5, 100);
|
||||||
|
|
||||||
vsp_cycles = fps * data_size * 8;
|
vsp_cycles = fps * data_size * 8;
|
||||||
vsp_cycles = div_u64(vsp_cycles, 2);
|
vsp_cycles = div_u64(vsp_cycles, 2);
|
||||||
/* VSP FW overhead 1.05 */
|
/* VSP FW overhead 1.05 */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user