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_close(struct file * filp)224 int iris_close(struct file *filp)
225 {
226 	struct iris_inst *inst = iris_get_inst(filp, NULL);
227 
228 	v4l2_ctrl_handler_free(&inst->ctrl_handler);
229 	v4l2_m2m_ctx_release(inst->m2m_ctx);
230 	v4l2_m2m_release(inst->m2m_dev);
231 	mutex_lock(&inst->lock);
232 	iris_vdec_inst_deinit(inst);
233 	iris_session_close(inst);
234 	iris_inst_change_state(inst, IRIS_INST_DEINIT);
235 	iris_v4l2_fh_deinit(inst);
236 	iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
237 	iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
238 	iris_remove_session(inst);
239 	mutex_unlock(&inst->lock);
240 	mutex_destroy(&inst->ctx_q_lock);
241 	mutex_destroy(&inst->lock);
242 	kfree(inst);
243 	filp->private_data = NULL;
244 
245 	return 0;
246 }
247 
iris_enum_fmt(struct file * filp,void * fh,struct v4l2_fmtdesc * f)248 static int iris_enum_fmt(struct file *filp, void *fh, struct v4l2_fmtdesc *f)
249 {
250 	struct iris_inst *inst = iris_get_inst(filp, NULL);
251 
252 	if (f->index)
253 		return -EINVAL;
254 
255 	return iris_vdec_enum_fmt(inst, f);
256 }
257 
iris_try_fmt_vid_mplane(struct file * filp,void * fh,struct v4l2_format * f)258 static int iris_try_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f)
259 {
260 	struct iris_inst *inst = iris_get_inst(filp, NULL);
261 	int ret;
262 
263 	mutex_lock(&inst->lock);
264 	ret = iris_vdec_try_fmt(inst, f);
265 	mutex_unlock(&inst->lock);
266 
267 	return ret;
268 }
269 
iris_s_fmt_vid_mplane(struct file * filp,void * fh,struct v4l2_format * f)270 static int iris_s_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f)
271 {
272 	struct iris_inst *inst = iris_get_inst(filp, NULL);
273 	int ret;
274 
275 	mutex_lock(&inst->lock);
276 	ret = iris_vdec_s_fmt(inst, f);
277 	mutex_unlock(&inst->lock);
278 
279 	return ret;
280 }
281 
iris_g_fmt_vid_mplane(struct file * filp,void * fh,struct v4l2_format * f)282 static int iris_g_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f)
283 {
284 	struct iris_inst *inst = iris_get_inst(filp, NULL);
285 	int ret = 0;
286 
287 	mutex_lock(&inst->lock);
288 	if (V4L2_TYPE_IS_OUTPUT(f->type))
289 		*f = *inst->fmt_src;
290 	else if (V4L2_TYPE_IS_CAPTURE(f->type))
291 		*f = *inst->fmt_dst;
292 	else
293 		ret = -EINVAL;
294 
295 	mutex_unlock(&inst->lock);
296 
297 	return ret;
298 }
299 
iris_enum_framesizes(struct file * filp,void * fh,struct v4l2_frmsizeenum * fsize)300 static int iris_enum_framesizes(struct file *filp, void *fh,
301 				struct v4l2_frmsizeenum *fsize)
302 {
303 	struct iris_inst *inst = iris_get_inst(filp, NULL);
304 	struct platform_inst_caps *caps;
305 
306 	if (fsize->index)
307 		return -EINVAL;
308 
309 	if (fsize->pixel_format != V4L2_PIX_FMT_H264 &&
310 	    fsize->pixel_format != V4L2_PIX_FMT_NV12)
311 		return -EINVAL;
312 
313 	caps = inst->core->iris_platform_data->inst_caps;
314 
315 	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
316 	fsize->stepwise.min_width = caps->min_frame_width;
317 	fsize->stepwise.max_width = caps->max_frame_width;
318 	fsize->stepwise.step_width = STEP_WIDTH;
319 	fsize->stepwise.min_height = caps->min_frame_height;
320 	fsize->stepwise.max_height = caps->max_frame_height;
321 	fsize->stepwise.step_height = STEP_HEIGHT;
322 
323 	return 0;
324 }
325 
iris_querycap(struct file * filp,void * fh,struct v4l2_capability * cap)326 static int iris_querycap(struct file *filp, void *fh, struct v4l2_capability *cap)
327 {
328 	strscpy(cap->driver, IRIS_DRV_NAME, sizeof(cap->driver));
329 	strscpy(cap->card, "Iris Decoder", sizeof(cap->card));
330 
331 	return 0;
332 }
333 
iris_g_selection(struct file * filp,void * fh,struct v4l2_selection * s)334 static int iris_g_selection(struct file *filp, void *fh, struct v4l2_selection *s)
335 {
336 	struct iris_inst *inst = iris_get_inst(filp, NULL);
337 
338 	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
339 		return -EINVAL;
340 
341 	switch (s->target) {
342 	case V4L2_SEL_TGT_CROP_BOUNDS:
343 	case V4L2_SEL_TGT_CROP_DEFAULT:
344 	case V4L2_SEL_TGT_CROP:
345 	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
346 	case V4L2_SEL_TGT_COMPOSE_PADDED:
347 	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
348 	case V4L2_SEL_TGT_COMPOSE:
349 		s->r.left = inst->crop.left;
350 		s->r.top = inst->crop.top;
351 		s->r.width = inst->crop.width;
352 		s->r.height = inst->crop.height;
353 		break;
354 	default:
355 		return -EINVAL;
356 	}
357 
358 	return 0;
359 }
360 
iris_subscribe_event(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)361 static int iris_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
362 {
363 	struct iris_inst *inst = container_of(fh, struct iris_inst, fh);
364 
365 	return iris_vdec_subscribe_event(inst, sub);
366 }
367 
iris_dec_cmd(struct file * filp,void * fh,struct v4l2_decoder_cmd * dec)368 static int iris_dec_cmd(struct file *filp, void *fh,
369 			struct v4l2_decoder_cmd *dec)
370 {
371 	struct iris_inst *inst = iris_get_inst(filp, NULL);
372 	int ret = 0;
373 
374 	mutex_lock(&inst->lock);
375 
376 	ret = v4l2_m2m_ioctl_decoder_cmd(filp, fh, dec);
377 	if (ret)
378 		goto unlock;
379 
380 	if (inst->state == IRIS_INST_DEINIT)
381 		goto unlock;
382 
383 	if (!iris_allow_cmd(inst, dec->cmd)) {
384 		ret = -EBUSY;
385 		goto unlock;
386 	}
387 
388 	if (dec->cmd == V4L2_DEC_CMD_START)
389 		ret = iris_vdec_start_cmd(inst);
390 	else if (dec->cmd == V4L2_DEC_CMD_STOP)
391 		ret = iris_vdec_stop_cmd(inst);
392 	else
393 		ret = -EINVAL;
394 
395 unlock:
396 	mutex_unlock(&inst->lock);
397 
398 	return ret;
399 }
400 
401 static struct v4l2_file_operations iris_v4l2_file_ops = {
402 	.owner                          = THIS_MODULE,
403 	.open                           = iris_open,
404 	.release                        = iris_close,
405 	.unlocked_ioctl                 = video_ioctl2,
406 	.poll                           = v4l2_m2m_fop_poll,
407 	.mmap                           = v4l2_m2m_fop_mmap,
408 };
409 
410 static const struct vb2_ops iris_vb2_ops = {
411 	.buf_init                       = iris_vb2_buf_init,
412 	.queue_setup                    = iris_vb2_queue_setup,
413 	.start_streaming                = iris_vb2_start_streaming,
414 	.stop_streaming                 = iris_vb2_stop_streaming,
415 	.buf_prepare                    = iris_vb2_buf_prepare,
416 	.buf_out_validate               = iris_vb2_buf_out_validate,
417 	.buf_queue                      = iris_vb2_buf_queue,
418 };
419 
420 static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = {
421 	.vidioc_enum_fmt_vid_cap        = iris_enum_fmt,
422 	.vidioc_enum_fmt_vid_out        = iris_enum_fmt,
423 	.vidioc_try_fmt_vid_cap_mplane  = iris_try_fmt_vid_mplane,
424 	.vidioc_try_fmt_vid_out_mplane  = iris_try_fmt_vid_mplane,
425 	.vidioc_s_fmt_vid_cap_mplane    = iris_s_fmt_vid_mplane,
426 	.vidioc_s_fmt_vid_out_mplane    = iris_s_fmt_vid_mplane,
427 	.vidioc_g_fmt_vid_cap_mplane    = iris_g_fmt_vid_mplane,
428 	.vidioc_g_fmt_vid_out_mplane    = iris_g_fmt_vid_mplane,
429 	.vidioc_enum_framesizes         = iris_enum_framesizes,
430 	.vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
431 	.vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
432 	.vidioc_create_bufs             = v4l2_m2m_ioctl_create_bufs,
433 	.vidioc_prepare_buf             = v4l2_m2m_ioctl_prepare_buf,
434 	.vidioc_expbuf                  = v4l2_m2m_ioctl_expbuf,
435 	.vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
436 	.vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
437 	.vidioc_remove_bufs             = v4l2_m2m_ioctl_remove_bufs,
438 	.vidioc_querycap                = iris_querycap,
439 	.vidioc_g_selection             = iris_g_selection,
440 	.vidioc_subscribe_event         = iris_subscribe_event,
441 	.vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
442 	.vidioc_streamon                = v4l2_m2m_ioctl_streamon,
443 	.vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
444 	.vidioc_try_decoder_cmd         = v4l2_m2m_ioctl_try_decoder_cmd,
445 	.vidioc_decoder_cmd             = iris_dec_cmd,
446 };
447 
iris_init_ops(struct iris_core * core)448 void iris_init_ops(struct iris_core *core)
449 {
450 	core->iris_v4l2_file_ops = &iris_v4l2_file_ops;
451 	core->iris_vb2_ops = &iris_vb2_ops;
452 	core->iris_v4l2_ioctl_ops = &iris_v4l2_ioctl_ops;
453 }
454