File Index
Files and directories
Sign in
FILE

wave5-vpu-enc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c C
   1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
   2/*
   3 * Wave5 series multi-standard codec IP - encoder interface
   4 *
   5 * Copyright (C) 2021-2023 CHIPS&MEDIA INC
   6 */
   7
   8#include <linux/pm_runtime.h>
   9#include "wave5-helper.h"
  10
  11#define VPU_ENC_DEV_NAME "C&M Wave5 VPU encoder"
  12#define VPU_ENC_DRV_NAME "wave5-enc"
  13
  14static const struct v4l2_frmsize_stepwise enc_frmsize[FMT_TYPES] = {
  15	[VPU_FMT_TYPE_CODEC] = {
  16		.min_width = W5_MIN_ENC_PIC_WIDTH,
  17		.max_width = W5_MAX_ENC_PIC_WIDTH,
  18		.step_width = W5_ENC_CODEC_STEP_WIDTH,
  19		.min_height = W5_MIN_ENC_PIC_HEIGHT,
  20		.max_height = W5_MAX_ENC_PIC_HEIGHT,
  21		.step_height = W5_ENC_CODEC_STEP_HEIGHT,
  22	},
  23	[VPU_FMT_TYPE_RAW] = {
  24		.min_width = W5_MIN_ENC_PIC_WIDTH,
  25		.max_width = W5_MAX_ENC_PIC_WIDTH,
  26		.step_width = W5_ENC_RAW_STEP_WIDTH,
  27		.min_height = W5_MIN_ENC_PIC_HEIGHT,
  28		.max_height = W5_MAX_ENC_PIC_HEIGHT,
  29		.step_height = W5_ENC_RAW_STEP_HEIGHT,
  30	},
  31};
  32
  33static const struct vpu_format enc_fmt_list[FMT_TYPES][MAX_FMTS] = {
  34	[VPU_FMT_TYPE_CODEC] = {
  35		{
  36			.v4l2_pix_fmt = V4L2_PIX_FMT_HEVC,
  37			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_CODEC],
  38		},
  39		{
  40			.v4l2_pix_fmt = V4L2_PIX_FMT_H264,
  41			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_CODEC],
  42		},
  43	},
  44	[VPU_FMT_TYPE_RAW] = {
  45		{
  46			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV420,
  47			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
  48		},
  49		{
  50			.v4l2_pix_fmt = V4L2_PIX_FMT_NV12,
  51			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
  52		},
  53		{
  54			.v4l2_pix_fmt = V4L2_PIX_FMT_NV21,
  55			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
  56		},
  57		{
  58			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV420M,
  59			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
  60		},
  61		{
  62			.v4l2_pix_fmt = V4L2_PIX_FMT_NV12M,
  63			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
  64		},
  65		{
  66			.v4l2_pix_fmt = V4L2_PIX_FMT_NV21M,
  67			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
  68		},
  69		{
  70			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV422P,
  71			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
  72		},
  73		{
  74			.v4l2_pix_fmt = V4L2_PIX_FMT_NV16,
  75			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
  76		},
  77		{
  78			.v4l2_pix_fmt = V4L2_PIX_FMT_NV61,
  79			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
  80		},
  81		{
  82			.v4l2_pix_fmt = V4L2_PIX_FMT_YUV422M,
  83			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
  84		},
  85		{
  86			.v4l2_pix_fmt = V4L2_PIX_FMT_NV16M,
  87			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
  88		},
  89		{
  90			.v4l2_pix_fmt = V4L2_PIX_FMT_NV61M,
  91			.v4l2_frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW],
  92		},
  93	}
  94};
  95
  96static int switch_state(struct vpu_instance *inst, enum vpu_instance_state state)
  97{
  98	switch (state) {
  99	case VPU_INST_STATE_NONE:
 100		goto invalid_state_switch;
 101	case VPU_INST_STATE_OPEN:
 102		if (inst->state != VPU_INST_STATE_NONE)
 103			goto invalid_state_switch;
 104		break;
 105	case VPU_INST_STATE_INIT_SEQ:
 106		if (inst->state != VPU_INST_STATE_OPEN && inst->state != VPU_INST_STATE_STOP)
 107			goto invalid_state_switch;
 108		break;
 109	case VPU_INST_STATE_PIC_RUN:
 110		if (inst->state != VPU_INST_STATE_INIT_SEQ)
 111			goto invalid_state_switch;
 112		break;
 113	case VPU_INST_STATE_STOP:
 114		break;
 115	}
 116
 117	dev_dbg(inst->dev->dev, "Switch state from %s to %s.\n",
 118		state_to_str(inst->state), state_to_str(state));
 119	inst->state = state;
 120	return 0;
 121
 122invalid_state_switch:
 123	WARN(1, "Invalid state switch from %s to %s.\n",
 124	     state_to_str(inst->state), state_to_str(state));
 125	return -EINVAL;
 126}
 127
 128static int start_encode(struct vpu_instance *inst, u32 *fail_res)
 129{
 130	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
 131	int ret;
 132	struct vb2_v4l2_buffer *src_buf;
 133	struct vb2_v4l2_buffer *dst_buf;
 134	struct frame_buffer frame_buf;
 135	struct enc_param pic_param;
 136	const struct v4l2_format_info *info;
 137	u32 stride = inst->src_fmt.plane_fmt[0].bytesperline;
 138	u32 luma_size = 0;
 139	u32 chroma_size = 0;
 140
 141	memset(&pic_param, 0, sizeof(struct enc_param));
 142	memset(&frame_buf, 0, sizeof(struct frame_buffer));
 143
 144	info = v4l2_format_info(inst->src_fmt.pixelformat);
 145	if (!info)
 146		return -EINVAL;
 147
 148	if (info->mem_planes == 1) {
 149		luma_size = stride * inst->dst_fmt.height;
 150		chroma_size = luma_size / (info->hdiv * info->vdiv);
 151	} else {
 152		luma_size = inst->src_fmt.plane_fmt[0].sizeimage;
 153		chroma_size = inst->src_fmt.plane_fmt[1].sizeimage;
 154	}
 155
 156	dst_buf = v4l2_m2m_next_dst_buf(m2m_ctx);
 157	if (!dst_buf) {
 158		dev_dbg(inst->dev->dev, "%s: No destination buffer found\n", __func__);
 159		return -EAGAIN;
 160	}
 161
 162	pic_param.pic_stream_buffer_addr =
 163		vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
 164	pic_param.pic_stream_buffer_size =
 165		vb2_plane_size(&dst_buf->vb2_buf, 0);
 166
 167	src_buf = v4l2_m2m_next_src_buf(m2m_ctx);
 168	if (!src_buf) {
 169		dev_dbg(inst->dev->dev, "%s: No source buffer found\n", __func__);
 170		if (m2m_ctx->is_draining)
 171			pic_param.src_end_flag = 1;
 172		else
 173			return -EAGAIN;
 174	} else {
 175		if (inst->src_fmt.num_planes == 1) {
 176			frame_buf.buf_y =
 177				vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
 178			frame_buf.buf_cb = frame_buf.buf_y + luma_size;
 179			frame_buf.buf_cr = frame_buf.buf_cb + chroma_size;
 180		} else if (inst->src_fmt.num_planes == 2) {
 181			frame_buf.buf_y =
 182				vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
 183			frame_buf.buf_cb =
 184				vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 1);
 185			frame_buf.buf_cr = frame_buf.buf_cb + chroma_size;
 186		} else if (inst->src_fmt.num_planes == 3) {
 187			frame_buf.buf_y =
 188				vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
 189			frame_buf.buf_cb =
 190				vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 1);
 191			frame_buf.buf_cr =
 192				vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 2);
 193		}
 194		frame_buf.stride = stride;
 195		pic_param.src_idx = src_buf->vb2_buf.index;
 196	}
 197
 198	pic_param.source_frame = &frame_buf;
 199	pic_param.code_option.implicit_header_encode = 1;
 200	pic_param.code_option.encode_aud = inst->encode_aud;
 201	ret = wave5_vpu_enc_start_one_frame(inst, &pic_param, fail_res);
 202	if (ret) {
 203		if (*fail_res == WAVE5_SYSERR_QUEUEING_FAIL)
 204			return -EINVAL;
 205
 206		dev_dbg(inst->dev->dev, "%s: wave5_vpu_enc_start_one_frame fail: %d\n",
 207			__func__, ret);
 208		src_buf = v4l2_m2m_src_buf_remove(m2m_ctx);
 209		if (!src_buf) {
 210			dev_dbg(inst->dev->dev,
 211				"%s: Removing src buf failed, the queue is empty\n",
 212				__func__);
 213			return -EINVAL;
 214		}
 215		dst_buf = v4l2_m2m_dst_buf_remove(m2m_ctx);
 216		if (!dst_buf) {
 217			dev_dbg(inst->dev->dev,
 218				"%s: Removing dst buf failed, the queue is empty\n",
 219				__func__);
 220			return -EINVAL;
 221		}
 222		switch_state(inst, VPU_INST_STATE_STOP);
 223		dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
 224		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
 225		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
 226	} else {
 227		dev_dbg(inst->dev->dev, "%s: wave5_vpu_enc_start_one_frame success\n",
 228			__func__);
 229		/*
 230		 * Remove the source buffer from the ready-queue now and finish
 231		 * it in the videobuf2 framework once the index is returned by the
 232		 * firmware in finish_encode
 233		 */
 234		if (src_buf)
 235			v4l2_m2m_src_buf_remove_by_idx(m2m_ctx, src_buf->vb2_buf.index);
 236	}
 237
 238	return 0;
 239}
 240
 241static void wave5_vpu_enc_finish_encode(struct vpu_instance *inst)
 242{
 243	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
 244	int ret;
 245	struct enc_output_info enc_output_info;
 246	struct vb2_v4l2_buffer *src_buf = NULL;
 247	struct vb2_v4l2_buffer *dst_buf = NULL;
 248
 249	ret = wave5_vpu_enc_get_output_info(inst, &enc_output_info);
 250	if (ret) {
 251		dev_dbg(inst->dev->dev,
 252			"%s: vpu_enc_get_output_info fail: %d  reason: %u | info: %u\n",
 253			__func__, ret, enc_output_info.error_reason, enc_output_info.warn_info);
 254		return;
 255	}
 256
 257	dev_dbg(inst->dev->dev,
 258		"%s: pic_type %i recon_idx %i src_idx %i pic_byte %u pts %llu\n",
 259		__func__,  enc_output_info.pic_type, enc_output_info.recon_frame_index,
 260		enc_output_info.enc_src_idx, enc_output_info.enc_pic_byte, enc_output_info.pts);
 261
 262	/*
 263	 * The source buffer will not be found in the ready-queue as it has been
 264	 * dropped after sending of the encode firmware command, locate it in
 265	 * the videobuf2 queue directly
 266	 */
 267	if (enc_output_info.enc_src_idx >= 0) {
 268		struct vb2_buffer *vb = vb2_get_buffer(v4l2_m2m_get_src_vq(m2m_ctx),
 269						       enc_output_info.enc_src_idx);
 270		if (vb->state != VB2_BUF_STATE_ACTIVE)
 271			dev_warn(inst->dev->dev,
 272				 "%s: encoded buffer (%d) was not in ready queue %i.",
 273				 __func__, enc_output_info.enc_src_idx, vb->state);
 274		else
 275			src_buf = to_vb2_v4l2_buffer(vb);
 276
 277		if (src_buf) {
 278			inst->timestamp = src_buf->vb2_buf.timestamp;
 279			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
 280		} else {
 281			dev_warn(inst->dev->dev, "%s: no source buffer with index: %d found\n",
 282				 __func__, enc_output_info.enc_src_idx);
 283		}
 284	}
 285
 286	dst_buf = v4l2_m2m_dst_buf_remove(m2m_ctx);
 287	if (enc_output_info.recon_frame_index == RECON_IDX_FLAG_ENC_END) {
 288		static const struct v4l2_event vpu_event_eos = {
 289			.type = V4L2_EVENT_EOS
 290		};
 291
 292		if (!WARN_ON(!dst_buf)) {
 293			vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
 294			dst_buf->field = V4L2_FIELD_NONE;
 295			v4l2_m2m_last_buffer_done(m2m_ctx, dst_buf);
 296		}
 297
 298		v4l2_event_queue_fh(&inst->v4l2_fh, &vpu_event_eos);
 299
 300		v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
 301	} else {
 302		if (!dst_buf) {
 303			dev_warn(inst->dev->dev, "No bitstream buffer.");
 304			v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
 305			return;
 306		}
 307
 308		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, enc_output_info.bitstream_size);
 309
 310		dst_buf->vb2_buf.timestamp = inst->timestamp;
 311		dst_buf->field = V4L2_FIELD_NONE;
 312		if (enc_output_info.pic_type == PIC_TYPE_I) {
 313			if (enc_output_info.enc_vcl_nut == 19 ||
 314			    enc_output_info.enc_vcl_nut == 20)
 315				dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
 316			else
 317				dst_buf->flags |= V4L2_BUF_FLAG_PFRAME;
 318		} else if (enc_output_info.pic_type == PIC_TYPE_P) {
 319			dst_buf->flags |= V4L2_BUF_FLAG_PFRAME;
 320		} else if (enc_output_info.pic_type == PIC_TYPE_B) {
 321			dst_buf->flags |= V4L2_BUF_FLAG_BFRAME;
 322		}
 323
 324		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
 325
 326		dev_dbg(inst->dev->dev, "%s: frame_cycle %8u\n",
 327			__func__, enc_output_info.frame_cycle);
 328
 329		v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
 330	}
 331}
 332
 333static int wave5_vpu_enc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
 334{
 335	strscpy(cap->driver, VPU_ENC_DRV_NAME, sizeof(cap->driver));
 336	strscpy(cap->card, VPU_ENC_DRV_NAME, sizeof(cap->card));
 337
 338	return 0;
 339}
 340
 341static int wave5_vpu_enc_enum_framesizes(struct file *f, void *fh, struct v4l2_frmsizeenum *fsize)
 342{
 343	const struct vpu_format *vpu_fmt;
 344
 345	if (fsize->index)
 346		return -EINVAL;
 347
 348	vpu_fmt = wave5_find_vpu_fmt(fsize->pixel_format, enc_fmt_list[VPU_FMT_TYPE_CODEC]);
 349	if (!vpu_fmt) {
 350		vpu_fmt = wave5_find_vpu_fmt(fsize->pixel_format, enc_fmt_list[VPU_FMT_TYPE_RAW]);
 351		if (!vpu_fmt)
 352			return -EINVAL;
 353	}
 354
 355	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
 356	fsize->stepwise = enc_frmsize[VPU_FMT_TYPE_CODEC];
 357
 358	return 0;
 359}
 360
 361static int wave5_vpu_enc_enum_fmt_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
 362{
 363	struct vpu_instance *inst = file_to_vpu_inst(file);
 364	const struct vpu_format *vpu_fmt;
 365
 366	dev_dbg(inst->dev->dev, "%s: index: %u\n", __func__, f->index);
 367
 368	vpu_fmt = wave5_find_vpu_fmt_by_idx(f->index, enc_fmt_list[VPU_FMT_TYPE_CODEC]);
 369	if (!vpu_fmt)
 370		return -EINVAL;
 371
 372	f->pixelformat = vpu_fmt->v4l2_pix_fmt;
 373	f->flags = 0;
 374
 375	return 0;
 376}
 377
 378static int wave5_vpu_enc_try_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
 379{
 380	struct vpu_instance *inst = file_to_vpu_inst(file);
 381	const struct v4l2_frmsize_stepwise *frmsize;
 382	const struct vpu_format *vpu_fmt;
 383	int width, height;
 384
 385	dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n",
 386		__func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height,
 387		f->fmt.pix_mp.num_planes, f->fmt.pix_mp.field);
 388
 389	vpu_fmt = wave5_find_vpu_fmt(f->fmt.pix_mp.pixelformat, enc_fmt_list[VPU_FMT_TYPE_CODEC]);
 390	if (!vpu_fmt) {
 391		width = inst->dst_fmt.width;
 392		height = inst->dst_fmt.height;
 393		f->fmt.pix_mp.pixelformat = inst->dst_fmt.pixelformat;
 394		frmsize = &enc_frmsize[VPU_FMT_TYPE_CODEC];
 395	} else {
 396		width = f->fmt.pix_mp.width;
 397		height = f->fmt.pix_mp.height;
 398		f->fmt.pix_mp.pixelformat = vpu_fmt->v4l2_pix_fmt;
 399		frmsize = vpu_fmt->v4l2_frmsize;
 400	}
 401
 402	wave5_update_pix_fmt(&f->fmt.pix_mp, VPU_FMT_TYPE_CODEC,
 403			     width, height, frmsize);
 404	f->fmt.pix_mp.colorspace = inst->colorspace;
 405	f->fmt.pix_mp.ycbcr_enc = inst->ycbcr_enc;
 406	f->fmt.pix_mp.quantization = inst->quantization;
 407	f->fmt.pix_mp.xfer_func = inst->xfer_func;
 408
 409	return 0;
 410}
 411
 412static int wave5_vpu_enc_s_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
 413{
 414	struct vpu_instance *inst = file_to_vpu_inst(file);
 415	int i, ret;
 416
 417	dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n",
 418		__func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height,
 419		f->fmt.pix_mp.num_planes, f->fmt.pix_mp.field);
 420
 421	ret = wave5_vpu_enc_try_fmt_cap(file, fh, f);
 422	if (ret)
 423		return ret;
 424
 425	inst->std = wave5_to_vpu_std(f->fmt.pix_mp.pixelformat, inst->type);
 426	if (inst->std == STD_UNKNOWN) {
 427		dev_warn(inst->dev->dev, "unsupported pixelformat: %.4s\n",
 428			 (char *)&f->fmt.pix_mp.pixelformat);
 429		return -EINVAL;
 430	}
 431
 432	inst->dst_fmt.width = f->fmt.pix_mp.width;
 433	inst->dst_fmt.height = f->fmt.pix_mp.height;
 434	inst->dst_fmt.pixelformat = f->fmt.pix_mp.pixelformat;
 435	inst->dst_fmt.field = f->fmt.pix_mp.field;
 436	inst->dst_fmt.flags = f->fmt.pix_mp.flags;
 437	inst->dst_fmt.num_planes = f->fmt.pix_mp.num_planes;
 438	for (i = 0; i < inst->dst_fmt.num_planes; i++) {
 439		inst->dst_fmt.plane_fmt[i].bytesperline = f->fmt.pix_mp.plane_fmt[i].bytesperline;
 440		inst->dst_fmt.plane_fmt[i].sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage;
 441	}
 442
 443	return 0;
 444}
 445
 446static int wave5_vpu_enc_g_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
 447{
 448	struct vpu_instance *inst = file_to_vpu_inst(file);
 449	int i;
 450
 451	f->fmt.pix_mp.width = inst->dst_fmt.width;
 452	f->fmt.pix_mp.height = inst->dst_fmt.height;
 453	f->fmt.pix_mp.pixelformat = inst->dst_fmt.pixelformat;
 454	f->fmt.pix_mp.field = inst->dst_fmt.field;
 455	f->fmt.pix_mp.flags = inst->dst_fmt.flags;
 456	f->fmt.pix_mp.num_planes = inst->dst_fmt.num_planes;
 457	for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
 458		f->fmt.pix_mp.plane_fmt[i].bytesperline = inst->dst_fmt.plane_fmt[i].bytesperline;
 459		f->fmt.pix_mp.plane_fmt[i].sizeimage = inst->dst_fmt.plane_fmt[i].sizeimage;
 460	}
 461
 462	f->fmt.pix_mp.colorspace = inst->colorspace;
 463	f->fmt.pix_mp.ycbcr_enc = inst->ycbcr_enc;
 464	f->fmt.pix_mp.quantization = inst->quantization;
 465	f->fmt.pix_mp.xfer_func = inst->xfer_func;
 466
 467	return 0;
 468}
 469
 470static int wave5_vpu_enc_enum_fmt_out(struct file *file, void *fh, struct v4l2_fmtdesc *f)
 471{
 472	struct vpu_instance *inst = file_to_vpu_inst(file);
 473	const struct vpu_format *vpu_fmt;
 474
 475	dev_dbg(inst->dev->dev, "%s: index: %u\n", __func__, f->index);
 476
 477	vpu_fmt = wave5_find_vpu_fmt_by_idx(f->index, enc_fmt_list[VPU_FMT_TYPE_RAW]);
 478	if (!vpu_fmt)
 479		return -EINVAL;
 480
 481	f->pixelformat = vpu_fmt->v4l2_pix_fmt;
 482	f->flags = 0;
 483
 484	return 0;
 485}
 486
 487static int wave5_vpu_enc_try_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
 488{
 489	struct vpu_instance *inst = file_to_vpu_inst(file);
 490	const struct v4l2_frmsize_stepwise *frmsize;
 491	const struct vpu_format *vpu_fmt;
 492	int width, height;
 493
 494	dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n",
 495		__func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height,
 496		f->fmt.pix_mp.num_planes, f->fmt.pix_mp.field);
 497
 498	vpu_fmt = wave5_find_vpu_fmt(f->fmt.pix_mp.pixelformat, enc_fmt_list[VPU_FMT_TYPE_RAW]);
 499	if (!vpu_fmt) {
 500		width = inst->src_fmt.width;
 501		height = inst->src_fmt.height;
 502		f->fmt.pix_mp.pixelformat = inst->src_fmt.pixelformat;
 503		frmsize = &enc_frmsize[VPU_FMT_TYPE_RAW];
 504	} else {
 505		width = f->fmt.pix_mp.width;
 506		height = f->fmt.pix_mp.height;
 507		f->fmt.pix_mp.pixelformat = vpu_fmt->v4l2_pix_fmt;
 508		frmsize = vpu_fmt->v4l2_frmsize;
 509	}
 510
 511	wave5_update_pix_fmt(&f->fmt.pix_mp, VPU_FMT_TYPE_RAW,
 512			     width, height, frmsize);
 513	return 0;
 514}
 515
 516static int wave5_vpu_enc_s_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
 517{
 518	struct vpu_instance *inst = file_to_vpu_inst(file);
 519	const struct vpu_format *vpu_fmt;
 520	const struct v4l2_format_info *info;
 521	int i, ret;
 522
 523	dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n",
 524		__func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, f->fmt.pix_mp.height,
 525		f->fmt.pix_mp.num_planes, f->fmt.pix_mp.field);
 526
 527	ret = wave5_vpu_enc_try_fmt_out(file, fh, f);
 528	if (ret)
 529		return ret;
 530
 531	inst->src_fmt.width = f->fmt.pix_mp.width;
 532	inst->src_fmt.height = f->fmt.pix_mp.height;
 533	inst->src_fmt.pixelformat = f->fmt.pix_mp.pixelformat;
 534	inst->src_fmt.field = f->fmt.pix_mp.field;
 535	inst->src_fmt.flags = f->fmt.pix_mp.flags;
 536	inst->src_fmt.num_planes = f->fmt.pix_mp.num_planes;
 537	for (i = 0; i < inst->src_fmt.num_planes; i++) {
 538		inst->src_fmt.plane_fmt[i].bytesperline = f->fmt.pix_mp.plane_fmt[i].bytesperline;
 539		inst->src_fmt.plane_fmt[i].sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage;
 540	}
 541
 542	info = v4l2_format_info(inst->src_fmt.pixelformat);
 543	if (!info)
 544		return -EINVAL;
 545
 546	inst->cbcr_interleave = info->comp_planes == 2;
 547
 548	switch (inst->src_fmt.pixelformat) {
 549	case V4L2_PIX_FMT_NV21:
 550	case V4L2_PIX_FMT_NV21M:
 551	case V4L2_PIX_FMT_NV61:
 552	case V4L2_PIX_FMT_NV61M:
 553		inst->nv21 = true;
 554		break;
 555	default:
 556		inst->nv21 = false;
 557	}
 558
 559	inst->colorspace = f->fmt.pix_mp.colorspace;
 560	inst->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
 561	inst->quantization = f->fmt.pix_mp.quantization;
 562	inst->xfer_func = f->fmt.pix_mp.xfer_func;
 563
 564	vpu_fmt = wave5_find_vpu_fmt(inst->dst_fmt.pixelformat, enc_fmt_list[VPU_FMT_TYPE_CODEC]);
 565	if (!vpu_fmt)
 566		return -EINVAL;
 567
 568	wave5_update_pix_fmt(&inst->dst_fmt, VPU_FMT_TYPE_CODEC,
 569			     f->fmt.pix_mp.width, f->fmt.pix_mp.height,
 570			     vpu_fmt->v4l2_frmsize);
 571	inst->conf_win.width = inst->dst_fmt.width;
 572	inst->conf_win.height = inst->dst_fmt.height;
 573
 574	return 0;
 575}
 576
 577static int wave5_vpu_enc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
 578{
 579	struct vpu_instance *inst = file_to_vpu_inst(file);
 580
 581	dev_dbg(inst->dev->dev, "%s: type: %u | target: %u\n", __func__, s->type, s->target);
 582
 583	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
 584		return -EINVAL;
 585	switch (s->target) {
 586	case V4L2_SEL_TGT_CROP_DEFAULT:
 587	case V4L2_SEL_TGT_CROP_BOUNDS:
 588		s->r.left = 0;
 589		s->r.top = 0;
 590		s->r.width = inst->dst_fmt.width;
 591		s->r.height = inst->dst_fmt.height;
 592		break;
 593	case V4L2_SEL_TGT_CROP:
 594		s->r.left = 0;
 595		s->r.top = 0;
 596		s->r.width = inst->conf_win.width;
 597		s->r.height = inst->conf_win.height;
 598		break;
 599	default:
 600		return -EINVAL;
 601	}
 602
 603	return 0;
 604}
 605
 606static int wave5_vpu_enc_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
 607{
 608	struct vpu_instance *inst = file_to_vpu_inst(file);
 609
 610	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
 611		return -EINVAL;
 612
 613	if (s->target != V4L2_SEL_TGT_CROP)
 614		return -EINVAL;
 615
 616	dev_dbg(inst->dev->dev, "%s: V4L2_SEL_TGT_CROP width: %u | height: %u\n",
 617		__func__, s->r.width, s->r.height);
 618
 619	s->r.left = 0;
 620	s->r.top = 0;
 621	s->r.width = min(s->r.width, inst->dst_fmt.width);
 622	s->r.height = min(s->r.height, inst->dst_fmt.height);
 623
 624	inst->conf_win = s->r;
 625
 626	return 0;
 627}
 628
 629static int wave5_vpu_enc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *ec)
 630{
 631	struct vpu_instance *inst = file_to_vpu_inst(file);
 632	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
 633	int ret;
 634
 635	ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, ec);
 636	if (ret)
 637		return ret;
 638
 639	if (!wave5_vpu_both_queues_are_streaming(inst))
 640		return 0;
 641
 642	switch (ec->cmd) {
 643	case V4L2_ENC_CMD_STOP:
 644		if (m2m_ctx->is_draining)
 645			return -EBUSY;
 646
 647		if (m2m_ctx->has_stopped)
 648			return 0;
 649
 650		m2m_ctx->last_src_buf = v4l2_m2m_last_src_buf(m2m_ctx);
 651		m2m_ctx->is_draining = true;
 652
 653		v4l2_m2m_try_schedule(m2m_ctx);
 654		break;
 655	case V4L2_ENC_CMD_START:
 656		break;
 657	default:
 658		return -EINVAL;
 659	}
 660
 661	return 0;
 662}
 663
 664static int wave5_vpu_enc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
 665{
 666	struct vpu_instance *inst = file_to_vpu_inst(file);
 667
 668	dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, a->type);
 669
 670	if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
 671		return -EINVAL;
 672
 673	a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
 674	a->parm.output.timeperframe.numerator = 1;
 675	a->parm.output.timeperframe.denominator = inst->frame_rate;
 676
 677	dev_dbg(inst->dev->dev, "%s: numerator: %u | denominator: %u\n",
 678		__func__, a->parm.output.timeperframe.numerator,
 679		a->parm.output.timeperframe.denominator);
 680
 681	return 0;
 682}
 683
 684static int wave5_vpu_enc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
 685{
 686	struct vpu_instance *inst = file_to_vpu_inst(file);
 687
 688	dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, a->type);
 689
 690	if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
 691		return -EINVAL;
 692
 693	a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
 694	if (a->parm.output.timeperframe.denominator && a->parm.output.timeperframe.numerator) {
 695		inst->frame_rate = a->parm.output.timeperframe.denominator /
 696				   a->parm.output.timeperframe.numerator;
 697	} else {
 698		a->parm.output.timeperframe.numerator = 1;
 699		a->parm.output.timeperframe.denominator = inst->frame_rate;
 700	}
 701
 702	dev_dbg(inst->dev->dev, "%s: numerator: %u | denominator: %u\n",
 703		__func__, a->parm.output.timeperframe.numerator,
 704		a->parm.output.timeperframe.denominator);
 705
 706	return 0;
 707}
 708
 709static const struct v4l2_ioctl_ops wave5_vpu_enc_ioctl_ops = {
 710	.vidioc_querycap = wave5_vpu_enc_querycap,
 711	.vidioc_enum_framesizes = wave5_vpu_enc_enum_framesizes,
 712
 713	.vidioc_enum_fmt_vid_cap	= wave5_vpu_enc_enum_fmt_cap,
 714	.vidioc_s_fmt_vid_cap_mplane = wave5_vpu_enc_s_fmt_cap,
 715	.vidioc_g_fmt_vid_cap_mplane = wave5_vpu_enc_g_fmt_cap,
 716	.vidioc_try_fmt_vid_cap_mplane = wave5_vpu_enc_try_fmt_cap,
 717
 718	.vidioc_enum_fmt_vid_out	= wave5_vpu_enc_enum_fmt_out,
 719	.vidioc_s_fmt_vid_out_mplane = wave5_vpu_enc_s_fmt_out,
 720	.vidioc_g_fmt_vid_out_mplane = wave5_vpu_g_fmt_out,
 721	.vidioc_try_fmt_vid_out_mplane = wave5_vpu_enc_try_fmt_out,
 722
 723	.vidioc_g_selection = wave5_vpu_enc_g_selection,
 724	.vidioc_s_selection = wave5_vpu_enc_s_selection,
 725
 726	.vidioc_g_parm = wave5_vpu_enc_g_parm,
 727	.vidioc_s_parm = wave5_vpu_enc_s_parm,
 728
 729	.vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
 730	.vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
 731	.vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
 732	.vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
 733	.vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
 734	.vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
 735	.vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
 736	.vidioc_streamon = v4l2_m2m_ioctl_streamon,
 737	.vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
 738
 739	.vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd,
 740	.vidioc_encoder_cmd = wave5_vpu_enc_encoder_cmd,
 741
 742	.vidioc_subscribe_event = wave5_vpu_subscribe_event,
 743	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 744};
 745
 746static int wave5_vpu_enc_s_ctrl(struct v4l2_ctrl *ctrl)
 747{
 748	struct vpu_instance *inst = wave5_ctrl_to_vpu_inst(ctrl);
 749
 750	dev_dbg(inst->dev->dev, "%s: name: %s | value: %d\n", __func__, ctrl->name, ctrl->val);
 751
 752	switch (ctrl->id) {
 753	case V4L2_CID_MPEG_VIDEO_AU_DELIMITER:
 754		inst->encode_aud = ctrl->val;
 755		break;
 756	case V4L2_CID_HFLIP:
 757		inst->mirror_direction |= (ctrl->val << 1);
 758		break;
 759	case V4L2_CID_VFLIP:
 760		inst->mirror_direction |= ctrl->val;
 761		break;
 762	case V4L2_CID_ROTATE:
 763		inst->rot_angle = ctrl->val;
 764		break;
 765	case V4L2_CID_MPEG_VIDEO_VBV_SIZE:
 766		inst->vbv_buf_size = ctrl->val;
 767		break;
 768	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
 769		switch (ctrl->val) {
 770		case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
 771			inst->rc_mode = 0;
 772			break;
 773		case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
 774			inst->rc_mode = 1;
 775			break;
 776		default:
 777			return -EINVAL;
 778		}
 779		break;
 780	case V4L2_CID_MPEG_VIDEO_BITRATE:
 781		inst->bit_rate = ctrl->val;
 782		break;
 783	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
 784		inst->enc_param.avc_idr_period = ctrl->val;
 785		break;
 786	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
 787		inst->enc_param.independ_slice_mode = ctrl->val;
 788		inst->enc_param.avc_slice_mode = ctrl->val;
 789		break;
 790	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
 791		inst->enc_param.independ_slice_mode_arg = ctrl->val;
 792		inst->enc_param.avc_slice_arg = ctrl->val;
 793		break;
 794	case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
 795		inst->rc_enable = ctrl->val;
 796		break;
 797	case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
 798		inst->enc_param.mb_level_rc_enable = ctrl->val;
 799		inst->enc_param.cu_level_rc_enable = ctrl->val;
 800		inst->enc_param.hvs_qp_enable = ctrl->val;
 801		break;
 802	case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
 803		switch (ctrl->val) {
 804		case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN:
 805			inst->enc_param.profile = HEVC_PROFILE_MAIN;
 806			inst->bit_depth = 8;
 807			break;
 808		case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE:
 809			inst->enc_param.profile = HEVC_PROFILE_STILLPICTURE;
 810			inst->enc_param.en_still_picture = 1;
 811			inst->bit_depth = 8;
 812			break;
 813		case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10:
 814			inst->enc_param.profile = HEVC_PROFILE_MAIN10;
 815			inst->bit_depth = 10;
 816			break;
 817		default:
 818			return -EINVAL;
 819		}
 820		break;
 821	case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
 822		switch (ctrl->val) {
 823		case V4L2_MPEG_VIDEO_HEVC_LEVEL_1:
 824			inst->enc_param.level = 10 * 3;
 825			break;
 826		case V4L2_MPEG_VIDEO_HEVC_LEVEL_2:
 827			inst->enc_param.level = 20 * 3;
 828			break;
 829		case V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1:
 830			inst->enc_param.level = 21 * 3;
 831			break;
 832		case V4L2_MPEG_VIDEO_HEVC_LEVEL_3:
 833			inst->enc_param.level = 30 * 3;
 834			break;
 835		case V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1:
 836			inst->enc_param.level = 31 * 3;
 837			break;
 838		case V4L2_MPEG_VIDEO_HEVC_LEVEL_4:
 839			inst->enc_param.level = 40 * 3;
 840			break;
 841		case V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1:
 842			inst->enc_param.level = 41 * 3;
 843			break;
 844		case V4L2_MPEG_VIDEO_HEVC_LEVEL_5:
 845			inst->enc_param.level = 50 * 3;
 846			break;
 847		case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1:
 848			inst->enc_param.level = 51 * 3;
 849			break;
 850		case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2:
 851			inst->enc_param.level = 52 * 3;
 852			break;
 853		default:
 854			return -EINVAL;
 855		}
 856		break;
 857	case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:
 858		inst->enc_param.min_qp_i = ctrl->val;
 859		inst->enc_param.min_qp_p = ctrl->val;
 860		inst->enc_param.min_qp_b = ctrl->val;
 861		break;
 862	case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
 863		inst->enc_param.max_qp_i = ctrl->val;
 864		inst->enc_param.max_qp_p = ctrl->val;
 865		inst->enc_param.max_qp_b = ctrl->val;
 866		break;
 867	case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:
 868		inst->enc_param.intra_qp = ctrl->val;
 869		break;
 870	case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE:
 871		switch (ctrl->val) {
 872		case V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED:
 873			inst->enc_param.disable_deblk = 1;
 874			inst->enc_param.sao_enable = 0;
 875			inst->enc_param.lf_cross_slice_boundary_enable = 0;
 876			break;
 877		case V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_ENABLED:
 878			inst->enc_param.disable_deblk = 0;
 879			inst->enc_param.sao_enable = 1;
 880			inst->enc_param.lf_cross_slice_boundary_enable = 1;
 881			break;
 882		case V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY:
 883			inst->enc_param.disable_deblk = 0;
 884			inst->enc_param.sao_enable = 1;
 885			inst->enc_param.lf_cross_slice_boundary_enable = 0;
 886			break;
 887		default:
 888			return -EINVAL;
 889		}
 890		break;
 891	case V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2:
 892		inst->enc_param.beta_offset_div2 = ctrl->val;
 893		break;
 894	case V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2:
 895		inst->enc_param.tc_offset_div2 = ctrl->val;
 896		break;
 897	case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE:
 898		switch (ctrl->val) {
 899		case V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE:
 900			inst->enc_param.decoding_refresh_type = 0;
 901			break;
 902		case V4L2_MPEG_VIDEO_HEVC_REFRESH_CRA:
 903			inst->enc_param.decoding_refresh_type = 1;
 904			break;
 905		case V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR:
 906			inst->enc_param.decoding_refresh_type = 2;
 907			break;
 908		default:
 909			return -EINVAL;
 910		}
 911		break;
 912	case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD:
 913		inst->enc_param.intra_period = ctrl->val;
 914		break;
 915	case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU:
 916		inst->enc_param.lossless_enable = ctrl->val;
 917		break;
 918	case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED:
 919		inst->enc_param.const_intra_pred_flag = ctrl->val;
 920		break;
 921	case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT:
 922		inst->enc_param.wpp_enable = ctrl->val;
 923		break;
 924	case V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING:
 925		inst->enc_param.strong_intra_smooth_enable = ctrl->val;
 926		break;
 927	case V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1:
 928		inst->enc_param.max_num_merge = ctrl->val;
 929		break;
 930	case V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION:
 931		inst->enc_param.tmvp_enable = ctrl->val;
 932		break;
 933	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
 934		switch (ctrl->val) {
 935		case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
 936		case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
 937			inst->enc_param.profile = H264_PROFILE_BP;
 938			inst->bit_depth = 8;
 939			break;
 940		case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
 941			inst->enc_param.profile = H264_PROFILE_MP;
 942			inst->bit_depth = 8;
 943			break;
 944		case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
 945			inst->enc_param.profile = H264_PROFILE_EXTENDED;
 946			inst->bit_depth = 8;
 947			break;
 948		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
 949			inst->enc_param.profile = H264_PROFILE_HP;
 950			inst->bit_depth = 8;
 951			break;
 952		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
 953			inst->enc_param.profile = H264_PROFILE_HIGH10;
 954			inst->bit_depth = 10;
 955			break;
 956		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
 957			inst->enc_param.profile = H264_PROFILE_HIGH422;
 958			inst->bit_depth = 10;
 959			break;
 960		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
 961			inst->enc_param.profile = H264_PROFILE_HIGH444;
 962			inst->bit_depth = 10;
 963			break;
 964		default:
 965			return -EINVAL;
 966		}
 967		break;
 968	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
 969		switch (ctrl->val) {
 970		case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
 971			inst->enc_param.level = 10;
 972			break;
 973		case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
 974			inst->enc_param.level = 9;
 975			break;
 976		case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
 977			inst->enc_param.level = 11;
 978			break;
 979		case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
 980			inst->enc_param.level = 12;
 981			break;
 982		case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
 983			inst->enc_param.level = 13;
 984			break;
 985		case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
 986			inst->enc_param.level = 20;
 987			break;
 988		case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
 989			inst->enc_param.level = 21;
 990			break;
 991		case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
 992			inst->enc_param.level = 22;
 993			break;
 994		case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
 995			inst->enc_param.level = 30;
 996			break;
 997		case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
 998			inst->enc_param.level = 31;
 999			break;
1000		case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
1001			inst->enc_param.level = 32;
1002			break;
1003		case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
1004			inst->enc_param.level = 40;
1005			break;
1006		case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
1007			inst->enc_param.level = 41;
1008			break;
1009		case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
1010			inst->enc_param.level = 42;
1011			break;
1012		case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
1013			inst->enc_param.level = 50;
1014			break;
1015		case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
1016			inst->enc_param.level = 51;
1017			break;
1018		default:
1019			return -EINVAL;
1020		}
1021		break;
1022	case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
1023		inst->enc_param.min_qp_i = ctrl->val;
1024		inst->enc_param.min_qp_p = ctrl->val;
1025		inst->enc_param.min_qp_b = ctrl->val;
1026		break;
1027	case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
1028		inst->enc_param.max_qp_i = ctrl->val;
1029		inst->enc_param.max_qp_p = ctrl->val;
1030		inst->enc_param.max_qp_b = ctrl->val;
1031		break;
1032	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
1033		inst->enc_param.intra_qp = ctrl->val;
1034		break;
1035	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
1036		switch (ctrl->val) {
1037		case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED:
1038			inst->enc_param.disable_deblk = 1;
1039			inst->enc_param.lf_cross_slice_boundary_enable = 1;
1040			break;
1041		case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED:
1042			inst->enc_param.disable_deblk = 0;
1043			inst->enc_param.lf_cross_slice_boundary_enable = 1;
1044			break;
1045		case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY:
1046			inst->enc_param.disable_deblk = 0;
1047			inst->enc_param.lf_cross_slice_boundary_enable = 0;
1048			break;
1049		default:
1050			return -EINVAL;
1051		}
1052		break;
1053	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
1054		inst->enc_param.beta_offset_div2 = ctrl->val;
1055		break;
1056	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
1057		inst->enc_param.tc_offset_div2 = ctrl->val;
1058		break;
1059	case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
1060		inst->enc_param.transform8x8_enable = ctrl->val;
1061		break;
1062	case V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION:
1063		inst->enc_param.const_intra_pred_flag = ctrl->val;
1064		break;
1065	case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET:
1066		inst->enc_param.chroma_cb_qp_offset = ctrl->val;
1067		inst->enc_param.chroma_cr_qp_offset = ctrl->val;
1068		break;
1069	case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
1070		inst->enc_param.intra_period = ctrl->val;
1071		break;
1072	case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
1073		inst->enc_param.entropy_coding_mode = ctrl->val;
1074		break;
1075	case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR:
1076		inst->enc_param.forced_idr_header_enable = ctrl->val;
1077		break;
1078	case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
1079		break;
1080	default:
1081		return -EINVAL;
1082	}
1083
1084	return 0;
1085}
1086
1087static const struct v4l2_ctrl_ops wave5_vpu_enc_ctrl_ops = {
1088	.s_ctrl = wave5_vpu_enc_s_ctrl,
1089};
1090
1091static int wave5_vpu_enc_queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
1092				     unsigned int *num_planes, unsigned int sizes[],
1093				     struct device *alloc_devs[])
1094{
1095	struct vpu_instance *inst = vb2_get_drv_priv(q);
1096	struct v4l2_pix_format_mplane inst_format =
1097		(q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? inst->src_fmt : inst->dst_fmt;
1098	unsigned int i;
1099
1100	dev_dbg(inst->dev->dev, "%s: num_buffers: %u | num_planes: %u | type: %u\n", __func__,
1101		*num_buffers, *num_planes, q->type);
1102
1103	if (*num_planes) {
1104		if (inst_format.num_planes != *num_planes)
1105			return -EINVAL;
1106
1107		for (i = 0; i < *num_planes; i++) {
1108			if (sizes[i] < inst_format.plane_fmt[i].sizeimage)
1109				return -EINVAL;
1110		}
1111	} else {
1112		*num_planes = inst_format.num_planes;
1113		for (i = 0; i < *num_planes; i++) {
1114			sizes[i] = inst_format.plane_fmt[i].sizeimage;
1115			dev_dbg(inst->dev->dev, "%s: size[%u]: %u\n", __func__, i, sizes[i]);
1116		}
1117	}
1118
1119	dev_dbg(inst->dev->dev, "%s: size: %u\n", __func__, sizes[0]);
1120
1121	return 0;
1122}
1123
1124static void wave5_vpu_enc_buf_queue(struct vb2_buffer *vb)
1125{
1126	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1127	struct vpu_instance *inst = vb2_get_drv_priv(vb->vb2_queue);
1128	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
1129
1130	dev_dbg(inst->dev->dev, "%s: type: %4u index: %4u size: ([0]=%4lu, [1]=%4lu, [2]=%4lu)\n",
1131		__func__, vb->type, vb->index, vb2_plane_size(&vbuf->vb2_buf, 0),
1132		vb2_plane_size(&vbuf->vb2_buf, 1), vb2_plane_size(&vbuf->vb2_buf, 2));
1133
1134	if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1135		vbuf->sequence = inst->queued_src_buf_num++;
1136	else
1137		vbuf->sequence = inst->queued_dst_buf_num++;
1138
1139	v4l2_m2m_buf_queue(m2m_ctx, vbuf);
1140}
1141
1142static int wave5_set_enc_openparam(struct enc_open_param *open_param,
1143				   struct vpu_instance *inst)
1144{
1145	struct enc_wave_param input = inst->enc_param;
1146	const struct v4l2_format_info *info;
1147	u32 num_ctu_row = ALIGN(inst->dst_fmt.height, 64) / 64;
1148	u32 num_mb_row = ALIGN(inst->dst_fmt.height, 16) / 16;
1149
1150	info = v4l2_format_info(inst->src_fmt.pixelformat);
1151	if (!info)
1152		return -EINVAL;
1153
1154	if (info->hdiv == 2 && info->vdiv == 1)
1155		open_param->src_format = FORMAT_422;
1156	else
1157		open_param->src_format = FORMAT_420;
1158
1159	open_param->wave_param.gop_preset_idx = PRESET_IDX_IPP_SINGLE;
1160	open_param->wave_param.hvs_qp_scale = 2;
1161	open_param->wave_param.hvs_max_delta_qp = 10;
1162	open_param->wave_param.skip_intra_trans = 1;
1163	open_param->wave_param.intra_nx_n_enable = 1;
1164	open_param->wave_param.nr_intra_weight_y = 7;
1165	open_param->wave_param.nr_intra_weight_cb = 7;
1166	open_param->wave_param.nr_intra_weight_cr = 7;
1167	open_param->wave_param.nr_inter_weight_y = 4;
1168	open_param->wave_param.nr_inter_weight_cb = 4;
1169	open_param->wave_param.nr_inter_weight_cr = 4;
1170	open_param->wave_param.rdo_skip = 1;
1171	open_param->wave_param.lambda_scaling_enable = 1;
1172
1173	open_param->line_buf_int_en = true;
1174	open_param->pic_width = inst->conf_win.width;
1175	open_param->pic_height = inst->conf_win.height;
1176	open_param->frame_rate_info = inst->frame_rate;
1177	open_param->rc_enable = inst->rc_enable;
1178	if (inst->rc_enable) {
1179		open_param->wave_param.initial_rc_qp = -1;
1180		open_param->wave_param.rc_weight_param = 16;
1181		open_param->wave_param.rc_weight_buf = 128;
1182	}
1183	open_param->wave_param.mb_level_rc_enable = input.mb_level_rc_enable;
1184	open_param->wave_param.cu_level_rc_enable = input.cu_level_rc_enable;
1185	open_param->wave_param.hvs_qp_enable = input.hvs_qp_enable;
1186	open_param->bit_rate = inst->bit_rate;
1187	open_param->vbv_buffer_size = inst->vbv_buf_size;
1188	if (inst->rc_mode == 0)
1189		open_param->vbv_buffer_size = 3000;
1190	open_param->wave_param.profile = input.profile;
1191	open_param->wave_param.en_still_picture = input.en_still_picture;
1192	open_param->wave_param.level = input.level;
1193	open_param->wave_param.internal_bit_depth = inst->bit_depth;
1194	open_param->wave_param.intra_qp = input.intra_qp;
1195	open_param->wave_param.min_qp_i = input.min_qp_i;
1196	open_param->wave_param.max_qp_i = input.max_qp_i;
1197	open_param->wave_param.min_qp_p = input.min_qp_p;
1198	open_param->wave_param.max_qp_p = input.max_qp_p;
1199	open_param->wave_param.min_qp_b = input.min_qp_b;
1200	open_param->wave_param.max_qp_b = input.max_qp_b;
1201	open_param->wave_param.disable_deblk = input.disable_deblk;
1202	open_param->wave_param.lf_cross_slice_boundary_enable =
1203		input.lf_cross_slice_boundary_enable;
1204	open_param->wave_param.tc_offset_div2 = input.tc_offset_div2;
1205	open_param->wave_param.beta_offset_div2 = input.beta_offset_div2;
1206	open_param->wave_param.decoding_refresh_type = input.decoding_refresh_type;
1207	open_param->wave_param.intra_period = input.intra_period;
1208	if (inst->std == W_HEVC_ENC) {
1209		if (input.intra_period == 0) {
1210			open_param->wave_param.decoding_refresh_type = DEC_REFRESH_TYPE_IDR;
1211			open_param->wave_param.intra_period = input.avc_idr_period;
1212		}
1213	} else {
1214		open_param->wave_param.avc_idr_period = input.avc_idr_period;
1215	}
1216	open_param->wave_param.entropy_coding_mode = input.entropy_coding_mode;
1217	open_param->wave_param.lossless_enable = input.lossless_enable;
1218	open_param->wave_param.const_intra_pred_flag = input.const_intra_pred_flag;
1219	open_param->wave_param.wpp_enable = input.wpp_enable;
1220	open_param->wave_param.strong_intra_smooth_enable = input.strong_intra_smooth_enable;
1221	open_param->wave_param.max_num_merge = input.max_num_merge;
1222	open_param->wave_param.tmvp_enable = input.tmvp_enable;
1223	open_param->wave_param.transform8x8_enable = input.transform8x8_enable;
1224	open_param->wave_param.chroma_cb_qp_offset = input.chroma_cb_qp_offset;
1225	open_param->wave_param.chroma_cr_qp_offset = input.chroma_cr_qp_offset;
1226	open_param->wave_param.independ_slice_mode = input.independ_slice_mode;
1227	open_param->wave_param.independ_slice_mode_arg = input.independ_slice_mode_arg;
1228	open_param->wave_param.avc_slice_mode = input.avc_slice_mode;
1229	open_param->wave_param.avc_slice_arg = input.avc_slice_arg;
1230	open_param->wave_param.intra_mb_refresh_mode = input.intra_mb_refresh_mode;
1231	if (input.intra_mb_refresh_mode != REFRESH_MB_MODE_NONE) {
1232		if (num_mb_row >= input.intra_mb_refresh_arg)
1233			open_param->wave_param.intra_mb_refresh_arg =
1234				num_mb_row / input.intra_mb_refresh_arg;
1235		else
1236			open_param->wave_param.intra_mb_refresh_arg = num_mb_row;
1237	}
1238	open_param->wave_param.intra_refresh_mode = input.intra_refresh_mode;
1239	if (input.intra_refresh_mode != 0) {
1240		if (num_ctu_row >= input.intra_refresh_arg)
1241			open_param->wave_param.intra_refresh_arg =
1242				num_ctu_row / input.intra_refresh_arg;
1243		else
1244			open_param->wave_param.intra_refresh_arg = num_ctu_row;
1245	}
1246	open_param->wave_param.forced_idr_header_enable = input.forced_idr_header_enable;
1247
1248	return 0;
1249}
1250
1251static int initialize_sequence(struct vpu_instance *inst)
1252{
1253	struct enc_initial_info initial_info;
1254	struct v4l2_ctrl *ctrl;
1255	int ret;
1256
1257	ret = wave5_vpu_enc_issue_seq_init(inst);
1258	if (ret) {
1259		dev_err(inst->dev->dev, "%s: wave5_vpu_enc_issue_seq_init, fail: %d\n",
1260			__func__, ret);
1261		return ret;
1262	}
1263
1264	if (wave5_vpu_wait_interrupt(inst, VPU_ENC_TIMEOUT) < 0) {
1265		dev_err(inst->dev->dev, "%s: wave5_vpu_wait_interrupt failed\n", __func__);
1266		return -EINVAL;
1267	}
1268
1269	ret = wave5_vpu_enc_complete_seq_init(inst, &initial_info);
1270	if (ret)
1271		return ret;
1272
1273	dev_dbg(inst->dev->dev, "%s: min_frame_buffer: %u | min_source_buffer: %u\n",
1274		__func__, initial_info.min_frame_buffer_count,
1275		initial_info.min_src_frame_count);
1276	inst->min_src_buf_count = initial_info.min_src_frame_count +
1277				  WAVE521_COMMAND_QUEUE_DEPTH;
1278
1279	ctrl = v4l2_ctrl_find(&inst->v4l2_ctrl_hdl,
1280			      V4L2_CID_MIN_BUFFERS_FOR_OUTPUT);
1281	if (ctrl)
1282		v4l2_ctrl_s_ctrl(ctrl, inst->min_src_buf_count);
1283
1284	inst->fbc_buf_count = initial_info.min_frame_buffer_count;
1285
1286	return 0;
1287}
1288
1289static int prepare_fb(struct vpu_instance *inst)
1290{
1291	u32 fb_stride = ALIGN(inst->dst_fmt.width, 32);
1292	u32 fb_height = ALIGN(inst->dst_fmt.height, 32);
1293	int i, ret = 0;
1294
1295	for (i = 0; i < inst->fbc_buf_count; i++) {
1296		u32 luma_size = fb_stride * fb_height;
1297		u32 chroma_size = ALIGN(fb_stride / 2, 16) * fb_height;
1298
1299		inst->frame_vbuf[i].size = luma_size + chroma_size;
1300		ret = wave5_vdi_allocate_dma_memory(inst->dev, &inst->frame_vbuf[i]);
1301		if (ret < 0) {
1302			dev_err(inst->dev->dev, "%s: failed to allocate FBC buffer %zu\n",
1303				__func__, inst->frame_vbuf[i].size);
1304			goto free_buffers;
1305		}
1306
1307		inst->frame_buf[i].buf_y = inst->frame_vbuf[i].daddr;
1308		inst->frame_buf[i].buf_cb = (dma_addr_t)-1;
1309		inst->frame_buf[i].buf_cr = (dma_addr_t)-1;
1310		inst->frame_buf[i].update_fb_info = true;
1311		inst->frame_buf[i].size = inst->frame_vbuf[i].size;
1312	}
1313
1314	ret = wave5_vpu_enc_register_frame_buffer(inst, inst->fbc_buf_count, fb_stride,
1315						  fb_height, COMPRESSED_FRAME_MAP);
1316	if (ret) {
1317		dev_err(inst->dev->dev,
1318			"%s: wave5_vpu_enc_register_frame_buffer, fail: %d\n",
1319			__func__, ret);
1320		goto free_buffers;
1321	}
1322
1323	return 0;
1324free_buffers:
1325	for (i = 0; i < inst->fbc_buf_count; i++)
1326		wave5_vpu_dec_reset_framebuffer(inst, i);
1327	return ret;
1328}
1329
1330static int wave5_vpu_enc_start_streaming(struct vb2_queue *q, unsigned int count)
1331{
1332	struct vpu_instance *inst = vb2_get_drv_priv(q);
1333	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
1334	int ret = 0;
1335
1336	pm_runtime_resume_and_get(inst->dev->dev);
1337	v4l2_m2m_update_start_streaming_state(m2m_ctx, q);
1338
1339	if (inst->state == VPU_INST_STATE_NONE && q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1340		struct enc_open_param open_param;
1341
1342		memset(&open_param, 0, sizeof(struct enc_open_param));
1343
1344		ret = wave5_set_enc_openparam(&open_param, inst);
1345		if (ret) {
1346			dev_dbg(inst->dev->dev, "%s: wave5_set_enc_openparam, fail: %d\n",
1347				__func__, ret);
1348			goto return_buffers;
1349		}
1350
1351		ret = wave5_vpu_enc_open(inst, &open_param);
1352		if (ret) {
1353			dev_dbg(inst->dev->dev, "%s: wave5_vpu_enc_open, fail: %d\n",
1354				__func__, ret);
1355			goto return_buffers;
1356		}
1357
1358		if (inst->mirror_direction) {
1359			wave5_vpu_enc_give_command(inst, ENABLE_MIRRORING, NULL);
1360			wave5_vpu_enc_give_command(inst, SET_MIRROR_DIRECTION,
1361						   &inst->mirror_direction);
1362		}
1363		if (inst->rot_angle) {
1364			wave5_vpu_enc_give_command(inst, ENABLE_ROTATION, NULL);
1365			wave5_vpu_enc_give_command(inst, SET_ROTATION_ANGLE, &inst->rot_angle);
1366		}
1367
1368		ret = switch_state(inst, VPU_INST_STATE_OPEN);
1369		if (ret)
1370			goto return_buffers;
1371	}
1372	if (inst->state == VPU_INST_STATE_OPEN &&
1373	    (m2m_ctx->cap_q_ctx.q.streaming || q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) {
1374		ret = initialize_sequence(inst);
1375		if (ret) {
1376			dev_warn(inst->dev->dev, "Sequence not found: %d\n", ret);
1377			goto return_buffers;
1378		}
1379		ret = switch_state(inst, VPU_INST_STATE_INIT_SEQ);
1380		if (ret)
1381			goto return_buffers;
1382		/*
1383		 * The sequence must be analyzed first to calculate the proper
1384		 * size of the auxiliary buffers.
1385		 */
1386		ret = prepare_fb(inst);
1387		if (ret) {
1388			dev_warn(inst->dev->dev, "Framebuffer preparation, fail: %d\n", ret);
1389			goto return_buffers;
1390		}
1391
1392		ret = switch_state(inst, VPU_INST_STATE_PIC_RUN);
1393	}
1394	if (ret)
1395		goto return_buffers;
1396
1397	pm_runtime_put_autosuspend(inst->dev->dev);
1398	return 0;
1399return_buffers:
1400	wave5_return_bufs(q, VB2_BUF_STATE_QUEUED);
1401	pm_runtime_put_autosuspend(inst->dev->dev);
1402	return ret;
1403}
1404
1405static void streamoff_output(struct vpu_instance *inst, struct vb2_queue *q)
1406{
1407	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
1408	struct vb2_v4l2_buffer *buf;
1409
1410	while ((buf = v4l2_m2m_src_buf_remove(m2m_ctx))) {
1411		dev_dbg(inst->dev->dev, "%s: buf type %4u | index %4u\n",
1412			__func__, buf->vb2_buf.type, buf->vb2_buf.index);
1413		v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR);
1414	}
1415}
1416
1417static void streamoff_capture(struct vpu_instance *inst, struct vb2_queue *q)
1418{
1419	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
1420	struct vb2_v4l2_buffer *buf;
1421
1422	while ((buf = v4l2_m2m_dst_buf_remove(m2m_ctx))) {
1423		dev_dbg(inst->dev->dev, "%s: buf type %4u | index %4u\n",
1424			__func__, buf->vb2_buf.type, buf->vb2_buf.index);
1425		vb2_set_plane_payload(&buf->vb2_buf, 0, 0);
1426		v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR);
1427	}
1428
1429	v4l2_m2m_clear_state(m2m_ctx);
1430}
1431
1432static void wave5_vpu_enc_stop_streaming(struct vb2_queue *q)
1433{
1434	struct vpu_instance *inst = vb2_get_drv_priv(q);
1435	bool check_cmd = true;
1436
1437	/*
1438	 * Note that we don't need m2m_ctx->next_buf_last for this driver, so we
1439	 * don't call v4l2_m2m_update_stop_streaming_state().
1440	 */
1441
1442	dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type);
1443	pm_runtime_resume_and_get(inst->dev->dev);
1444
1445	if (wave5_vpu_both_queues_are_streaming(inst))
1446		switch_state(inst, VPU_INST_STATE_STOP);
1447
1448	while (check_cmd) {
1449		struct queue_status_info q_status;
1450		struct enc_output_info enc_output_info;
1451
1452		wave5_vpu_enc_give_command(inst, ENC_GET_QUEUE_STATUS, &q_status);
1453
1454		if (q_status.report_queue_count == 0)
1455			break;
1456
1457		if (wave5_vpu_wait_interrupt(inst, VPU_ENC_TIMEOUT) < 0)
1458			break;
1459
1460		if (wave5_vpu_enc_get_output_info(inst, &enc_output_info))
1461			dev_dbg(inst->dev->dev, "Getting encoding results from fw, fail\n");
1462	}
1463
1464	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1465		streamoff_output(inst, q);
1466	else
1467		streamoff_capture(inst, q);
1468
1469	pm_runtime_put_autosuspend(inst->dev->dev);
1470}
1471
1472static const struct vb2_ops wave5_vpu_enc_vb2_ops = {
1473	.queue_setup = wave5_vpu_enc_queue_setup,
1474	.buf_queue = wave5_vpu_enc_buf_queue,
1475	.start_streaming = wave5_vpu_enc_start_streaming,
1476	.stop_streaming = wave5_vpu_enc_stop_streaming,
1477};
1478
1479static void wave5_set_default_format(struct v4l2_pix_format_mplane *src_fmt,
1480				     struct v4l2_pix_format_mplane *dst_fmt)
1481{
1482	src_fmt->pixelformat = enc_fmt_list[VPU_FMT_TYPE_RAW][0].v4l2_pix_fmt;
1483	wave5_update_pix_fmt(src_fmt, VPU_FMT_TYPE_RAW,
1484			     W5_DEF_ENC_PIC_WIDTH, W5_DEF_ENC_PIC_HEIGHT,
1485			     &enc_frmsize[VPU_FMT_TYPE_RAW]);
1486
1487	dst_fmt->pixelformat = enc_fmt_list[VPU_FMT_TYPE_CODEC][0].v4l2_pix_fmt;
1488	wave5_update_pix_fmt(dst_fmt, VPU_FMT_TYPE_CODEC,
1489			     W5_DEF_ENC_PIC_WIDTH, W5_DEF_ENC_PIC_HEIGHT,
1490			     &enc_frmsize[VPU_FMT_TYPE_CODEC]);
1491}
1492
1493static int wave5_vpu_enc_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
1494{
1495	return wave5_vpu_queue_init(priv, src_vq, dst_vq, &wave5_vpu_enc_vb2_ops);
1496}
1497
1498static const struct vpu_instance_ops wave5_vpu_enc_inst_ops = {
1499	.finish_process = wave5_vpu_enc_finish_encode,
1500};
1501
1502static void wave5_vpu_enc_device_run(void *priv)
1503{
1504	struct vpu_instance *inst = priv;
1505	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
1506	u32 fail_res = 0;
1507	int ret = 0;
1508
1509	pm_runtime_resume_and_get(inst->dev->dev);
1510	switch (inst->state) {
1511	case VPU_INST_STATE_PIC_RUN:
1512		ret = start_encode(inst, &fail_res);
1513		if (ret) {
1514			if (ret == -EINVAL)
1515				dev_err(inst->dev->dev,
1516					"Frame encoding on m2m context (%p), fail: %d (res: %d)\n",
1517					m2m_ctx, ret, fail_res);
1518			else if (ret == -EAGAIN)
1519				dev_dbg(inst->dev->dev, "Missing buffers for encode, try again\n");
1520			break;
1521		}
1522		dev_dbg(inst->dev->dev, "%s: leave with active job", __func__);
1523		pm_runtime_put_autosuspend(inst->dev->dev);
1524		return;
1525	default:
1526		WARN(1, "Execution of a job in state %s is invalid.\n",
1527		     state_to_str(inst->state));
1528		break;
1529	}
1530	dev_dbg(inst->dev->dev, "%s: leave and finish job", __func__);
1531	pm_runtime_put_autosuspend(inst->dev->dev);
1532	v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
1533}
1534
1535static int wave5_vpu_enc_job_ready(void *priv)
1536{
1537	struct vpu_instance *inst = priv;
1538	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
1539
1540	switch (inst->state) {
1541	case VPU_INST_STATE_NONE:
1542		dev_dbg(inst->dev->dev, "Encoder must be open to start queueing M2M jobs!\n");
1543		return false;
1544	case VPU_INST_STATE_PIC_RUN:
1545		if (m2m_ctx->is_draining || v4l2_m2m_num_src_bufs_ready(m2m_ctx)) {
1546			dev_dbg(inst->dev->dev, "Encoder ready for a job, state: %s\n",
1547				state_to_str(inst->state));
1548			return true;
1549		}
1550		fallthrough;
1551	default:
1552		dev_dbg(inst->dev->dev,
1553			"Encoder not ready for a job, state: %s, %s draining, %d src bufs ready\n",
1554			state_to_str(inst->state), m2m_ctx->is_draining ? "is" : "is not",
1555			v4l2_m2m_num_src_bufs_ready(m2m_ctx));
1556		break;
1557	}
1558	return false;
1559}
1560
1561static const struct v4l2_m2m_ops wave5_vpu_enc_m2m_ops = {
1562	.device_run = wave5_vpu_enc_device_run,
1563	.job_ready = wave5_vpu_enc_job_ready,
1564};
1565
1566static int wave5_vpu_open_enc(struct file *filp)
1567{
1568	struct video_device *vdev = video_devdata(filp);
1569	struct vpu_device *dev = video_drvdata(filp);
1570	struct vpu_instance *inst = NULL;
1571	struct v4l2_ctrl_handler *v4l2_ctrl_hdl;
1572	int ret = 0;
1573
1574	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
1575	if (!inst)
1576		return -ENOMEM;
1577	v4l2_ctrl_hdl = &inst->v4l2_ctrl_hdl;
1578
1579	inst->dev = dev;
1580	inst->type = VPU_INST_TYPE_ENC;
1581	inst->ops = &wave5_vpu_enc_inst_ops;
1582
1583	inst->codec_info = kzalloc(sizeof(*inst->codec_info), GFP_KERNEL);
1584	if (!inst->codec_info) {
1585		kfree(inst);
1586		return -ENOMEM;
1587	}
1588
1589	v4l2_fh_init(&inst->v4l2_fh, vdev);
1590	v4l2_fh_add(&inst->v4l2_fh, filp);
1591
1592	INIT_LIST_HEAD(&inst->list);
1593
1594	inst->v4l2_m2m_dev = inst->dev->v4l2_m2m_enc_dev;
1595	inst->v4l2_fh.m2m_ctx =
1596		v4l2_m2m_ctx_init(inst->v4l2_m2m_dev, inst, wave5_vpu_enc_queue_init);
1597	if (IS_ERR(inst->v4l2_fh.m2m_ctx)) {
1598		ret = PTR_ERR(inst->v4l2_fh.m2m_ctx);
1599		goto cleanup_inst;
1600	}
1601	v4l2_m2m_set_src_buffered(inst->v4l2_fh.m2m_ctx, true);
1602
1603	v4l2_ctrl_handler_init(v4l2_ctrl_hdl, 50);
1604	v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1605			       V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
1606			       V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10, 0,
1607			       V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN);
1608	v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1609			       V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
1610			       V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, 0,
1611			       V4L2_MPEG_VIDEO_HEVC_LEVEL_1);
1612	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1613			  V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
1614			  0, 63, 1, 8);
1615	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1616			  V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
1617			  0, 63, 1, 51);
1618	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1619			  V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP,
1620			  0, 63, 1, 30);
1621	v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1622			       V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE,
1623			       V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY, 0,
1624			       V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_ENABLED);
1625	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1626			  V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2,
1627			  -6, 6, 1, 0);
1628	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1629			  V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2,
1630			  -6, 6, 1, 0);
1631	v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1632			       V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE,
1633			       V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR, 0,
1634			       V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR);
1635	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1636			  V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD,
1637			  0, 2047, 1, 0);
1638	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1639			  V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU,
1640			  0, 1, 1, 0);
1641	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1642			  V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED,
1643			  0, 1, 1, 0);
1644	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1645			  V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT,
1646			  0, 1, 1, 0);
1647	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1648			  V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING,
1649			  0, 1, 1, 1);
1650	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1651			  V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1,
1652			  1, 2, 1, 2);
1653	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1654			  V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION,
1655			  0, 1, 1, 1);
1656
1657	v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1658			       V4L2_CID_MPEG_VIDEO_H264_PROFILE,
1659			       V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE, 0,
1660			       V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE);
1661	v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1662			       V4L2_CID_MPEG_VIDEO_H264_LEVEL,
1663			       V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 0,
1664			       V4L2_MPEG_VIDEO_H264_LEVEL_1_0);
1665	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1666			  V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
1667			  0, 63, 1, 8);
1668	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1669			  V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
1670			  0, 63, 1, 51);
1671	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1672			  V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
1673			  0, 63, 1, 30);
1674	v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1675			       V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
1676			       V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY, 0,
1677			       V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED);
1678	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1679			  V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA,
1680			  -6, 6, 1, 0);
1681	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1682			  V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA,
1683			  -6, 6, 1, 0);
1684	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1685			  V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM,
1686			  0, 1, 1, 1);
1687	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1688			  V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION,
1689			  0, 1, 1, 0);
1690	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1691			  V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET,
1692			  -12, 12, 1, 0);
1693	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1694			  V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
1695			  0, 2047, 1, 0);
1696	v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1697			       V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
1698			       V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC, 0,
1699			       V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC);
1700	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1701			  V4L2_CID_MPEG_VIDEO_AU_DELIMITER,
1702			  0, 1, 1, 1);
1703	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1704			  V4L2_CID_HFLIP,
1705			  0, 1, 1, 0);
1706	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1707			  V4L2_CID_VFLIP,
1708			  0, 1, 1, 0);
1709	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1710			  V4L2_CID_ROTATE,
1711			  0, 270, 90, 0);
1712	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1713			  V4L2_CID_MPEG_VIDEO_VBV_SIZE,
1714			  10, 3000, 1, 1000);
1715	v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1716			       V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
1717			       V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
1718			       V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
1719	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1720			  V4L2_CID_MPEG_VIDEO_BITRATE,
1721			  0, 700000000, 1, 0);
1722	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1723			  V4L2_CID_MPEG_VIDEO_GOP_SIZE,
1724			  0, 2047, 1, 0);
1725	v4l2_ctrl_new_std_menu(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1726			       V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
1727			       V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB, 0,
1728			       V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE);
1729	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1730			  V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
1731			  0, 0xFFFF, 1, 0);
1732	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1733			  V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE,
1734			  0, 1, 1, 0);
1735	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1736			  V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE,
1737			  0, 1, 1, 0);
1738	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1739			  V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 1);
1740	v4l2_ctrl_new_std(v4l2_ctrl_hdl, &wave5_vpu_enc_ctrl_ops,
1741			  V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR,
1742			  0, 1, 1, 0);
1743
1744	if (v4l2_ctrl_hdl->error) {
1745		ret = -ENODEV;
1746		goto cleanup_inst;
1747	}
1748
1749	inst->v4l2_fh.ctrl_handler = v4l2_ctrl_hdl;
1750	v4l2_ctrl_handler_setup(v4l2_ctrl_hdl);
1751
1752	wave5_set_default_format(&inst->src_fmt, &inst->dst_fmt);
1753	inst->conf_win.width = inst->dst_fmt.width;
1754	inst->conf_win.height = inst->dst_fmt.height;
1755	inst->colorspace = V4L2_COLORSPACE_REC709;
1756	inst->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
1757	inst->quantization = V4L2_QUANTIZATION_DEFAULT;
1758	inst->xfer_func = V4L2_XFER_FUNC_DEFAULT;
1759	inst->frame_rate = 30;
1760
1761	init_completion(&inst->irq_done);
1762	ret = wave5_kfifo_alloc(inst);
1763	if (ret) {
1764		dev_err(inst->dev->dev, "failed to allocate fifo\n");
1765		goto cleanup_inst;
1766	}
1767
1768	inst->id = ida_alloc(&inst->dev->inst_ida, GFP_KERNEL);
1769	if (inst->id < 0) {
1770		dev_warn(inst->dev->dev, "Allocating instance ID, fail: %d\n", inst->id);
1771		ret = inst->id;
1772		goto cleanup_inst;
1773	}
1774
1775	wave5_vdi_allocate_sram(inst->dev);
1776
1777	ret = mutex_lock_interruptible(&dev->dev_lock);
1778	if (ret)
1779		goto cleanup_inst;
1780
1781	list_add_tail(&inst->list, &dev->instances);
1782
1783	mutex_unlock(&dev->dev_lock);
1784
1785	return 0;
1786
1787cleanup_inst:
1788	wave5_cleanup_instance(inst, filp);
1789	return ret;
1790}
1791
1792static int wave5_vpu_enc_release(struct file *filp)
1793{
1794	return wave5_vpu_release_device(filp, wave5_vpu_enc_close, "encoder");
1795}
1796
1797static const struct v4l2_file_operations wave5_vpu_enc_fops = {
1798	.owner = THIS_MODULE,
1799	.open = wave5_vpu_open_enc,
1800	.release = wave5_vpu_enc_release,
1801	.unlocked_ioctl = video_ioctl2,
1802	.poll = v4l2_m2m_fop_poll,
1803	.mmap = v4l2_m2m_fop_mmap,
1804};
1805
1806int wave5_vpu_enc_register_device(struct vpu_device *dev)
1807{
1808	struct video_device *vdev_enc;
1809	int ret;
1810
1811	vdev_enc = devm_kzalloc(dev->v4l2_dev.dev, sizeof(*vdev_enc), GFP_KERNEL);
1812	if (!vdev_enc)
1813		return -ENOMEM;
1814
1815	dev->v4l2_m2m_enc_dev = v4l2_m2m_init(&wave5_vpu_enc_m2m_ops);
1816	if (IS_ERR(dev->v4l2_m2m_enc_dev)) {
1817		ret = PTR_ERR(dev->v4l2_m2m_enc_dev);
1818		dev_err(dev->dev, "v4l2_m2m_init, fail: %d\n", ret);
1819		return -EINVAL;
1820	}
1821
1822	dev->video_dev_enc = vdev_enc;
1823
1824	strscpy(vdev_enc->name, VPU_ENC_DEV_NAME, sizeof(vdev_enc->name));
1825	vdev_enc->fops = &wave5_vpu_enc_fops;
1826	vdev_enc->ioctl_ops = &wave5_vpu_enc_ioctl_ops;
1827	vdev_enc->release = video_device_release_empty;
1828	vdev_enc->v4l2_dev = &dev->v4l2_dev;
1829	vdev_enc->vfl_dir = VFL_DIR_M2M;
1830	vdev_enc->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
1831	vdev_enc->lock = &dev->dev_lock;
1832
1833	ret = video_register_device(vdev_enc, VFL_TYPE_VIDEO, -1);
1834	if (ret)
1835		return ret;
1836
1837	video_set_drvdata(vdev_enc, dev);
1838
1839	return 0;
1840}
1841
1842void wave5_vpu_enc_unregister_device(struct vpu_device *dev)
1843{
1844	video_unregister_device(dev->video_dev_enc);
1845	if (dev->v4l2_m2m_enc_dev)
1846		v4l2_m2m_release(dev->v4l2_m2m_enc_dev);
1847}
~/ Read-only file preview.