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
iris_v4l2_fh_init(struct iris_inst * inst)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
iris_v4l2_fh_deinit(struct iris_inst * inst)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
iris_add_session(struct iris_inst * inst)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
iris_remove_session(struct iris_inst * inst)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
iris_get_inst(struct file * filp,void * fh)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
iris_m2m_device_run(void * priv)75 static void iris_m2m_device_run(void *priv)
76 {
77 }
78
iris_m2m_job_abort(void * priv)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
iris_m2m_queue_init(void * priv,struct vb2_queue * src_vq,struct vb2_queue * dst_vq)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
iris_open(struct file * filp)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
iris_session_close(struct iris_inst * inst)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
iris_check_num_queued_internal_buffers(struct iris_inst * inst,u32 plane)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
iris_close(struct file * filp)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
iris_enum_fmt(struct file * filp,void * fh,struct v4l2_fmtdesc * f)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
iris_try_fmt_vid_mplane(struct file * filp,void * fh,struct v4l2_format * f)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
iris_s_fmt_vid_mplane(struct file * filp,void * fh,struct v4l2_format * f)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
iris_g_fmt_vid_mplane(struct file * filp,void * fh,struct v4l2_format * f)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
iris_enum_framesizes(struct file * filp,void * fh,struct v4l2_frmsizeenum * fsize)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
iris_querycap(struct file * filp,void * fh,struct v4l2_capability * cap)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
iris_g_selection(struct file * filp,void * fh,struct v4l2_selection * s)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
iris_subscribe_event(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)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
iris_dec_cmd(struct file * filp,void * fh,struct v4l2_decoder_cmd * dec)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
iris_init_ops(struct iris_core * core)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