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