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 <media/v4l2-event.h>
7 #include <media/v4l2-mem2mem.h>
8
9 #include "iris_buffer.h"
10 #include "iris_ctrls.h"
11 #include "iris_instance.h"
12 #include "iris_power.h"
13 #include "iris_vdec.h"
14 #include "iris_vpu_buffer.h"
15
16 #define DEFAULT_WIDTH 320
17 #define DEFAULT_HEIGHT 240
18 #define DEFAULT_CODEC_ALIGNMENT 16
19
iris_vdec_inst_init(struct iris_inst * inst)20 int iris_vdec_inst_init(struct iris_inst *inst)
21 {
22 struct iris_core *core = inst->core;
23 struct v4l2_format *f;
24
25 inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL);
26 inst->fmt_dst = kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL);
27
28 inst->fw_min_count = MIN_BUFFERS;
29
30 f = inst->fmt_src;
31 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_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_INPUT);
39 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
40 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT);
41 inst->buffers[BUF_INPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
42
43 f = inst->fmt_dst;
44 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
45 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
46 f->fmt.pix_mp.width = ALIGN(DEFAULT_WIDTH, 128);
47 f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32);
48 f->fmt.pix_mp.num_planes = 1;
49 f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128);
50 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
51 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
52 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
53 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
54 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
55 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
56 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
57 inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
58
59 memcpy(&inst->fw_caps[0], &core->inst_fw_caps[0],
60 INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap));
61
62 return iris_ctrls_init(inst);
63 }
64
iris_vdec_inst_deinit(struct iris_inst * inst)65 void iris_vdec_inst_deinit(struct iris_inst *inst)
66 {
67 kfree(inst->fmt_dst);
68 kfree(inst->fmt_src);
69 }
70
71 static const struct iris_fmt iris_vdec_formats[] = {
72 [IRIS_FMT_H264] = {
73 .pixfmt = V4L2_PIX_FMT_H264,
74 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
75 },
76 [IRIS_FMT_HEVC] = {
77 .pixfmt = V4L2_PIX_FMT_HEVC,
78 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
79 },
80 [IRIS_FMT_VP9] = {
81 .pixfmt = V4L2_PIX_FMT_VP9,
82 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
83 },
84 };
85
86 static const struct iris_fmt *
find_format(struct iris_inst * inst,u32 pixfmt,u32 type)87 find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
88 {
89 unsigned int size = ARRAY_SIZE(iris_vdec_formats);
90 const struct iris_fmt *fmt = iris_vdec_formats;
91 unsigned int i;
92
93 for (i = 0; i < size; i++) {
94 if (fmt[i].pixfmt == pixfmt)
95 break;
96 }
97
98 if (i == size || fmt[i].type != type)
99 return NULL;
100
101 return &fmt[i];
102 }
103
104 static const struct iris_fmt *
find_format_by_index(struct iris_inst * inst,u32 index,u32 type)105 find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
106 {
107 const struct iris_fmt *fmt = iris_vdec_formats;
108 unsigned int size = ARRAY_SIZE(iris_vdec_formats);
109
110 if (index >= size || fmt[index].type != type)
111 return NULL;
112
113 return &fmt[index];
114 }
115
iris_vdec_enum_fmt(struct iris_inst * inst,struct v4l2_fmtdesc * f)116 int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
117 {
118 const struct iris_fmt *fmt;
119
120 switch (f->type) {
121 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
122 fmt = find_format_by_index(inst, f->index, f->type);
123 if (!fmt)
124 return -EINVAL;
125
126 f->pixelformat = fmt->pixfmt;
127 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION;
128 break;
129 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
130 if (f->index)
131 return -EINVAL;
132 f->pixelformat = V4L2_PIX_FMT_NV12;
133 break;
134 default:
135 return -EINVAL;
136 }
137
138 return 0;
139 }
140
iris_vdec_try_fmt(struct iris_inst * inst,struct v4l2_format * f)141 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
142 {
143 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
144 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
145 const struct iris_fmt *fmt;
146 struct v4l2_format *f_inst;
147 struct vb2_queue *src_q;
148
149 memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
150 fmt = find_format(inst, pixmp->pixelformat, f->type);
151 switch (f->type) {
152 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
153 if (!fmt) {
154 f_inst = inst->fmt_src;
155 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
156 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
157 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
158 }
159 break;
160 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
161 if (!fmt) {
162 f_inst = inst->fmt_dst;
163 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
164 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
165 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
166 }
167
168 src_q = v4l2_m2m_get_src_vq(m2m_ctx);
169 if (vb2_is_streaming(src_q)) {
170 f_inst = inst->fmt_src;
171 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
172 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
173 }
174 break;
175 default:
176 return -EINVAL;
177 }
178
179 if (pixmp->field == V4L2_FIELD_ANY)
180 pixmp->field = V4L2_FIELD_NONE;
181
182 pixmp->num_planes = 1;
183
184 return 0;
185 }
186
iris_vdec_s_fmt(struct iris_inst * inst,struct v4l2_format * f)187 int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
188 {
189 struct v4l2_format *fmt, *output_fmt;
190 struct vb2_queue *q;
191 u32 codec_align;
192
193 q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type);
194 if (!q)
195 return -EINVAL;
196
197 if (vb2_is_busy(q))
198 return -EBUSY;
199
200 iris_vdec_try_fmt(inst, f);
201
202 switch (f->type) {
203 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
204 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type)))
205 return -EINVAL;
206
207 fmt = inst->fmt_src;
208 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
209 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
210 inst->codec = fmt->fmt.pix_mp.pixelformat;
211 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
212 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
213 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align);
214 fmt->fmt.pix_mp.num_planes = 1;
215 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
216 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
217 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT);
218 inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
219
220 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
221 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
222 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
223 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
224
225 output_fmt = inst->fmt_dst;
226 output_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
227 output_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
228 output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
229 output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
230
231 /* Update capture format based on new ip w/h */
232 output_fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128);
233 output_fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32);
234 inst->buffers[BUF_OUTPUT].size = iris_get_buffer_size(inst, BUF_OUTPUT);
235
236 inst->crop.left = 0;
237 inst->crop.top = 0;
238 inst->crop.width = f->fmt.pix_mp.width;
239 inst->crop.height = f->fmt.pix_mp.height;
240 break;
241 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
242 fmt = inst->fmt_dst;
243 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
244 if (fmt->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12)
245 return -EINVAL;
246 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
247 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128);
248 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32);
249 fmt->fmt.pix_mp.num_planes = 1;
250 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128);
251 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
252 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
253 inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
254
255 inst->crop.top = 0;
256 inst->crop.left = 0;
257 inst->crop.width = f->fmt.pix_mp.width;
258 inst->crop.height = f->fmt.pix_mp.height;
259 break;
260 default:
261 return -EINVAL;
262 }
263 memcpy(f, fmt, sizeof(*fmt));
264
265 return 0;
266 }
267
iris_vdec_subscribe_event(struct iris_inst * inst,const struct v4l2_event_subscription * sub)268 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub)
269 {
270 int ret = 0;
271
272 switch (sub->type) {
273 case V4L2_EVENT_EOS:
274 ret = v4l2_event_subscribe(&inst->fh, sub, 0, NULL);
275 break;
276 case V4L2_EVENT_SOURCE_CHANGE:
277 ret = v4l2_src_change_event_subscribe(&inst->fh, sub);
278 break;
279 case V4L2_EVENT_CTRL:
280 ret = v4l2_ctrl_subscribe_event(&inst->fh, sub);
281 break;
282 default:
283 return -EINVAL;
284 }
285
286 return ret;
287 }
288
iris_vdec_src_change(struct iris_inst * inst)289 void iris_vdec_src_change(struct iris_inst *inst)
290 {
291 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
292 struct v4l2_event event = {0};
293 struct vb2_queue *src_q;
294
295 src_q = v4l2_m2m_get_src_vq(m2m_ctx);
296 if (!vb2_is_streaming(src_q))
297 return;
298
299 event.type = V4L2_EVENT_SOURCE_CHANGE;
300 event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
301 v4l2_event_queue_fh(&inst->fh, &event);
302 }
303
304
iris_vdec_flush_deferred_buffers(struct iris_inst * inst,enum iris_buffer_type type)305 static void iris_vdec_flush_deferred_buffers(struct iris_inst *inst,
306 enum iris_buffer_type type)
307 {
308 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
309 struct v4l2_m2m_buffer *buffer, *n;
310 struct iris_buffer *buf;
311
312 if (type == BUF_INPUT) {
313 v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
314 buf = to_iris_buffer(&buffer->vb);
315 if (buf->attr & BUF_ATTR_DEFERRED) {
316 if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
317 buf->attr |= BUF_ATTR_BUFFER_DONE;
318 buf->data_size = 0;
319 iris_vb2_buffer_done(inst, buf);
320 }
321 }
322 }
323 } else {
324 v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) {
325 buf = to_iris_buffer(&buffer->vb);
326 if (buf->attr & BUF_ATTR_DEFERRED) {
327 if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
328 buf->attr |= BUF_ATTR_BUFFER_DONE;
329 buf->data_size = 0;
330 iris_vb2_buffer_done(inst, buf);
331 }
332 }
333 }
334 }
335 }
336
iris_vdec_kill_session(struct iris_inst * inst)337 static void iris_vdec_kill_session(struct iris_inst *inst)
338 {
339 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
340
341 if (!inst->session_id)
342 return;
343
344 hfi_ops->session_close(inst);
345 iris_inst_change_state(inst, IRIS_INST_ERROR);
346 }
347
iris_vdec_session_streamoff(struct iris_inst * inst,u32 plane)348 int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane)
349 {
350 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
351 enum iris_buffer_type buffer_type;
352 int ret;
353
354 switch (plane) {
355 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
356 buffer_type = BUF_INPUT;
357 break;
358 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
359 buffer_type = BUF_OUTPUT;
360 break;
361 default:
362 return -EINVAL;
363 }
364
365 ret = hfi_ops->session_stop(inst, plane);
366 if (ret)
367 goto error;
368
369 ret = iris_inst_state_change_streamoff(inst, plane);
370 if (ret)
371 goto error;
372
373 iris_vdec_flush_deferred_buffers(inst, buffer_type);
374
375 return 0;
376
377 error:
378 iris_vdec_kill_session(inst);
379 iris_vdec_flush_deferred_buffers(inst, buffer_type);
380
381 return ret;
382 }
383
iris_vdec_process_streamon_input(struct iris_inst * inst)384 static int iris_vdec_process_streamon_input(struct iris_inst *inst)
385 {
386 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
387 enum iris_inst_sub_state set_sub_state = 0;
388 int ret;
389
390 iris_scale_power(inst);
391
392 ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
393 if (ret)
394 return ret;
395
396 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
397 ret = iris_inst_change_sub_state(inst, IRIS_INST_SUB_INPUT_PAUSE, 0);
398 if (ret)
399 return ret;
400 }
401
402 if (inst->sub_state & IRIS_INST_SUB_DRC ||
403 inst->sub_state & IRIS_INST_SUB_DRAIN ||
404 inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) {
405 if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) {
406 if (hfi_ops->session_pause) {
407 ret = hfi_ops->session_pause(inst,
408 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
409 if (ret)
410 return ret;
411 }
412 set_sub_state = IRIS_INST_SUB_INPUT_PAUSE;
413 }
414 }
415
416 ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
417 if (ret)
418 return ret;
419
420 return iris_inst_change_sub_state(inst, 0, set_sub_state);
421 }
422
iris_vdec_streamon_input(struct iris_inst * inst)423 int iris_vdec_streamon_input(struct iris_inst *inst)
424 {
425 int ret;
426
427 ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
428 if (ret)
429 return ret;
430
431 ret = iris_alloc_and_queue_persist_bufs(inst);
432 if (ret)
433 return ret;
434
435 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
436
437 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
438 if (ret)
439 return ret;
440
441 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
442 if (ret)
443 return ret;
444
445 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
446 if (ret)
447 return ret;
448
449 return iris_vdec_process_streamon_input(inst);
450 }
451
iris_vdec_process_streamon_output(struct iris_inst * inst)452 static int iris_vdec_process_streamon_output(struct iris_inst *inst)
453 {
454 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
455 bool drain_active = false, drc_active = false;
456 enum iris_inst_sub_state clear_sub_state = 0;
457 int ret = 0;
458
459 iris_scale_power(inst);
460
461 drain_active = inst->sub_state & IRIS_INST_SUB_DRAIN &&
462 inst->sub_state & IRIS_INST_SUB_DRAIN_LAST;
463
464 drc_active = inst->sub_state & IRIS_INST_SUB_DRC &&
465 inst->sub_state & IRIS_INST_SUB_DRC_LAST;
466
467 if (drc_active)
468 clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST;
469 else if (drain_active)
470 clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
471
472 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
473 ret = iris_alloc_and_queue_input_int_bufs(inst);
474 if (ret)
475 return ret;
476 ret = iris_set_stage(inst, STAGE);
477 if (ret)
478 return ret;
479 ret = iris_set_pipe(inst, PIPE);
480 if (ret)
481 return ret;
482 }
483
484 if (inst->state == IRIS_INST_INPUT_STREAMING &&
485 inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
486 if (!drain_active)
487 ret = hfi_ops->session_resume_drc(inst,
488 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
489 else if (hfi_ops->session_resume_drain)
490 ret = hfi_ops->session_resume_drain(inst,
491 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
492 if (ret)
493 return ret;
494 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
495 }
496
497 if (inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)
498 clear_sub_state |= IRIS_INST_SUB_FIRST_IPSC;
499
500 ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
501 if (ret)
502 return ret;
503
504 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE)
505 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
506
507 ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
508 if (ret)
509 return ret;
510
511 inst->last_buffer_dequeued = false;
512
513 return iris_inst_change_sub_state(inst, clear_sub_state, 0);
514 }
515
iris_vdec_streamon_output(struct iris_inst * inst)516 int iris_vdec_streamon_output(struct iris_inst *inst)
517 {
518 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
519 int ret;
520
521 ret = hfi_ops->session_set_config_params(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
522 if (ret)
523 return ret;
524
525 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
526
527 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
528 if (ret)
529 return ret;
530
531 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
532 if (ret)
533 return ret;
534
535 ret = iris_vdec_process_streamon_output(inst);
536 if (ret)
537 goto error;
538
539 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
540 if (ret)
541 goto error;
542
543 return ret;
544
545 error:
546 iris_vdec_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
547
548 return ret;
549 }
550
551 static int
iris_vdec_vb2_buffer_to_driver(struct vb2_buffer * vb2,struct iris_buffer * buf)552 iris_vdec_vb2_buffer_to_driver(struct vb2_buffer *vb2, struct iris_buffer *buf)
553 {
554 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
555
556 buf->type = iris_v4l2_type_to_driver(vb2->type);
557 buf->index = vb2->index;
558 buf->fd = vb2->planes[0].m.fd;
559 buf->buffer_size = vb2->planes[0].length;
560 buf->data_offset = vb2->planes[0].data_offset;
561 buf->data_size = vb2->planes[0].bytesused - vb2->planes[0].data_offset;
562 buf->flags = vbuf->flags;
563 buf->timestamp = vb2->timestamp;
564 buf->attr = 0;
565
566 return 0;
567 }
568
569 static void
iris_set_ts_metadata(struct iris_inst * inst,struct vb2_v4l2_buffer * vbuf)570 iris_set_ts_metadata(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
571 {
572 u32 mask = V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
573 struct vb2_buffer *vb = &vbuf->vb2_buf;
574 u64 ts_us = vb->timestamp;
575
576 if (inst->metadata_idx >= ARRAY_SIZE(inst->tss))
577 inst->metadata_idx = 0;
578
579 do_div(ts_us, NSEC_PER_USEC);
580
581 inst->tss[inst->metadata_idx].flags = vbuf->flags & mask;
582 inst->tss[inst->metadata_idx].tc = vbuf->timecode;
583 inst->tss[inst->metadata_idx].ts_us = ts_us;
584 inst->tss[inst->metadata_idx].ts_ns = vb->timestamp;
585
586 inst->metadata_idx++;
587 }
588
iris_vdec_qbuf(struct iris_inst * inst,struct vb2_v4l2_buffer * vbuf)589 int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
590 {
591 struct iris_buffer *buf = to_iris_buffer(vbuf);
592 struct vb2_buffer *vb2 = &vbuf->vb2_buf;
593 struct vb2_queue *q;
594 int ret;
595
596 ret = iris_vdec_vb2_buffer_to_driver(vb2, buf);
597 if (ret)
598 return ret;
599
600 if (buf->type == BUF_INPUT)
601 iris_set_ts_metadata(inst, vbuf);
602
603 q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type);
604 if (!vb2_is_streaming(q)) {
605 buf->attr |= BUF_ATTR_DEFERRED;
606 return 0;
607 }
608
609 iris_scale_power(inst);
610
611 return iris_queue_buffer(inst, buf);
612 }
613
iris_vdec_start_cmd(struct iris_inst * inst)614 int iris_vdec_start_cmd(struct iris_inst *inst)
615 {
616 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
617 enum iris_inst_sub_state clear_sub_state = 0;
618 struct vb2_queue *dst_vq;
619 int ret;
620
621 dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
622
623 if (inst->sub_state & IRIS_INST_SUB_DRC &&
624 inst->sub_state & IRIS_INST_SUB_DRC_LAST) {
625 vb2_clear_last_buffer_dequeued(dst_vq);
626 clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST;
627
628 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
629 ret = hfi_ops->session_resume_drc(inst,
630 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
631 if (ret)
632 return ret;
633 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
634 }
635 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) {
636 ret = hfi_ops->session_resume_drc(inst,
637 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
638 if (ret)
639 return ret;
640 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
641 }
642 } else if (inst->sub_state & IRIS_INST_SUB_DRAIN &&
643 inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) {
644 vb2_clear_last_buffer_dequeued(dst_vq);
645 clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
646 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
647 if (hfi_ops->session_resume_drain) {
648 ret =
649 hfi_ops->session_resume_drain(inst,
650 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
651 if (ret)
652 return ret;
653 }
654
655 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
656 }
657 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) {
658 if (hfi_ops->session_resume_drain) {
659 ret =
660 hfi_ops->session_resume_drain(inst,
661 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
662 if (ret)
663 return ret;
664 }
665
666 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
667 }
668 } else {
669 dev_err(inst->core->dev, "start called before receiving last_flag\n");
670 iris_inst_change_state(inst, IRIS_INST_ERROR);
671 return -EBUSY;
672 }
673
674 return iris_inst_change_sub_state(inst, clear_sub_state, 0);
675 }
676
iris_vdec_stop_cmd(struct iris_inst * inst)677 int iris_vdec_stop_cmd(struct iris_inst *inst)
678 {
679 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
680 int ret;
681
682 ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
683 if (ret)
684 return ret;
685
686 return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN);
687 }
688