xref: /linux/drivers/media/platform/qcom/iris/iris_vidc.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 <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)
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);
29 }
30 
31 static void iris_v4l2_fh_deinit(struct iris_inst *inst)
32 {
33 	v4l2_fh_del(&inst->fh);
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, void *fh)
71 {
72 	return container_of(filp->private_data, 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);
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 	filp->private_data = &inst->fh;
189 
190 	return 0;
191 
192 fail_m2m_ctx_release:
193 	v4l2_m2m_ctx_release(inst->m2m_ctx);
194 fail_m2m_release:
195 	v4l2_m2m_release(inst->m2m_dev);
196 fail_v4l2_fh_deinit:
197 	iris_v4l2_fh_deinit(inst);
198 	mutex_destroy(&inst->ctx_q_lock);
199 	mutex_destroy(&inst->lock);
200 	kfree(inst);
201 
202 	return ret;
203 }
204 
205 static void iris_session_close(struct iris_inst *inst)
206 {
207 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
208 	bool wait_for_response = true;
209 	int ret;
210 
211 	if (inst->state == IRIS_INST_DEINIT)
212 		return;
213 
214 	reinit_completion(&inst->completion);
215 
216 	ret = hfi_ops->session_close(inst);
217 	if (ret)
218 		wait_for_response = false;
219 
220 	if (wait_for_response)
221 		iris_wait_for_session_response(inst, false);
222 }
223 
224 static void iris_check_num_queued_internal_buffers(struct iris_inst *inst, u32 plane)
225 {
226 	const struct iris_platform_data *platform_data = inst->core->iris_platform_data;
227 	struct iris_buffer *buf, *next;
228 	struct iris_buffers *buffers;
229 	const u32 *internal_buf_type;
230 	u32 internal_buffer_count, i;
231 	u32 count = 0;
232 
233 	if (V4L2_TYPE_IS_OUTPUT(plane)) {
234 		internal_buf_type = platform_data->dec_ip_int_buf_tbl;
235 		internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
236 	} else {
237 		internal_buf_type = platform_data->dec_op_int_buf_tbl;
238 		internal_buffer_count = platform_data->dec_op_int_buf_tbl_size;
239 	}
240 
241 	for (i = 0; i < internal_buffer_count; i++) {
242 		buffers = &inst->buffers[internal_buf_type[i]];
243 		list_for_each_entry_safe(buf, next, &buffers->list, list)
244 			count++;
245 		if (count)
246 			dev_err(inst->core->dev, "%d buffer of type %d not released",
247 				count, internal_buf_type[i]);
248 	}
249 }
250 
251 int iris_close(struct file *filp)
252 {
253 	struct iris_inst *inst = iris_get_inst(filp, NULL);
254 
255 	v4l2_ctrl_handler_free(&inst->ctrl_handler);
256 	v4l2_m2m_ctx_release(inst->m2m_ctx);
257 	v4l2_m2m_release(inst->m2m_dev);
258 	mutex_lock(&inst->lock);
259 	iris_vdec_inst_deinit(inst);
260 	iris_session_close(inst);
261 	iris_inst_change_state(inst, IRIS_INST_DEINIT);
262 	iris_v4l2_fh_deinit(inst);
263 	iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
264 	iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
265 	iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
266 	iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
267 	iris_remove_session(inst);
268 	mutex_unlock(&inst->lock);
269 	mutex_destroy(&inst->ctx_q_lock);
270 	mutex_destroy(&inst->lock);
271 	kfree(inst);
272 	filp->private_data = NULL;
273 
274 	return 0;
275 }
276 
277 static int iris_enum_fmt(struct file *filp, void *fh, struct v4l2_fmtdesc *f)
278 {
279 	struct iris_inst *inst = iris_get_inst(filp, NULL);
280 
281 	return iris_vdec_enum_fmt(inst, f);
282 }
283 
284 static int iris_try_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f)
285 {
286 	struct iris_inst *inst = iris_get_inst(filp, NULL);
287 	int ret;
288 
289 	mutex_lock(&inst->lock);
290 	ret = iris_vdec_try_fmt(inst, f);
291 	mutex_unlock(&inst->lock);
292 
293 	return ret;
294 }
295 
296 static int iris_s_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f)
297 {
298 	struct iris_inst *inst = iris_get_inst(filp, NULL);
299 	int ret;
300 
301 	mutex_lock(&inst->lock);
302 	ret = iris_vdec_s_fmt(inst, f);
303 	mutex_unlock(&inst->lock);
304 
305 	return ret;
306 }
307 
308 static int iris_g_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f)
309 {
310 	struct iris_inst *inst = iris_get_inst(filp, NULL);
311 	int ret = 0;
312 
313 	mutex_lock(&inst->lock);
314 	if (V4L2_TYPE_IS_OUTPUT(f->type))
315 		*f = *inst->fmt_src;
316 	else if (V4L2_TYPE_IS_CAPTURE(f->type))
317 		*f = *inst->fmt_dst;
318 	else
319 		ret = -EINVAL;
320 
321 	mutex_unlock(&inst->lock);
322 
323 	return ret;
324 }
325 
326 static int iris_enum_framesizes(struct file *filp, void *fh,
327 				struct v4l2_frmsizeenum *fsize)
328 {
329 	struct iris_inst *inst = iris_get_inst(filp, NULL);
330 	struct platform_inst_caps *caps;
331 
332 	if (fsize->index)
333 		return -EINVAL;
334 
335 	if (fsize->pixel_format != V4L2_PIX_FMT_H264 &&
336 	    fsize->pixel_format != V4L2_PIX_FMT_NV12)
337 		return -EINVAL;
338 
339 	caps = inst->core->iris_platform_data->inst_caps;
340 
341 	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
342 	fsize->stepwise.min_width = caps->min_frame_width;
343 	fsize->stepwise.max_width = caps->max_frame_width;
344 	fsize->stepwise.step_width = STEP_WIDTH;
345 	fsize->stepwise.min_height = caps->min_frame_height;
346 	fsize->stepwise.max_height = caps->max_frame_height;
347 	fsize->stepwise.step_height = STEP_HEIGHT;
348 
349 	return 0;
350 }
351 
352 static int iris_querycap(struct file *filp, void *fh, struct v4l2_capability *cap)
353 {
354 	strscpy(cap->driver, IRIS_DRV_NAME, sizeof(cap->driver));
355 	strscpy(cap->card, "Iris Decoder", sizeof(cap->card));
356 
357 	return 0;
358 }
359 
360 static int iris_g_selection(struct file *filp, void *fh, struct v4l2_selection *s)
361 {
362 	struct iris_inst *inst = iris_get_inst(filp, NULL);
363 
364 	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
365 		return -EINVAL;
366 
367 	switch (s->target) {
368 	case V4L2_SEL_TGT_CROP_BOUNDS:
369 	case V4L2_SEL_TGT_CROP_DEFAULT:
370 	case V4L2_SEL_TGT_CROP:
371 	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
372 	case V4L2_SEL_TGT_COMPOSE_PADDED:
373 	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
374 	case V4L2_SEL_TGT_COMPOSE:
375 		s->r.left = inst->crop.left;
376 		s->r.top = inst->crop.top;
377 		s->r.width = inst->crop.width;
378 		s->r.height = inst->crop.height;
379 		break;
380 	default:
381 		return -EINVAL;
382 	}
383 
384 	return 0;
385 }
386 
387 static int iris_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
388 {
389 	struct iris_inst *inst = container_of(fh, struct iris_inst, fh);
390 
391 	return iris_vdec_subscribe_event(inst, sub);
392 }
393 
394 static int iris_dec_cmd(struct file *filp, void *fh,
395 			struct v4l2_decoder_cmd *dec)
396 {
397 	struct iris_inst *inst = iris_get_inst(filp, NULL);
398 	int ret = 0;
399 
400 	mutex_lock(&inst->lock);
401 
402 	ret = v4l2_m2m_ioctl_decoder_cmd(filp, fh, dec);
403 	if (ret)
404 		goto unlock;
405 
406 	if (inst->state == IRIS_INST_DEINIT)
407 		goto unlock;
408 
409 	if (!iris_allow_cmd(inst, dec->cmd)) {
410 		ret = -EBUSY;
411 		goto unlock;
412 	}
413 
414 	if (dec->cmd == V4L2_DEC_CMD_START)
415 		ret = iris_vdec_start_cmd(inst);
416 	else if (dec->cmd == V4L2_DEC_CMD_STOP)
417 		ret = iris_vdec_stop_cmd(inst);
418 	else
419 		ret = -EINVAL;
420 
421 unlock:
422 	mutex_unlock(&inst->lock);
423 
424 	return ret;
425 }
426 
427 static struct v4l2_file_operations iris_v4l2_file_ops = {
428 	.owner                          = THIS_MODULE,
429 	.open                           = iris_open,
430 	.release                        = iris_close,
431 	.unlocked_ioctl                 = video_ioctl2,
432 	.poll                           = v4l2_m2m_fop_poll,
433 	.mmap                           = v4l2_m2m_fop_mmap,
434 };
435 
436 static const struct vb2_ops iris_vb2_ops = {
437 	.buf_init                       = iris_vb2_buf_init,
438 	.queue_setup                    = iris_vb2_queue_setup,
439 	.start_streaming                = iris_vb2_start_streaming,
440 	.stop_streaming                 = iris_vb2_stop_streaming,
441 	.buf_prepare                    = iris_vb2_buf_prepare,
442 	.buf_out_validate               = iris_vb2_buf_out_validate,
443 	.buf_queue                      = iris_vb2_buf_queue,
444 };
445 
446 static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = {
447 	.vidioc_enum_fmt_vid_cap        = iris_enum_fmt,
448 	.vidioc_enum_fmt_vid_out        = iris_enum_fmt,
449 	.vidioc_try_fmt_vid_cap_mplane  = iris_try_fmt_vid_mplane,
450 	.vidioc_try_fmt_vid_out_mplane  = iris_try_fmt_vid_mplane,
451 	.vidioc_s_fmt_vid_cap_mplane    = iris_s_fmt_vid_mplane,
452 	.vidioc_s_fmt_vid_out_mplane    = iris_s_fmt_vid_mplane,
453 	.vidioc_g_fmt_vid_cap_mplane    = iris_g_fmt_vid_mplane,
454 	.vidioc_g_fmt_vid_out_mplane    = iris_g_fmt_vid_mplane,
455 	.vidioc_enum_framesizes         = iris_enum_framesizes,
456 	.vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
457 	.vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
458 	.vidioc_create_bufs             = v4l2_m2m_ioctl_create_bufs,
459 	.vidioc_prepare_buf             = v4l2_m2m_ioctl_prepare_buf,
460 	.vidioc_expbuf                  = v4l2_m2m_ioctl_expbuf,
461 	.vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
462 	.vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
463 	.vidioc_remove_bufs             = v4l2_m2m_ioctl_remove_bufs,
464 	.vidioc_querycap                = iris_querycap,
465 	.vidioc_g_selection             = iris_g_selection,
466 	.vidioc_subscribe_event         = iris_subscribe_event,
467 	.vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
468 	.vidioc_streamon                = v4l2_m2m_ioctl_streamon,
469 	.vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
470 	.vidioc_try_decoder_cmd         = v4l2_m2m_ioctl_try_decoder_cmd,
471 	.vidioc_decoder_cmd             = iris_dec_cmd,
472 };
473 
474 void iris_init_ops(struct iris_core *core)
475 {
476 	core->iris_v4l2_file_ops = &iris_v4l2_file_ops;
477 	core->iris_vb2_ops = &iris_vb2_ops;
478 	core->iris_v4l2_ioctl_ops = &iris_v4l2_ioctl_ops;
479 }
480