cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

venc.c (36302B)


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