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