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

vdec.c (41450B)


      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/vmalloc.h>
     13#include <linux/videodev2.h>
     14#include <media/v4l2-device.h>
     15#include <media/v4l2-event.h>
     16#include <media/v4l2-mem2mem.h>
     17#include <media/v4l2-ioctl.h>
     18#include <media/videobuf2-v4l2.h>
     19#include <media/videobuf2-dma-contig.h>
     20#include <media/videobuf2-vmalloc.h>
     21#include "vpu.h"
     22#include "vpu_defs.h"
     23#include "vpu_core.h"
     24#include "vpu_helpers.h"
     25#include "vpu_v4l2.h"
     26#include "vpu_cmds.h"
     27#include "vpu_rpc.h"
     28
     29#define VDEC_MIN_BUFFER_CAP		8
     30#define VDEC_MIN_BUFFER_OUT		8
     31
     32struct vdec_fs_info {
     33	char name[8];
     34	u32 type;
     35	u32 max_count;
     36	u32 req_count;
     37	u32 count;
     38	u32 index;
     39	u32 size;
     40	struct vpu_buffer buffer[32];
     41	u32 tag;
     42};
     43
     44struct vdec_t {
     45	u32 seq_hdr_found;
     46	struct vpu_buffer udata;
     47	struct vpu_decode_params params;
     48	struct vpu_dec_codec_info codec_info;
     49	enum vpu_codec_state state;
     50
     51	struct vpu_vb2_buffer *slots[VB2_MAX_FRAME];
     52	u32 req_frame_count;
     53	struct vdec_fs_info mbi;
     54	struct vdec_fs_info dcp;
     55	u32 seq_tag;
     56
     57	bool reset_codec;
     58	bool fixed_fmt;
     59	u32 decoded_frame_count;
     60	u32 display_frame_count;
     61	u32 sequence;
     62	u32 eos_received;
     63	bool is_source_changed;
     64	u32 source_change;
     65	u32 drain;
     66};
     67
     68static const struct vpu_format vdec_formats[] = {
     69	{
     70		.pixfmt = V4L2_PIX_FMT_NV12M_8L128,
     71		.num_planes = 2,
     72		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
     73	},
     74	{
     75		.pixfmt = V4L2_PIX_FMT_NV12M_10BE_8L128,
     76		.num_planes = 2,
     77		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
     78	},
     79	{
     80		.pixfmt = V4L2_PIX_FMT_H264,
     81		.num_planes = 1,
     82		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
     83		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
     84	},
     85	{
     86		.pixfmt = V4L2_PIX_FMT_H264_MVC,
     87		.num_planes = 1,
     88		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
     89		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
     90	},
     91	{
     92		.pixfmt = V4L2_PIX_FMT_HEVC,
     93		.num_planes = 1,
     94		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
     95		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
     96	},
     97	{
     98		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G,
     99		.num_planes = 1,
    100		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
    101		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
    102	},
    103	{
    104		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
    105		.num_planes = 1,
    106		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
    107		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
    108	},
    109	{
    110		.pixfmt = V4L2_PIX_FMT_MPEG2,
    111		.num_planes = 1,
    112		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
    113		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
    114	},
    115	{
    116		.pixfmt = V4L2_PIX_FMT_MPEG4,
    117		.num_planes = 1,
    118		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
    119		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
    120	},
    121	{
    122		.pixfmt = V4L2_PIX_FMT_XVID,
    123		.num_planes = 1,
    124		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
    125		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
    126	},
    127	{
    128		.pixfmt = V4L2_PIX_FMT_VP8,
    129		.num_planes = 1,
    130		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
    131		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
    132	},
    133	{
    134		.pixfmt = V4L2_PIX_FMT_H263,
    135		.num_planes = 1,
    136		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
    137		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
    138	},
    139	{0, 0, 0, 0},
    140};
    141
    142static const struct v4l2_ctrl_ops vdec_ctrl_ops = {
    143	.g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
    144};
    145
    146static int vdec_ctrl_init(struct vpu_inst *inst)
    147{
    148	struct v4l2_ctrl *ctrl;
    149	int ret;
    150
    151	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
    152	if (ret)
    153		return ret;
    154
    155	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
    156				 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
    157	if (ctrl)
    158		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
    159
    160	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
    161				 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
    162	if (ctrl)
    163		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
    164
    165	if (inst->ctrl_handler.error) {
    166		ret = inst->ctrl_handler.error;
    167		v4l2_ctrl_handler_free(&inst->ctrl_handler);
    168		return ret;
    169	}
    170
    171	ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
    172	if (ret) {
    173		dev_err(inst->dev, "[%d] setup ctrls fail, ret = %d\n", inst->id, ret);
    174		v4l2_ctrl_handler_free(&inst->ctrl_handler);
    175		return ret;
    176	}
    177
    178	return 0;
    179}
    180
    181static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst)
    182{
    183	struct vdec_t *vdec = inst->priv;
    184
    185	if (vdec->eos_received) {
    186		if (!vpu_set_last_buffer_dequeued(inst))
    187			vdec->eos_received--;
    188	}
    189}
    190
    191static void vdec_handle_resolution_change(struct vpu_inst *inst)
    192{
    193	struct vdec_t *vdec = inst->priv;
    194	struct vb2_queue *q;
    195
    196	if (!inst->fh.m2m_ctx)
    197		return;
    198
    199	if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
    200		return;
    201	if (!vdec->source_change)
    202		return;
    203
    204	q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
    205	if (!list_empty(&q->done_list))
    206		return;
    207
    208	vdec->source_change--;
    209	vpu_notify_source_change(inst);
    210}
    211
    212static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state, u32 force)
    213{
    214	struct vdec_t *vdec = inst->priv;
    215	enum vpu_codec_state pre_state = inst->state;
    216
    217	if (state == VPU_CODEC_STATE_SEEK) {
    218		if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
    219			vdec->state = inst->state;
    220		else
    221			vdec->state = VPU_CODEC_STATE_ACTIVE;
    222	}
    223	if (inst->state != VPU_CODEC_STATE_SEEK || force)
    224		inst->state = state;
    225	else if (state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
    226		vdec->state = VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE;
    227
    228	if (inst->state != pre_state)
    229		vpu_trace(inst->dev, "[%d] %d -> %d\n", inst->id, pre_state, inst->state);
    230
    231	if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
    232		vdec_handle_resolution_change(inst);
    233
    234	return 0;
    235}
    236
    237static int vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
    238{
    239	strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver));
    240	strscpy(cap->card, "amphion vpu decoder", sizeof(cap->card));
    241	strscpy(cap->bus_info, "platform: amphion-vpu", sizeof(cap->bus_info));
    242
    243	return 0;
    244}
    245
    246static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
    247{
    248	struct vpu_inst *inst = to_inst(file);
    249	struct vdec_t *vdec = inst->priv;
    250	const struct vpu_format *fmt;
    251	int ret = -EINVAL;
    252
    253	vpu_inst_lock(inst);
    254	if (!V4L2_TYPE_IS_OUTPUT(f->type) && vdec->fixed_fmt) {
    255		if (f->index == 0) {
    256			f->pixelformat = inst->cap_format.pixfmt;
    257			f->flags = inst->cap_format.flags;
    258			ret = 0;
    259		}
    260	} else {
    261		fmt = vpu_helper_enum_format(inst, f->type, f->index);
    262		memset(f->reserved, 0, sizeof(f->reserved));
    263		if (!fmt)
    264			goto exit;
    265
    266		f->pixelformat = fmt->pixfmt;
    267		f->flags = fmt->flags;
    268		ret = 0;
    269	}
    270
    271exit:
    272	vpu_inst_unlock(inst);
    273	return ret;
    274}
    275
    276static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
    277{
    278	struct vpu_inst *inst = to_inst(file);
    279	struct vdec_t *vdec = inst->priv;
    280	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
    281	struct vpu_format *cur_fmt;
    282	int i;
    283
    284	cur_fmt = vpu_get_format(inst, f->type);
    285
    286	pixmp->pixelformat = cur_fmt->pixfmt;
    287	pixmp->num_planes = cur_fmt->num_planes;
    288	pixmp->width = cur_fmt->width;
    289	pixmp->height = cur_fmt->height;
    290	pixmp->field = cur_fmt->field;
    291	pixmp->flags = cur_fmt->flags;
    292	for (i = 0; i < pixmp->num_planes; i++) {
    293		pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
    294		pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
    295	}
    296
    297	f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
    298	f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
    299	f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
    300	f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
    301
    302	return 0;
    303}
    304
    305static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
    306{
    307	struct vpu_inst *inst = to_inst(file);
    308	struct vdec_t *vdec = inst->priv;
    309
    310	vpu_try_fmt_common(inst, f);
    311
    312	vpu_inst_lock(inst);
    313	if (vdec->fixed_fmt) {
    314		f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
    315		f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
    316		f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
    317		f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
    318	} else {
    319		f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
    320		f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
    321		f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
    322		f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
    323	}
    324	vpu_inst_unlock(inst);
    325
    326	return 0;
    327}
    328
    329static int vdec_s_fmt_common(struct vpu_inst *inst, struct v4l2_format *f)
    330{
    331	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
    332	const struct vpu_format *fmt;
    333	struct vpu_format *cur_fmt;
    334	struct vb2_queue *q;
    335	struct vdec_t *vdec = inst->priv;
    336	int i;
    337
    338	if (!inst->fh.m2m_ctx)
    339		return -EINVAL;
    340
    341	q = v4l2_m2m_get_vq(inst->fh.m2m_ctx, f->type);
    342	if (!q)
    343		return -EINVAL;
    344	if (vb2_is_busy(q))
    345		return -EBUSY;
    346
    347	fmt = vpu_try_fmt_common(inst, f);
    348	if (!fmt)
    349		return -EINVAL;
    350
    351	cur_fmt = vpu_get_format(inst, f->type);
    352	if (V4L2_TYPE_IS_OUTPUT(f->type) && inst->state != VPU_CODEC_STATE_DEINIT) {
    353		if (cur_fmt->pixfmt != fmt->pixfmt) {
    354			vdec->reset_codec = true;
    355			vdec->fixed_fmt = false;
    356		}
    357	}
    358	cur_fmt->pixfmt = fmt->pixfmt;
    359	if (V4L2_TYPE_IS_OUTPUT(f->type) || !vdec->fixed_fmt) {
    360		cur_fmt->num_planes = fmt->num_planes;
    361		cur_fmt->flags = fmt->flags;
    362		cur_fmt->width = pixmp->width;
    363		cur_fmt->height = pixmp->height;
    364		for (i = 0; i < fmt->num_planes; i++) {
    365			cur_fmt->sizeimage[i] = pixmp->plane_fmt[i].sizeimage;
    366			cur_fmt->bytesperline[i] = pixmp->plane_fmt[i].bytesperline;
    367		}
    368		if (pixmp->field != V4L2_FIELD_ANY)
    369			cur_fmt->field = pixmp->field;
    370	} else {
    371		pixmp->num_planes = cur_fmt->num_planes;
    372		pixmp->width = cur_fmt->width;
    373		pixmp->height = cur_fmt->height;
    374		for (i = 0; i < pixmp->num_planes; i++) {
    375			pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
    376			pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
    377		}
    378		pixmp->field = cur_fmt->field;
    379	}
    380
    381	if (!vdec->fixed_fmt) {
    382		if (V4L2_TYPE_IS_OUTPUT(f->type)) {
    383			vdec->params.codec_format = cur_fmt->pixfmt;
    384			vdec->codec_info.color_primaries = f->fmt.pix_mp.colorspace;
    385			vdec->codec_info.transfer_chars = f->fmt.pix_mp.xfer_func;
    386			vdec->codec_info.matrix_coeffs = f->fmt.pix_mp.ycbcr_enc;
    387			vdec->codec_info.full_range = f->fmt.pix_mp.quantization;
    388		} else {
    389			vdec->params.output_format = cur_fmt->pixfmt;
    390			inst->crop.left = 0;
    391			inst->crop.top = 0;
    392			inst->crop.width = cur_fmt->width;
    393			inst->crop.height = cur_fmt->height;
    394		}
    395	}
    396
    397	vpu_trace(inst->dev, "[%d] %c%c%c%c %dx%d\n", inst->id,
    398		  f->fmt.pix_mp.pixelformat,
    399		  f->fmt.pix_mp.pixelformat >> 8,
    400		  f->fmt.pix_mp.pixelformat >> 16,
    401		  f->fmt.pix_mp.pixelformat >> 24,
    402		  f->fmt.pix_mp.width,
    403		  f->fmt.pix_mp.height);
    404
    405	return 0;
    406}
    407
    408static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
    409{
    410	struct vpu_inst *inst = to_inst(file);
    411	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
    412	struct vdec_t *vdec = inst->priv;
    413	int ret = 0;
    414
    415	vpu_inst_lock(inst);
    416	ret = vdec_s_fmt_common(inst, f);
    417	if (ret)
    418		goto exit;
    419
    420	if (V4L2_TYPE_IS_OUTPUT(f->type) && !vdec->fixed_fmt) {
    421		struct v4l2_format fc;
    422
    423		memset(&fc, 0, sizeof(fc));
    424		fc.type = inst->cap_format.type;
    425		fc.fmt.pix_mp.pixelformat = inst->cap_format.pixfmt;
    426		fc.fmt.pix_mp.width = pixmp->width;
    427		fc.fmt.pix_mp.height = pixmp->height;
    428		vdec_s_fmt_common(inst, &fc);
    429	}
    430
    431	f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
    432	f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
    433	f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
    434	f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
    435
    436exit:
    437	vpu_inst_unlock(inst);
    438	return ret;
    439}
    440
    441static int vdec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
    442{
    443	struct vpu_inst *inst = to_inst(file);
    444
    445	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
    446		return -EINVAL;
    447
    448	switch (s->target) {
    449	case V4L2_SEL_TGT_COMPOSE:
    450	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
    451	case V4L2_SEL_TGT_COMPOSE_PADDED:
    452		s->r = inst->crop;
    453		break;
    454	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
    455		s->r.left = 0;
    456		s->r.top = 0;
    457		s->r.width = inst->cap_format.width;
    458		s->r.height = inst->cap_format.height;
    459		break;
    460	default:
    461		return -EINVAL;
    462	}
    463
    464	return 0;
    465}
    466
    467static int vdec_drain(struct vpu_inst *inst)
    468{
    469	struct vdec_t *vdec = inst->priv;
    470
    471	if (!inst->fh.m2m_ctx)
    472		return 0;
    473
    474	if (!vdec->drain)
    475		return 0;
    476
    477	if (!vpu_is_source_empty(inst))
    478		return 0;
    479
    480	if (!vdec->params.frame_count) {
    481		vpu_set_last_buffer_dequeued(inst);
    482		return 0;
    483	}
    484
    485	vpu_iface_add_scode(inst, SCODE_PADDING_EOS);
    486	vdec->params.end_flag = 1;
    487	vpu_iface_set_decode_params(inst, &vdec->params, 1);
    488	vdec->drain = 0;
    489	vpu_trace(inst->dev, "[%d] frame_count = %d\n", inst->id, vdec->params.frame_count);
    490
    491	return 0;
    492}
    493
    494static int vdec_cmd_start(struct vpu_inst *inst)
    495{
    496	switch (inst->state) {
    497	case VPU_CODEC_STATE_STARTED:
    498	case VPU_CODEC_STATE_DRAIN:
    499	case VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE:
    500		vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0);
    501		break;
    502	default:
    503		break;
    504	}
    505	vpu_process_capture_buffer(inst);
    506	return 0;
    507}
    508
    509static int vdec_cmd_stop(struct vpu_inst *inst)
    510{
    511	struct vdec_t *vdec = inst->priv;
    512
    513	vpu_trace(inst->dev, "[%d]\n", inst->id);
    514
    515	if (inst->state == VPU_CODEC_STATE_DEINIT) {
    516		vpu_set_last_buffer_dequeued(inst);
    517	} else {
    518		vdec->drain = 1;
    519		vdec_drain(inst);
    520	}
    521
    522	return 0;
    523}
    524
    525static int vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
    526{
    527	struct vpu_inst *inst = to_inst(file);
    528	int ret;
    529
    530	ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
    531	if (ret)
    532		return ret;
    533
    534	vpu_inst_lock(inst);
    535	switch (cmd->cmd) {
    536	case V4L2_DEC_CMD_START:
    537		vdec_cmd_start(inst);
    538		break;
    539	case V4L2_DEC_CMD_STOP:
    540		vdec_cmd_stop(inst);
    541		break;
    542	default:
    543		break;
    544	}
    545	vpu_inst_unlock(inst);
    546
    547	return 0;
    548}
    549
    550static int vdec_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
    551{
    552	switch (sub->type) {
    553	case V4L2_EVENT_EOS:
    554		return v4l2_event_subscribe(fh, sub, 0, NULL);
    555	case V4L2_EVENT_SOURCE_CHANGE:
    556		return v4l2_src_change_event_subscribe(fh, sub);
    557	case V4L2_EVENT_CTRL:
    558		return v4l2_ctrl_subscribe_event(fh, sub);
    559	default:
    560		return -EINVAL;
    561	}
    562
    563	return 0;
    564}
    565
    566static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
    567	.vidioc_querycap               = vdec_querycap,
    568	.vidioc_enum_fmt_vid_cap       = vdec_enum_fmt,
    569	.vidioc_enum_fmt_vid_out       = vdec_enum_fmt,
    570	.vidioc_g_fmt_vid_cap_mplane   = vdec_g_fmt,
    571	.vidioc_g_fmt_vid_out_mplane   = vdec_g_fmt,
    572	.vidioc_try_fmt_vid_cap_mplane = vdec_try_fmt,
    573	.vidioc_try_fmt_vid_out_mplane = vdec_try_fmt,
    574	.vidioc_s_fmt_vid_cap_mplane   = vdec_s_fmt,
    575	.vidioc_s_fmt_vid_out_mplane   = vdec_s_fmt,
    576	.vidioc_g_selection            = vdec_g_selection,
    577	.vidioc_try_decoder_cmd        = v4l2_m2m_ioctl_try_decoder_cmd,
    578	.vidioc_decoder_cmd            = vdec_decoder_cmd,
    579	.vidioc_subscribe_event        = vdec_subscribe_event,
    580	.vidioc_unsubscribe_event      = v4l2_event_unsubscribe,
    581	.vidioc_reqbufs                = v4l2_m2m_ioctl_reqbufs,
    582	.vidioc_create_bufs	       = v4l2_m2m_ioctl_create_bufs,
    583	.vidioc_prepare_buf	       = v4l2_m2m_ioctl_prepare_buf,
    584	.vidioc_querybuf               = v4l2_m2m_ioctl_querybuf,
    585	.vidioc_qbuf                   = v4l2_m2m_ioctl_qbuf,
    586	.vidioc_expbuf                 = v4l2_m2m_ioctl_expbuf,
    587	.vidioc_dqbuf                  = v4l2_m2m_ioctl_dqbuf,
    588	.vidioc_streamon               = v4l2_m2m_ioctl_streamon,
    589	.vidioc_streamoff              = v4l2_m2m_ioctl_streamoff,
    590};
    591
    592static bool vdec_check_ready(struct vpu_inst *inst, unsigned int type)
    593{
    594	struct vdec_t *vdec = inst->priv;
    595
    596	if (V4L2_TYPE_IS_OUTPUT(type))
    597		return true;
    598
    599	if (vdec->req_frame_count)
    600		return true;
    601
    602	return false;
    603}
    604
    605static struct vb2_v4l2_buffer *vdec_get_src_buffer(struct vpu_inst *inst, u32 count)
    606{
    607	if (count > 1)
    608		vpu_skip_frame(inst, count - 1);
    609
    610	return vpu_next_src_buf(inst);
    611}
    612
    613static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
    614{
    615	struct vdec_t *vdec = inst->priv;
    616	struct vpu_dec_pic_info *info = arg;
    617	struct vpu_vb2_buffer *vpu_buf;
    618	struct vb2_v4l2_buffer *vbuf;
    619	struct vb2_v4l2_buffer *src_buf;
    620	int ret = 0;
    621
    622	if (!info || info->id >= ARRAY_SIZE(vdec->slots))
    623		return -EINVAL;
    624
    625	vpu_inst_lock(inst);
    626	vpu_buf = vdec->slots[info->id];
    627	if (!vpu_buf) {
    628		dev_err(inst->dev, "[%d] decoded invalid frame[%d]\n", inst->id, info->id);
    629		ret = -EINVAL;
    630		goto exit;
    631	}
    632	vbuf = &vpu_buf->m2m_buf.vb;
    633	src_buf = vdec_get_src_buffer(inst, info->consumed_count);
    634	if (src_buf) {
    635		v4l2_m2m_buf_copy_metadata(src_buf, vbuf, true);
    636		if (info->consumed_count) {
    637			v4l2_m2m_src_buf_remove(inst->fh.m2m_ctx);
    638			vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE);
    639			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
    640		} else {
    641			vpu_set_buffer_state(src_buf, VPU_BUF_STATE_DECODED);
    642		}
    643	}
    644	if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED)
    645		dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id);
    646	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED);
    647	vdec->decoded_frame_count++;
    648exit:
    649	vpu_inst_unlock(inst);
    650
    651	return ret;
    652}
    653
    654static struct vpu_vb2_buffer *vdec_find_buffer(struct vpu_inst *inst, u32 luma)
    655{
    656	struct vdec_t *vdec = inst->priv;
    657	int i;
    658
    659	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
    660		if (!vdec->slots[i])
    661			continue;
    662		if (luma == vdec->slots[i]->luma)
    663			return vdec->slots[i];
    664	}
    665
    666	return NULL;
    667}
    668
    669static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
    670{
    671	struct vdec_t *vdec = inst->priv;
    672	struct vpu_vb2_buffer *vpu_buf;
    673	struct vb2_v4l2_buffer *vbuf;
    674	u32 sequence;
    675
    676	if (!frame)
    677		return;
    678
    679	vpu_inst_lock(inst);
    680	sequence = vdec->sequence++;
    681	vpu_buf = vdec_find_buffer(inst, frame->luma);
    682	vpu_inst_unlock(inst);
    683	if (!vpu_buf) {
    684		dev_err(inst->dev, "[%d] can't find buffer, id = %d, addr = 0x%x\n",
    685			inst->id, frame->id, frame->luma);
    686		return;
    687	}
    688	if (frame->skipped) {
    689		dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);
    690		return;
    691	}
    692
    693	vbuf = &vpu_buf->m2m_buf.vb;
    694	if (vbuf->vb2_buf.index != frame->id)
    695		dev_err(inst->dev, "[%d] buffer id(%d, %d) dismatch\n",
    696			inst->id, vbuf->vb2_buf.index, frame->id);
    697
    698	if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_DECODED)
    699		dev_err(inst->dev, "[%d] buffer(%d) ready without decoded\n", inst->id, frame->id);
    700	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);
    701	vb2_set_plane_payload(&vbuf->vb2_buf, 0, inst->cap_format.sizeimage[0]);
    702	vb2_set_plane_payload(&vbuf->vb2_buf, 1, inst->cap_format.sizeimage[1]);
    703	vbuf->field = inst->cap_format.field;
    704	vbuf->sequence = sequence;
    705	dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
    706
    707	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
    708	vpu_inst_lock(inst);
    709	vdec->display_frame_count++;
    710	vpu_inst_unlock(inst);
    711	dev_dbg(inst->dev, "[%d] decoded : %d, display : %d, sequence : %d\n",
    712		inst->id, vdec->decoded_frame_count, vdec->display_frame_count, vdec->sequence);
    713}
    714
    715static void vdec_stop_done(struct vpu_inst *inst)
    716{
    717	struct vdec_t *vdec = inst->priv;
    718
    719	vpu_inst_lock(inst);
    720	vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 0);
    721	vdec->seq_hdr_found = 0;
    722	vdec->req_frame_count = 0;
    723	vdec->reset_codec = false;
    724	vdec->fixed_fmt = false;
    725	vdec->params.end_flag = 0;
    726	vdec->drain = 0;
    727	vdec->params.frame_count = 0;
    728	vdec->decoded_frame_count = 0;
    729	vdec->display_frame_count = 0;
    730	vdec->sequence = 0;
    731	vdec->eos_received = 0;
    732	vdec->is_source_changed = false;
    733	vdec->source_change = 0;
    734	vpu_inst_unlock(inst);
    735}
    736
    737static bool vdec_check_source_change(struct vpu_inst *inst)
    738{
    739	struct vdec_t *vdec = inst->priv;
    740	const struct vpu_format *fmt;
    741	int i;
    742
    743	if (!inst->fh.m2m_ctx)
    744		return false;
    745
    746	if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx)))
    747		return true;
    748	fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
    749	if (inst->cap_format.pixfmt != vdec->codec_info.pixfmt)
    750		return true;
    751	if (inst->cap_format.width != vdec->codec_info.decoded_width)
    752		return true;
    753	if (inst->cap_format.height != vdec->codec_info.decoded_height)
    754		return true;
    755	if (vpu_get_num_buffers(inst, inst->cap_format.type) < inst->min_buffer_cap)
    756		return true;
    757	if (inst->crop.left != vdec->codec_info.offset_x)
    758		return true;
    759	if (inst->crop.top != vdec->codec_info.offset_y)
    760		return true;
    761	if (inst->crop.width != vdec->codec_info.width)
    762		return true;
    763	if (inst->crop.height != vdec->codec_info.height)
    764		return true;
    765	if (fmt && inst->cap_format.num_planes != fmt->num_planes)
    766		return true;
    767	for (i = 0; i < inst->cap_format.num_planes; i++) {
    768		if (inst->cap_format.bytesperline[i] != vdec->codec_info.bytesperline[i])
    769			return true;
    770		if (inst->cap_format.sizeimage[i] != vdec->codec_info.sizeimage[i])
    771			return true;
    772	}
    773
    774	return false;
    775}
    776
    777static void vdec_init_fmt(struct vpu_inst *inst)
    778{
    779	struct vdec_t *vdec = inst->priv;
    780	const struct vpu_format *fmt;
    781	int i;
    782
    783	fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
    784	inst->out_format.width = vdec->codec_info.width;
    785	inst->out_format.height = vdec->codec_info.height;
    786	inst->cap_format.width = vdec->codec_info.decoded_width;
    787	inst->cap_format.height = vdec->codec_info.decoded_height;
    788	inst->cap_format.pixfmt = vdec->codec_info.pixfmt;
    789	if (fmt) {
    790		inst->cap_format.num_planes = fmt->num_planes;
    791		inst->cap_format.flags = fmt->flags;
    792	}
    793	for (i = 0; i < inst->cap_format.num_planes; i++) {
    794		inst->cap_format.bytesperline[i] = vdec->codec_info.bytesperline[i];
    795		inst->cap_format.sizeimage[i] = vdec->codec_info.sizeimage[i];
    796	}
    797	if (vdec->codec_info.progressive)
    798		inst->cap_format.field = V4L2_FIELD_NONE;
    799	else
    800		inst->cap_format.field = V4L2_FIELD_SEQ_TB;
    801	if (vdec->codec_info.color_primaries == V4L2_COLORSPACE_DEFAULT)
    802		vdec->codec_info.color_primaries = V4L2_COLORSPACE_REC709;
    803	if (vdec->codec_info.transfer_chars == V4L2_XFER_FUNC_DEFAULT)
    804		vdec->codec_info.transfer_chars = V4L2_XFER_FUNC_709;
    805	if (vdec->codec_info.matrix_coeffs == V4L2_YCBCR_ENC_DEFAULT)
    806		vdec->codec_info.matrix_coeffs = V4L2_YCBCR_ENC_709;
    807	if (vdec->codec_info.full_range == V4L2_QUANTIZATION_DEFAULT)
    808		vdec->codec_info.full_range = V4L2_QUANTIZATION_LIM_RANGE;
    809}
    810
    811static void vdec_init_crop(struct vpu_inst *inst)
    812{
    813	struct vdec_t *vdec = inst->priv;
    814
    815	inst->crop.left = vdec->codec_info.offset_x;
    816	inst->crop.top = vdec->codec_info.offset_y;
    817	inst->crop.width = vdec->codec_info.width;
    818	inst->crop.height = vdec->codec_info.height;
    819}
    820
    821static void vdec_init_mbi(struct vpu_inst *inst)
    822{
    823	struct vdec_t *vdec = inst->priv;
    824
    825	vdec->mbi.size = vdec->codec_info.mbi_size;
    826	vdec->mbi.max_count = ARRAY_SIZE(vdec->mbi.buffer);
    827	scnprintf(vdec->mbi.name, sizeof(vdec->mbi.name), "mbi");
    828	vdec->mbi.type = MEM_RES_MBI;
    829	vdec->mbi.tag = vdec->seq_tag;
    830}
    831
    832static void vdec_init_dcp(struct vpu_inst *inst)
    833{
    834	struct vdec_t *vdec = inst->priv;
    835
    836	vdec->dcp.size = vdec->codec_info.dcp_size;
    837	vdec->dcp.max_count = ARRAY_SIZE(vdec->dcp.buffer);
    838	scnprintf(vdec->dcp.name, sizeof(vdec->dcp.name), "dcp");
    839	vdec->dcp.type = MEM_RES_DCP;
    840	vdec->dcp.tag = vdec->seq_tag;
    841}
    842
    843static void vdec_request_one_fs(struct vdec_fs_info *fs)
    844{
    845	fs->req_count++;
    846	if (fs->req_count > fs->max_count)
    847		fs->req_count = fs->max_count;
    848}
    849
    850static int vdec_alloc_fs_buffer(struct vpu_inst *inst, struct vdec_fs_info *fs)
    851{
    852	struct vpu_buffer *buffer;
    853
    854	if (!fs->size)
    855		return -EINVAL;
    856
    857	if (fs->count >= fs->req_count)
    858		return -EINVAL;
    859
    860	buffer = &fs->buffer[fs->count];
    861	if (buffer->virt && buffer->length >= fs->size)
    862		return 0;
    863
    864	vpu_free_dma(buffer);
    865	buffer->length = fs->size;
    866	return vpu_alloc_dma(inst->core, buffer);
    867}
    868
    869static void vdec_alloc_fs(struct vpu_inst *inst, struct vdec_fs_info *fs)
    870{
    871	int ret;
    872
    873	while (fs->count < fs->req_count) {
    874		ret = vdec_alloc_fs_buffer(inst, fs);
    875		if (ret)
    876			break;
    877		fs->count++;
    878	}
    879}
    880
    881static void vdec_clear_fs(struct vdec_fs_info *fs)
    882{
    883	u32 i;
    884
    885	if (!fs)
    886		return;
    887
    888	for (i = 0; i < ARRAY_SIZE(fs->buffer); i++)
    889		vpu_free_dma(&fs->buffer[i]);
    890	memset(fs, 0, sizeof(*fs));
    891}
    892
    893static int vdec_response_fs(struct vpu_inst *inst, struct vdec_fs_info *fs)
    894{
    895	struct vpu_fs_info info;
    896	int ret;
    897
    898	if (fs->index >= fs->count)
    899		return 0;
    900
    901	memset(&info, 0, sizeof(info));
    902	info.id = fs->index;
    903	info.type = fs->type;
    904	info.tag = fs->tag;
    905	info.luma_addr = fs->buffer[fs->index].phys;
    906	info.luma_size = fs->buffer[fs->index].length;
    907	ret = vpu_session_alloc_fs(inst, &info);
    908	if (ret)
    909		return ret;
    910
    911	fs->index++;
    912	return 0;
    913}
    914
    915static int vdec_response_frame_abnormal(struct vpu_inst *inst)
    916{
    917	struct vdec_t *vdec = inst->priv;
    918	struct vpu_fs_info info;
    919
    920	if (!vdec->req_frame_count)
    921		return 0;
    922
    923	memset(&info, 0, sizeof(info));
    924	info.type = MEM_RES_FRAME;
    925	info.tag = vdec->seq_tag + 0xf0;
    926	vpu_session_alloc_fs(inst, &info);
    927	vdec->req_frame_count--;
    928
    929	return 0;
    930}
    931
    932static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf)
    933{
    934	struct vdec_t *vdec = inst->priv;
    935	struct vpu_vb2_buffer *vpu_buf;
    936	struct vpu_fs_info info;
    937	int ret;
    938
    939	if (inst->state != VPU_CODEC_STATE_ACTIVE)
    940		return -EINVAL;
    941
    942	if (!vdec->req_frame_count)
    943		return -EINVAL;
    944
    945	if (!vbuf)
    946		return -EINVAL;
    947
    948	if (vdec->slots[vbuf->vb2_buf.index]) {
    949		dev_err(inst->dev, "[%d] repeat alloc fs %d\n",
    950			inst->id, vbuf->vb2_buf.index);
    951		return -EINVAL;
    952	}
    953
    954	dev_dbg(inst->dev, "[%d] state = %d, alloc fs %d, tag = 0x%x\n",
    955		inst->id, inst->state, vbuf->vb2_buf.index, vdec->seq_tag);
    956	vpu_buf = to_vpu_vb2_buffer(vbuf);
    957
    958	memset(&info, 0, sizeof(info));
    959	info.id = vbuf->vb2_buf.index;
    960	info.type = MEM_RES_FRAME;
    961	info.tag = vdec->seq_tag;
    962	info.luma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 0);
    963	info.luma_size = inst->cap_format.sizeimage[0];
    964	info.chroma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 1);
    965	info.chromau_size = inst->cap_format.sizeimage[1];
    966	info.bytesperline = inst->cap_format.bytesperline[0];
    967	ret = vpu_session_alloc_fs(inst, &info);
    968	if (ret)
    969		return ret;
    970
    971	vpu_buf->tag = info.tag;
    972	vpu_buf->luma = info.luma_addr;
    973	vpu_buf->chroma_u = info.chromau_size;
    974	vpu_buf->chroma_v = 0;
    975	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
    976	vdec->slots[info.id] = vpu_buf;
    977	vdec->req_frame_count--;
    978
    979	return 0;
    980}
    981
    982static void vdec_response_fs_request(struct vpu_inst *inst, bool force)
    983{
    984	struct vdec_t *vdec = inst->priv;
    985	int i;
    986	int ret;
    987
    988	if (force) {
    989		for (i = vdec->req_frame_count; i > 0; i--)
    990			vdec_response_frame_abnormal(inst);
    991		return;
    992	}
    993
    994	for (i = vdec->req_frame_count; i > 0; i--) {
    995		ret = vpu_process_capture_buffer(inst);
    996		if (ret)
    997			break;
    998		if (vdec->eos_received)
    999			break;
   1000	}
   1001
   1002	for (i = vdec->mbi.index; i < vdec->mbi.count; i++) {
   1003		if (vdec_response_fs(inst, &vdec->mbi))
   1004			break;
   1005		if (vdec->eos_received)
   1006			break;
   1007	}
   1008	for (i = vdec->dcp.index; i < vdec->dcp.count; i++) {
   1009		if (vdec_response_fs(inst, &vdec->dcp))
   1010			break;
   1011		if (vdec->eos_received)
   1012			break;
   1013	}
   1014}
   1015
   1016static void vdec_response_fs_release(struct vpu_inst *inst, u32 id, u32 tag)
   1017{
   1018	struct vpu_fs_info info;
   1019
   1020	memset(&info, 0, sizeof(info));
   1021	info.id = id;
   1022	info.tag = tag;
   1023	vpu_session_release_fs(inst, &info);
   1024}
   1025
   1026static void vdec_recycle_buffer(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf)
   1027{
   1028	if (!inst->fh.m2m_ctx)
   1029		return;
   1030	if (vbuf->vb2_buf.state != VB2_BUF_STATE_ACTIVE)
   1031		return;
   1032	if (vpu_find_buf_by_idx(inst, vbuf->vb2_buf.type, vbuf->vb2_buf.index))
   1033		return;
   1034	v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf);
   1035}
   1036
   1037static void vdec_clear_slots(struct vpu_inst *inst)
   1038{
   1039	struct vdec_t *vdec = inst->priv;
   1040	struct vpu_vb2_buffer *vpu_buf;
   1041	struct vb2_v4l2_buffer *vbuf;
   1042	int i;
   1043
   1044	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
   1045		if (!vdec->slots[i])
   1046			continue;
   1047
   1048		vpu_buf = vdec->slots[i];
   1049		vbuf = &vpu_buf->m2m_buf.vb;
   1050
   1051		vdec_recycle_buffer(inst, vbuf);
   1052		vdec->slots[i]->state = VPU_BUF_STATE_IDLE;
   1053		vdec->slots[i] = NULL;
   1054	}
   1055}
   1056
   1057static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info *hdr)
   1058{
   1059	struct vdec_t *vdec = inst->priv;
   1060
   1061	vpu_inst_lock(inst);
   1062	memcpy(&vdec->codec_info, hdr, sizeof(vdec->codec_info));
   1063
   1064	vpu_trace(inst->dev, "[%d] %d x %d, crop : (%d, %d) %d x %d, %d, %d\n",
   1065		  inst->id,
   1066		  vdec->codec_info.decoded_width,
   1067		  vdec->codec_info.decoded_height,
   1068		  vdec->codec_info.offset_x,
   1069		  vdec->codec_info.offset_y,
   1070		  vdec->codec_info.width,
   1071		  vdec->codec_info.height,
   1072		  hdr->num_ref_frms,
   1073		  hdr->num_dpb_frms);
   1074	inst->min_buffer_cap = hdr->num_ref_frms + hdr->num_dpb_frms;
   1075	vdec->is_source_changed = vdec_check_source_change(inst);
   1076	vdec_init_fmt(inst);
   1077	vdec_init_crop(inst);
   1078	vdec_init_mbi(inst);
   1079	vdec_init_dcp(inst);
   1080	if (!vdec->seq_hdr_found) {
   1081		vdec->seq_tag = vdec->codec_info.tag;
   1082		if (vdec->is_source_changed) {
   1083			vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
   1084			vpu_notify_source_change(inst);
   1085			vdec->is_source_changed = false;
   1086		}
   1087	}
   1088	if (vdec->seq_tag != vdec->codec_info.tag) {
   1089		vdec_response_fs_request(inst, true);
   1090		vpu_trace(inst->dev, "[%d] seq tag change: %d -> %d\n",
   1091			  inst->id, vdec->seq_tag, vdec->codec_info.tag);
   1092	}
   1093	vdec->seq_hdr_found++;
   1094	vdec->fixed_fmt = true;
   1095	vpu_inst_unlock(inst);
   1096}
   1097
   1098static void vdec_event_resolution_change(struct vpu_inst *inst)
   1099{
   1100	struct vdec_t *vdec = inst->priv;
   1101
   1102	vpu_trace(inst->dev, "[%d]\n", inst->id);
   1103	vpu_inst_lock(inst);
   1104	vdec->seq_tag = vdec->codec_info.tag;
   1105	vdec_clear_fs(&vdec->mbi);
   1106	vdec_clear_fs(&vdec->dcp);
   1107	vdec_clear_slots(inst);
   1108	vdec_init_mbi(inst);
   1109	vdec_init_dcp(inst);
   1110	if (vdec->is_source_changed) {
   1111		vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
   1112		vdec->source_change++;
   1113		vdec_handle_resolution_change(inst);
   1114		vdec->is_source_changed = false;
   1115	}
   1116	vpu_inst_unlock(inst);
   1117}
   1118
   1119static void vdec_event_req_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
   1120{
   1121	struct vdec_t *vdec = inst->priv;
   1122
   1123	if (!fs)
   1124		return;
   1125
   1126	vpu_inst_lock(inst);
   1127
   1128	switch (fs->type) {
   1129	case MEM_RES_FRAME:
   1130		vdec->req_frame_count++;
   1131		break;
   1132	case MEM_RES_MBI:
   1133		vdec_request_one_fs(&vdec->mbi);
   1134		break;
   1135	case MEM_RES_DCP:
   1136		vdec_request_one_fs(&vdec->dcp);
   1137		break;
   1138	default:
   1139		break;
   1140	}
   1141
   1142	vdec_alloc_fs(inst, &vdec->mbi);
   1143	vdec_alloc_fs(inst, &vdec->dcp);
   1144
   1145	vdec_response_fs_request(inst, false);
   1146
   1147	vpu_inst_unlock(inst);
   1148}
   1149
   1150static void vdec_evnet_rel_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
   1151{
   1152	struct vdec_t *vdec = inst->priv;
   1153	struct vpu_vb2_buffer *vpu_buf;
   1154	struct vb2_v4l2_buffer *vbuf;
   1155
   1156	if (!fs || fs->id >= ARRAY_SIZE(vdec->slots))
   1157		return;
   1158	if (fs->type != MEM_RES_FRAME)
   1159		return;
   1160
   1161	if (fs->id >= vpu_get_num_buffers(inst, inst->cap_format.type)) {
   1162		dev_err(inst->dev, "[%d] invalid fs(%d) to release\n", inst->id, fs->id);
   1163		return;
   1164	}
   1165
   1166	vpu_inst_lock(inst);
   1167	vpu_buf = vdec->slots[fs->id];
   1168	vdec->slots[fs->id] = NULL;
   1169
   1170	if (!vpu_buf) {
   1171		dev_dbg(inst->dev, "[%d] fs[%d] has bee released\n", inst->id, fs->id);
   1172		goto exit;
   1173	}
   1174
   1175	vbuf = &vpu_buf->m2m_buf.vb;
   1176	if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED) {
   1177		dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);
   1178		vdec->sequence++;
   1179	}
   1180
   1181	vdec_response_fs_release(inst, fs->id, vpu_buf->tag);
   1182	if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_READY)
   1183		vdec_recycle_buffer(inst, vbuf);
   1184
   1185	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
   1186	vpu_process_capture_buffer(inst);
   1187
   1188exit:
   1189	vpu_inst_unlock(inst);
   1190}
   1191
   1192static void vdec_event_eos(struct vpu_inst *inst)
   1193{
   1194	struct vdec_t *vdec = inst->priv;
   1195
   1196	vpu_trace(inst->dev, "[%d] input : %d, decoded : %d, display : %d, sequence : %d\n",
   1197		  inst->id,
   1198		  vdec->params.frame_count,
   1199		  vdec->decoded_frame_count,
   1200		  vdec->display_frame_count,
   1201		  vdec->sequence);
   1202	vpu_inst_lock(inst);
   1203	vdec->eos_received++;
   1204	vdec->fixed_fmt = false;
   1205	inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
   1206	vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0);
   1207	vdec_set_last_buffer_dequeued(inst);
   1208	vpu_inst_unlock(inst);
   1209}
   1210
   1211static void vdec_event_notify(struct vpu_inst *inst, u32 event, void *data)
   1212{
   1213	switch (event) {
   1214	case VPU_MSG_ID_SEQ_HDR_FOUND:
   1215		vdec_event_seq_hdr(inst, data);
   1216		break;
   1217	case VPU_MSG_ID_RES_CHANGE:
   1218		vdec_event_resolution_change(inst);
   1219		break;
   1220	case VPU_MSG_ID_FRAME_REQ:
   1221		vdec_event_req_fs(inst, data);
   1222		break;
   1223	case VPU_MSG_ID_FRAME_RELEASE:
   1224		vdec_evnet_rel_fs(inst, data);
   1225		break;
   1226	case VPU_MSG_ID_PIC_EOS:
   1227		vdec_event_eos(inst);
   1228		break;
   1229	default:
   1230		break;
   1231	}
   1232}
   1233
   1234static int vdec_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
   1235{
   1236	struct vdec_t *vdec = inst->priv;
   1237	struct vb2_v4l2_buffer *vbuf;
   1238	struct vpu_rpc_buffer_desc desc;
   1239	u32 free_space;
   1240	int ret;
   1241
   1242	vbuf = to_vb2_v4l2_buffer(vb);
   1243	dev_dbg(inst->dev, "[%d] dec output [%d] %d : %ld\n",
   1244		inst->id, vbuf->sequence, vb->index, vb2_get_plane_payload(vb, 0));
   1245
   1246	if (inst->state == VPU_CODEC_STATE_DEINIT)
   1247		return -EINVAL;
   1248	if (vdec->reset_codec)
   1249		return -EINVAL;
   1250
   1251	if (inst->state == VPU_CODEC_STATE_STARTED)
   1252		vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0);
   1253
   1254	ret = vpu_iface_get_stream_buffer_desc(inst, &desc);
   1255	if (ret)
   1256		return ret;
   1257
   1258	free_space = vpu_helper_get_free_space(inst);
   1259	if (free_space < vb2_get_plane_payload(vb, 0) + 0x40000)
   1260		return -ENOMEM;
   1261
   1262	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
   1263	ret = vpu_iface_input_frame(inst, vb);
   1264	if (ret < 0)
   1265		return -ENOMEM;
   1266
   1267	dev_dbg(inst->dev, "[%d][INPUT  TS]%32lld\n", inst->id, vb->timestamp);
   1268	vdec->params.frame_count++;
   1269
   1270	if (vdec->drain)
   1271		vdec_drain(inst);
   1272
   1273	return 0;
   1274}
   1275
   1276static int vdec_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
   1277{
   1278	struct vdec_t *vdec = inst->priv;
   1279	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
   1280	int ret;
   1281
   1282	if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
   1283		return -EINVAL;
   1284	if (vdec->reset_codec)
   1285		return -EINVAL;
   1286
   1287	ret = vdec_response_frame(inst, vbuf);
   1288	if (ret)
   1289		return ret;
   1290	v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
   1291	return 0;
   1292}
   1293
   1294static void vdec_on_queue_empty(struct vpu_inst *inst, u32 type)
   1295{
   1296	struct vdec_t *vdec = inst->priv;
   1297
   1298	if (V4L2_TYPE_IS_OUTPUT(type))
   1299		return;
   1300
   1301	vdec_handle_resolution_change(inst);
   1302	if (vdec->eos_received)
   1303		vdec_set_last_buffer_dequeued(inst);
   1304}
   1305
   1306static void vdec_abort(struct vpu_inst *inst)
   1307{
   1308	struct vdec_t *vdec = inst->priv;
   1309	struct vpu_rpc_buffer_desc desc;
   1310	int ret;
   1311
   1312	vpu_trace(inst->dev, "[%d] state = %d\n", inst->id, inst->state);
   1313	vpu_iface_add_scode(inst, SCODE_PADDING_ABORT);
   1314	vdec->params.end_flag = 1;
   1315	vpu_iface_set_decode_params(inst, &vdec->params, 1);
   1316
   1317	vpu_session_abort(inst);
   1318
   1319	ret = vpu_iface_get_stream_buffer_desc(inst, &desc);
   1320	if (!ret)
   1321		vpu_iface_update_stream_buffer(inst, desc.rptr, 1);
   1322
   1323	vpu_session_rst_buf(inst);
   1324	vpu_trace(inst->dev, "[%d] input : %d, decoded : %d, display : %d, sequence : %d\n",
   1325		  inst->id,
   1326		  vdec->params.frame_count,
   1327		  vdec->decoded_frame_count,
   1328		  vdec->display_frame_count,
   1329		  vdec->sequence);
   1330	vdec->params.end_flag = 0;
   1331	vdec->drain = 0;
   1332	vdec->params.frame_count = 0;
   1333	vdec->decoded_frame_count = 0;
   1334	vdec->display_frame_count = 0;
   1335	vdec->sequence = 0;
   1336}
   1337
   1338static void vdec_stop(struct vpu_inst *inst, bool free)
   1339{
   1340	struct vdec_t *vdec = inst->priv;
   1341
   1342	vdec_clear_slots(inst);
   1343	if (inst->state != VPU_CODEC_STATE_DEINIT)
   1344		vpu_session_stop(inst);
   1345	vdec_clear_fs(&vdec->mbi);
   1346	vdec_clear_fs(&vdec->dcp);
   1347	if (free) {
   1348		vpu_free_dma(&vdec->udata);
   1349		vpu_free_dma(&inst->stream_buffer);
   1350	}
   1351	vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 1);
   1352	vdec->reset_codec = false;
   1353}
   1354
   1355static void vdec_release(struct vpu_inst *inst)
   1356{
   1357	if (inst->id != VPU_INST_NULL_ID)
   1358		vpu_trace(inst->dev, "[%d]\n", inst->id);
   1359	vpu_inst_lock(inst);
   1360	vdec_stop(inst, true);
   1361	vpu_inst_unlock(inst);
   1362}
   1363
   1364static void vdec_cleanup(struct vpu_inst *inst)
   1365{
   1366	struct vdec_t *vdec;
   1367
   1368	if (!inst)
   1369		return;
   1370
   1371	vdec = inst->priv;
   1372	if (vdec)
   1373		vfree(vdec);
   1374	inst->priv = NULL;
   1375	vfree(inst);
   1376}
   1377
   1378static void vdec_init_params(struct vdec_t *vdec)
   1379{
   1380	vdec->params.frame_count = 0;
   1381	vdec->params.end_flag = 0;
   1382}
   1383
   1384static int vdec_start(struct vpu_inst *inst)
   1385{
   1386	struct vdec_t *vdec = inst->priv;
   1387	int stream_buffer_size;
   1388	int ret;
   1389
   1390	if (inst->state != VPU_CODEC_STATE_DEINIT)
   1391		return 0;
   1392
   1393	vpu_trace(inst->dev, "[%d]\n", inst->id);
   1394	if (!vdec->udata.virt) {
   1395		vdec->udata.length = 0x1000;
   1396		ret = vpu_alloc_dma(inst->core, &vdec->udata);
   1397		if (ret) {
   1398			dev_err(inst->dev, "[%d] alloc udata fail\n", inst->id);
   1399			goto error;
   1400		}
   1401	}
   1402
   1403	if (!inst->stream_buffer.virt) {
   1404		stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
   1405		if (stream_buffer_size > 0) {
   1406			inst->stream_buffer.length = stream_buffer_size;
   1407			ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
   1408			if (ret) {
   1409				dev_err(inst->dev, "[%d] alloc stream buffer fail\n", inst->id);
   1410				goto error;
   1411			}
   1412			inst->use_stream_buffer = true;
   1413		}
   1414	}
   1415
   1416	if (inst->use_stream_buffer)
   1417		vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
   1418	vpu_iface_init_instance(inst);
   1419	vdec->params.udata.base = vdec->udata.phys;
   1420	vdec->params.udata.size = vdec->udata.length;
   1421	ret = vpu_iface_set_decode_params(inst, &vdec->params, 0);
   1422	if (ret) {
   1423		dev_err(inst->dev, "[%d] set decode params fail\n", inst->id);
   1424		goto error;
   1425	}
   1426
   1427	vdec_init_params(vdec);
   1428	ret = vpu_session_start(inst);
   1429	if (ret) {
   1430		dev_err(inst->dev, "[%d] start fail\n", inst->id);
   1431		goto error;
   1432	}
   1433
   1434	vdec_update_state(inst, VPU_CODEC_STATE_STARTED, 0);
   1435
   1436	return 0;
   1437error:
   1438	vpu_free_dma(&vdec->udata);
   1439	vpu_free_dma(&inst->stream_buffer);
   1440	return ret;
   1441}
   1442
   1443static int vdec_start_session(struct vpu_inst *inst, u32 type)
   1444{
   1445	struct vdec_t *vdec = inst->priv;
   1446	int ret = 0;
   1447
   1448	if (V4L2_TYPE_IS_OUTPUT(type)) {
   1449		if (vdec->reset_codec)
   1450			vdec_stop(inst, false);
   1451		if (inst->state == VPU_CODEC_STATE_DEINIT) {
   1452			ret = vdec_start(inst);
   1453			if (ret)
   1454				return ret;
   1455		}
   1456	}
   1457
   1458	if (V4L2_TYPE_IS_OUTPUT(type)) {
   1459		if (inst->state == VPU_CODEC_STATE_SEEK)
   1460			vdec_update_state(inst, vdec->state, 1);
   1461		vdec->eos_received = 0;
   1462		vpu_process_output_buffer(inst);
   1463	} else {
   1464		vdec_cmd_start(inst);
   1465	}
   1466	if (inst->state == VPU_CODEC_STATE_ACTIVE)
   1467		vdec_response_fs_request(inst, false);
   1468
   1469	return ret;
   1470}
   1471
   1472static int vdec_stop_session(struct vpu_inst *inst, u32 type)
   1473{
   1474	struct vdec_t *vdec = inst->priv;
   1475
   1476	if (inst->state == VPU_CODEC_STATE_DEINIT)
   1477		return 0;
   1478
   1479	if (V4L2_TYPE_IS_OUTPUT(type)) {
   1480		vdec_update_state(inst, VPU_CODEC_STATE_SEEK, 0);
   1481		vdec->drain = 0;
   1482	} else {
   1483		if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
   1484			vdec_abort(inst);
   1485
   1486		vdec->eos_received = 0;
   1487		vdec_clear_slots(inst);
   1488	}
   1489
   1490	return 0;
   1491}
   1492
   1493static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
   1494{
   1495	struct vdec_t *vdec = inst->priv;
   1496	int num = -1;
   1497
   1498	switch (i) {
   1499	case 0:
   1500		num = scnprintf(str, size,
   1501				"req_frame_count = %d\ninterlaced = %d\n",
   1502				vdec->req_frame_count,
   1503				vdec->codec_info.progressive ? 0 : 1);
   1504		break;
   1505	case 1:
   1506		num = scnprintf(str, size,
   1507				"mbi: size = 0x%x request = %d, alloc = %d, response = %d\n",
   1508				vdec->mbi.size,
   1509				vdec->mbi.req_count,
   1510				vdec->mbi.count,
   1511				vdec->mbi.index);
   1512		break;
   1513	case 2:
   1514		num = scnprintf(str, size,
   1515				"dcp: size = 0x%x request = %d, alloc = %d, response = %d\n",
   1516				vdec->dcp.size,
   1517				vdec->dcp.req_count,
   1518				vdec->dcp.count,
   1519				vdec->dcp.index);
   1520		break;
   1521	case 3:
   1522		num = scnprintf(str, size, "input_frame_count = %d\n", vdec->params.frame_count);
   1523		break;
   1524	case 4:
   1525		num = scnprintf(str, size, "decoded_frame_count = %d\n", vdec->decoded_frame_count);
   1526		break;
   1527	case 5:
   1528		num = scnprintf(str, size, "display_frame_count = %d\n", vdec->display_frame_count);
   1529		break;
   1530	case 6:
   1531		num = scnprintf(str, size, "sequence = %d\n", vdec->sequence);
   1532		break;
   1533	case 7:
   1534		num = scnprintf(str, size, "drain = %d, eos = %d, source_change = %d\n",
   1535				vdec->drain, vdec->eos_received, vdec->source_change);
   1536		break;
   1537	case 8:
   1538		num = scnprintf(str, size, "fps = %d/%d\n",
   1539				vdec->codec_info.frame_rate.numerator,
   1540				vdec->codec_info.frame_rate.denominator);
   1541		break;
   1542	default:
   1543		break;
   1544	}
   1545
   1546	return num;
   1547}
   1548
   1549static struct vpu_inst_ops vdec_inst_ops = {
   1550	.ctrl_init = vdec_ctrl_init,
   1551	.check_ready = vdec_check_ready,
   1552	.buf_done = vdec_buf_done,
   1553	.get_one_frame = vdec_frame_decoded,
   1554	.stop_done = vdec_stop_done,
   1555	.event_notify = vdec_event_notify,
   1556	.release = vdec_release,
   1557	.cleanup = vdec_cleanup,
   1558	.start = vdec_start_session,
   1559	.stop = vdec_stop_session,
   1560	.process_output = vdec_process_output,
   1561	.process_capture = vdec_process_capture,
   1562	.on_queue_empty = vdec_on_queue_empty,
   1563	.get_debug_info = vdec_get_debug_info,
   1564	.wait_prepare = vpu_inst_unlock,
   1565	.wait_finish = vpu_inst_lock,
   1566};
   1567
   1568static void vdec_init(struct file *file)
   1569{
   1570	struct vpu_inst *inst = to_inst(file);
   1571	struct v4l2_format f;
   1572
   1573	memset(&f, 0, sizeof(f));
   1574	f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1575	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
   1576	f.fmt.pix_mp.width = 1280;
   1577	f.fmt.pix_mp.height = 720;
   1578	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
   1579	vdec_s_fmt(file, &inst->fh, &f);
   1580
   1581	memset(&f, 0, sizeof(f));
   1582	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1583	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M_8L128;
   1584	f.fmt.pix_mp.width = 1280;
   1585	f.fmt.pix_mp.height = 720;
   1586	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
   1587	vdec_s_fmt(file, &inst->fh, &f);
   1588}
   1589
   1590static int vdec_open(struct file *file)
   1591{
   1592	struct vpu_inst *inst;
   1593	struct vdec_t *vdec;
   1594	int ret;
   1595
   1596	inst = vzalloc(sizeof(*inst));
   1597	if (!inst)
   1598		return -ENOMEM;
   1599
   1600	vdec = vzalloc(sizeof(*vdec));
   1601	if (!vdec) {
   1602		vfree(inst);
   1603		return -ENOMEM;
   1604	}
   1605
   1606	inst->ops = &vdec_inst_ops;
   1607	inst->formats = vdec_formats;
   1608	inst->type = VPU_CORE_TYPE_DEC;
   1609	inst->priv = vdec;
   1610
   1611	ret = vpu_v4l2_open(file, inst);
   1612	if (ret)
   1613		return ret;
   1614
   1615	vdec->fixed_fmt = false;
   1616	inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
   1617	inst->min_buffer_out = VDEC_MIN_BUFFER_OUT;
   1618	vdec_init(file);
   1619
   1620	return 0;
   1621}
   1622
   1623static const struct v4l2_file_operations vdec_fops = {
   1624	.owner = THIS_MODULE,
   1625	.open = vdec_open,
   1626	.release = vpu_v4l2_close,
   1627	.unlocked_ioctl = video_ioctl2,
   1628	.poll = v4l2_m2m_fop_poll,
   1629	.mmap = v4l2_m2m_fop_mmap,
   1630};
   1631
   1632const struct v4l2_ioctl_ops *vdec_get_ioctl_ops(void)
   1633{
   1634	return &vdec_ioctl_ops;
   1635}
   1636
   1637const struct v4l2_file_operations *vdec_get_fops(void)
   1638{
   1639	return &vdec_fops;
   1640}