xref: /linux/drivers/media/platform/qcom/iris/iris_vidc.c (revision ce4c356d760f6fb22d69f0c5091542891ba6f394)
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/pm_runtime.h>
7 #include <media/v4l2-event.h>
8 #include <media/v4l2-ioctl.h>
9 #include <media/v4l2-mem2mem.h>
10 #include <media/videobuf2-dma-contig.h>
11 
12 #include "iris_vidc.h"
13 #include "iris_instance.h"
14 #include "iris_vdec.h"
15 #include "iris_vb2.h"
16 #include "iris_vpu_buffer.h"
17 #include "iris_platform_common.h"
18 
19 #define IRIS_DRV_NAME "iris_driver"
20 #define IRIS_BUS_NAME "platform:iris_icc"
21 #define STEP_WIDTH 1
22 #define STEP_HEIGHT 1
23 
24 static void iris_v4l2_fh_init(struct iris_inst *inst, struct file *filp)
25 {
26 	v4l2_fh_init(&inst->fh, inst->core->vdev_dec);
27 	inst->fh.ctrl_handler = &inst->ctrl_handler;
28 	v4l2_fh_add(&inst->fh, filp);
29 }
30 
31 static void iris_v4l2_fh_deinit(struct iris_inst *inst, struct file *filp)
32 {
33 	v4l2_fh_del(&inst->fh, filp);
34 	inst->fh.ctrl_handler = NULL;
35 	v4l2_fh_exit(&inst->fh);
36 }
37 
38 static void iris_add_session(struct iris_inst *inst)
39 {
40 	struct iris_core *core = inst->core;
41 	struct iris_inst *iter;
42 	u32 count = 0;
43 
44 	mutex_lock(&core->lock);
45 
46 	list_for_each_entry(iter, &core->instances, list)
47 		count++;
48 
49 	if (count < core->iris_platform_data->max_session_count)
50 		list_add_tail(&inst->list, &core->instances);
51 
52 	mutex_unlock(&core->lock);
53 }
54 
55 static void iris_remove_session(struct iris_inst *inst)
56 {
57 	struct iris_core *core = inst->core;
58 	struct iris_inst *iter, *temp;
59 
60 	mutex_lock(&core->lock);
61 	list_for_each_entry_safe(iter, temp, &core->instances, list) {
62 		if (iter->session_id == inst->session_id) {
63 			list_del_init(&iter->list);
64 			break;
65 		}
66 	}
67 	mutex_unlock(&core->lock);
68 }
69 
70 static inline struct iris_inst *iris_get_inst(struct file *filp)
71 {
72 	return container_of(file_to_v4l2_fh(filp), struct iris_inst, fh);
73 }
74 
75 static void iris_m2m_device_run(void *priv)
76 {
77 }
78 
79 static void iris_m2m_job_abort(void *priv)
80 {
81 	struct iris_inst *inst = priv;
82 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
83 
84 	v4l2_m2m_job_finish(inst->m2m_dev, m2m_ctx);
85 }
86 
87 static const struct v4l2_m2m_ops iris_m2m_ops = {
88 	.device_run = iris_m2m_device_run,
89 	.job_abort = iris_m2m_job_abort,
90 };
91 
92 static int
93 iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
94 {
95 	struct iris_inst *inst = priv;
96 	int ret;
97 
98 	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
99 	src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
100 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
101 	src_vq->ops = inst->core->iris_vb2_ops;
102 	src_vq->mem_ops = &vb2_dma_contig_memops;
103 	src_vq->drv_priv = inst;
104 	src_vq->buf_struct_size = sizeof(struct iris_buffer);
105 	src_vq->min_reqbufs_allocation = MIN_BUFFERS;
106 	src_vq->dev = inst->core->dev;
107 	src_vq->lock = &inst->ctx_q_lock;
108 	ret = vb2_queue_init(src_vq);
109 	if (ret)
110 		return ret;
111 
112 	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
113 	dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
114 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
115 	dst_vq->ops = inst->core->iris_vb2_ops;
116 	dst_vq->mem_ops = &vb2_dma_contig_memops;
117 	dst_vq->drv_priv = inst;
118 	dst_vq->buf_struct_size = sizeof(struct iris_buffer);
119 	dst_vq->min_reqbufs_allocation = MIN_BUFFERS;
120 	dst_vq->dev = inst->core->dev;
121 	dst_vq->lock = &inst->ctx_q_lock;
122 
123 	return vb2_queue_init(dst_vq);
124 }
125 
126 int iris_open(struct file *filp)
127 {
128 	struct iris_core *core = video_drvdata(filp);
129 	struct iris_inst *inst;
130 	int ret;
131 
132 	ret = pm_runtime_resume_and_get(core->dev);
133 	if (ret < 0)
134 		return ret;
135 
136 	ret = iris_core_init(core);
137 	if (ret) {
138 		dev_err(core->dev, "core init failed\n");
139 		pm_runtime_put_sync(core->dev);
140 		return ret;
141 	}
142 
143 	pm_runtime_put_sync(core->dev);
144 
145 	inst = core->iris_platform_data->get_instance();
146 	if (!inst)
147 		return -ENOMEM;
148 
149 	inst->core = core;
150 	inst->session_id = hash32_ptr(inst);
151 	inst->state = IRIS_INST_DEINIT;
152 
153 	mutex_init(&inst->lock);
154 	mutex_init(&inst->ctx_q_lock);
155 
156 	INIT_LIST_HEAD(&inst->buffers[BUF_BIN].list);
157 	INIT_LIST_HEAD(&inst->buffers[BUF_ARP].list);
158 	INIT_LIST_HEAD(&inst->buffers[BUF_COMV].list);
159 	INIT_LIST_HEAD(&inst->buffers[BUF_NON_COMV].list);
160 	INIT_LIST_HEAD(&inst->buffers[BUF_LINE].list);
161 	INIT_LIST_HEAD(&inst->buffers[BUF_DPB].list);
162 	INIT_LIST_HEAD(&inst->buffers[BUF_PERSIST].list);
163 	INIT_LIST_HEAD(&inst->buffers[BUF_SCRATCH_1].list);
164 	init_completion(&inst->completion);
165 	init_completion(&inst->flush_completion);
166 
167 	iris_v4l2_fh_init(inst, filp);
168 
169 	inst->m2m_dev = v4l2_m2m_init(&iris_m2m_ops);
170 	if (IS_ERR_OR_NULL(inst->m2m_dev)) {
171 		ret = -EINVAL;
172 		goto fail_v4l2_fh_deinit;
173 	}
174 
175 	inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, iris_m2m_queue_init);
176 	if (IS_ERR_OR_NULL(inst->m2m_ctx)) {
177 		ret = -EINVAL;
178 		goto fail_m2m_release;
179 	}
180 
181 	ret = iris_vdec_inst_init(inst);
182 	if (ret)
183 		goto fail_m2m_ctx_release;
184 
185 	iris_add_session(inst);
186 
187 	inst->fh.m2m_ctx = inst->m2m_ctx;
188 
189 	return 0;
190 
191 fail_m2m_ctx_release:
192 	v4l2_m2m_ctx_release(inst->m2m_ctx);
193 fail_m2m_release:
194 	v4l2_m2m_release(inst->m2m_dev);
195 fail_v4l2_fh_deinit:
196 	iris_v4l2_fh_deinit(inst, filp);
197 	mutex_destroy(&inst->ctx_q_lock);
198 	mutex_destroy(&inst->lock);
199 	kfree(inst);
200 
201 	return ret;
202 }
203 
204 static void iris_session_close(struct iris_inst *inst)
205 {
206 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
207 	bool wait_for_response = true;
208 	int ret;
209 
210 	if (inst->state == IRIS_INST_DEINIT)
211 		return;
212 
213 	reinit_completion(&inst->completion);
214 
215 	ret = hfi_ops->session_close(inst);
216 	if (ret)
217 		wait_for_response = false;
218 
219 	if (wait_for_response)
220 		iris_wait_for_session_response(inst, false);
221 }
222 
223 static void iris_check_num_queued_internal_buffers(struct iris_inst *inst, u32 plane)
224 {
225 	const struct iris_platform_data *platform_data = inst->core->iris_platform_data;
226 	struct iris_buffer *buf, *next;
227 	struct iris_buffers *buffers;
228 	const u32 *internal_buf_type;
229 	u32 internal_buffer_count, i;
230 	u32 count = 0;
231 
232 	if (V4L2_TYPE_IS_OUTPUT(plane)) {
233 		internal_buf_type = platform_data->dec_ip_int_buf_tbl;
234 		internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
235 	} else {
236 		internal_buf_type = platform_data->dec_op_int_buf_tbl;
237 		internal_buffer_count = platform_data->dec_op_int_buf_tbl_size;
238 	}
239 
240 	for (i = 0; i < internal_buffer_count; i++) {
241 		buffers = &inst->buffers[internal_buf_type[i]];
242 		list_for_each_entry_safe(buf, next, &buffers->list, list)
243 			count++;
244 		if (count)
245 			dev_err(inst->core->dev, "%d buffer of type %d not released",
246 				count, internal_buf_type[i]);
247 	}
248 }
249 
250 int iris_close(struct file *filp)
251 {
252 	struct iris_inst *inst = iris_get_inst(filp);
253 
254 	v4l2_ctrl_handler_free(&inst->ctrl_handler);
255 	v4l2_m2m_ctx_release(inst->m2m_ctx);
256 	v4l2_m2m_release(inst->m2m_dev);
257 	mutex_lock(&inst->lock);
258 	iris_vdec_inst_deinit(inst);
259 	iris_session_close(inst);
260 	iris_inst_change_state(inst, IRIS_INST_DEINIT);
261 	iris_v4l2_fh_deinit(inst, filp);
262 	iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
263 	iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
264 	iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
265 	iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
266 	iris_remove_session(inst);
267 	mutex_unlock(&inst->lock);
268 	mutex_destroy(&inst->ctx_q_lock);
269 	mutex_destroy(&inst->lock);
270 	kfree(inst);
271 
272 	return 0;
273 }
274 
275 static int iris_enum_fmt(struct file *filp, void *fh, struct v4l2_fmtdesc *f)
276 {
277 	struct iris_inst *inst = iris_get_inst(filp);
278 
279 	return iris_vdec_enum_fmt(inst, f);
280 }
281 
282 static int iris_try_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f)
283 {
284 	struct iris_inst *inst = iris_get_inst(filp);
285 	int ret;
286 
287 	mutex_lock(&inst->lock);
288 	ret = iris_vdec_try_fmt(inst, f);
289 	mutex_unlock(&inst->lock);
290 
291 	return ret;
292 }
293 
294 static int iris_s_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f)
295 {
296 	struct iris_inst *inst = iris_get_inst(filp);
297 	int ret;
298 
299 	mutex_lock(&inst->lock);
300 	ret = iris_vdec_s_fmt(inst, f);
301 	mutex_unlock(&inst->lock);
302 
303 	return ret;
304 }
305 
306 static int iris_g_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f)
307 {
308 	struct iris_inst *inst = iris_get_inst(filp);
309 	int ret = 0;
310 
311 	mutex_lock(&inst->lock);
312 	if (V4L2_TYPE_IS_OUTPUT(f->type))
313 		*f = *inst->fmt_src;
314 	else if (V4L2_TYPE_IS_CAPTURE(f->type))
315 		*f = *inst->fmt_dst;
316 	else
317 		ret = -EINVAL;
318 
319 	mutex_unlock(&inst->lock);
320 
321 	return ret;
322 }
323 
324 static int iris_enum_framesizes(struct file *filp, void *fh,
325 				struct v4l2_frmsizeenum *fsize)
326 {
327 	struct iris_inst *inst = iris_get_inst(filp);
328 	struct platform_inst_caps *caps;
329 
330 	if (fsize->index)
331 		return -EINVAL;
332 
333 	if (fsize->pixel_format != V4L2_PIX_FMT_H264 &&
334 	    fsize->pixel_format != V4L2_PIX_FMT_NV12)
335 		return -EINVAL;
336 
337 	caps = inst->core->iris_platform_data->inst_caps;
338 
339 	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
340 	fsize->stepwise.min_width = caps->min_frame_width;
341 	fsize->stepwise.max_width = caps->max_frame_width;
342 	fsize->stepwise.step_width = STEP_WIDTH;
343 	fsize->stepwise.min_height = caps->min_frame_height;
344 	fsize->stepwise.max_height = caps->max_frame_height;
345 	fsize->stepwise.step_height = STEP_HEIGHT;
346 
347 	return 0;
348 }
349 
350 static int iris_querycap(struct file *filp, void *fh, struct v4l2_capability *cap)
351 {
352 	strscpy(cap->driver, IRIS_DRV_NAME, sizeof(cap->driver));
353 	strscpy(cap->card, "Iris Decoder", sizeof(cap->card));
354 
355 	return 0;
356 }
357 
358 static int iris_g_selection(struct file *filp, void *fh, struct v4l2_selection *s)
359 {
360 	struct iris_inst *inst = iris_get_inst(filp);
361 
362 	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
363 		return -EINVAL;
364 
365 	switch (s->target) {
366 	case V4L2_SEL_TGT_CROP_BOUNDS:
367 	case V4L2_SEL_TGT_CROP_DEFAULT:
368 	case V4L2_SEL_TGT_CROP:
369 	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
370 	case V4L2_SEL_TGT_COMPOSE_PADDED:
371 	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
372 	case V4L2_SEL_TGT_COMPOSE:
373 		s->r.left = inst->crop.left;
374 		s->r.top = inst->crop.top;
375 		s->r.width = inst->crop.width;
376 		s->r.height = inst->crop.height;
377 		break;
378 	default:
379 		return -EINVAL;
380 	}
381 
382 	return 0;
383 }
384 
385 static int iris_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
386 {
387 	struct iris_inst *inst = container_of(fh, struct iris_inst, fh);
388 
389 	return iris_vdec_subscribe_event(inst, sub);
390 }
391 
392 static int iris_dec_cmd(struct file *filp, void *fh,
393 			struct v4l2_decoder_cmd *dec)
394 {
395 	struct iris_inst *inst = iris_get_inst(filp);
396 	int ret = 0;
397 
398 	mutex_lock(&inst->lock);
399 
400 	ret = v4l2_m2m_ioctl_decoder_cmd(filp, fh, dec);
401 	if (ret)
402 		goto unlock;
403 
404 	if (inst->state == IRIS_INST_DEINIT)
405 		goto unlock;
406 
407 	if (!iris_allow_cmd(inst, dec->cmd)) {
408 		ret = -EBUSY;
409 		goto unlock;
410 	}
411 
412 	if (dec->cmd == V4L2_DEC_CMD_START)
413 		ret = iris_vdec_start_cmd(inst);
414 	else if (dec->cmd == V4L2_DEC_CMD_STOP)
415 		ret = iris_vdec_stop_cmd(inst);
416 	else
417 		ret = -EINVAL;
418 
419 unlock:
420 	mutex_unlock(&inst->lock);
421 
422 	return ret;
423 }
424 
425 static struct v4l2_file_operations iris_v4l2_file_ops = {
426 	.owner                          = THIS_MODULE,
427 	.open                           = iris_open,
428 	.release                        = iris_close,
429 	.unlocked_ioctl                 = video_ioctl2,
430 	.poll                           = v4l2_m2m_fop_poll,
431 	.mmap                           = v4l2_m2m_fop_mmap,
432 };
433 
434 static const struct vb2_ops iris_vb2_ops = {
435 	.buf_init                       = iris_vb2_buf_init,
436 	.queue_setup                    = iris_vb2_queue_setup,
437 	.start_streaming                = iris_vb2_start_streaming,
438 	.stop_streaming                 = iris_vb2_stop_streaming,
439 	.buf_prepare                    = iris_vb2_buf_prepare,
440 	.buf_out_validate               = iris_vb2_buf_out_validate,
441 	.buf_queue                      = iris_vb2_buf_queue,
442 };
443 
444 static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = {
445 	.vidioc_enum_fmt_vid_cap        = iris_enum_fmt,
446 	.vidioc_enum_fmt_vid_out        = iris_enum_fmt,
447 	.vidioc_try_fmt_vid_cap_mplane  = iris_try_fmt_vid_mplane,
448 	.vidioc_try_fmt_vid_out_mplane  = iris_try_fmt_vid_mplane,
449 	.vidioc_s_fmt_vid_cap_mplane    = iris_s_fmt_vid_mplane,
450 	.vidioc_s_fmt_vid_out_mplane    = iris_s_fmt_vid_mplane,
451 	.vidioc_g_fmt_vid_cap_mplane    = iris_g_fmt_vid_mplane,
452 	.vidioc_g_fmt_vid_out_mplane    = iris_g_fmt_vid_mplane,
453 	.vidioc_enum_framesizes         = iris_enum_framesizes,
454 	.vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
455 	.vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
456 	.vidioc_create_bufs             = v4l2_m2m_ioctl_create_bufs,
457 	.vidioc_prepare_buf             = v4l2_m2m_ioctl_prepare_buf,
458 	.vidioc_expbuf                  = v4l2_m2m_ioctl_expbuf,
459 	.vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
460 	.vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
461 	.vidioc_remove_bufs             = v4l2_m2m_ioctl_remove_bufs,
462 	.vidioc_querycap                = iris_querycap,
463 	.vidioc_g_selection             = iris_g_selection,
464 	.vidioc_subscribe_event         = iris_subscribe_event,
465 	.vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
466 	.vidioc_streamon                = v4l2_m2m_ioctl_streamon,
467 	.vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
468 	.vidioc_try_decoder_cmd         = v4l2_m2m_ioctl_try_decoder_cmd,
469 	.vidioc_decoder_cmd             = iris_dec_cmd,
470 };
471 
472 void iris_init_ops(struct iris_core *core)
473 {
474 	core->iris_v4l2_file_ops = &iris_v4l2_file_ops;
475 	core->iris_vb2_ops = &iris_vb2_ops;
476 	core->iris_v4l2_ioctl_ops = &iris_v4l2_ioctl_ops;
477 }
478