xref: /linux/drivers/media/platform/qcom/iris/iris_vdec.c (revision 22c55fb9eb92395d999b8404d73e58540d11bdd8)
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 
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 
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 *
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 *
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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
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
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 
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 
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 
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