xref: /linux/drivers/media/platform/qcom/iris/iris_ctrls.c (revision 6bdfa3f947a735778fc3e76b0762430276b7a3c0)
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/types.h>
7 #include <media/v4l2-mem2mem.h>
8 
9 #include "iris_ctrls.h"
10 #include "iris_instance.h"
11 
12 static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id)
13 {
14 	return cap_id >= 1 && cap_id < INST_FW_CAP_MAX;
15 }
16 
17 static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
18 {
19 	switch (id) {
20 	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
21 		return PROFILE_H264;
22 	case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
23 		return PROFILE_HEVC;
24 	case V4L2_CID_MPEG_VIDEO_VP9_PROFILE:
25 		return PROFILE_VP9;
26 	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
27 		return LEVEL_H264;
28 	case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
29 		return LEVEL_HEVC;
30 	case V4L2_CID_MPEG_VIDEO_VP9_LEVEL:
31 		return LEVEL_VP9;
32 	case V4L2_CID_MPEG_VIDEO_HEVC_TIER:
33 		return TIER;
34 	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
35 		return HEADER_MODE;
36 	case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR:
37 		return PREPEND_SPSPPS_TO_IDR;
38 	case V4L2_CID_MPEG_VIDEO_BITRATE:
39 		return BITRATE;
40 	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
41 		return BITRATE_PEAK;
42 	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
43 		return BITRATE_MODE;
44 	case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE:
45 		return FRAME_SKIP_MODE;
46 	case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
47 		return FRAME_RC_ENABLE;
48 	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
49 		return GOP_SIZE;
50 	case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
51 		return ENTROPY_MODE;
52 	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
53 		return MIN_FRAME_QP_H264;
54 	case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:
55 		return MIN_FRAME_QP_HEVC;
56 	case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
57 		return MAX_FRAME_QP_H264;
58 	case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
59 		return MAX_FRAME_QP_HEVC;
60 	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP:
61 		return I_FRAME_MIN_QP_H264;
62 	case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP:
63 		return I_FRAME_MIN_QP_HEVC;
64 	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP:
65 		return P_FRAME_MIN_QP_H264;
66 	case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP:
67 		return P_FRAME_MIN_QP_HEVC;
68 	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP:
69 		return B_FRAME_MIN_QP_H264;
70 	case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP:
71 		return B_FRAME_MIN_QP_HEVC;
72 	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP:
73 		return I_FRAME_MAX_QP_H264;
74 	case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP:
75 		return I_FRAME_MAX_QP_HEVC;
76 	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP:
77 		return P_FRAME_MAX_QP_H264;
78 	case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP:
79 		return P_FRAME_MAX_QP_HEVC;
80 	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP:
81 		return B_FRAME_MAX_QP_H264;
82 	case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP:
83 		return B_FRAME_MAX_QP_HEVC;
84 	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
85 		return I_FRAME_QP_H264;
86 	case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:
87 		return I_FRAME_QP_HEVC;
88 	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
89 		return P_FRAME_QP_H264;
90 	case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP:
91 		return P_FRAME_QP_HEVC;
92 	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
93 		return B_FRAME_QP_H264;
94 	case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP:
95 		return B_FRAME_QP_HEVC;
96 	default:
97 		return INST_FW_CAP_MAX;
98 	}
99 }
100 
101 static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
102 {
103 	if (!iris_valid_cap_id(cap_id))
104 		return 0;
105 
106 	switch (cap_id) {
107 	case PROFILE_H264:
108 		return V4L2_CID_MPEG_VIDEO_H264_PROFILE;
109 	case PROFILE_HEVC:
110 		return V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
111 	case PROFILE_VP9:
112 		return V4L2_CID_MPEG_VIDEO_VP9_PROFILE;
113 	case LEVEL_H264:
114 		return V4L2_CID_MPEG_VIDEO_H264_LEVEL;
115 	case LEVEL_HEVC:
116 		return V4L2_CID_MPEG_VIDEO_HEVC_LEVEL;
117 	case LEVEL_VP9:
118 		return V4L2_CID_MPEG_VIDEO_VP9_LEVEL;
119 	case TIER:
120 		return V4L2_CID_MPEG_VIDEO_HEVC_TIER;
121 	case HEADER_MODE:
122 		return V4L2_CID_MPEG_VIDEO_HEADER_MODE;
123 	case PREPEND_SPSPPS_TO_IDR:
124 		return V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR;
125 	case BITRATE:
126 		return V4L2_CID_MPEG_VIDEO_BITRATE;
127 	case BITRATE_PEAK:
128 		return V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
129 	case BITRATE_MODE:
130 		return V4L2_CID_MPEG_VIDEO_BITRATE_MODE;
131 	case FRAME_SKIP_MODE:
132 		return V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE;
133 	case FRAME_RC_ENABLE:
134 		return V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
135 	case GOP_SIZE:
136 		return V4L2_CID_MPEG_VIDEO_GOP_SIZE;
137 	case ENTROPY_MODE:
138 		return V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
139 	case MIN_FRAME_QP_H264:
140 		return V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
141 	case MIN_FRAME_QP_HEVC:
142 		return V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP;
143 	case MAX_FRAME_QP_H264:
144 		return V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
145 	case MAX_FRAME_QP_HEVC:
146 		return V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP;
147 	case I_FRAME_MIN_QP_H264:
148 		return V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP;
149 	case I_FRAME_MIN_QP_HEVC:
150 		return V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP;
151 	case P_FRAME_MIN_QP_H264:
152 		return V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP;
153 	case P_FRAME_MIN_QP_HEVC:
154 		return V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP;
155 	case B_FRAME_MIN_QP_H264:
156 		return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP;
157 	case B_FRAME_MIN_QP_HEVC:
158 		return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP;
159 	case I_FRAME_MAX_QP_H264:
160 		return V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP;
161 	case I_FRAME_MAX_QP_HEVC:
162 		return V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP;
163 	case P_FRAME_MAX_QP_H264:
164 		return V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP;
165 	case P_FRAME_MAX_QP_HEVC:
166 		return V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP;
167 	case B_FRAME_MAX_QP_H264:
168 		return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP;
169 	case B_FRAME_MAX_QP_HEVC:
170 		return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP;
171 	case I_FRAME_QP_H264:
172 		return V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
173 	case I_FRAME_QP_HEVC:
174 		return V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP;
175 	case P_FRAME_QP_H264:
176 		return V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
177 	case P_FRAME_QP_HEVC:
178 		return V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP;
179 	case B_FRAME_QP_H264:
180 		return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
181 	case B_FRAME_QP_HEVC:
182 		return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP;
183 	default:
184 		return 0;
185 	}
186 }
187 
188 static int iris_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
189 {
190 	struct iris_inst *inst = container_of(ctrl->handler, struct iris_inst, ctrl_handler);
191 	enum platform_inst_fw_cap_type cap_id;
192 	struct platform_inst_fw_cap *cap;
193 	struct vb2_queue *q;
194 
195 	cap = &inst->fw_caps[0];
196 	cap_id = iris_get_cap_id(ctrl->id);
197 	if (!iris_valid_cap_id(cap_id))
198 		return -EINVAL;
199 
200 	q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
201 	if (vb2_is_streaming(q) &&
202 	    (!(inst->fw_caps[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED)))
203 		return -EINVAL;
204 
205 	cap[cap_id].flags |= CAP_FLAG_CLIENT_SET;
206 
207 	inst->fw_caps[cap_id].value = ctrl->val;
208 
209 	return 0;
210 }
211 
212 static const struct v4l2_ctrl_ops iris_ctrl_ops = {
213 	.s_ctrl = iris_vdec_op_s_ctrl,
214 };
215 
216 int iris_ctrls_init(struct iris_inst *inst)
217 {
218 	struct platform_inst_fw_cap *cap = &inst->fw_caps[0];
219 	u32 num_ctrls = 0, ctrl_idx = 0, idx = 0;
220 	u32 v4l2_id;
221 	int ret;
222 
223 	for (idx = 1; idx < INST_FW_CAP_MAX; idx++) {
224 		if (iris_get_v4l2_id(cap[idx].cap_id))
225 			num_ctrls++;
226 	}
227 
228 	/* Adding 1 to num_ctrls to include
229 	 * V4L2_CID_MIN_BUFFERS_FOR_CAPTURE for decoder and
230 	 * V4L2_CID_MIN_BUFFERS_FOR_OUTPUT for encoder
231 	 */
232 
233 	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls + 1);
234 	if (ret)
235 		return ret;
236 
237 	for (idx = 1; idx < INST_FW_CAP_MAX; idx++) {
238 		struct v4l2_ctrl *ctrl;
239 
240 		v4l2_id = iris_get_v4l2_id(cap[idx].cap_id);
241 		if (!v4l2_id)
242 			continue;
243 
244 		if (ctrl_idx >= num_ctrls) {
245 			ret = -EINVAL;
246 			goto error;
247 		}
248 
249 		if (cap[idx].flags & CAP_FLAG_MENU) {
250 			ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler,
251 						      &iris_ctrl_ops,
252 						      v4l2_id,
253 						      cap[idx].max,
254 						      ~(cap[idx].step_or_mask),
255 						      cap[idx].value);
256 		} else {
257 			ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
258 						 &iris_ctrl_ops,
259 						 v4l2_id,
260 						 cap[idx].min,
261 						 cap[idx].max,
262 						 cap[idx].step_or_mask,
263 						 cap[idx].value);
264 		}
265 		if (!ctrl) {
266 			ret = -EINVAL;
267 			goto error;
268 		}
269 
270 		ctrl_idx++;
271 	}
272 
273 	if (inst->domain == DECODER) {
274 		v4l2_ctrl_new_std(&inst->ctrl_handler, NULL,
275 				  V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 4);
276 	} else {
277 		v4l2_ctrl_new_std(&inst->ctrl_handler, NULL,
278 				  V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 4);
279 	}
280 
281 	ret = inst->ctrl_handler.error;
282 	if (ret)
283 		goto error;
284 
285 	return 0;
286 error:
287 	v4l2_ctrl_handler_free(&inst->ctrl_handler);
288 
289 	return ret;
290 }
291 
292 void iris_session_init_caps(struct iris_core *core)
293 {
294 	struct platform_inst_fw_cap *caps;
295 	u32 i, num_cap, cap_id;
296 
297 	caps = core->iris_platform_data->inst_fw_caps_dec;
298 	num_cap = core->iris_platform_data->inst_fw_caps_dec_size;
299 
300 	for (i = 0; i < num_cap; i++) {
301 		cap_id = caps[i].cap_id;
302 		if (!iris_valid_cap_id(cap_id))
303 			continue;
304 
305 		core->inst_fw_caps_dec[cap_id].cap_id = caps[i].cap_id;
306 		core->inst_fw_caps_dec[cap_id].min = caps[i].min;
307 		core->inst_fw_caps_dec[cap_id].max = caps[i].max;
308 		core->inst_fw_caps_dec[cap_id].step_or_mask = caps[i].step_or_mask;
309 		core->inst_fw_caps_dec[cap_id].value = caps[i].value;
310 		core->inst_fw_caps_dec[cap_id].flags = caps[i].flags;
311 		core->inst_fw_caps_dec[cap_id].hfi_id = caps[i].hfi_id;
312 		core->inst_fw_caps_dec[cap_id].set = caps[i].set;
313 	}
314 
315 	caps = core->iris_platform_data->inst_fw_caps_enc;
316 	num_cap = core->iris_platform_data->inst_fw_caps_enc_size;
317 
318 	for (i = 0; i < num_cap; i++) {
319 		cap_id = caps[i].cap_id;
320 		if (!iris_valid_cap_id(cap_id))
321 			continue;
322 
323 		core->inst_fw_caps_enc[cap_id].cap_id = caps[i].cap_id;
324 		core->inst_fw_caps_enc[cap_id].min = caps[i].min;
325 		core->inst_fw_caps_enc[cap_id].max = caps[i].max;
326 		core->inst_fw_caps_enc[cap_id].step_or_mask = caps[i].step_or_mask;
327 		core->inst_fw_caps_enc[cap_id].value = caps[i].value;
328 		core->inst_fw_caps_enc[cap_id].flags = caps[i].flags;
329 		core->inst_fw_caps_enc[cap_id].hfi_id = caps[i].hfi_id;
330 	}
331 }
332 
333 static u32 iris_get_port_info(struct iris_inst *inst,
334 			      enum platform_inst_fw_cap_type cap_id)
335 {
336 	if (inst->fw_caps[cap_id].flags & CAP_FLAG_INPUT_PORT)
337 		return HFI_PORT_BITSTREAM;
338 	else if (inst->fw_caps[cap_id].flags & CAP_FLAG_OUTPUT_PORT)
339 		return HFI_PORT_RAW;
340 
341 	return HFI_PORT_NONE;
342 }
343 
344 int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
345 {
346 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
347 	u32 hfi_value = inst->fw_caps[cap_id].value;
348 	u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
349 
350 	return hfi_ops->session_set_property(inst, hfi_id,
351 					     HFI_HOST_FLAGS_NONE,
352 					     iris_get_port_info(inst, cap_id),
353 					     HFI_PAYLOAD_U32_ENUM,
354 					     &hfi_value, sizeof(u32));
355 }
356 
357 int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
358 {
359 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
360 	u32 hfi_value = inst->fw_caps[cap_id].value;
361 	u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
362 
363 	return hfi_ops->session_set_property(inst, hfi_id,
364 					     HFI_HOST_FLAGS_NONE,
365 					     iris_get_port_info(inst, cap_id),
366 					     HFI_PAYLOAD_U32,
367 					     &hfi_value, sizeof(u32));
368 }
369 
370 int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
371 {
372 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
373 	struct v4l2_format *inp_f = inst->fmt_src;
374 	u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
375 	u32 height = inp_f->fmt.pix_mp.height;
376 	u32 width = inp_f->fmt.pix_mp.width;
377 	u32 work_mode = STAGE_2;
378 
379 	if (iris_res_is_less_than(width, height, 1280, 720))
380 		work_mode = STAGE_1;
381 
382 	return hfi_ops->session_set_property(inst, hfi_id,
383 					     HFI_HOST_FLAGS_NONE,
384 					     iris_get_port_info(inst, cap_id),
385 					     HFI_PAYLOAD_U32,
386 					     &work_mode, sizeof(u32));
387 }
388 
389 int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
390 {
391 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
392 	u32 work_route = inst->fw_caps[PIPE].value;
393 	u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
394 
395 	return hfi_ops->session_set_property(inst, hfi_id,
396 					     HFI_HOST_FLAGS_NONE,
397 					     iris_get_port_info(inst, cap_id),
398 					     HFI_PAYLOAD_U32,
399 					     &work_route, sizeof(u32));
400 }
401 
402 int iris_set_properties(struct iris_inst *inst, u32 plane)
403 {
404 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
405 	struct platform_inst_fw_cap *cap;
406 	int ret;
407 	u32 i;
408 
409 	ret = hfi_ops->session_set_config_params(inst, plane);
410 	if (ret)
411 		return ret;
412 
413 	for (i = 1; i < INST_FW_CAP_MAX; i++) {
414 		cap = &inst->fw_caps[i];
415 		if (!iris_valid_cap_id(cap->cap_id))
416 			continue;
417 
418 		if (cap->cap_id && cap->set)
419 			cap->set(inst, i);
420 	}
421 
422 	return 0;
423 }
424