File Index
Files and directories
Sign in
FILE

vdec.c

File preview with syntax highlighting.

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