1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
4 */
5
6 #include <media/v4l2-event.h>
7 #include <media/v4l2-mem2mem.h>
8
9 #include "iris_buffer.h"
10 #include "iris_common.h"
11 #include "iris_ctrls.h"
12 #include "iris_instance.h"
13 #include "iris_power.h"
14 #include "iris_venc.h"
15 #include "iris_vpu_buffer.h"
16
iris_venc_inst_init(struct iris_inst * inst)17 int iris_venc_inst_init(struct iris_inst *inst)
18 {
19 struct iris_core *core = inst->core;
20 struct v4l2_format *f;
21
22 inst->fmt_src = kzalloc_obj(*inst->fmt_src);
23 inst->fmt_dst = kzalloc_obj(*inst->fmt_dst);
24 if (!inst->fmt_src || !inst->fmt_dst) {
25 kfree(inst->fmt_src);
26 kfree(inst->fmt_dst);
27 return -ENOMEM;
28 }
29
30 f = inst->fmt_dst;
31 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
32 f->fmt.pix_mp.width = DEFAULT_WIDTH;
33 f->fmt.pix_mp.height = DEFAULT_HEIGHT;
34 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
35 inst->codec = f->fmt.pix_mp.pixelformat;
36 f->fmt.pix_mp.num_planes = 1;
37 f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
38 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
39 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
40 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
41 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
42 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
43 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
44 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
45 inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
46
47 f = inst->fmt_src;
48 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
49 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
50 f->fmt.pix_mp.width = ALIGN(DEFAULT_WIDTH, 128);
51 f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32);
52 f->fmt.pix_mp.num_planes = 1;
53 f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128);
54 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
55 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
56 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
57 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
58 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
59 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
60 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT);
61 inst->buffers[BUF_INPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
62
63 inst->crop.left = 0;
64 inst->crop.top = 0;
65 inst->crop.width = DEFAULT_WIDTH;
66 inst->crop.height = DEFAULT_HEIGHT;
67
68 inst->operating_rate = DEFAULT_FPS;
69 inst->frame_rate = DEFAULT_FPS;
70
71 inst->enc_raw_width = DEFAULT_WIDTH;
72 inst->enc_raw_height = DEFAULT_HEIGHT;
73 inst->enc_scale_width = DEFAULT_WIDTH;
74 inst->enc_scale_height = DEFAULT_HEIGHT;
75
76 memcpy(&inst->fw_caps[0], &core->inst_fw_caps_enc[0],
77 INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap));
78
79 return iris_ctrls_init(inst);
80 }
81
iris_venc_inst_deinit(struct iris_inst * inst)82 void iris_venc_inst_deinit(struct iris_inst *inst)
83 {
84 kfree(inst->fmt_dst);
85 kfree(inst->fmt_src);
86 }
87
88 static const struct iris_fmt iris_venc_formats_cap[] = {
89 [IRIS_FMT_H264] = {
90 .pixfmt = V4L2_PIX_FMT_H264,
91 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
92 },
93 [IRIS_FMT_HEVC] = {
94 .pixfmt = V4L2_PIX_FMT_HEVC,
95 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
96 },
97 };
98
99 static const struct iris_fmt iris_venc_formats_out[] = {
100 [IRIS_FMT_NV12] = {
101 .pixfmt = V4L2_PIX_FMT_NV12,
102 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
103 },
104 [IRIS_FMT_QC08C] = {
105 .pixfmt = V4L2_PIX_FMT_QC08C,
106 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
107 },
108 };
109
110 static const struct iris_fmt *
find_format(struct iris_inst * inst,u32 pixfmt,u32 type)111 find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
112 {
113 const struct iris_fmt *fmt = NULL;
114 unsigned int size = 0;
115 unsigned int i;
116 switch (type) {
117 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
118 fmt = iris_venc_formats_out;
119 size = ARRAY_SIZE(iris_venc_formats_out);
120 break;
121 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
122 fmt = iris_venc_formats_cap;
123 size = ARRAY_SIZE(iris_venc_formats_cap);
124 break;
125 default:
126 return NULL;
127 }
128
129 for (i = 0; i < size; i++) {
130 if (fmt[i].pixfmt == pixfmt)
131 break;
132 }
133
134 if (i == size || fmt[i].type != type)
135 return NULL;
136
137 return &fmt[i];
138 }
139
140 static const struct iris_fmt *
find_format_by_index(struct iris_inst * inst,u32 index,u32 type)141 find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
142 {
143 const struct iris_fmt *fmt = NULL;
144 unsigned int size = 0;
145
146 switch (type) {
147 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
148 fmt = iris_venc_formats_out;
149 size = ARRAY_SIZE(iris_venc_formats_out);
150 break;
151 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
152 fmt = iris_venc_formats_cap;
153 size = ARRAY_SIZE(iris_venc_formats_cap);
154 break;
155 default:
156 return NULL;
157 }
158
159 if (index >= size || fmt[index].type != type)
160 return NULL;
161
162 return &fmt[index];
163 }
164
iris_venc_enum_fmt(struct iris_inst * inst,struct v4l2_fmtdesc * f)165 int iris_venc_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
166 {
167 const struct iris_fmt *fmt;
168
169 switch (f->type) {
170 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
171 fmt = find_format_by_index(inst, f->index, f->type);
172 if (!fmt)
173 return -EINVAL;
174
175 f->pixelformat = fmt->pixfmt;
176 break;
177 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
178 fmt = find_format_by_index(inst, f->index, f->type);
179 if (!fmt)
180 return -EINVAL;
181
182 f->pixelformat = fmt->pixfmt;
183 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL;
184 break;
185 default:
186 return -EINVAL;
187 }
188
189 return 0;
190 }
191
iris_venc_try_fmt(struct iris_inst * inst,struct v4l2_format * f)192 int iris_venc_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
193 {
194 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
195 const struct iris_fmt *fmt;
196 struct v4l2_format *f_inst;
197
198 memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
199 fmt = find_format(inst, pixmp->pixelformat, f->type);
200 switch (f->type) {
201 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
202 if (!fmt) {
203 f_inst = inst->fmt_src;
204 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
205 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
206 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
207 }
208 break;
209 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
210 if (!fmt) {
211 f_inst = inst->fmt_dst;
212 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
213 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
214 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
215 }
216 break;
217 default:
218 return -EINVAL;
219 }
220
221 if (pixmp->field == V4L2_FIELD_ANY)
222 pixmp->field = V4L2_FIELD_NONE;
223
224 pixmp->num_planes = 1;
225
226 return 0;
227 }
228
iris_venc_s_fmt_output(struct iris_inst * inst,struct v4l2_format * f)229 static int iris_venc_s_fmt_output(struct iris_inst *inst, struct v4l2_format *f)
230 {
231 const struct iris_fmt *venc_fmt;
232 struct v4l2_format *fmt;
233 u32 codec_align;
234
235 iris_venc_try_fmt(inst, f);
236
237 venc_fmt = find_format(inst, f->fmt.pix_mp.pixelformat, f->type);
238 if (!venc_fmt)
239 return -EINVAL;
240
241 codec_align = venc_fmt->pixfmt == V4L2_PIX_FMT_HEVC ? 32 : 16;
242
243 fmt = inst->fmt_dst;
244 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
245 /*
246 * If output format size != input format size,
247 * it is considered a scaling case,
248 * and the scaled size needs to be saved.
249 */
250 if (f->fmt.pix_mp.width != inst->fmt_src->fmt.pix_mp.width ||
251 f->fmt.pix_mp.height != inst->fmt_src->fmt.pix_mp.height) {
252 inst->enc_scale_width = f->fmt.pix_mp.width;
253 inst->enc_scale_height = f->fmt.pix_mp.height;
254 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
255 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align);
256 }
257 fmt->fmt.pix_mp.num_planes = 1;
258 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
259 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
260
261 if (f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_DEFAULT &&
262 f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_REC709)
263 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
264 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
265 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
266 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
267 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
268
269 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
270 inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
271 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
272 inst->codec = f->fmt.pix_mp.pixelformat;
273 memcpy(f, fmt, sizeof(struct v4l2_format));
274
275 return 0;
276 }
277
iris_venc_s_fmt_input(struct iris_inst * inst,struct v4l2_format * f)278 static int iris_venc_s_fmt_input(struct iris_inst *inst, struct v4l2_format *f)
279 {
280 struct v4l2_format *fmt, *output_fmt;
281
282 iris_venc_try_fmt(inst, f);
283
284 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type)))
285 return -EINVAL;
286
287 fmt = inst->fmt_src;
288 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
289 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128);
290 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32);
291 fmt->fmt.pix_mp.num_planes = 1;
292 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
293 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128);
294 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
295
296 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
297 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
298 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
299 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
300
301 output_fmt = inst->fmt_dst;
302 output_fmt->fmt.pix_mp.width = fmt->fmt.pix_mp.width;
303 output_fmt->fmt.pix_mp.height = fmt->fmt.pix_mp.height;
304 output_fmt->fmt.pix_mp.colorspace = fmt->fmt.pix_mp.colorspace;
305 output_fmt->fmt.pix_mp.xfer_func = fmt->fmt.pix_mp.xfer_func;
306 output_fmt->fmt.pix_mp.ycbcr_enc = fmt->fmt.pix_mp.ycbcr_enc;
307 output_fmt->fmt.pix_mp.quantization = fmt->fmt.pix_mp.quantization;
308
309 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT);
310 inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
311
312 inst->enc_raw_width = f->fmt.pix_mp.width;
313 inst->enc_raw_height = f->fmt.pix_mp.height;
314 inst->enc_scale_width = f->fmt.pix_mp.width;
315 inst->enc_scale_height = f->fmt.pix_mp.height;
316
317 if (f->fmt.pix_mp.width != inst->crop.width ||
318 f->fmt.pix_mp.height != inst->crop.height) {
319 inst->crop.top = 0;
320 inst->crop.left = 0;
321 inst->crop.width = fmt->fmt.pix_mp.width;
322 inst->crop.height = fmt->fmt.pix_mp.height;
323
324 iris_venc_s_fmt_output(inst, output_fmt);
325 }
326
327 memcpy(f, fmt, sizeof(struct v4l2_format));
328
329 return 0;
330 }
331
iris_venc_s_fmt(struct iris_inst * inst,struct v4l2_format * f)332 int iris_venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
333 {
334 struct vb2_queue *q;
335
336 q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type);
337
338 if (vb2_is_busy(q))
339 return -EBUSY;
340
341 switch (f->type) {
342 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
343 return iris_venc_s_fmt_input(inst, f);
344 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
345 return iris_venc_s_fmt_output(inst, f);
346 default:
347 return -EINVAL;
348 }
349 }
350
iris_venc_validate_format(struct iris_inst * inst,u32 pixelformat)351 int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat)
352 {
353 const struct iris_fmt *fmt = NULL;
354
355 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
356 if (!fmt) {
357 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
358 if (!fmt)
359 return -EINVAL;
360 }
361
362 return 0;
363 }
364
iris_venc_subscribe_event(struct iris_inst * inst,const struct v4l2_event_subscription * sub)365 int iris_venc_subscribe_event(struct iris_inst *inst,
366 const struct v4l2_event_subscription *sub)
367 {
368 switch (sub->type) {
369 case V4L2_EVENT_EOS:
370 return v4l2_event_subscribe(&inst->fh, sub, 0, NULL);
371 case V4L2_EVENT_CTRL:
372 return v4l2_ctrl_subscribe_event(&inst->fh, sub);
373 default:
374 return -EINVAL;
375 }
376 }
377
iris_venc_s_selection(struct iris_inst * inst,struct v4l2_selection * s)378 int iris_venc_s_selection(struct iris_inst *inst, struct v4l2_selection *s)
379 {
380 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
381 return -EINVAL;
382
383 switch (s->target) {
384 case V4L2_SEL_TGT_CROP:
385 s->r.left = 0;
386 s->r.top = 0;
387
388 if (s->r.width > inst->fmt_src->fmt.pix_mp.width ||
389 s->r.height > inst->fmt_src->fmt.pix_mp.height)
390 return -EINVAL;
391
392 inst->crop.left = s->r.left;
393 inst->crop.top = s->r.top;
394 inst->crop.width = s->r.width;
395 inst->crop.height = s->r.height;
396 inst->fmt_dst->fmt.pix_mp.width = inst->crop.width;
397 inst->fmt_dst->fmt.pix_mp.height = inst->crop.height;
398 return iris_venc_s_fmt_output(inst, inst->fmt_dst);
399 default:
400 return -EINVAL;
401 }
402 }
403
iris_venc_s_param(struct iris_inst * inst,struct v4l2_streamparm * s_parm)404 int iris_venc_s_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm)
405 {
406 struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps;
407 struct vb2_queue *src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
408 struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
409 struct v4l2_fract *timeperframe = NULL;
410 u32 default_rate = DEFAULT_FPS;
411 bool is_frame_rate = false;
412 u32 fps, max_rate;
413
414 int ret = 0;
415
416 if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
417 timeperframe = &s_parm->parm.output.timeperframe;
418 max_rate = caps->max_operating_rate;
419 s_parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
420 } else {
421 timeperframe = &s_parm->parm.capture.timeperframe;
422 is_frame_rate = true;
423 max_rate = caps->max_frame_rate;
424 s_parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
425 }
426
427 if (!timeperframe->denominator || !timeperframe->numerator) {
428 if (!timeperframe->numerator)
429 timeperframe->numerator = 1;
430 if (!timeperframe->denominator)
431 timeperframe->denominator = default_rate;
432 }
433
434 fps = timeperframe->denominator / timeperframe->numerator;
435 if (!fps)
436 return -EINVAL;
437
438 if (fps > max_rate) {
439 ret = -ENOMEM;
440 goto reset_rate;
441 }
442
443 if (is_frame_rate)
444 inst->frame_rate = fps;
445 else
446 inst->operating_rate = fps;
447
448 if ((s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && vb2_is_streaming(src_q)) ||
449 (s_parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && vb2_is_streaming(dst_q))) {
450 ret = iris_check_core_mbpf(inst);
451 if (ret)
452 goto reset_rate;
453 ret = iris_check_core_mbps(inst);
454 if (ret)
455 goto reset_rate;
456 }
457
458 return 0;
459
460 reset_rate:
461 if (ret) {
462 if (is_frame_rate)
463 inst->frame_rate = default_rate;
464 else
465 inst->operating_rate = default_rate;
466 }
467
468 return ret;
469 }
470
iris_venc_g_param(struct iris_inst * inst,struct v4l2_streamparm * s_parm)471 int iris_venc_g_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm)
472 {
473 struct v4l2_fract *timeperframe = NULL;
474
475 if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
476 timeperframe = &s_parm->parm.output.timeperframe;
477 timeperframe->numerator = 1;
478 timeperframe->denominator = inst->operating_rate;
479 s_parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
480 } else {
481 timeperframe = &s_parm->parm.capture.timeperframe;
482 timeperframe->numerator = 1;
483 timeperframe->denominator = inst->frame_rate;
484 s_parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
485 }
486
487 return 0;
488 }
489
iris_venc_streamon_input(struct iris_inst * inst)490 int iris_venc_streamon_input(struct iris_inst *inst)
491 {
492 int ret;
493
494 ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
495 if (ret)
496 return ret;
497
498 ret = iris_alloc_and_queue_persist_bufs(inst, BUF_ARP);
499 if (ret)
500 return ret;
501
502 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
503
504 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
505 if (ret)
506 return ret;
507
508 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
509 if (ret)
510 return ret;
511
512 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
513 if (ret)
514 return ret;
515
516 return iris_process_streamon_input(inst);
517 }
518
iris_venc_streamon_output(struct iris_inst * inst)519 int iris_venc_streamon_output(struct iris_inst *inst)
520 {
521 int ret;
522
523 ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
524 if (ret)
525 goto error;
526
527 ret = iris_alloc_and_queue_persist_bufs(inst, BUF_ARP);
528 if (ret)
529 return ret;
530
531 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
532
533 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
534 if (ret)
535 goto error;
536
537 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
538 if (ret)
539 goto error;
540
541 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
542 if (ret)
543 goto error;
544
545 ret = iris_process_streamon_output(inst);
546 if (ret)
547 goto error;
548
549 return ret;
550
551 error:
552 iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
553
554 return ret;
555 }
556
iris_venc_qbuf(struct iris_inst * inst,struct vb2_v4l2_buffer * vbuf)557 int iris_venc_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
558 {
559 struct iris_buffer *buf = to_iris_buffer(vbuf);
560 struct vb2_buffer *vb2 = &vbuf->vb2_buf;
561 struct vb2_queue *q;
562 int ret;
563
564 ret = iris_vb2_buffer_to_driver(vb2, buf);
565 if (ret)
566 return ret;
567
568 if (buf->type == BUF_INPUT)
569 iris_set_ts_metadata(inst, vbuf);
570
571 q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type);
572 if (!vb2_is_streaming(q)) {
573 buf->attr |= BUF_ATTR_DEFERRED;
574 return 0;
575 }
576
577 iris_scale_power(inst);
578
579 return iris_queue_buffer(inst, buf);
580 }
581
iris_venc_start_cmd(struct iris_inst * inst)582 int iris_venc_start_cmd(struct iris_inst *inst)
583 {
584 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
585 enum iris_inst_sub_state clear_sub_state = 0;
586 struct vb2_queue *dst_vq;
587 int ret;
588
589 dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
590
591 if (inst->sub_state & IRIS_INST_SUB_DRAIN &&
592 inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) {
593 vb2_clear_last_buffer_dequeued(dst_vq);
594 clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
595 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
596 if (hfi_ops->session_resume_drain) {
597 ret = hfi_ops->session_resume_drain(inst,
598 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
599 if (ret)
600 return ret;
601 }
602 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
603 }
604 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) {
605 if (hfi_ops->session_resume_drain) {
606 ret = hfi_ops->session_resume_drain(inst,
607 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
608 if (ret)
609 return ret;
610 }
611 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
612 }
613 } else {
614 dev_err(inst->core->dev, "start called before receiving last_flag\n");
615 iris_inst_change_state(inst, IRIS_INST_ERROR);
616 return -EBUSY;
617 }
618
619 inst->last_buffer_dequeued = false;
620
621 return iris_inst_change_sub_state(inst, clear_sub_state, 0);
622 }
623
iris_venc_stop_cmd(struct iris_inst * inst)624 int iris_venc_stop_cmd(struct iris_inst *inst)
625 {
626 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
627 int ret;
628
629 ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
630 if (ret)
631 return ret;
632
633 ret = iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN);
634
635 iris_scale_power(inst);
636
637 return ret;
638 }
639