Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4 */
5
6#include <linux/pm_runtime.h>
7#include <media/v4l2-mem2mem.h>
8
9#include "iris_instance.h"
10#include "iris_utils.h"
11
12bool iris_res_is_less_than(u32 width, u32 height,
13 u32 ref_width, u32 ref_height)
14{
15 u32 num_mbs = NUM_MBS_PER_FRAME(height, width);
16 u32 max_side = max(ref_width, ref_height);
17
18 if (num_mbs < NUM_MBS_PER_FRAME(ref_height, ref_width) &&
19 width < max_side &&
20 height < max_side)
21 return true;
22
23 return false;
24}
25
26int iris_get_mbpf(struct iris_inst *inst)
27{
28 struct v4l2_format *inp_f = inst->fmt_src;
29 u32 height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
30 u32 width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
31
32 return NUM_MBS_PER_FRAME(height, width);
33}
34
35bool iris_split_mode_enabled(struct iris_inst *inst)
36{
37 return inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12 ||
38 inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C;
39}
40
41void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type,
42 enum vb2_buffer_state state)
43{
44 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
45 struct vb2_v4l2_buffer *buf;
46
47 if (V4L2_TYPE_IS_OUTPUT(type)) {
48 while ((buf = v4l2_m2m_src_buf_remove(m2m_ctx)))
49 v4l2_m2m_buf_done(buf, state);
50 } else if (V4L2_TYPE_IS_CAPTURE(type)) {
51 while ((buf = v4l2_m2m_dst_buf_remove(m2m_ctx)))
52 v4l2_m2m_buf_done(buf, state);
53 }
54}
55
56int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush)
57{
58 struct iris_core *core = inst->core;
59 u32 hw_response_timeout_val;
60 struct completion *done;
61 int ret;
62
63 hw_response_timeout_val = core->iris_platform_data->hw_response_timeout;
64 done = is_flush ? &inst->flush_completion : &inst->completion;
65
66 mutex_unlock(&inst->lock);
67 ret = wait_for_completion_timeout(done, msecs_to_jiffies(hw_response_timeout_val));
68 mutex_lock(&inst->lock);
69 if (!ret) {
70 iris_inst_change_state(inst, IRIS_INST_ERROR);
71 return -ETIMEDOUT;
72 }
73
74 return 0;
75}
76
77struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id)
78{
79 struct iris_inst *inst;
80
81 mutex_lock(&core->lock);
82 list_for_each_entry(inst, &core->instances, list) {
83 if (inst->session_id == session_id) {
84 mutex_unlock(&core->lock);
85 return inst;
86 }
87 }
88
89 mutex_unlock(&core->lock);
90 return NULL;
91}
92
93int iris_check_core_mbpf(struct iris_inst *inst)
94{
95 struct iris_core *core = inst->core;
96 struct iris_inst *instance;
97 u32 total_mbpf = 0;
98
99 mutex_lock(&core->lock);
100 list_for_each_entry(instance, &core->instances, list)
101 total_mbpf += iris_get_mbpf(instance);
102 mutex_unlock(&core->lock);
103
104 if (total_mbpf > core->iris_platform_data->max_core_mbpf)
105 return -ENOMEM;
106
107 return 0;
108}
109
110int iris_check_core_mbps(struct iris_inst *inst)
111{
112 struct iris_core *core = inst->core;
113 struct iris_inst *instance;
114 u32 total_mbps = 0, fps = 0;
115
116 mutex_lock(&core->lock);
117 list_for_each_entry(instance, &core->instances, list) {
118 fps = max(instance->frame_rate, instance->operating_rate);
119 total_mbps += iris_get_mbpf(instance) * fps;
120 }
121 mutex_unlock(&core->lock);
122
123 if (total_mbps > core->iris_platform_data->max_core_mbps)
124 return -ENOMEM;
125
126 return 0;
127}