1 /*
2  * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
3  * Copyright (C) 2017 Linaro Ltd.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 and
7  * only version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15 #include <linux/clk.h>
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/slab.h>
20 #include <media/v4l2-ioctl.h>
21 #include <media/v4l2-event.h>
22 #include <media/v4l2-ctrls.h>
23 #include <media/v4l2-mem2mem.h>
24 #include <media/videobuf2-dma-sg.h>
25 
26 #include "hfi_venus_io.h"
27 #include "core.h"
28 #include "helpers.h"
29 #include "vdec.h"
30 
31 static u32 get_framesize_uncompressed(unsigned int plane, u32 width, u32 height)
32 {
33 	u32 y_stride, uv_stride, y_plane;
34 	u32 y_sclines, uv_sclines, uv_plane;
35 	u32 size;
36 
37 	y_stride = ALIGN(width, 128);
38 	uv_stride = ALIGN(width, 128);
39 	y_sclines = ALIGN(height, 32);
40 	uv_sclines = ALIGN(((height + 1) >> 1), 16);
41 
42 	y_plane = y_stride * y_sclines;
43 	uv_plane = uv_stride * uv_sclines + SZ_4K;
44 	size = y_plane + uv_plane + SZ_8K;
45 
46 	return ALIGN(size, SZ_4K);
47 }
48 
49 static u32 get_framesize_compressed(unsigned int width, unsigned int height)
50 {
51 	return ((width * height * 3 / 2) / 2) + 128;
52 }
53 
54 /*
55  * Three resons to keep MPLANE formats (despite that the number of planes
56  * currently is one):
57  * - the MPLANE formats allow only one plane to be used
58  * - the downstream driver use MPLANE formats too
59  * - future firmware versions could add support for >1 planes
60  */
61 static const struct venus_format vdec_formats[] = {
62 	{
63 		.pixfmt = V4L2_PIX_FMT_NV12,
64 		.num_planes = 1,
65 		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
66 	}, {
67 		.pixfmt = V4L2_PIX_FMT_MPEG4,
68 		.num_planes = 1,
69 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
70 	}, {
71 		.pixfmt = V4L2_PIX_FMT_MPEG2,
72 		.num_planes = 1,
73 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
74 	}, {
75 		.pixfmt = V4L2_PIX_FMT_H263,
76 		.num_planes = 1,
77 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
78 	}, {
79 		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G,
80 		.num_planes = 1,
81 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
82 	}, {
83 		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
84 		.num_planes = 1,
85 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
86 	}, {
87 		.pixfmt = V4L2_PIX_FMT_H264,
88 		.num_planes = 1,
89 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
90 	}, {
91 		.pixfmt = V4L2_PIX_FMT_VP8,
92 		.num_planes = 1,
93 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
94 	}, {
95 		.pixfmt = V4L2_PIX_FMT_VP9,
96 		.num_planes = 1,
97 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
98 	}, {
99 		.pixfmt = V4L2_PIX_FMT_XVID,
100 		.num_planes = 1,
101 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
102 	},
103 };
104 
105 static const struct venus_format *
106 find_format(struct venus_inst *inst, u32 pixfmt, u32 type)
107 {
108 	const struct venus_format *fmt = vdec_formats;
109 	unsigned int size = ARRAY_SIZE(vdec_formats);
110 	unsigned int i;
111 
112 	for (i = 0; i < size; i++) {
113 		if (fmt[i].pixfmt == pixfmt)
114 			break;
115 	}
116 
117 	if (i == size || fmt[i].type != type)
118 		return NULL;
119 
120 	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
121 	    !venus_helper_check_codec(inst, fmt[i].pixfmt))
122 		return NULL;
123 
124 	return &fmt[i];
125 }
126 
127 static const struct venus_format *
128 find_format_by_index(struct venus_inst *inst, unsigned int index, u32 type)
129 {
130 	const struct venus_format *fmt = vdec_formats;
131 	unsigned int size = ARRAY_SIZE(vdec_formats);
132 	unsigned int i, k = 0;
133 
134 	if (index > size)
135 		return NULL;
136 
137 	for (i = 0; i < size; i++) {
138 		bool valid;
139 
140 		if (fmt[i].type != type)
141 			continue;
142 		valid = type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
143 			venus_helper_check_codec(inst, fmt[i].pixfmt);
144 		if (k == index && valid)
145 			break;
146 		if (valid)
147 			k++;
148 	}
149 
150 	if (i == size)
151 		return NULL;
152 
153 	return &fmt[i];
154 }
155 
156 static const struct venus_format *
157 vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)
158 {
159 	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
160 	struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt;
161 	const struct venus_format *fmt;
162 	unsigned int p;
163 
164 	memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved));
165 	memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
166 
167 	fmt = find_format(inst, pixmp->pixelformat, f->type);
168 	if (!fmt) {
169 		if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
170 			pixmp->pixelformat = V4L2_PIX_FMT_NV12;
171 		else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
172 			pixmp->pixelformat = V4L2_PIX_FMT_H264;
173 		else
174 			return NULL;
175 		fmt = find_format(inst, pixmp->pixelformat, f->type);
176 		pixmp->width = 1280;
177 		pixmp->height = 720;
178 	}
179 
180 	pixmp->width = clamp(pixmp->width, inst->cap_width.min,
181 			     inst->cap_width.max);
182 	pixmp->height = clamp(pixmp->height, inst->cap_height.min,
183 			      inst->cap_height.max);
184 
185 	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
186 		pixmp->height = ALIGN(pixmp->height, 32);
187 
188 	if (pixmp->field == V4L2_FIELD_ANY)
189 		pixmp->field = V4L2_FIELD_NONE;
190 	pixmp->num_planes = fmt->num_planes;
191 	pixmp->flags = 0;
192 
193 	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
194 		for (p = 0; p < pixmp->num_planes; p++) {
195 			pfmt[p].sizeimage =
196 				get_framesize_uncompressed(p, pixmp->width,
197 							   pixmp->height);
198 			pfmt[p].bytesperline = ALIGN(pixmp->width, 128);
199 		}
200 	} else {
201 		pfmt[0].sizeimage = get_framesize_compressed(pixmp->width,
202 							     pixmp->height);
203 		pfmt[0].bytesperline = 0;
204 	}
205 
206 	return fmt;
207 }
208 
209 static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
210 {
211 	struct venus_inst *inst = to_inst(file);
212 
213 	vdec_try_fmt_common(inst, f);
214 
215 	return 0;
216 }
217 
218 static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
219 {
220 	struct venus_inst *inst = to_inst(file);
221 	const struct venus_format *fmt = NULL;
222 	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
223 
224 	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
225 		fmt = inst->fmt_cap;
226 	else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
227 		fmt = inst->fmt_out;
228 
229 	if (inst->reconfig) {
230 		struct v4l2_format format = {};
231 
232 		inst->out_width = inst->reconfig_width;
233 		inst->out_height = inst->reconfig_height;
234 		inst->reconfig = false;
235 
236 		format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
237 		format.fmt.pix_mp.pixelformat = inst->fmt_cap->pixfmt;
238 		format.fmt.pix_mp.width = inst->out_width;
239 		format.fmt.pix_mp.height = inst->out_height;
240 
241 		vdec_try_fmt_common(inst, &format);
242 
243 		inst->width = format.fmt.pix_mp.width;
244 		inst->height = format.fmt.pix_mp.height;
245 	}
246 
247 	pixmp->pixelformat = fmt->pixfmt;
248 
249 	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
250 		pixmp->width = inst->width;
251 		pixmp->height = inst->height;
252 		pixmp->colorspace = inst->colorspace;
253 		pixmp->ycbcr_enc = inst->ycbcr_enc;
254 		pixmp->quantization = inst->quantization;
255 		pixmp->xfer_func = inst->xfer_func;
256 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
257 		pixmp->width = inst->out_width;
258 		pixmp->height = inst->out_height;
259 	}
260 
261 	vdec_try_fmt_common(inst, f);
262 
263 	return 0;
264 }
265 
266 static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
267 {
268 	struct venus_inst *inst = to_inst(file);
269 	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
270 	struct v4l2_pix_format_mplane orig_pixmp;
271 	const struct venus_format *fmt;
272 	struct v4l2_format format;
273 	u32 pixfmt_out = 0, pixfmt_cap = 0;
274 
275 	orig_pixmp = *pixmp;
276 
277 	fmt = vdec_try_fmt_common(inst, f);
278 
279 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
280 		pixfmt_out = pixmp->pixelformat;
281 		pixfmt_cap = inst->fmt_cap->pixfmt;
282 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
283 		pixfmt_cap = pixmp->pixelformat;
284 		pixfmt_out = inst->fmt_out->pixfmt;
285 	}
286 
287 	memset(&format, 0, sizeof(format));
288 
289 	format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
290 	format.fmt.pix_mp.pixelformat = pixfmt_out;
291 	format.fmt.pix_mp.width = orig_pixmp.width;
292 	format.fmt.pix_mp.height = orig_pixmp.height;
293 	vdec_try_fmt_common(inst, &format);
294 
295 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
296 		inst->out_width = format.fmt.pix_mp.width;
297 		inst->out_height = format.fmt.pix_mp.height;
298 		inst->colorspace = pixmp->colorspace;
299 		inst->ycbcr_enc = pixmp->ycbcr_enc;
300 		inst->quantization = pixmp->quantization;
301 		inst->xfer_func = pixmp->xfer_func;
302 	}
303 
304 	memset(&format, 0, sizeof(format));
305 
306 	format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
307 	format.fmt.pix_mp.pixelformat = pixfmt_cap;
308 	format.fmt.pix_mp.width = orig_pixmp.width;
309 	format.fmt.pix_mp.height = orig_pixmp.height;
310 	vdec_try_fmt_common(inst, &format);
311 
312 	inst->width = format.fmt.pix_mp.width;
313 	inst->height = format.fmt.pix_mp.height;
314 
315 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
316 		inst->fmt_out = fmt;
317 	else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
318 		inst->fmt_cap = fmt;
319 
320 	return 0;
321 }
322 
323 static int
324 vdec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
325 {
326 	struct venus_inst *inst = to_inst(file);
327 
328 	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
329 	    s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
330 		return -EINVAL;
331 
332 	switch (s->target) {
333 	case V4L2_SEL_TGT_CROP_BOUNDS:
334 	case V4L2_SEL_TGT_CROP_DEFAULT:
335 	case V4L2_SEL_TGT_CROP:
336 		if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
337 			return -EINVAL;
338 		s->r.width = inst->out_width;
339 		s->r.height = inst->out_height;
340 		break;
341 	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
342 	case V4L2_SEL_TGT_COMPOSE_PADDED:
343 		if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
344 			return -EINVAL;
345 		s->r.width = inst->width;
346 		s->r.height = inst->height;
347 		break;
348 	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
349 	case V4L2_SEL_TGT_COMPOSE:
350 		if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
351 			return -EINVAL;
352 		s->r.width = inst->out_width;
353 		s->r.height = inst->out_height;
354 		break;
355 	default:
356 		return -EINVAL;
357 	}
358 
359 	s->r.top = 0;
360 	s->r.left = 0;
361 
362 	return 0;
363 }
364 
365 static int
366 vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
367 {
368 	strlcpy(cap->driver, "qcom-venus", sizeof(cap->driver));
369 	strlcpy(cap->card, "Qualcomm Venus video decoder", sizeof(cap->card));
370 	strlcpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info));
371 
372 	return 0;
373 }
374 
375 static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
376 {
377 	struct venus_inst *inst = to_inst(file);
378 	const struct venus_format *fmt;
379 
380 	memset(f->reserved, 0, sizeof(f->reserved));
381 
382 	fmt = find_format_by_index(inst, f->index, f->type);
383 	if (!fmt)
384 		return -EINVAL;
385 
386 	f->pixelformat = fmt->pixfmt;
387 
388 	return 0;
389 }
390 
391 static int vdec_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
392 {
393 	struct venus_inst *inst = to_inst(file);
394 	struct v4l2_captureparm *cap = &a->parm.capture;
395 	struct v4l2_fract *timeperframe = &cap->timeperframe;
396 	u64 us_per_frame, fps;
397 
398 	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
399 	    a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
400 		return -EINVAL;
401 
402 	memset(cap->reserved, 0, sizeof(cap->reserved));
403 	if (!timeperframe->denominator)
404 		timeperframe->denominator = inst->timeperframe.denominator;
405 	if (!timeperframe->numerator)
406 		timeperframe->numerator = inst->timeperframe.numerator;
407 	cap->readbuffers = 0;
408 	cap->extendedmode = 0;
409 	cap->capability = V4L2_CAP_TIMEPERFRAME;
410 	us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC;
411 	do_div(us_per_frame, timeperframe->denominator);
412 
413 	if (!us_per_frame)
414 		return -EINVAL;
415 
416 	fps = (u64)USEC_PER_SEC;
417 	do_div(fps, us_per_frame);
418 
419 	inst->fps = fps;
420 	inst->timeperframe = *timeperframe;
421 
422 	return 0;
423 }
424 
425 static int vdec_enum_framesizes(struct file *file, void *fh,
426 				struct v4l2_frmsizeenum *fsize)
427 {
428 	struct venus_inst *inst = to_inst(file);
429 	const struct venus_format *fmt;
430 
431 	fmt = find_format(inst, fsize->pixel_format,
432 			  V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
433 	if (!fmt) {
434 		fmt = find_format(inst, fsize->pixel_format,
435 				  V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
436 		if (!fmt)
437 			return -EINVAL;
438 	}
439 
440 	if (fsize->index)
441 		return -EINVAL;
442 
443 	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
444 
445 	fsize->stepwise.min_width = inst->cap_width.min;
446 	fsize->stepwise.max_width = inst->cap_width.max;
447 	fsize->stepwise.step_width = inst->cap_width.step_size;
448 	fsize->stepwise.min_height = inst->cap_height.min;
449 	fsize->stepwise.max_height = inst->cap_height.max;
450 	fsize->stepwise.step_height = inst->cap_height.step_size;
451 
452 	return 0;
453 }
454 
455 static int vdec_subscribe_event(struct v4l2_fh *fh,
456 				const struct v4l2_event_subscription *sub)
457 {
458 	switch (sub->type) {
459 	case V4L2_EVENT_EOS:
460 		return v4l2_event_subscribe(fh, sub, 2, NULL);
461 	case V4L2_EVENT_SOURCE_CHANGE:
462 		return v4l2_src_change_event_subscribe(fh, sub);
463 	case V4L2_EVENT_CTRL:
464 		return v4l2_ctrl_subscribe_event(fh, sub);
465 	default:
466 		return -EINVAL;
467 	}
468 }
469 
470 static int
471 vdec_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
472 {
473 	switch (cmd->cmd) {
474 	case V4L2_DEC_CMD_STOP:
475 		if (cmd->flags & V4L2_DEC_CMD_STOP_TO_BLACK)
476 			return -EINVAL;
477 		break;
478 	default:
479 		return -EINVAL;
480 	}
481 
482 	return 0;
483 }
484 
485 static int
486 vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
487 {
488 	struct venus_inst *inst = to_inst(file);
489 	struct hfi_frame_data fdata = {0};
490 	int ret;
491 
492 	ret = vdec_try_decoder_cmd(file, fh, cmd);
493 	if (ret)
494 		return ret;
495 
496 	mutex_lock(&inst->lock);
497 
498 	/*
499 	 * Implement V4L2_DEC_CMD_STOP by enqueue an empty buffer on decoder
500 	 * input to signal EOS.
501 	 */
502 	if (!(inst->streamon_out & inst->streamon_cap))
503 		goto unlock;
504 
505 	fdata.buffer_type = HFI_BUFFER_INPUT;
506 	fdata.flags |= HFI_BUFFERFLAG_EOS;
507 	fdata.device_addr = 0xdeadbeef;
508 
509 	ret = hfi_session_process_buf(inst, &fdata);
510 
511 unlock:
512 	mutex_unlock(&inst->lock);
513 	return ret;
514 }
515 
516 static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
517 	.vidioc_querycap = vdec_querycap,
518 	.vidioc_enum_fmt_vid_cap_mplane = vdec_enum_fmt,
519 	.vidioc_enum_fmt_vid_out_mplane = vdec_enum_fmt,
520 	.vidioc_s_fmt_vid_cap_mplane = vdec_s_fmt,
521 	.vidioc_s_fmt_vid_out_mplane = vdec_s_fmt,
522 	.vidioc_g_fmt_vid_cap_mplane = vdec_g_fmt,
523 	.vidioc_g_fmt_vid_out_mplane = vdec_g_fmt,
524 	.vidioc_try_fmt_vid_cap_mplane = vdec_try_fmt,
525 	.vidioc_try_fmt_vid_out_mplane = vdec_try_fmt,
526 	.vidioc_g_selection = vdec_g_selection,
527 	.vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
528 	.vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
529 	.vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
530 	.vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
531 	.vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
532 	.vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
533 	.vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
534 	.vidioc_streamon = v4l2_m2m_ioctl_streamon,
535 	.vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
536 	.vidioc_s_parm = vdec_s_parm,
537 	.vidioc_enum_framesizes = vdec_enum_framesizes,
538 	.vidioc_subscribe_event = vdec_subscribe_event,
539 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
540 	.vidioc_try_decoder_cmd = vdec_try_decoder_cmd,
541 	.vidioc_decoder_cmd = vdec_decoder_cmd,
542 };
543 
544 static int vdec_set_properties(struct venus_inst *inst)
545 {
546 	struct vdec_controls *ctr = &inst->controls.dec;
547 	struct venus_core *core = inst->core;
548 	struct hfi_enable en = { .enable = 1 };
549 	u32 ptype;
550 	int ret;
551 
552 	if (core->res->hfi_version == HFI_VERSION_1XX) {
553 		ptype = HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
554 		ret = hfi_session_set_property(inst, ptype, &en);
555 		if (ret)
556 			return ret;
557 	}
558 
559 	if (core->res->hfi_version == HFI_VERSION_3XX ||
560 	    inst->cap_bufs_mode_dynamic) {
561 		struct hfi_buffer_alloc_mode mode;
562 
563 		ptype = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE;
564 		mode.type = HFI_BUFFER_OUTPUT;
565 		mode.mode = HFI_BUFFER_MODE_DYNAMIC;
566 
567 		ret = hfi_session_set_property(inst, ptype, &mode);
568 		if (ret)
569 			return ret;
570 	}
571 
572 	if (ctr->post_loop_deb_mode) {
573 		ptype = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
574 		en.enable = 1;
575 		ret = hfi_session_set_property(inst, ptype, &en);
576 		if (ret)
577 			return ret;
578 	}
579 
580 	return 0;
581 }
582 
583 static int vdec_init_session(struct venus_inst *inst)
584 {
585 	int ret;
586 
587 	ret = hfi_session_init(inst, inst->fmt_out->pixfmt);
588 	if (ret)
589 		return ret;
590 
591 	ret = venus_helper_set_input_resolution(inst, inst->out_width,
592 						inst->out_height);
593 	if (ret)
594 		goto deinit;
595 
596 	ret = venus_helper_set_color_format(inst, inst->fmt_cap->pixfmt);
597 	if (ret)
598 		goto deinit;
599 
600 	return 0;
601 deinit:
602 	hfi_session_deinit(inst);
603 	return ret;
604 }
605 
606 static int vdec_cap_num_buffers(struct venus_inst *inst, unsigned int *num)
607 {
608 	struct hfi_buffer_requirements bufreq;
609 	int ret;
610 
611 	ret = vdec_init_session(inst);
612 	if (ret)
613 		return ret;
614 
615 	ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);
616 
617 	*num = bufreq.count_actual;
618 
619 	hfi_session_deinit(inst);
620 
621 	return ret;
622 }
623 
624 static int vdec_queue_setup(struct vb2_queue *q,
625 			    unsigned int *num_buffers, unsigned int *num_planes,
626 			    unsigned int sizes[], struct device *alloc_devs[])
627 {
628 	struct venus_inst *inst = vb2_get_drv_priv(q);
629 	unsigned int p, num;
630 	int ret = 0;
631 
632 	if (*num_planes) {
633 		if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
634 		    *num_planes != inst->fmt_out->num_planes)
635 			return -EINVAL;
636 
637 		if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
638 		    *num_planes != inst->fmt_cap->num_planes)
639 			return -EINVAL;
640 
641 		if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
642 		    sizes[0] < inst->input_buf_size)
643 			return -EINVAL;
644 
645 		if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
646 		    sizes[0] < inst->output_buf_size)
647 			return -EINVAL;
648 
649 		return 0;
650 	}
651 
652 	switch (q->type) {
653 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
654 		*num_planes = inst->fmt_out->num_planes;
655 		sizes[0] = get_framesize_compressed(inst->out_width,
656 						    inst->out_height);
657 		inst->input_buf_size = sizes[0];
658 		inst->num_input_bufs = *num_buffers;
659 
660 		ret = vdec_cap_num_buffers(inst, &num);
661 		if (ret)
662 			break;
663 
664 		inst->num_output_bufs = num;
665 		break;
666 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
667 		*num_planes = inst->fmt_cap->num_planes;
668 
669 		ret = vdec_cap_num_buffers(inst, &num);
670 		if (ret)
671 			break;
672 
673 		*num_buffers = max(*num_buffers, num);
674 
675 		for (p = 0; p < *num_planes; p++)
676 			sizes[p] = get_framesize_uncompressed(p, inst->width,
677 							      inst->height);
678 
679 		inst->num_output_bufs = *num_buffers;
680 		inst->output_buf_size = sizes[0];
681 		break;
682 	default:
683 		ret = -EINVAL;
684 		break;
685 	}
686 
687 	return ret;
688 }
689 
690 static int vdec_verify_conf(struct venus_inst *inst)
691 {
692 	struct hfi_buffer_requirements bufreq;
693 	int ret;
694 
695 	if (!inst->num_input_bufs || !inst->num_output_bufs)
696 		return -EINVAL;
697 
698 	ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);
699 	if (ret)
700 		return ret;
701 
702 	if (inst->num_output_bufs < bufreq.count_actual ||
703 	    inst->num_output_bufs < bufreq.count_min)
704 		return -EINVAL;
705 
706 	ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq);
707 	if (ret)
708 		return ret;
709 
710 	if (inst->num_input_bufs < bufreq.count_min)
711 		return -EINVAL;
712 
713 	return 0;
714 }
715 
716 static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
717 {
718 	struct venus_inst *inst = vb2_get_drv_priv(q);
719 	struct venus_core *core = inst->core;
720 	u32 ptype;
721 	int ret;
722 
723 	mutex_lock(&inst->lock);
724 
725 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
726 		inst->streamon_out = 1;
727 	else
728 		inst->streamon_cap = 1;
729 
730 	if (!(inst->streamon_out & inst->streamon_cap)) {
731 		mutex_unlock(&inst->lock);
732 		return 0;
733 	}
734 
735 	venus_helper_init_instance(inst);
736 
737 	inst->reconfig = false;
738 	inst->sequence_cap = 0;
739 	inst->sequence_out = 0;
740 
741 	ret = vdec_init_session(inst);
742 	if (ret)
743 		goto bufs_done;
744 
745 	ret = vdec_set_properties(inst);
746 	if (ret)
747 		goto deinit_sess;
748 
749 	if (core->res->hfi_version == HFI_VERSION_3XX) {
750 		struct hfi_buffer_size_actual buf_sz;
751 
752 		ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
753 		buf_sz.type = HFI_BUFFER_OUTPUT;
754 		buf_sz.size = inst->output_buf_size;
755 
756 		ret = hfi_session_set_property(inst, ptype, &buf_sz);
757 		if (ret)
758 			goto deinit_sess;
759 	}
760 
761 	ret = vdec_verify_conf(inst);
762 	if (ret)
763 		goto deinit_sess;
764 
765 	ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
766 					VB2_MAX_FRAME);
767 	if (ret)
768 		goto deinit_sess;
769 
770 	ret = venus_helper_vb2_start_streaming(inst);
771 	if (ret)
772 		goto deinit_sess;
773 
774 	mutex_unlock(&inst->lock);
775 
776 	return 0;
777 
778 deinit_sess:
779 	hfi_session_deinit(inst);
780 bufs_done:
781 	venus_helper_buffers_done(inst, VB2_BUF_STATE_QUEUED);
782 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
783 		inst->streamon_out = 0;
784 	else
785 		inst->streamon_cap = 0;
786 	mutex_unlock(&inst->lock);
787 	return ret;
788 }
789 
790 static const struct vb2_ops vdec_vb2_ops = {
791 	.queue_setup = vdec_queue_setup,
792 	.buf_init = venus_helper_vb2_buf_init,
793 	.buf_prepare = venus_helper_vb2_buf_prepare,
794 	.start_streaming = vdec_start_streaming,
795 	.stop_streaming = venus_helper_vb2_stop_streaming,
796 	.buf_queue = venus_helper_vb2_buf_queue,
797 };
798 
799 static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
800 			  u32 tag, u32 bytesused, u32 data_offset, u32 flags,
801 			  u32 hfi_flags, u64 timestamp_us)
802 {
803 	enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
804 	struct vb2_v4l2_buffer *vbuf;
805 	struct vb2_buffer *vb;
806 	unsigned int type;
807 
808 	if (buf_type == HFI_BUFFER_INPUT)
809 		type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
810 	else
811 		type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
812 
813 	vbuf = venus_helper_find_buf(inst, type, tag);
814 	if (!vbuf)
815 		return;
816 
817 	vbuf->flags = flags;
818 	vbuf->field = V4L2_FIELD_NONE;
819 
820 	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
821 		vb = &vbuf->vb2_buf;
822 		vb->planes[0].bytesused =
823 			max_t(unsigned int, inst->output_buf_size, bytesused);
824 		vb->planes[0].data_offset = data_offset;
825 		vb->timestamp = timestamp_us * NSEC_PER_USEC;
826 		vbuf->sequence = inst->sequence_cap++;
827 
828 		if (vbuf->flags & V4L2_BUF_FLAG_LAST) {
829 			const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
830 
831 			v4l2_event_queue_fh(&inst->fh, &ev);
832 		}
833 	} else {
834 		vbuf->sequence = inst->sequence_out++;
835 	}
836 
837 	if (hfi_flags & HFI_BUFFERFLAG_READONLY)
838 		venus_helper_acquire_buf_ref(vbuf);
839 
840 	if (hfi_flags & HFI_BUFFERFLAG_DATACORRUPT)
841 		state = VB2_BUF_STATE_ERROR;
842 
843 	v4l2_m2m_buf_done(vbuf, state);
844 }
845 
846 static void vdec_event_notify(struct venus_inst *inst, u32 event,
847 			      struct hfi_event_data *data)
848 {
849 	struct venus_core *core = inst->core;
850 	struct device *dev = core->dev_dec;
851 	static const struct v4l2_event ev = {
852 		.type = V4L2_EVENT_SOURCE_CHANGE,
853 		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION };
854 
855 	switch (event) {
856 	case EVT_SESSION_ERROR:
857 		inst->session_error = true;
858 		dev_err(dev, "dec: event session error %x\n", inst->error);
859 		break;
860 	case EVT_SYS_EVENT_CHANGE:
861 		switch (data->event_type) {
862 		case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES:
863 			hfi_session_continue(inst);
864 			dev_dbg(dev, "event sufficient resources\n");
865 			break;
866 		case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES:
867 			inst->reconfig_height = data->height;
868 			inst->reconfig_width = data->width;
869 			inst->reconfig = true;
870 
871 			v4l2_event_queue_fh(&inst->fh, &ev);
872 
873 			dev_dbg(dev, "event not sufficient resources (%ux%u)\n",
874 				data->width, data->height);
875 			break;
876 		case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
877 			venus_helper_release_buf_ref(inst, data->tag);
878 			break;
879 		default:
880 			break;
881 		}
882 		break;
883 	default:
884 		break;
885 	}
886 }
887 
888 static const struct hfi_inst_ops vdec_hfi_ops = {
889 	.buf_done = vdec_buf_done,
890 	.event_notify = vdec_event_notify,
891 };
892 
893 static void vdec_inst_init(struct venus_inst *inst)
894 {
895 	inst->fmt_out = &vdec_formats[6];
896 	inst->fmt_cap = &vdec_formats[0];
897 	inst->width = 1280;
898 	inst->height = ALIGN(720, 32);
899 	inst->out_width = 1280;
900 	inst->out_height = 720;
901 	inst->fps = 30;
902 	inst->timeperframe.numerator = 1;
903 	inst->timeperframe.denominator = 30;
904 
905 	inst->cap_width.min = 64;
906 	inst->cap_width.max = 1920;
907 	if (inst->core->res->hfi_version == HFI_VERSION_3XX)
908 		inst->cap_width.max = 3840;
909 	inst->cap_width.step_size = 1;
910 	inst->cap_height.min = 64;
911 	inst->cap_height.max = ALIGN(1080, 32);
912 	if (inst->core->res->hfi_version == HFI_VERSION_3XX)
913 		inst->cap_height.max = ALIGN(2160, 32);
914 	inst->cap_height.step_size = 1;
915 	inst->cap_framerate.min = 1;
916 	inst->cap_framerate.max = 30;
917 	inst->cap_framerate.step_size = 1;
918 	inst->cap_mbs_per_frame.min = 16;
919 	inst->cap_mbs_per_frame.max = 8160;
920 }
921 
922 static const struct v4l2_m2m_ops vdec_m2m_ops = {
923 	.device_run = venus_helper_m2m_device_run,
924 	.job_abort = venus_helper_m2m_job_abort,
925 };
926 
927 static int m2m_queue_init(void *priv, struct vb2_queue *src_vq,
928 			  struct vb2_queue *dst_vq)
929 {
930 	struct venus_inst *inst = priv;
931 	int ret;
932 
933 	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
934 	src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
935 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
936 	src_vq->ops = &vdec_vb2_ops;
937 	src_vq->mem_ops = &vb2_dma_sg_memops;
938 	src_vq->drv_priv = inst;
939 	src_vq->buf_struct_size = sizeof(struct venus_buffer);
940 	src_vq->allow_zero_bytesused = 1;
941 	src_vq->min_buffers_needed = 1;
942 	src_vq->dev = inst->core->dev;
943 	ret = vb2_queue_init(src_vq);
944 	if (ret)
945 		return ret;
946 
947 	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
948 	dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
949 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
950 	dst_vq->ops = &vdec_vb2_ops;
951 	dst_vq->mem_ops = &vb2_dma_sg_memops;
952 	dst_vq->drv_priv = inst;
953 	dst_vq->buf_struct_size = sizeof(struct venus_buffer);
954 	dst_vq->allow_zero_bytesused = 1;
955 	dst_vq->min_buffers_needed = 1;
956 	dst_vq->dev = inst->core->dev;
957 	ret = vb2_queue_init(dst_vq);
958 	if (ret) {
959 		vb2_queue_release(src_vq);
960 		return ret;
961 	}
962 
963 	return 0;
964 }
965 
966 static int vdec_open(struct file *file)
967 {
968 	struct venus_core *core = video_drvdata(file);
969 	struct venus_inst *inst;
970 	int ret;
971 
972 	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
973 	if (!inst)
974 		return -ENOMEM;
975 
976 	INIT_LIST_HEAD(&inst->registeredbufs);
977 	INIT_LIST_HEAD(&inst->internalbufs);
978 	INIT_LIST_HEAD(&inst->list);
979 	mutex_init(&inst->lock);
980 
981 	inst->core = core;
982 	inst->session_type = VIDC_SESSION_TYPE_DEC;
983 	inst->num_output_bufs = 1;
984 
985 	venus_helper_init_instance(inst);
986 
987 	ret = pm_runtime_get_sync(core->dev_dec);
988 	if (ret < 0)
989 		goto err_free_inst;
990 
991 	ret = vdec_ctrl_init(inst);
992 	if (ret)
993 		goto err_put_sync;
994 
995 	ret = hfi_session_create(inst, &vdec_hfi_ops);
996 	if (ret)
997 		goto err_ctrl_deinit;
998 
999 	vdec_inst_init(inst);
1000 
1001 	/*
1002 	 * create m2m device for every instance, the m2m context scheduling
1003 	 * is made by firmware side so we do not need to care about.
1004 	 */
1005 	inst->m2m_dev = v4l2_m2m_init(&vdec_m2m_ops);
1006 	if (IS_ERR(inst->m2m_dev)) {
1007 		ret = PTR_ERR(inst->m2m_dev);
1008 		goto err_session_destroy;
1009 	}
1010 
1011 	inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, m2m_queue_init);
1012 	if (IS_ERR(inst->m2m_ctx)) {
1013 		ret = PTR_ERR(inst->m2m_ctx);
1014 		goto err_m2m_release;
1015 	}
1016 
1017 	v4l2_fh_init(&inst->fh, core->vdev_dec);
1018 
1019 	inst->fh.ctrl_handler = &inst->ctrl_handler;
1020 	v4l2_fh_add(&inst->fh);
1021 	inst->fh.m2m_ctx = inst->m2m_ctx;
1022 	file->private_data = &inst->fh;
1023 
1024 	return 0;
1025 
1026 err_m2m_release:
1027 	v4l2_m2m_release(inst->m2m_dev);
1028 err_session_destroy:
1029 	hfi_session_destroy(inst);
1030 err_ctrl_deinit:
1031 	vdec_ctrl_deinit(inst);
1032 err_put_sync:
1033 	pm_runtime_put_sync(core->dev_dec);
1034 err_free_inst:
1035 	kfree(inst);
1036 	return ret;
1037 }
1038 
1039 static int vdec_close(struct file *file)
1040 {
1041 	struct venus_inst *inst = to_inst(file);
1042 
1043 	v4l2_m2m_ctx_release(inst->m2m_ctx);
1044 	v4l2_m2m_release(inst->m2m_dev);
1045 	vdec_ctrl_deinit(inst);
1046 	hfi_session_destroy(inst);
1047 	mutex_destroy(&inst->lock);
1048 	v4l2_fh_del(&inst->fh);
1049 	v4l2_fh_exit(&inst->fh);
1050 
1051 	pm_runtime_put_sync(inst->core->dev_dec);
1052 
1053 	kfree(inst);
1054 	return 0;
1055 }
1056 
1057 static const struct v4l2_file_operations vdec_fops = {
1058 	.owner = THIS_MODULE,
1059 	.open = vdec_open,
1060 	.release = vdec_close,
1061 	.unlocked_ioctl = video_ioctl2,
1062 	.poll = v4l2_m2m_fop_poll,
1063 	.mmap = v4l2_m2m_fop_mmap,
1064 #ifdef CONFIG_COMPAT
1065 	.compat_ioctl32 = v4l2_compat_ioctl32,
1066 #endif
1067 };
1068 
1069 static int vdec_probe(struct platform_device *pdev)
1070 {
1071 	struct device *dev = &pdev->dev;
1072 	struct video_device *vdev;
1073 	struct venus_core *core;
1074 	int ret;
1075 
1076 	if (!dev->parent)
1077 		return -EPROBE_DEFER;
1078 
1079 	core = dev_get_drvdata(dev->parent);
1080 	if (!core)
1081 		return -EPROBE_DEFER;
1082 
1083 	if (core->res->hfi_version == HFI_VERSION_3XX) {
1084 		core->core0_clk = devm_clk_get(dev, "core");
1085 		if (IS_ERR(core->core0_clk))
1086 			return PTR_ERR(core->core0_clk);
1087 	}
1088 
1089 	platform_set_drvdata(pdev, core);
1090 
1091 	vdev = video_device_alloc();
1092 	if (!vdev)
1093 		return -ENOMEM;
1094 
1095 	strlcpy(vdev->name, "qcom-venus-decoder", sizeof(vdev->name));
1096 	vdev->release = video_device_release;
1097 	vdev->fops = &vdec_fops;
1098 	vdev->ioctl_ops = &vdec_ioctl_ops;
1099 	vdev->vfl_dir = VFL_DIR_M2M;
1100 	vdev->v4l2_dev = &core->v4l2_dev;
1101 	vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
1102 
1103 	ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1104 	if (ret)
1105 		goto err_vdev_release;
1106 
1107 	core->vdev_dec = vdev;
1108 	core->dev_dec = dev;
1109 
1110 	video_set_drvdata(vdev, core);
1111 	pm_runtime_enable(dev);
1112 
1113 	return 0;
1114 
1115 err_vdev_release:
1116 	video_device_release(vdev);
1117 	return ret;
1118 }
1119 
1120 static int vdec_remove(struct platform_device *pdev)
1121 {
1122 	struct venus_core *core = dev_get_drvdata(pdev->dev.parent);
1123 
1124 	video_unregister_device(core->vdev_dec);
1125 	pm_runtime_disable(core->dev_dec);
1126 
1127 	return 0;
1128 }
1129 
1130 static __maybe_unused int vdec_runtime_suspend(struct device *dev)
1131 {
1132 	struct venus_core *core = dev_get_drvdata(dev);
1133 
1134 	if (core->res->hfi_version == HFI_VERSION_1XX)
1135 		return 0;
1136 
1137 	writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
1138 	clk_disable_unprepare(core->core0_clk);
1139 	writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
1140 
1141 	return 0;
1142 }
1143 
1144 static __maybe_unused int vdec_runtime_resume(struct device *dev)
1145 {
1146 	struct venus_core *core = dev_get_drvdata(dev);
1147 	int ret;
1148 
1149 	if (core->res->hfi_version == HFI_VERSION_1XX)
1150 		return 0;
1151 
1152 	writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
1153 	ret = clk_prepare_enable(core->core0_clk);
1154 	writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
1155 
1156 	return ret;
1157 }
1158 
1159 static const struct dev_pm_ops vdec_pm_ops = {
1160 	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1161 				pm_runtime_force_resume)
1162 	SET_RUNTIME_PM_OPS(vdec_runtime_suspend, vdec_runtime_resume, NULL)
1163 };
1164 
1165 static const struct of_device_id vdec_dt_match[] = {
1166 	{ .compatible = "venus-decoder" },
1167 	{ }
1168 };
1169 MODULE_DEVICE_TABLE(of, vdec_dt_match);
1170 
1171 static struct platform_driver qcom_venus_dec_driver = {
1172 	.probe = vdec_probe,
1173 	.remove = vdec_remove,
1174 	.driver = {
1175 		.name = "qcom-venus-decoder",
1176 		.of_match_table = vdec_dt_match,
1177 		.pm = &vdec_pm_ops,
1178 	},
1179 };
1180 module_platform_driver(qcom_venus_dec_driver);
1181 
1182 MODULE_ALIAS("platform:qcom-venus-decoder");
1183 MODULE_DESCRIPTION("Qualcomm Venus video decoder driver");
1184 MODULE_LICENSE("GPL v2");
1185