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