1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2020-2021 NXP
4 */
5
6#include <linux/init.h>
7#include <linux/interconnect.h>
8#include <linux/ioctl.h>
9#include <linux/list.h>
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/delay.h>
13#include <linux/videodev2.h>
14#include <linux/ktime.h>
15#include <linux/rational.h>
16#include <linux/vmalloc.h>
17#include <media/v4l2-device.h>
18#include <media/v4l2-event.h>
19#include <media/v4l2-mem2mem.h>
20#include <media/v4l2-ioctl.h>
21#include <media/videobuf2-v4l2.h>
22#include <media/videobuf2-dma-contig.h>
23#include <media/videobuf2-vmalloc.h>
24#include "vpu.h"
25#include "vpu_defs.h"
26#include "vpu_core.h"
27#include "vpu_helpers.h"
28#include "vpu_v4l2.h"
29#include "vpu_cmds.h"
30#include "vpu_rpc.h"
31
32#define VENC_OUTPUT_ENABLE	BIT(0)
33#define VENC_CAPTURE_ENABLE	BIT(1)
34#define VENC_ENABLE_MASK	(VENC_OUTPUT_ENABLE | VENC_CAPTURE_ENABLE)
35#define VENC_MAX_BUF_CNT	8
36#define VENC_MIN_BUFFER_OUT	6
37#define VENC_MIN_BUFFER_CAP	6
38
39struct venc_t {
40	struct vpu_encode_params params;
41	u32 request_key_frame;
42	u32 input_ready;
43	u32 cpb_size;
44	bool bitrate_change;
45
46	struct vpu_buffer enc[VENC_MAX_BUF_CNT];
47	struct vpu_buffer ref[VENC_MAX_BUF_CNT];
48	struct vpu_buffer act[VENC_MAX_BUF_CNT];
49	struct list_head frames;
50	u32 frame_count;
51	u32 encode_count;
52	u32 ready_count;
53	u32 enable;
54	u32 stopped;
55
56	u32 skipped_count;
57	u32 skipped_bytes;
58
59	wait_queue_head_t wq;
60};
61
62struct venc_frame_t {
63	struct list_head list;
64	struct vpu_enc_pic_info info;
65	u32 bytesused;
66	s64 timestamp;
67};
68
69static const struct vpu_format venc_formats[] = {
70	{
71		.pixfmt = V4L2_PIX_FMT_NV12M,
72		.mem_planes = 2,
73		.comp_planes = 2,
74		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
75		.sibling = V4L2_PIX_FMT_NV12,
76	},
77	{
78		.pixfmt = V4L2_PIX_FMT_NV12,
79		.mem_planes = 1,
80		.comp_planes = 2,
81		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
82		.sibling = V4L2_PIX_FMT_NV12M,
83	},
84	{
85		.pixfmt = V4L2_PIX_FMT_H264,
86		.mem_planes = 1,
87		.comp_planes = 1,
88		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
89		.flags = V4L2_FMT_FLAG_COMPRESSED
90	},
91	{0, 0, 0, 0},
92};
93
94static int venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
95{
96	strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver));
97	strscpy(cap->card, "amphion vpu encoder", sizeof(cap->card));
98	strscpy(cap->bus_info, "platform: amphion-vpu", sizeof(cap->bus_info));
99
100	return 0;
101}
102
103static int venc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
104{
105	struct vpu_inst *inst = to_inst(file);
106	const struct vpu_format *fmt;
107
108	memset(f->reserved, 0, sizeof(f->reserved));
109	fmt = vpu_helper_enum_format(inst, f->type, f->index);
110	if (!fmt)
111		return -EINVAL;
112
113	f->pixelformat = fmt->pixfmt;
114	f->flags = fmt->flags;
115
116	return 0;
117}
118
119static int venc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize)
120{
121	struct vpu_inst *inst = to_inst(file);
122	const struct vpu_core_resources *res;
123
124	if (!fsize || fsize->index)
125		return -EINVAL;
126
127	if (!vpu_helper_find_format(inst, 0, fsize->pixel_format))
128		return -EINVAL;
129
130	res = vpu_get_resource(inst);
131	if (!res)
132		return -EINVAL;
133	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
134	fsize->stepwise.max_width = res->max_width;
135	fsize->stepwise.max_height = res->max_height;
136	fsize->stepwise.min_width = res->min_width;
137	fsize->stepwise.min_height = res->min_height;
138	fsize->stepwise.step_width = res->step_width;
139	fsize->stepwise.step_height = res->step_height;
140
141	return 0;
142}
143
144static int venc_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival)
145{
146	struct vpu_inst *inst = to_inst(file);
147	const struct vpu_core_resources *res;
148
149	if (!fival || fival->index)
150		return -EINVAL;
151
152	if (!vpu_helper_find_format(inst, 0, fival->pixel_format))
153		return -EINVAL;
154
155	if (!fival->width || !fival->height)
156		return -EINVAL;
157
158	res = vpu_get_resource(inst);
159	if (!res)
160		return -EINVAL;
161	if (fival->width < res->min_width || fival->width > res->max_width ||
162	    fival->height < res->min_height || fival->height > res->max_height)
163		return -EINVAL;
164
165	fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
166	fival->stepwise.min.numerator = 1;
167	fival->stepwise.min.denominator = USHRT_MAX;
168	fival->stepwise.max.numerator = USHRT_MAX;
169	fival->stepwise.max.denominator = 1;
170	fival->stepwise.step.numerator = 1;
171	fival->stepwise.step.denominator = 1;
172
173	return 0;
174}
175
176static int venc_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
177{
178	struct vpu_inst *inst = to_inst(file);
179	struct venc_t *venc = inst->priv;
180	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
181	struct vpu_format *cur_fmt;
182	int i;
183
184	cur_fmt = vpu_get_format(inst, f->type);
185
186	pixmp->pixelformat = cur_fmt->pixfmt;
187	pixmp->num_planes = cur_fmt->mem_planes;
188	pixmp->width = cur_fmt->width;
189	pixmp->height = cur_fmt->height;
190	pixmp->field = cur_fmt->field;
191	pixmp->flags = cur_fmt->flags;
192	for (i = 0; i < pixmp->num_planes; i++) {
193		pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
194		pixmp->plane_fmt[i].sizeimage = vpu_get_fmt_plane_size(cur_fmt, i);
195	}
196
197	f->fmt.pix_mp.colorspace = venc->params.color.primaries;
198	f->fmt.pix_mp.xfer_func = venc->params.color.transfer;
199	f->fmt.pix_mp.ycbcr_enc = venc->params.color.matrix;
200	f->fmt.pix_mp.quantization = venc->params.color.full_range;
201
202	return 0;
203}
204
205static int venc_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
206{
207	struct vpu_inst *inst = to_inst(file);
208	struct vpu_format fmt;
209
210	vpu_try_fmt_common(inst, f, &fmt);
211
212	return 0;
213}
214
215static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
216{
217	struct vpu_inst *inst = to_inst(file);
218	struct vpu_format fmt;
219	struct vpu_format *cur_fmt;
220	struct vb2_queue *q;
221	struct venc_t *venc = inst->priv;
222	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
223
224	q = v4l2_m2m_get_vq(inst->fh.m2m_ctx, f->type);
225	if (!q)
226		return -EINVAL;
227	if (vb2_is_busy(q))
228		return -EBUSY;
229
230	if (vpu_try_fmt_common(inst, f, &fmt))
231		return -EINVAL;
232
233	cur_fmt = vpu_get_format(inst, f->type);
234
235	memcpy(cur_fmt, &fmt, sizeof(*cur_fmt));
236
237	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
238		venc->params.input_format = cur_fmt->pixfmt;
239		venc->params.src_stride = cur_fmt->bytesperline[0];
240		venc->params.src_width = cur_fmt->width;
241		venc->params.src_height = cur_fmt->height;
242		venc->params.crop.left = 0;
243		venc->params.crop.top = 0;
244		venc->params.crop.width = cur_fmt->width;
245		venc->params.crop.height = cur_fmt->height;
246	} else {
247		venc->params.codec_format = cur_fmt->pixfmt;
248		venc->params.out_width = cur_fmt->width;
249		venc->params.out_height = cur_fmt->height;
250	}
251
252	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
253		venc->params.color.primaries = pix_mp->colorspace;
254		venc->params.color.transfer = pix_mp->xfer_func;
255		venc->params.color.matrix = pix_mp->ycbcr_enc;
256		venc->params.color.full_range = pix_mp->quantization;
257	}
258
259	pix_mp->colorspace = venc->params.color.primaries;
260	pix_mp->xfer_func = venc->params.color.transfer;
261	pix_mp->ycbcr_enc = venc->params.color.matrix;
262	pix_mp->quantization = venc->params.color.full_range;
263
264	return 0;
265}
266
267static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
268{
269	struct vpu_inst *inst = to_inst(file);
270	struct venc_t *venc = inst->priv;
271	struct v4l2_fract *timeperframe;
272
273	if (!parm)
274		return -EINVAL;
275
276	if (!V4L2_TYPE_IS_OUTPUT(parm->type))
277		return -EINVAL;
278
279	if (!vpu_helper_check_type(inst, parm->type))
280		return -EINVAL;
281
282	timeperframe = &parm->parm.capture.timeperframe;
283	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
284	parm->parm.capture.readbuffers = 0;
285	timeperframe->numerator = venc->params.frame_rate.numerator;
286	timeperframe->denominator = venc->params.frame_rate.denominator;
287
288	return 0;
289}
290
291static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
292{
293	struct vpu_inst *inst = to_inst(file);
294	struct venc_t *venc = inst->priv;
295	struct v4l2_fract *timeperframe;
296	unsigned long n, d;
297
298	if (!parm)
299		return -EINVAL;
300
301	if (!V4L2_TYPE_IS_OUTPUT(parm->type))
302		return -EINVAL;
303
304	if (!vpu_helper_check_type(inst, parm->type))
305		return -EINVAL;
306
307	timeperframe = &parm->parm.capture.timeperframe;
308	if (!timeperframe->numerator)
309		timeperframe->numerator = venc->params.frame_rate.numerator;
310	if (!timeperframe->denominator)
311		timeperframe->denominator = venc->params.frame_rate.denominator;
312
313	venc->params.frame_rate.numerator = timeperframe->numerator;
314	venc->params.frame_rate.denominator = timeperframe->denominator;
315
316	rational_best_approximation(venc->params.frame_rate.numerator,
317				    venc->params.frame_rate.denominator,
318				    venc->params.frame_rate.numerator,
319				    venc->params.frame_rate.denominator,
320				    &n, &d);
321	venc->params.frame_rate.numerator = n;
322	venc->params.frame_rate.denominator = d;
323
324	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
325	memset(parm->parm.capture.reserved, 0, sizeof(parm->parm.capture.reserved));
326
327	return 0;
328}
329
330static int venc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
331{
332	struct vpu_inst *inst = to_inst(file);
333	struct venc_t *venc = inst->priv;
334
335	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
336		return -EINVAL;
337
338	switch (s->target) {
339	case V4L2_SEL_TGT_CROP_DEFAULT:
340	case V4L2_SEL_TGT_CROP_BOUNDS:
341		s->r.left = 0;
342		s->r.top = 0;
343		s->r.width = inst->out_format.width;
344		s->r.height = inst->out_format.height;
345		break;
346	case V4L2_SEL_TGT_CROP:
347		s->r = venc->params.crop;
348		break;
349	default:
350		return -EINVAL;
351	}
352
353	return 0;
354}
355
356static int venc_valid_crop(struct venc_t *venc, const struct vpu_core_resources *res)
357{
358	struct v4l2_rect *rect = NULL;
359	u32 min_width;
360	u32 min_height;
361	u32 src_width;
362	u32 src_height;
363
364	rect = &venc->params.crop;
365	min_width = res->min_width;
366	min_height = res->min_height;
367	src_width = venc->params.src_width;
368	src_height = venc->params.src_height;
369
370	if (rect->width == 0 || rect->height == 0)
371		return -EINVAL;
372	if (rect->left > src_width - min_width || rect->top > src_height - min_height)
373		return -EINVAL;
374
375	rect->width = min(rect->width, src_width - rect->left);
376	rect->width = max_t(u32, rect->width, min_width);
377
378	rect->height = min(rect->height, src_height - rect->top);
379	rect->height = max_t(u32, rect->height, min_height);
380
381	return 0;
382}
383
384static int venc_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
385{
386	struct vpu_inst *inst = to_inst(file);
387	const struct vpu_core_resources *res;
388	struct venc_t *venc = inst->priv;
389
390	res = vpu_get_resource(inst);
391	if (!res)
392		return -EINVAL;
393
394	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
395		return -EINVAL;
396	if (s->target != V4L2_SEL_TGT_CROP)
397		return -EINVAL;
398
399	venc->params.crop.left = ALIGN(s->r.left, res->step_width);
400	venc->params.crop.top = ALIGN(s->r.top, res->step_height);
401	venc->params.crop.width = ALIGN(s->r.width, res->step_width);
402	venc->params.crop.height = ALIGN(s->r.height, res->step_height);
403	if (venc_valid_crop(venc, res)) {
404		venc->params.crop.left = 0;
405		venc->params.crop.top = 0;
406		venc->params.crop.width = venc->params.src_width;
407		venc->params.crop.height = venc->params.src_height;
408	}
409
410	inst->crop = venc->params.crop;
411
412	return 0;
413}
414
415static int venc_drain(struct vpu_inst *inst)
416{
417	struct venc_t *venc = inst->priv;
418	int ret;
419
420	if (!inst->fh.m2m_ctx)
421		return 0;
422
423	if (inst->state != VPU_CODEC_STATE_DRAIN)
424		return 0;
425
426	if (!vpu_is_source_empty(inst))
427		return 0;
428
429	if (!venc->input_ready)
430		return 0;
431
432	venc->input_ready = false;
433	vpu_trace(inst->dev, "[%d]\n", inst->id);
434	ret = vpu_session_stop(inst);
435	if (ret)
436		return ret;
437	inst->state = VPU_CODEC_STATE_STOP;
438	wake_up_all(&venc->wq);
439
440	return 0;
441}
442
443static int venc_request_eos(struct vpu_inst *inst)
444{
445	inst->state = VPU_CODEC_STATE_DRAIN;
446	venc_drain(inst);
447
448	return 0;
449}
450
451static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *cmd)
452{
453	struct vpu_inst *inst = to_inst(file);
454	int ret;
455
456	ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
457	if (ret)
458		return ret;
459
460	vpu_inst_lock(inst);
461	if (cmd->cmd == V4L2_ENC_CMD_STOP) {
462		if (inst->state == VPU_CODEC_STATE_DEINIT)
463			vpu_set_last_buffer_dequeued(inst, true);
464		else
465			venc_request_eos(inst);
466	}
467	vpu_inst_unlock(inst);
468
469	return 0;
470}
471
472static int venc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
473{
474	switch (sub->type) {
475	case V4L2_EVENT_EOS:
476		return v4l2_event_subscribe(fh, sub, 0, NULL);
477	case V4L2_EVENT_CTRL:
478		return v4l2_ctrl_subscribe_event(fh, sub);
479	default:
480		return -EINVAL;
481	}
482}
483
484static const struct v4l2_ioctl_ops venc_ioctl_ops = {
485	.vidioc_querycap               = venc_querycap,
486	.vidioc_enum_fmt_vid_cap       = venc_enum_fmt,
487	.vidioc_enum_fmt_vid_out       = venc_enum_fmt,
488	.vidioc_enum_framesizes        = venc_enum_framesizes,
489	.vidioc_enum_frameintervals    = venc_enum_frameintervals,
490	.vidioc_g_fmt_vid_cap_mplane   = venc_g_fmt,
491	.vidioc_g_fmt_vid_out_mplane   = venc_g_fmt,
492	.vidioc_try_fmt_vid_cap_mplane = venc_try_fmt,
493	.vidioc_try_fmt_vid_out_mplane = venc_try_fmt,
494	.vidioc_s_fmt_vid_cap_mplane   = venc_s_fmt,
495	.vidioc_s_fmt_vid_out_mplane   = venc_s_fmt,
496	.vidioc_g_parm                 = venc_g_parm,
497	.vidioc_s_parm                 = venc_s_parm,
498	.vidioc_g_selection            = venc_g_selection,
499	.vidioc_s_selection            = venc_s_selection,
500	.vidioc_try_encoder_cmd        = v4l2_m2m_ioctl_try_encoder_cmd,
501	.vidioc_encoder_cmd            = venc_encoder_cmd,
502	.vidioc_subscribe_event        = venc_subscribe_event,
503	.vidioc_unsubscribe_event      = v4l2_event_unsubscribe,
504	.vidioc_reqbufs                = v4l2_m2m_ioctl_reqbufs,
505	.vidioc_querybuf               = v4l2_m2m_ioctl_querybuf,
506	.vidioc_create_bufs	       = v4l2_m2m_ioctl_create_bufs,
507	.vidioc_prepare_buf	       = v4l2_m2m_ioctl_prepare_buf,
508	.vidioc_qbuf                   = v4l2_m2m_ioctl_qbuf,
509	.vidioc_expbuf                 = v4l2_m2m_ioctl_expbuf,
510	.vidioc_dqbuf                  = v4l2_m2m_ioctl_dqbuf,
511	.vidioc_streamon               = v4l2_m2m_ioctl_streamon,
512	.vidioc_streamoff              = v4l2_m2m_ioctl_streamoff,
513};
514
515static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
516{
517	struct vpu_inst *inst = ctrl_to_inst(ctrl);
518	struct venc_t *venc = inst->priv;
519	int ret = 0;
520
521	vpu_inst_lock(inst);
522	switch (ctrl->id) {
523	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
524		venc->params.profile = ctrl->val;
525		break;
526	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
527		venc->params.level = ctrl->val;
528		break;
529	case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
530		venc->params.rc_enable = ctrl->val;
531		break;
532	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
533		venc->params.rc_mode = ctrl->val;
534		break;
535	case V4L2_CID_MPEG_VIDEO_BITRATE:
536		if (ctrl->val != venc->params.bitrate)
537			venc->bitrate_change = true;
538		venc->params.bitrate = ctrl->val;
539		break;
540	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
541		venc->params.bitrate_max = ctrl->val;
542		break;
543	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
544		venc->params.gop_length = ctrl->val;
545		break;
546	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
547		venc->params.bframes = ctrl->val;
548		break;
549	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
550		venc->params.i_frame_qp = ctrl->val;
551		break;
552	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
553		venc->params.p_frame_qp = ctrl->val;
554		break;
555	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
556		venc->params.b_frame_qp = ctrl->val;
557		break;
558	case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
559		venc->request_key_frame = 1;
560		break;
561	case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
562		venc->cpb_size = ctrl->val * 1024;
563		break;
564	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
565		venc->params.sar.enable = ctrl->val;
566		break;
567	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
568		venc->params.sar.idc = ctrl->val;
569		break;
570	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
571		venc->params.sar.width = ctrl->val;
572		break;
573	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
574		venc->params.sar.height = ctrl->val;
575		break;
576	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
577		break;
578	default:
579		ret = -EINVAL;
580		break;
581	}
582	vpu_inst_unlock(inst);
583
584	return ret;
585}
586
587static const struct v4l2_ctrl_ops venc_ctrl_ops = {
588	.s_ctrl = venc_op_s_ctrl,
589	.g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
590};
591
592static int venc_ctrl_init(struct vpu_inst *inst)
593{
594	struct v4l2_ctrl *ctrl;
595	int ret;
596
597	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
598	if (ret)
599		return ret;
600
601	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
602			       V4L2_CID_MPEG_VIDEO_H264_PROFILE,
603			       V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
604			       ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
605				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
606				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
607			       V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
608
609	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
610			       V4L2_CID_MPEG_VIDEO_H264_LEVEL,
611			       V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
612			       0x0,
613			       V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
614
615	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
616			  V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, 0, 1, 1, 1);
617
618	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
619			       V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
620			       V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
621			       ~((1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
622				 (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)),
623			       V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
624
625	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
626			  V4L2_CID_MPEG_VIDEO_BITRATE,
627			  BITRATE_MIN,
628			  BITRATE_MAX,
629			  BITRATE_STEP,
630			  BITRATE_DEFAULT);
631
632	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
633			  V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
634			  BITRATE_MIN, BITRATE_MAX,
635			  BITRATE_STEP,
636			  BITRATE_DEFAULT_PEAK);
637
638	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
639			  V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 8000, 1, 30);
640
641	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
642			  V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);
643
644	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
645			  V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 26);
646	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
647			  V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 28);
648	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
649			  V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, 1, 51, 1, 30);
650	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
651			  V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0);
652	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
653				 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
654	if (ctrl)
655		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
656	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
657				 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
658	if (ctrl)
659		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
660
661	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
662			  V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, 64, 10240, 1, 1024);
663
664	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
665			  V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE, 0, 1, 1, 1);
666	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
667			       V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
668			       V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,
669			       0x0,
670			       V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1);
671	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
672			  V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,
673			  0, USHRT_MAX, 1, 1);
674	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
675			  V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,
676			  0, USHRT_MAX, 1, 1);
677	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
678			       V4L2_CID_MPEG_VIDEO_HEADER_MODE,
679			       V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
680			       ~(1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
681			       V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);
682
683	if (inst->ctrl_handler.error) {
684		ret = inst->ctrl_handler.error;
685		v4l2_ctrl_handler_free(&inst->ctrl_handler);
686		return ret;
687	}
688
689	ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
690	if (ret) {
691		dev_err(inst->dev, "[%d] setup ctrls fail, ret = %d\n", inst->id, ret);
692		v4l2_ctrl_handler_free(&inst->ctrl_handler);
693		return ret;
694	}
695
696	return 0;
697}
698
699static bool venc_check_ready(struct vpu_inst *inst, unsigned int type)
700{
701	struct venc_t *venc = inst->priv;
702
703	if (V4L2_TYPE_IS_OUTPUT(type)) {
704		if (vpu_helper_get_free_space(inst) < venc->cpb_size)
705			return false;
706		return venc->input_ready;
707	}
708
709	if (list_empty(&venc->frames))
710		return false;
711	return true;
712}
713
714static u32 venc_get_enable_mask(u32 type)
715{
716	if (V4L2_TYPE_IS_OUTPUT(type))
717		return VENC_OUTPUT_ENABLE;
718	else
719		return VENC_CAPTURE_ENABLE;
720}
721
722static void venc_set_enable(struct venc_t *venc, u32 type, int enable)
723{
724	u32 mask = venc_get_enable_mask(type);
725
726	if (enable)
727		venc->enable |= mask;
728	else
729		venc->enable &= ~mask;
730}
731
732static u32 venc_get_enable(struct venc_t *venc, u32 type)
733{
734	return venc->enable & venc_get_enable_mask(type);
735}
736
737static void venc_input_done(struct vpu_inst *inst)
738{
739	struct venc_t *venc = inst->priv;
740
741	vpu_inst_lock(inst);
742	venc->input_ready = true;
743	vpu_process_output_buffer(inst);
744	if (inst->state == VPU_CODEC_STATE_DRAIN)
745		venc_drain(inst);
746	vpu_inst_unlock(inst);
747}
748
749/*
750 * It's hardware limitation, that there may be several bytes
751 * redundant data at the beginning of frame.
752 * For android platform, the redundant data may cause cts test fail
753 * So driver will strip them
754 */
755static int venc_precheck_encoded_frame(struct vpu_inst *inst, struct venc_frame_t *frame)
756{
757	struct venc_t *venc;
758	int skipped;
759
760	if (!frame || !frame->bytesused)
761		return -EINVAL;
762
763	venc = inst->priv;
764	skipped = vpu_helper_find_startcode(&inst->stream_buffer,
765					    inst->cap_format.pixfmt,
766					    frame->info.wptr - inst->stream_buffer.phys,
767					    frame->bytesused);
768	if (skipped > 0) {
769		frame->bytesused -= skipped;
770		frame->info.wptr = vpu_helper_step_walk(&inst->stream_buffer,
771							frame->info.wptr, skipped);
772		venc->skipped_bytes += skipped;
773		venc->skipped_count++;
774	}
775
776	return 0;
777}
778
779static int venc_get_one_encoded_frame(struct vpu_inst *inst,
780				      struct venc_frame_t *frame,
781				      struct vb2_v4l2_buffer *vbuf)
782{
783	struct venc_t *venc = inst->priv;
784	struct vb2_v4l2_buffer *src_buf;
785
786	if (!vbuf)
787		return -EAGAIN;
788
789	src_buf = vpu_find_buf_by_sequence(inst, inst->out_format.type, frame->info.frame_id);
790	if (src_buf) {
791		v4l2_m2m_buf_copy_metadata(src_buf, vbuf, true);
792		vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE);
793		v4l2_m2m_src_buf_remove_by_buf(inst->fh.m2m_ctx, src_buf);
794		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
795	} else {
796		vbuf->vb2_buf.timestamp = frame->info.timestamp;
797	}
798	if (!venc_get_enable(inst->priv, vbuf->vb2_buf.type)) {
799		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
800		return 0;
801	}
802	if (frame->bytesused > vbuf->vb2_buf.planes[0].length) {
803		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
804		return -ENOMEM;
805	}
806
807	venc_precheck_encoded_frame(inst, frame);
808
809	if (frame->bytesused) {
810		u32 rptr = frame->info.wptr;
811		void *dst = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
812
813		vpu_helper_copy_from_stream_buffer(&inst->stream_buffer,
814						   &rptr, frame->bytesused, dst);
815		vpu_iface_update_stream_buffer(inst, rptr, 0);
816	}
817	vb2_set_plane_payload(&vbuf->vb2_buf, 0, frame->bytesused);
818	vbuf->sequence = frame->info.frame_id;
819	vbuf->field = inst->cap_format.field;
820	vbuf->flags |= frame->info.pic_type;
821	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
822	dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
823	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
824	venc->ready_count++;
825
826	if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)
827		dev_dbg(inst->dev, "[%d][%d]key frame\n", inst->id, frame->info.frame_id);
828
829	return 0;
830}
831
832static int venc_get_encoded_frames(struct vpu_inst *inst)
833{
834	struct venc_t *venc;
835	struct venc_frame_t *frame;
836	struct venc_frame_t *tmp;
837
838	if (!inst->fh.m2m_ctx)
839		return 0;
840	venc = inst->priv;
841	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
842		if (venc_get_one_encoded_frame(inst, frame,
843					       v4l2_m2m_dst_buf_remove(inst->fh.m2m_ctx)))
844			break;
845		list_del_init(&frame->list);
846		vfree(frame);
847	}
848
849	return 0;
850}
851
852static int venc_frame_encoded(struct vpu_inst *inst, void *arg)
853{
854	struct vpu_enc_pic_info *info = arg;
855	struct venc_frame_t *frame;
856	struct venc_t *venc;
857	int ret = 0;
858
859	if (!info)
860		return -EINVAL;
861	venc = inst->priv;
862	frame = vzalloc(sizeof(*frame));
863	if (!frame)
864		return -ENOMEM;
865
866	memcpy(&frame->info, info, sizeof(frame->info));
867	frame->bytesused = info->frame_size;
868
869	vpu_inst_lock(inst);
870	list_add_tail(&frame->list, &venc->frames);
871	venc->encode_count++;
872	venc_get_encoded_frames(inst);
873	vpu_inst_unlock(inst);
874
875	return ret;
876}
877
878static void venc_set_last_buffer_dequeued(struct vpu_inst *inst)
879{
880	struct venc_t *venc = inst->priv;
881
882	if (venc->stopped && list_empty(&venc->frames))
883		vpu_set_last_buffer_dequeued(inst, true);
884}
885
886static void venc_stop_done(struct vpu_inst *inst)
887{
888	struct venc_t *venc = inst->priv;
889
890	vpu_inst_lock(inst);
891	venc->stopped = true;
892	venc_set_last_buffer_dequeued(inst);
893	vpu_inst_unlock(inst);
894
895	wake_up_all(&venc->wq);
896}
897
898static void venc_event_notify(struct vpu_inst *inst, u32 event, void *data)
899{
900}
901
902static void venc_release(struct vpu_inst *inst)
903{
904}
905
906static void venc_cleanup(struct vpu_inst *inst)
907{
908	struct venc_t *venc;
909
910	if (!inst)
911		return;
912
913	venc = inst->priv;
914	vfree(venc);
915	inst->priv = NULL;
916	vfree(inst);
917}
918
919static int venc_start_session(struct vpu_inst *inst, u32 type)
920{
921	struct venc_t *venc = inst->priv;
922	int stream_buffer_size;
923	int ret;
924
925	venc_set_enable(venc, type, 1);
926	if ((venc->enable & VENC_ENABLE_MASK) != VENC_ENABLE_MASK)
927		return 0;
928
929	vpu_iface_init_instance(inst);
930	stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
931	if (stream_buffer_size > 0) {
932		inst->stream_buffer.length = max_t(u32, stream_buffer_size, venc->cpb_size * 3);
933		ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
934		if (ret)
935			goto error;
936
937		inst->use_stream_buffer = true;
938		vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
939	}
940
941	ret = vpu_iface_set_encode_params(inst, &venc->params, 0);
942	if (ret)
943		goto error;
944	ret = vpu_session_configure_codec(inst);
945	if (ret)
946		goto error;
947
948	inst->state = VPU_CODEC_STATE_CONFIGURED;
949	/*vpu_iface_config_memory_resource*/
950
951	/*config enc expert mode parameter*/
952	ret = vpu_iface_set_encode_params(inst, &venc->params, 1);
953	if (ret)
954		goto error;
955
956	ret = vpu_session_start(inst);
957	if (ret)
958		goto error;
959	inst->state = VPU_CODEC_STATE_STARTED;
960
961	venc->bitrate_change = false;
962	venc->input_ready = true;
963	venc->frame_count = 0;
964	venc->encode_count = 0;
965	venc->ready_count = 0;
966	venc->stopped = false;
967	vpu_process_output_buffer(inst);
968	if (venc->frame_count == 0)
969		dev_err(inst->dev, "[%d] there is no input when starting\n", inst->id);
970
971	return 0;
972error:
973	venc_set_enable(venc, type, 0);
974	inst->state = VPU_CODEC_STATE_DEINIT;
975
976	vpu_free_dma(&inst->stream_buffer);
977	return ret;
978}
979
980static void venc_cleanup_mem_resource(struct vpu_inst *inst)
981{
982	struct venc_t *venc;
983	u32 i;
984
985	venc = inst->priv;
986
987	for (i = 0; i < ARRAY_SIZE(venc->enc); i++)
988		vpu_free_dma(&venc->enc[i]);
989	for (i = 0; i < ARRAY_SIZE(venc->ref); i++)
990		vpu_free_dma(&venc->ref[i]);
991}
992
993static void venc_request_mem_resource(struct vpu_inst *inst,
994				      u32 enc_frame_size,
995				      u32 enc_frame_num,
996				      u32 ref_frame_size,
997				      u32 ref_frame_num,
998				      u32 act_frame_size,
999				      u32 act_frame_num)
1000{
1001	struct venc_t *venc;
1002	u32 i;
1003	int ret;
1004
1005	venc = inst->priv;
1006	if (enc_frame_num > ARRAY_SIZE(venc->enc)) {
1007		dev_err(inst->dev, "[%d] enc num(%d) is out of range\n", inst->id, enc_frame_num);
1008		return;
1009	}
1010	if (ref_frame_num > ARRAY_SIZE(venc->ref)) {
1011		dev_err(inst->dev, "[%d] ref num(%d) is out of range\n", inst->id, ref_frame_num);
1012		return;
1013	}
1014	if (act_frame_num > ARRAY_SIZE(venc->act)) {
1015		dev_err(inst->dev, "[%d] act num(%d) is out of range\n", inst->id, act_frame_num);
1016		return;
1017	}
1018
1019	for (i = 0; i < enc_frame_num; i++) {
1020		venc->enc[i].length = enc_frame_size;
1021		ret = vpu_alloc_dma(inst->core, &venc->enc[i]);
1022		if (ret) {
1023			venc_cleanup_mem_resource(inst);
1024			return;
1025		}
1026	}
1027	for (i = 0; i < ref_frame_num; i++) {
1028		venc->ref[i].length = ref_frame_size;
1029		ret = vpu_alloc_dma(inst->core, &venc->ref[i]);
1030		if (ret) {
1031			venc_cleanup_mem_resource(inst);
1032			return;
1033		}
1034	}
1035	if (act_frame_num != 1 || act_frame_size > inst->act.length) {
1036		venc_cleanup_mem_resource(inst);
1037		return;
1038	}
1039	venc->act[0].length = act_frame_size;
1040	venc->act[0].phys = inst->act.phys;
1041	venc->act[0].virt = inst->act.virt;
1042
1043	for (i = 0; i < enc_frame_num; i++)
1044		vpu_iface_config_memory_resource(inst, MEM_RES_ENC, i, &venc->enc[i]);
1045	for (i = 0; i < ref_frame_num; i++)
1046		vpu_iface_config_memory_resource(inst, MEM_RES_REF, i, &venc->ref[i]);
1047	for (i = 0; i < act_frame_num; i++)
1048		vpu_iface_config_memory_resource(inst, MEM_RES_ACT, i, &venc->act[i]);
1049}
1050
1051static void venc_cleanup_frames(struct venc_t *venc)
1052{
1053	struct venc_frame_t *frame;
1054	struct venc_frame_t *tmp;
1055
1056	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
1057		list_del_init(&frame->list);
1058		vfree(frame);
1059	}
1060}
1061
1062static int venc_stop_session(struct vpu_inst *inst, u32 type)
1063{
1064	struct venc_t *venc = inst->priv;
1065
1066	venc_set_enable(venc, type, 0);
1067	if (venc->enable & VENC_ENABLE_MASK)
1068		return 0;
1069
1070	if (inst->state == VPU_CODEC_STATE_DEINIT)
1071		return 0;
1072
1073	if (inst->state != VPU_CODEC_STATE_STOP)
1074		venc_request_eos(inst);
1075
1076	call_void_vop(inst, wait_prepare);
1077	if (!wait_event_timeout(venc->wq, venc->stopped, VPU_TIMEOUT)) {
1078		set_bit(inst->id, &inst->core->hang_mask);
1079		vpu_session_debug(inst);
1080	}
1081	call_void_vop(inst, wait_finish);
1082
1083	inst->state = VPU_CODEC_STATE_DEINIT;
1084	venc_cleanup_frames(inst->priv);
1085	vpu_free_dma(&inst->stream_buffer);
1086	venc_cleanup_mem_resource(inst);
1087
1088	return 0;
1089}
1090
1091static int venc_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
1092{
1093	struct venc_t *venc = inst->priv;
1094	struct vb2_v4l2_buffer *vbuf;
1095	u32 flags;
1096
1097	if (inst->state == VPU_CODEC_STATE_DEINIT)
1098		return -EINVAL;
1099
1100	vbuf = to_vb2_v4l2_buffer(vb);
1101	if (inst->state == VPU_CODEC_STATE_STARTED)
1102		inst->state = VPU_CODEC_STATE_ACTIVE;
1103
1104	flags = vbuf->flags;
1105	if (venc->request_key_frame) {
1106		vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
1107		venc->request_key_frame = 0;
1108	}
1109	if (venc->bitrate_change) {
1110		vpu_session_update_parameters(inst, &venc->params);
1111		venc->bitrate_change = false;
1112	}
1113	dev_dbg(inst->dev, "[%d][INPUT  TS]%32lld\n", inst->id, vb->timestamp);
1114	vpu_iface_input_frame(inst, vb);
1115	vbuf->flags = flags;
1116	venc->input_ready = false;
1117	venc->frame_count++;
1118	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
1119
1120	return 0;
1121}
1122
1123static int venc_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
1124{
1125	struct venc_t *venc;
1126	struct venc_frame_t *frame = NULL;
1127	struct vb2_v4l2_buffer *vbuf;
1128	int ret;
1129
1130	venc = inst->priv;
1131	if (list_empty(&venc->frames))
1132		return -EINVAL;
1133
1134	frame = list_first_entry(&venc->frames, struct venc_frame_t, list);
1135	vbuf = to_vb2_v4l2_buffer(vb);
1136	v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
1137	ret = venc_get_one_encoded_frame(inst, frame, vbuf);
1138	if (ret)
1139		return ret;
1140
1141	list_del_init(&frame->list);
1142	vfree(frame);
1143	return 0;
1144}
1145
1146static void venc_on_queue_empty(struct vpu_inst *inst, u32 type)
1147{
1148	struct venc_t *venc = inst->priv;
1149
1150	if (V4L2_TYPE_IS_OUTPUT(type))
1151		return;
1152
1153	if (venc->stopped)
1154		venc_set_last_buffer_dequeued(inst);
1155}
1156
1157static int venc_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
1158{
1159	struct venc_t *venc = inst->priv;
1160	int num = -1;
1161
1162	switch (i) {
1163	case 0:
1164		num = scnprintf(str, size, "profile = %d\n", venc->params.profile);
1165		break;
1166	case 1:
1167		num = scnprintf(str, size, "level = %d\n", venc->params.level);
1168		break;
1169	case 2:
1170		num = scnprintf(str, size, "fps = %d/%d\n",
1171				venc->params.frame_rate.numerator,
1172				venc->params.frame_rate.denominator);
1173		break;
1174	case 3:
1175		num = scnprintf(str, size, "%d x %d -> %d x %d\n",
1176				venc->params.src_width,
1177				venc->params.src_height,
1178				venc->params.out_width,
1179				venc->params.out_height);
1180		break;
1181	case 4:
1182		num = scnprintf(str, size, "(%d, %d)  %d x %d\n",
1183				venc->params.crop.left,
1184				venc->params.crop.top,
1185				venc->params.crop.width,
1186				venc->params.crop.height);
1187		break;
1188	case 5:
1189		num = scnprintf(str, size,
1190				"enable = 0x%x, input = %d, encode = %d, ready = %d, stopped = %d\n",
1191				venc->enable,
1192				venc->frame_count, venc->encode_count,
1193				venc->ready_count,
1194				venc->stopped);
1195		break;
1196	case 6:
1197		num = scnprintf(str, size, "gop = %d\n", venc->params.gop_length);
1198		break;
1199	case 7:
1200		num = scnprintf(str, size, "bframes = %d\n", venc->params.bframes);
1201		break;
1202	case 8:
1203		num = scnprintf(str, size, "rc: %s, mode = %d, bitrate = %d(%d), qp = %d\n",
1204				venc->params.rc_enable ? "enable" : "disable",
1205				venc->params.rc_mode,
1206				venc->params.bitrate,
1207				venc->params.bitrate_max,
1208				venc->params.i_frame_qp);
1209		break;
1210	case 9:
1211		num = scnprintf(str, size, "sar: enable = %d, idc = %d, %d x %d\n",
1212				venc->params.sar.enable,
1213				venc->params.sar.idc,
1214				venc->params.sar.width,
1215				venc->params.sar.height);
1216
1217		break;
1218	case 10:
1219		num = scnprintf(str, size,
1220				"colorspace: primaries = %d, transfer = %d, matrix = %d, full_range = %d\n",
1221				venc->params.color.primaries,
1222				venc->params.color.transfer,
1223				venc->params.color.matrix,
1224				venc->params.color.full_range);
1225		break;
1226	case 11:
1227		num = scnprintf(str, size, "skipped: count = %d, bytes = %d\n",
1228				venc->skipped_count, venc->skipped_bytes);
1229		break;
1230	default:
1231		break;
1232	}
1233
1234	return num;
1235}
1236
1237static struct vpu_inst_ops venc_inst_ops = {
1238	.ctrl_init = venc_ctrl_init,
1239	.check_ready = venc_check_ready,
1240	.input_done = venc_input_done,
1241	.get_one_frame = venc_frame_encoded,
1242	.stop_done = venc_stop_done,
1243	.event_notify = venc_event_notify,
1244	.release = venc_release,
1245	.cleanup = venc_cleanup,
1246	.start = venc_start_session,
1247	.mem_request = venc_request_mem_resource,
1248	.stop = venc_stop_session,
1249	.process_output = venc_process_output,
1250	.process_capture = venc_process_capture,
1251	.on_queue_empty = venc_on_queue_empty,
1252	.get_debug_info = venc_get_debug_info,
1253	.wait_prepare = vpu_inst_unlock,
1254	.wait_finish = vpu_inst_lock,
1255};
1256
1257static void venc_init(struct file *file)
1258{
1259	struct vpu_inst *inst = to_inst(file);
1260	struct venc_t *venc;
1261	struct v4l2_format f;
1262	struct v4l2_streamparm parm;
1263
1264	venc = inst->priv;
1265	venc->params.qp_min = 1;
1266	venc->params.qp_max = 51;
1267	venc->params.qp_min_i = 1;
1268	venc->params.qp_max_i = 51;
1269	venc->params.bitrate_min = BITRATE_MIN;
1270
1271	memset(&f, 0, sizeof(f));
1272	f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1273	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
1274	f.fmt.pix_mp.width = 1280;
1275	f.fmt.pix_mp.height = 720;
1276	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
1277	venc_s_fmt(file, &inst->fh, &f);
1278
1279	memset(&f, 0, sizeof(f));
1280	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1281	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
1282	f.fmt.pix_mp.width = 1280;
1283	f.fmt.pix_mp.height = 720;
1284	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
1285	venc_s_fmt(file, &inst->fh, &f);
1286
1287	memset(&parm, 0, sizeof(parm));
1288	parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1289	parm.parm.capture.timeperframe.numerator = 1;
1290	parm.parm.capture.timeperframe.denominator = 30;
1291	venc_s_parm(file, &inst->fh, &parm);
1292}
1293
1294static int venc_open(struct file *file)
1295{
1296	struct vpu_inst *inst;
1297	struct venc_t *venc;
1298	int ret;
1299
1300	inst = vzalloc(sizeof(*inst));
1301	if (!inst)
1302		return -ENOMEM;
1303
1304	venc = vzalloc(sizeof(*venc));
1305	if (!venc) {
1306		vfree(inst);
1307		return -ENOMEM;
1308	}
1309
1310	inst->ops = &venc_inst_ops;
1311	inst->formats = venc_formats;
1312	inst->type = VPU_CORE_TYPE_ENC;
1313	inst->priv = venc;
1314	INIT_LIST_HEAD(&venc->frames);
1315	init_waitqueue_head(&venc->wq);
1316
1317	ret = vpu_v4l2_open(file, inst);
1318	if (ret)
1319		return ret;
1320
1321	inst->min_buffer_out = VENC_MIN_BUFFER_OUT;
1322	inst->min_buffer_cap = VENC_MIN_BUFFER_CAP;
1323	venc_init(file);
1324
1325	return 0;
1326}
1327
1328static const struct v4l2_file_operations venc_fops = {
1329	.owner = THIS_MODULE,
1330	.open = venc_open,
1331	.release = vpu_v4l2_close,
1332	.unlocked_ioctl = video_ioctl2,
1333	.poll = v4l2_m2m_fop_poll,
1334	.mmap = v4l2_m2m_fop_mmap,
1335};
1336
1337const struct v4l2_ioctl_ops *venc_get_ioctl_ops(void)
1338{
1339	return &venc_ioctl_ops;
1340}
1341
1342const struct v4l2_file_operations *venc_get_fops(void)
1343{
1344	return &venc_fops;
1345}
1346