1
2
3
4
5
6
7
8
9
10#include <linux/clk.h>
11#include <linux/interrupt.h>
12#include <linux/io.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/sched.h>
16#include <linux/slab.h>
17#include <linux/videodev2.h>
18#include <linux/workqueue.h>
19#include <media/v4l2-ctrls.h>
20#include <media/v4l2-event.h>
21#include <media/videobuf2-v4l2.h>
22#include "s5p_mfc_common.h"
23#include "s5p_mfc_ctrl.h"
24#include "s5p_mfc_debug.h"
25#include "s5p_mfc_dec.h"
26#include "s5p_mfc_intr.h"
27#include "s5p_mfc_opr.h"
28#include "s5p_mfc_pm.h"
29
30static struct s5p_mfc_fmt formats[] = {
31 {
32 .name = "4:2:0 2 Planes 16x16 Tiles",
33 .fourcc = V4L2_PIX_FMT_NV12MT_16X16,
34 .codec_mode = S5P_MFC_CODEC_NONE,
35 .type = MFC_FMT_RAW,
36 .num_planes = 2,
37 .versions = MFC_V6_BIT | MFC_V7_BIT,
38 },
39 {
40 .name = "4:2:0 2 Planes 64x32 Tiles",
41 .fourcc = V4L2_PIX_FMT_NV12MT,
42 .codec_mode = S5P_MFC_CODEC_NONE,
43 .type = MFC_FMT_RAW,
44 .num_planes = 2,
45 .versions = MFC_V5_BIT,
46 },
47 {
48 .name = "4:2:0 2 Planes Y/CbCr",
49 .fourcc = V4L2_PIX_FMT_NV12M,
50 .codec_mode = S5P_MFC_CODEC_NONE,
51 .type = MFC_FMT_RAW,
52 .num_planes = 2,
53 .versions = MFC_V6PLUS_BITS,
54 },
55 {
56 .name = "4:2:0 2 Planes Y/CrCb",
57 .fourcc = V4L2_PIX_FMT_NV21M,
58 .codec_mode = S5P_MFC_CODEC_NONE,
59 .type = MFC_FMT_RAW,
60 .num_planes = 2,
61 .versions = MFC_V6PLUS_BITS,
62 },
63 {
64 .name = "H264 Encoded Stream",
65 .fourcc = V4L2_PIX_FMT_H264,
66 .codec_mode = S5P_MFC_CODEC_H264_DEC,
67 .type = MFC_FMT_DEC,
68 .num_planes = 1,
69 .versions = MFC_V5PLUS_BITS,
70 },
71 {
72 .name = "H264/MVC Encoded Stream",
73 .fourcc = V4L2_PIX_FMT_H264_MVC,
74 .codec_mode = S5P_MFC_CODEC_H264_MVC_DEC,
75 .type = MFC_FMT_DEC,
76 .num_planes = 1,
77 .versions = MFC_V6PLUS_BITS,
78 },
79 {
80 .name = "H263 Encoded Stream",
81 .fourcc = V4L2_PIX_FMT_H263,
82 .codec_mode = S5P_MFC_CODEC_H263_DEC,
83 .type = MFC_FMT_DEC,
84 .num_planes = 1,
85 .versions = MFC_V5PLUS_BITS,
86 },
87 {
88 .name = "MPEG1 Encoded Stream",
89 .fourcc = V4L2_PIX_FMT_MPEG1,
90 .codec_mode = S5P_MFC_CODEC_MPEG2_DEC,
91 .type = MFC_FMT_DEC,
92 .num_planes = 1,
93 .versions = MFC_V5PLUS_BITS,
94 },
95 {
96 .name = "MPEG2 Encoded Stream",
97 .fourcc = V4L2_PIX_FMT_MPEG2,
98 .codec_mode = S5P_MFC_CODEC_MPEG2_DEC,
99 .type = MFC_FMT_DEC,
100 .num_planes = 1,
101 .versions = MFC_V5PLUS_BITS,
102 },
103 {
104 .name = "MPEG4 Encoded Stream",
105 .fourcc = V4L2_PIX_FMT_MPEG4,
106 .codec_mode = S5P_MFC_CODEC_MPEG4_DEC,
107 .type = MFC_FMT_DEC,
108 .num_planes = 1,
109 .versions = MFC_V5PLUS_BITS,
110 },
111 {
112 .name = "XviD Encoded Stream",
113 .fourcc = V4L2_PIX_FMT_XVID,
114 .codec_mode = S5P_MFC_CODEC_MPEG4_DEC,
115 .type = MFC_FMT_DEC,
116 .num_planes = 1,
117 .versions = MFC_V5PLUS_BITS,
118 },
119 {
120 .name = "VC1 Encoded Stream",
121 .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
122 .codec_mode = S5P_MFC_CODEC_VC1_DEC,
123 .type = MFC_FMT_DEC,
124 .num_planes = 1,
125 .versions = MFC_V5PLUS_BITS,
126 },
127 {
128 .name = "VC1 RCV Encoded Stream",
129 .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
130 .codec_mode = S5P_MFC_CODEC_VC1RCV_DEC,
131 .type = MFC_FMT_DEC,
132 .num_planes = 1,
133 .versions = MFC_V5PLUS_BITS,
134 },
135 {
136 .name = "VP8 Encoded Stream",
137 .fourcc = V4L2_PIX_FMT_VP8,
138 .codec_mode = S5P_MFC_CODEC_VP8_DEC,
139 .type = MFC_FMT_DEC,
140 .num_planes = 1,
141 .versions = MFC_V6PLUS_BITS,
142 },
143 {
144 .fourcc = V4L2_PIX_FMT_HEVC,
145 .codec_mode = S5P_FIMV_CODEC_HEVC_DEC,
146 .type = MFC_FMT_DEC,
147 .num_planes = 1,
148 .versions = MFC_V10_BIT,
149 },
150 {
151 .fourcc = V4L2_PIX_FMT_VP9,
152 .codec_mode = S5P_FIMV_CODEC_VP9_DEC,
153 .type = MFC_FMT_DEC,
154 .num_planes = 1,
155 .versions = MFC_V10_BIT,
156 },
157};
158
159#define NUM_FORMATS ARRAY_SIZE(formats)
160
161
162static struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t)
163{
164 unsigned int i;
165
166 for (i = 0; i < NUM_FORMATS; i++) {
167 if (formats[i].fourcc == f->fmt.pix_mp.pixelformat &&
168 formats[i].type == t)
169 return &formats[i];
170 }
171 return NULL;
172}
173
174static struct mfc_control controls[] = {
175 {
176 .id = V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY,
177 .type = V4L2_CTRL_TYPE_INTEGER,
178 .name = "H264 Display Delay",
179 .minimum = 0,
180 .maximum = 16383,
181 .step = 1,
182 .default_value = 0,
183 },
184 {
185 .id = V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE,
186 .type = V4L2_CTRL_TYPE_BOOLEAN,
187 .name = "H264 Display Delay Enable",
188 .minimum = 0,
189 .maximum = 1,
190 .step = 1,
191 .default_value = 0,
192 },
193 {
194 .id = V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER,
195 .type = V4L2_CTRL_TYPE_BOOLEAN,
196 .name = "Mpeg4 Loop Filter Enable",
197 .minimum = 0,
198 .maximum = 1,
199 .step = 1,
200 .default_value = 0,
201 },
202 {
203 .id = V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE,
204 .type = V4L2_CTRL_TYPE_BOOLEAN,
205 .name = "Slice Interface Enable",
206 .minimum = 0,
207 .maximum = 1,
208 .step = 1,
209 .default_value = 0,
210 },
211 {
212 .id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
213 .type = V4L2_CTRL_TYPE_INTEGER,
214 .name = "Minimum number of cap bufs",
215 .minimum = 1,
216 .maximum = 32,
217 .step = 1,
218 .default_value = 1,
219 .is_volatile = 1,
220 },
221};
222
223#define NUM_CTRLS ARRAY_SIZE(controls)
224
225
226static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)
227{
228
229 if (ctx->src_queue_cnt >= 1 && ctx->state == MFCINST_GOT_INST)
230 return 1;
231
232 if (ctx->src_queue_cnt >= 1 &&
233 ctx->state == MFCINST_RUNNING &&
234 ctx->dst_queue_cnt >= ctx->pb_count)
235 return 1;
236
237 if (ctx->state == MFCINST_FINISHING &&
238 ctx->dst_queue_cnt >= ctx->pb_count)
239 return 1;
240
241 if (ctx->src_queue_cnt >= 1 &&
242 ctx->state == MFCINST_HEAD_PARSED &&
243 ctx->capture_state == QUEUE_BUFS_MMAPED)
244 return 1;
245
246 if ((ctx->state == MFCINST_RES_CHANGE_INIT ||
247 ctx->state == MFCINST_RES_CHANGE_FLUSH) &&
248 ctx->dst_queue_cnt >= ctx->pb_count)
249 return 1;
250 if (ctx->state == MFCINST_RES_CHANGE_END &&
251 ctx->src_queue_cnt >= 1)
252 return 1;
253 mfc_debug(2, "ctx is not ready\n");
254 return 0;
255}
256
257static const struct s5p_mfc_codec_ops decoder_codec_ops = {
258 .pre_seq_start = NULL,
259 .post_seq_start = NULL,
260 .pre_frame_start = NULL,
261 .post_frame_start = NULL,
262};
263
264
265static int vidioc_querycap(struct file *file, void *priv,
266 struct v4l2_capability *cap)
267{
268 struct s5p_mfc_dev *dev = video_drvdata(file);
269
270 strscpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver));
271 strscpy(cap->card, dev->vfd_dec->name, sizeof(cap->card));
272 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
273 dev_name(&dev->plat_dev->dev));
274 return 0;
275}
276
277
278static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f,
279 bool out)
280{
281 struct s5p_mfc_dev *dev = video_drvdata(file);
282 struct s5p_mfc_fmt *fmt;
283 int i, j = 0;
284
285 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
286 if (out && formats[i].type != MFC_FMT_DEC)
287 continue;
288 else if (!out && formats[i].type != MFC_FMT_RAW)
289 continue;
290 else if ((dev->variant->version_bit & formats[i].versions) == 0)
291 continue;
292
293 if (j == f->index)
294 break;
295 ++j;
296 }
297 if (i == ARRAY_SIZE(formats))
298 return -EINVAL;
299 fmt = &formats[i];
300 strscpy(f->description, fmt->name, sizeof(f->description));
301 f->pixelformat = fmt->fourcc;
302 return 0;
303}
304
305static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv,
306 struct v4l2_fmtdesc *f)
307{
308 return vidioc_enum_fmt(file, f, false);
309}
310
311static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
312 struct v4l2_fmtdesc *f)
313{
314 return vidioc_enum_fmt(file, f, true);
315}
316
317
318static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
319{
320 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
321 struct v4l2_pix_format_mplane *pix_mp;
322
323 mfc_debug_enter();
324 pix_mp = &f->fmt.pix_mp;
325 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
326 (ctx->state == MFCINST_GOT_INST || ctx->state ==
327 MFCINST_RES_CHANGE_END)) {
328
329
330 s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_SEQ_DONE_RET,
331 0);
332 }
333 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
334 ctx->state >= MFCINST_HEAD_PARSED &&
335 ctx->state < MFCINST_ABORT) {
336
337
338
339
340
341 pix_mp->width = ctx->buf_width;
342 pix_mp->height = ctx->buf_height;
343 pix_mp->field = V4L2_FIELD_NONE;
344 pix_mp->num_planes = 2;
345
346
347 pix_mp->pixelformat = ctx->dst_fmt->fourcc;
348 pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
349 pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
350 pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
351 pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
352 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
353
354
355
356 pix_mp->width = 0;
357 pix_mp->height = 0;
358 pix_mp->field = V4L2_FIELD_NONE;
359 pix_mp->plane_fmt[0].bytesperline = ctx->dec_src_buf_size;
360 pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size;
361 pix_mp->pixelformat = ctx->src_fmt->fourcc;
362 pix_mp->num_planes = ctx->src_fmt->num_planes;
363 } else {
364 mfc_err("Format could not be read\n");
365 mfc_debug(2, "%s-- with error\n", __func__);
366 return -EINVAL;
367 }
368 mfc_debug_leave();
369 return 0;
370}
371
372
373static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
374{
375 struct s5p_mfc_dev *dev = video_drvdata(file);
376 struct s5p_mfc_fmt *fmt;
377
378 mfc_debug(2, "Type is %d\n", f->type);
379 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
380 fmt = find_format(f, MFC_FMT_DEC);
381 if (!fmt) {
382 mfc_err("Unsupported format for source.\n");
383 return -EINVAL;
384 }
385 if (fmt->codec_mode == S5P_FIMV_CODEC_NONE) {
386 mfc_err("Unknown codec\n");
387 return -EINVAL;
388 }
389 if ((dev->variant->version_bit & fmt->versions) == 0) {
390 mfc_err("Unsupported format by this MFC version.\n");
391 return -EINVAL;
392 }
393 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
394 fmt = find_format(f, MFC_FMT_RAW);
395 if (!fmt) {
396 mfc_err("Unsupported format for destination.\n");
397 return -EINVAL;
398 }
399 if ((dev->variant->version_bit & fmt->versions) == 0) {
400 mfc_err("Unsupported format by this MFC version.\n");
401 return -EINVAL;
402 }
403 }
404
405 return 0;
406}
407
408
409static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
410{
411 struct s5p_mfc_dev *dev = video_drvdata(file);
412 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
413 int ret = 0;
414 struct v4l2_pix_format_mplane *pix_mp;
415 struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size;
416
417 mfc_debug_enter();
418 ret = vidioc_try_fmt(file, priv, f);
419 pix_mp = &f->fmt.pix_mp;
420 if (ret)
421 return ret;
422 if (vb2_is_streaming(&ctx->vq_src) || vb2_is_streaming(&ctx->vq_dst)) {
423 v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__);
424 ret = -EBUSY;
425 goto out;
426 }
427 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
428
429 ctx->dst_fmt = find_format(f, MFC_FMT_RAW);
430 ret = 0;
431 goto out;
432 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
433
434 ctx->src_fmt = find_format(f, MFC_FMT_DEC);
435 ctx->codec_mode = ctx->src_fmt->codec_mode;
436 mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
437 pix_mp->height = 0;
438 pix_mp->width = 0;
439 if (pix_mp->plane_fmt[0].sizeimage == 0)
440 pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size =
441 DEF_CPB_SIZE;
442 else if (pix_mp->plane_fmt[0].sizeimage > buf_size->cpb)
443 ctx->dec_src_buf_size = buf_size->cpb;
444 else
445 ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage;
446 pix_mp->plane_fmt[0].bytesperline = 0;
447 ctx->state = MFCINST_INIT;
448 ret = 0;
449 goto out;
450 } else {
451 mfc_err("Wrong type error for S_FMT : %d", f->type);
452 ret = -EINVAL;
453 goto out;
454 }
455
456out:
457 mfc_debug_leave();
458 return ret;
459}
460
461static int reqbufs_output(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx,
462 struct v4l2_requestbuffers *reqbufs)
463{
464 int ret = 0;
465
466 s5p_mfc_clock_on();
467
468 if (reqbufs->count == 0) {
469 mfc_debug(2, "Freeing buffers\n");
470 ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
471 if (ret)
472 goto out;
473 ctx->src_bufs_cnt = 0;
474 ctx->output_state = QUEUE_FREE;
475 } else if (ctx->output_state == QUEUE_FREE) {
476
477 WARN_ON(ctx->src_bufs_cnt != 0);
478 if (ctx->state != MFCINST_INIT) {
479 mfc_err("Reqbufs called in an invalid state\n");
480 ret = -EINVAL;
481 goto out;
482 }
483
484 mfc_debug(2, "Allocating %d buffers for OUTPUT queue\n",
485 reqbufs->count);
486 ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
487 if (ret)
488 goto out;
489
490 ret = s5p_mfc_open_mfc_inst(dev, ctx);
491 if (ret) {
492 reqbufs->count = 0;
493 vb2_reqbufs(&ctx->vq_src, reqbufs);
494 goto out;
495 }
496
497 ctx->output_state = QUEUE_BUFS_REQUESTED;
498 } else {
499 mfc_err("Buffers have already been requested\n");
500 ret = -EINVAL;
501 }
502out:
503 s5p_mfc_clock_off();
504 if (ret)
505 mfc_err("Failed allocating buffers for OUTPUT queue\n");
506 return ret;
507}
508
509static int reqbufs_capture(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx,
510 struct v4l2_requestbuffers *reqbufs)
511{
512 int ret = 0;
513
514 s5p_mfc_clock_on();
515
516 if (reqbufs->count == 0) {
517 mfc_debug(2, "Freeing buffers\n");
518 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
519 if (ret)
520 goto out;
521 s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx);
522 ctx->dst_bufs_cnt = 0;
523 } else if (ctx->capture_state == QUEUE_FREE) {
524 WARN_ON(ctx->dst_bufs_cnt != 0);
525 mfc_debug(2, "Allocating %d buffers for CAPTURE queue\n",
526 reqbufs->count);
527 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
528 if (ret)
529 goto out;
530
531 ctx->capture_state = QUEUE_BUFS_REQUESTED;
532 ctx->total_dpb_count = reqbufs->count;
533
534 ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_codec_buffers, ctx);
535 if (ret) {
536 mfc_err("Failed to allocate decoding buffers\n");
537 reqbufs->count = 0;
538 vb2_reqbufs(&ctx->vq_dst, reqbufs);
539 ret = -ENOMEM;
540 ctx->capture_state = QUEUE_FREE;
541 goto out;
542 }
543
544 WARN_ON(ctx->dst_bufs_cnt != ctx->total_dpb_count);
545 ctx->capture_state = QUEUE_BUFS_MMAPED;
546
547 if (s5p_mfc_ctx_ready(ctx))
548 set_work_bit_irqsave(ctx);
549 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
550 s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_INIT_BUFFERS_RET,
551 0);
552 } else {
553 mfc_err("Buffers have already been requested\n");
554 ret = -EINVAL;
555 }
556out:
557 s5p_mfc_clock_off();
558 if (ret)
559 mfc_err("Failed allocating buffers for CAPTURE queue\n");
560 return ret;
561}
562
563
564static int vidioc_reqbufs(struct file *file, void *priv,
565 struct v4l2_requestbuffers *reqbufs)
566{
567 struct s5p_mfc_dev *dev = video_drvdata(file);
568 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
569
570 if (reqbufs->memory != V4L2_MEMORY_MMAP) {
571 mfc_debug(2, "Only V4L2_MEMORY_MMAP is supported\n");
572 return -EINVAL;
573 }
574
575 if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
576 return reqbufs_output(dev, ctx, reqbufs);
577 } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
578 return reqbufs_capture(dev, ctx, reqbufs);
579 } else {
580 mfc_err("Invalid type requested\n");
581 return -EINVAL;
582 }
583}
584
585
586static int vidioc_querybuf(struct file *file, void *priv,
587 struct v4l2_buffer *buf)
588{
589 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
590 int ret;
591 int i;
592
593 if (buf->memory != V4L2_MEMORY_MMAP) {
594 mfc_err("Only mmapped buffers can be used\n");
595 return -EINVAL;
596 }
597 mfc_debug(2, "State: %d, buf->type: %d\n", ctx->state, buf->type);
598 if (ctx->state == MFCINST_GOT_INST &&
599 buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
600 ret = vb2_querybuf(&ctx->vq_src, buf);
601 } else if (ctx->state == MFCINST_RUNNING &&
602 buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
603 ret = vb2_querybuf(&ctx->vq_dst, buf);
604 for (i = 0; i < buf->length; i++)
605 buf->m.planes[i].m.mem_offset += DST_QUEUE_OFF_BASE;
606 } else {
607 mfc_err("vidioc_querybuf called in an inappropriate state\n");
608 ret = -EINVAL;
609 }
610 mfc_debug_leave();
611 return ret;
612}
613
614
615static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
616{
617 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
618
619 if (ctx->state == MFCINST_ERROR) {
620 mfc_err("Call on QBUF after unrecoverable error\n");
621 return -EIO;
622 }
623 if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
624 return vb2_qbuf(&ctx->vq_src, NULL, buf);
625 else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
626 return vb2_qbuf(&ctx->vq_dst, NULL, buf);
627 return -EINVAL;
628}
629
630
631static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
632{
633 const struct v4l2_event ev = {
634 .type = V4L2_EVENT_EOS
635 };
636 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
637 int ret;
638
639 if (ctx->state == MFCINST_ERROR) {
640 mfc_err_limited("Call on DQBUF after unrecoverable error\n");
641 return -EIO;
642 }
643
644 switch (buf->type) {
645 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
646 return vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
647 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
648 ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
649 if (ret)
650 return ret;
651
652 if (ctx->state == MFCINST_FINISHED &&
653 (ctx->dst_bufs[buf->index].flags & MFC_BUF_FLAG_EOS))
654 v4l2_event_queue_fh(&ctx->fh, &ev);
655 return 0;
656 default:
657 return -EINVAL;
658 }
659}
660
661
662static int vidioc_expbuf(struct file *file, void *priv,
663 struct v4l2_exportbuffer *eb)
664{
665 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
666
667 if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
668 return vb2_expbuf(&ctx->vq_src, eb);
669 if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
670 return vb2_expbuf(&ctx->vq_dst, eb);
671 return -EINVAL;
672}
673
674
675static int vidioc_streamon(struct file *file, void *priv,
676 enum v4l2_buf_type type)
677{
678 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
679 int ret = -EINVAL;
680
681 mfc_debug_enter();
682 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
683 ret = vb2_streamon(&ctx->vq_src, type);
684 else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
685 ret = vb2_streamon(&ctx->vq_dst, type);
686 mfc_debug_leave();
687 return ret;
688}
689
690
691static int vidioc_streamoff(struct file *file, void *priv,
692 enum v4l2_buf_type type)
693{
694 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
695
696 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
697 return vb2_streamoff(&ctx->vq_src, type);
698 else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
699 return vb2_streamoff(&ctx->vq_dst, type);
700 return -EINVAL;
701}
702
703
704static int s5p_mfc_dec_s_ctrl(struct v4l2_ctrl *ctrl)
705{
706 struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl);
707
708 switch (ctrl->id) {
709 case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY:
710 ctx->display_delay = ctrl->val;
711 break;
712 case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE:
713 ctx->display_delay_enable = ctrl->val;
714 break;
715 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
716 ctx->loop_filter_mpeg4 = ctrl->val;
717 break;
718 case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE:
719 ctx->slice_interface = ctrl->val;
720 break;
721 default:
722 mfc_err("Invalid control 0x%08x\n", ctrl->id);
723 return -EINVAL;
724 }
725 return 0;
726}
727
728static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl)
729{
730 struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl);
731 struct s5p_mfc_dev *dev = ctx->dev;
732
733 switch (ctrl->id) {
734 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
735 if (ctx->state >= MFCINST_HEAD_PARSED &&
736 ctx->state < MFCINST_ABORT) {
737 ctrl->val = ctx->pb_count;
738 break;
739 } else if (ctx->state != MFCINST_INIT &&
740 ctx->state != MFCINST_RES_CHANGE_END) {
741 v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n");
742 return -EINVAL;
743 }
744
745 s5p_mfc_wait_for_done_ctx(ctx,
746 S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0);
747 if (ctx->state >= MFCINST_HEAD_PARSED &&
748 ctx->state < MFCINST_ABORT) {
749 ctrl->val = ctx->pb_count;
750 } else {
751 v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n");
752 return -EINVAL;
753 }
754 break;
755 }
756 return 0;
757}
758
759
760static const struct v4l2_ctrl_ops s5p_mfc_dec_ctrl_ops = {
761 .s_ctrl = s5p_mfc_dec_s_ctrl,
762 .g_volatile_ctrl = s5p_mfc_dec_g_v_ctrl,
763};
764
765
766static int vidioc_g_selection(struct file *file, void *priv,
767 struct v4l2_selection *s)
768{
769 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
770 struct s5p_mfc_dev *dev = ctx->dev;
771 u32 left, right, top, bottom;
772 u32 width, height;
773
774 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
775 return -EINVAL;
776
777 if (ctx->state != MFCINST_HEAD_PARSED &&
778 ctx->state != MFCINST_RUNNING &&
779 ctx->state != MFCINST_FINISHING &&
780 ctx->state != MFCINST_FINISHED) {
781 mfc_err("Can not get compose information\n");
782 return -EINVAL;
783 }
784 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264) {
785 left = s5p_mfc_hw_call(dev->mfc_ops, get_crop_info_h, ctx);
786 right = left >> S5P_FIMV_SHARED_CROP_RIGHT_SHIFT;
787 left = left & S5P_FIMV_SHARED_CROP_LEFT_MASK;
788 top = s5p_mfc_hw_call(dev->mfc_ops, get_crop_info_v, ctx);
789 bottom = top >> S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT;
790 top = top & S5P_FIMV_SHARED_CROP_TOP_MASK;
791 width = ctx->img_width - left - right;
792 height = ctx->img_height - top - bottom;
793 mfc_debug(2, "Composing info [h264]: l=%d t=%d w=%d h=%d (r=%d b=%d fw=%d fh=%d\n",
794 left, top, s->r.width, s->r.height, right, bottom,
795 ctx->buf_width, ctx->buf_height);
796 } else {
797 left = 0;
798 top = 0;
799 width = ctx->img_width;
800 height = ctx->img_height;
801 mfc_debug(2, "Composing info: w=%d h=%d fw=%d fh=%d\n",
802 s->r.width, s->r.height, ctx->buf_width,
803 ctx->buf_height);
804 }
805
806 switch (s->target) {
807 case V4L2_SEL_TGT_COMPOSE:
808 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
809 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
810 s->r.left = left;
811 s->r.top = top;
812 s->r.width = width;
813 s->r.height = height;
814 break;
815 default:
816 return -EINVAL;
817 }
818 return 0;
819}
820
821static int vidioc_decoder_cmd(struct file *file, void *priv,
822 struct v4l2_decoder_cmd *cmd)
823{
824 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
825 struct s5p_mfc_dev *dev = ctx->dev;
826 struct s5p_mfc_buf *buf;
827 unsigned long flags;
828
829 switch (cmd->cmd) {
830 case V4L2_DEC_CMD_STOP:
831 if (cmd->flags != 0)
832 return -EINVAL;
833
834 if (!vb2_is_streaming(&ctx->vq_src))
835 return -EINVAL;
836
837 spin_lock_irqsave(&dev->irqlock, flags);
838 if (list_empty(&ctx->src_queue)) {
839 mfc_err("EOS: empty src queue, entering finishing state");
840 ctx->state = MFCINST_FINISHING;
841 if (s5p_mfc_ctx_ready(ctx))
842 set_work_bit_irqsave(ctx);
843 spin_unlock_irqrestore(&dev->irqlock, flags);
844 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
845 } else {
846 mfc_err("EOS: marking last buffer of stream");
847 buf = list_entry(ctx->src_queue.prev,
848 struct s5p_mfc_buf, list);
849 if (buf->flags & MFC_BUF_FLAG_USED)
850 ctx->state = MFCINST_FINISHING;
851 else
852 buf->flags |= MFC_BUF_FLAG_EOS;
853 spin_unlock_irqrestore(&dev->irqlock, flags);
854 }
855 break;
856 default:
857 return -EINVAL;
858 }
859 return 0;
860}
861
862static int vidioc_subscribe_event(struct v4l2_fh *fh,
863 const struct v4l2_event_subscription *sub)
864{
865 switch (sub->type) {
866 case V4L2_EVENT_EOS:
867 return v4l2_event_subscribe(fh, sub, 2, NULL);
868 case V4L2_EVENT_SOURCE_CHANGE:
869 return v4l2_src_change_event_subscribe(fh, sub);
870 default:
871 return -EINVAL;
872 }
873}
874
875
876
877static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
878 .vidioc_querycap = vidioc_querycap,
879 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
880 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
881 .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt,
882 .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt,
883 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt,
884 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt,
885 .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt,
886 .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt,
887 .vidioc_reqbufs = vidioc_reqbufs,
888 .vidioc_querybuf = vidioc_querybuf,
889 .vidioc_qbuf = vidioc_qbuf,
890 .vidioc_dqbuf = vidioc_dqbuf,
891 .vidioc_expbuf = vidioc_expbuf,
892 .vidioc_streamon = vidioc_streamon,
893 .vidioc_streamoff = vidioc_streamoff,
894 .vidioc_g_selection = vidioc_g_selection,
895 .vidioc_decoder_cmd = vidioc_decoder_cmd,
896 .vidioc_subscribe_event = vidioc_subscribe_event,
897 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
898};
899
900static int s5p_mfc_queue_setup(struct vb2_queue *vq,
901 unsigned int *buf_count,
902 unsigned int *plane_count, unsigned int psize[],
903 struct device *alloc_devs[])
904{
905 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
906 struct s5p_mfc_dev *dev = ctx->dev;
907
908
909
910 if (ctx->state == MFCINST_INIT &&
911 vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
912
913 *plane_count = 1;
914 if (*buf_count < 1)
915 *buf_count = 1;
916 if (*buf_count > MFC_MAX_BUFFERS)
917 *buf_count = MFC_MAX_BUFFERS;
918
919
920 } else if (ctx->state == MFCINST_HEAD_PARSED &&
921 vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
922
923 *plane_count = 2;
924
925 if (*buf_count < ctx->pb_count)
926 *buf_count = ctx->pb_count;
927 if (*buf_count > ctx->pb_count + MFC_MAX_EXTRA_DPB)
928 *buf_count = ctx->pb_count + MFC_MAX_EXTRA_DPB;
929 if (*buf_count > MFC_MAX_BUFFERS)
930 *buf_count = MFC_MAX_BUFFERS;
931 } else {
932 mfc_err("State seems invalid. State = %d, vq->type = %d\n",
933 ctx->state, vq->type);
934 return -EINVAL;
935 }
936 mfc_debug(2, "Buffer count=%d, plane count=%d\n",
937 *buf_count, *plane_count);
938 if (ctx->state == MFCINST_HEAD_PARSED &&
939 vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
940 psize[0] = ctx->luma_size;
941 psize[1] = ctx->chroma_size;
942
943 if (IS_MFCV6_PLUS(dev))
944 alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
945 else
946 alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
947 alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
948 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
949 ctx->state == MFCINST_INIT) {
950 psize[0] = ctx->dec_src_buf_size;
951 alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
952 } else {
953 mfc_err("This video node is dedicated to decoding. Decoding not initialized\n");
954 return -EINVAL;
955 }
956 return 0;
957}
958
959static int s5p_mfc_buf_init(struct vb2_buffer *vb)
960{
961 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
962 struct vb2_queue *vq = vb->vb2_queue;
963 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
964 unsigned int i;
965
966 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
967 if (ctx->capture_state == QUEUE_BUFS_MMAPED)
968 return 0;
969 for (i = 0; i < ctx->dst_fmt->num_planes; i++) {
970 if (IS_ERR_OR_NULL(ERR_PTR(
971 vb2_dma_contig_plane_dma_addr(vb, i)))) {
972 mfc_err("Plane mem not allocated\n");
973 return -EINVAL;
974 }
975 }
976 if (vb2_plane_size(vb, 0) < ctx->luma_size ||
977 vb2_plane_size(vb, 1) < ctx->chroma_size) {
978 mfc_err("Plane buffer (CAPTURE) is too small\n");
979 return -EINVAL;
980 }
981 i = vb->index;
982 ctx->dst_bufs[i].b = vbuf;
983 ctx->dst_bufs[i].cookie.raw.luma =
984 vb2_dma_contig_plane_dma_addr(vb, 0);
985 ctx->dst_bufs[i].cookie.raw.chroma =
986 vb2_dma_contig_plane_dma_addr(vb, 1);
987 ctx->dst_bufs_cnt++;
988 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
989 if (IS_ERR_OR_NULL(ERR_PTR(
990 vb2_dma_contig_plane_dma_addr(vb, 0)))) {
991 mfc_err("Plane memory not allocated\n");
992 return -EINVAL;
993 }
994 if (vb2_plane_size(vb, 0) < ctx->dec_src_buf_size) {
995 mfc_err("Plane buffer (OUTPUT) is too small\n");
996 return -EINVAL;
997 }
998
999 i = vb->index;
1000 ctx->src_bufs[i].b = vbuf;
1001 ctx->src_bufs[i].cookie.stream =
1002 vb2_dma_contig_plane_dma_addr(vb, 0);
1003 ctx->src_bufs_cnt++;
1004 } else {
1005 mfc_err("s5p_mfc_buf_init: unknown queue type\n");
1006 return -EINVAL;
1007 }
1008 return 0;
1009}
1010
1011static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
1012{
1013 struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
1014 struct s5p_mfc_dev *dev = ctx->dev;
1015
1016 v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1017 if (ctx->state == MFCINST_FINISHING ||
1018 ctx->state == MFCINST_FINISHED)
1019 ctx->state = MFCINST_RUNNING;
1020
1021 if (s5p_mfc_ctx_ready(ctx))
1022 set_work_bit_irqsave(ctx);
1023 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
1024 return 0;
1025}
1026
1027static void s5p_mfc_stop_streaming(struct vb2_queue *q)
1028{
1029 unsigned long flags;
1030 struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
1031 struct s5p_mfc_dev *dev = ctx->dev;
1032 int aborted = 0;
1033
1034 spin_lock_irqsave(&dev->irqlock, flags);
1035 if ((ctx->state == MFCINST_FINISHING ||
1036 ctx->state == MFCINST_RUNNING) &&
1037 dev->curr_ctx == ctx->num && dev->hw_lock) {
1038 ctx->state = MFCINST_ABORT;
1039 spin_unlock_irqrestore(&dev->irqlock, flags);
1040 s5p_mfc_wait_for_done_ctx(ctx,
1041 S5P_MFC_R2H_CMD_FRAME_DONE_RET, 0);
1042 aborted = 1;
1043 spin_lock_irqsave(&dev->irqlock, flags);
1044 }
1045 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1046 s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
1047 INIT_LIST_HEAD(&ctx->dst_queue);
1048 ctx->dst_queue_cnt = 0;
1049 ctx->dpb_flush_flag = 1;
1050 ctx->dec_dst_flag = 0;
1051 if (IS_MFCV6_PLUS(dev) && (ctx->state == MFCINST_RUNNING)) {
1052 ctx->state = MFCINST_FLUSH;
1053 set_work_bit_irqsave(ctx);
1054 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
1055 spin_unlock_irqrestore(&dev->irqlock, flags);
1056 if (s5p_mfc_wait_for_done_ctx(ctx,
1057 S5P_MFC_R2H_CMD_DPB_FLUSH_RET, 0))
1058 mfc_err("Err flushing buffers\n");
1059 spin_lock_irqsave(&dev->irqlock, flags);
1060 }
1061 } else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1062 s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
1063 INIT_LIST_HEAD(&ctx->src_queue);
1064 ctx->src_queue_cnt = 0;
1065 }
1066 if (aborted)
1067 ctx->state = MFCINST_RUNNING;
1068 spin_unlock_irqrestore(&dev->irqlock, flags);
1069}
1070
1071
1072static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
1073{
1074 struct vb2_queue *vq = vb->vb2_queue;
1075 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
1076 struct s5p_mfc_dev *dev = ctx->dev;
1077 unsigned long flags;
1078 struct s5p_mfc_buf *mfc_buf;
1079
1080 if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1081 mfc_buf = &ctx->src_bufs[vb->index];
1082 mfc_buf->flags &= ~MFC_BUF_FLAG_USED;
1083 spin_lock_irqsave(&dev->irqlock, flags);
1084 list_add_tail(&mfc_buf->list, &ctx->src_queue);
1085 ctx->src_queue_cnt++;
1086 spin_unlock_irqrestore(&dev->irqlock, flags);
1087 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1088 mfc_buf = &ctx->dst_bufs[vb->index];
1089 mfc_buf->flags &= ~MFC_BUF_FLAG_USED;
1090
1091 spin_lock_irqsave(&dev->irqlock, flags);
1092 set_bit(vb->index, &ctx->dec_dst_flag);
1093 list_add_tail(&mfc_buf->list, &ctx->dst_queue);
1094 ctx->dst_queue_cnt++;
1095 spin_unlock_irqrestore(&dev->irqlock, flags);
1096 } else {
1097 mfc_err("Unsupported buffer type (%d)\n", vq->type);
1098 }
1099 if (s5p_mfc_ctx_ready(ctx))
1100 set_work_bit_irqsave(ctx);
1101 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
1102}
1103
1104static struct vb2_ops s5p_mfc_dec_qops = {
1105 .queue_setup = s5p_mfc_queue_setup,
1106 .wait_prepare = vb2_ops_wait_prepare,
1107 .wait_finish = vb2_ops_wait_finish,
1108 .buf_init = s5p_mfc_buf_init,
1109 .start_streaming = s5p_mfc_start_streaming,
1110 .stop_streaming = s5p_mfc_stop_streaming,
1111 .buf_queue = s5p_mfc_buf_queue,
1112};
1113
1114const struct s5p_mfc_codec_ops *get_dec_codec_ops(void)
1115{
1116 return &decoder_codec_ops;
1117}
1118
1119struct vb2_ops *get_dec_queue_ops(void)
1120{
1121 return &s5p_mfc_dec_qops;
1122}
1123
1124const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void)
1125{
1126 return &s5p_mfc_dec_ioctl_ops;
1127}
1128
1129#define IS_MFC51_PRIV(x) ((V4L2_CTRL_ID2WHICH(x) == V4L2_CTRL_CLASS_MPEG) \
1130 && V4L2_CTRL_DRIVER_PRIV(x))
1131
1132int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx)
1133{
1134 struct v4l2_ctrl_config cfg;
1135 int i;
1136
1137 v4l2_ctrl_handler_init(&ctx->ctrl_handler, NUM_CTRLS);
1138 if (ctx->ctrl_handler.error) {
1139 mfc_err("v4l2_ctrl_handler_init failed\n");
1140 return ctx->ctrl_handler.error;
1141 }
1142
1143 for (i = 0; i < NUM_CTRLS; i++) {
1144 if (IS_MFC51_PRIV(controls[i].id)) {
1145 memset(&cfg, 0, sizeof(struct v4l2_ctrl_config));
1146 cfg.ops = &s5p_mfc_dec_ctrl_ops;
1147 cfg.id = controls[i].id;
1148 cfg.min = controls[i].minimum;
1149 cfg.max = controls[i].maximum;
1150 cfg.def = controls[i].default_value;
1151 cfg.name = controls[i].name;
1152 cfg.type = controls[i].type;
1153
1154 cfg.step = controls[i].step;
1155 cfg.menu_skip_mask = 0;
1156
1157 ctx->ctrls[i] = v4l2_ctrl_new_custom(&ctx->ctrl_handler,
1158 &cfg, NULL);
1159 } else {
1160 ctx->ctrls[i] = v4l2_ctrl_new_std(&ctx->ctrl_handler,
1161 &s5p_mfc_dec_ctrl_ops,
1162 controls[i].id, controls[i].minimum,
1163 controls[i].maximum, controls[i].step,
1164 controls[i].default_value);
1165 }
1166 if (ctx->ctrl_handler.error) {
1167 mfc_err("Adding control (%d) failed\n", i);
1168 return ctx->ctrl_handler.error;
1169 }
1170 if (controls[i].is_volatile && ctx->ctrls[i])
1171 ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;
1172 }
1173 return 0;
1174}
1175
1176void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx)
1177{
1178 int i;
1179
1180 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1181 for (i = 0; i < NUM_CTRLS; i++)
1182 ctx->ctrls[i] = NULL;
1183}
1184
1185void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx)
1186{
1187 struct v4l2_format f;
1188 f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
1189 ctx->src_fmt = find_format(&f, MFC_FMT_DEC);
1190 if (IS_MFCV8_PLUS(ctx->dev))
1191 f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
1192 else if (IS_MFCV6_PLUS(ctx->dev))
1193 f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16;
1194 else
1195 f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT;
1196 ctx->dst_fmt = find_format(&f, MFC_FMT_RAW);
1197 mfc_debug(2, "Default src_fmt is %p, dest_fmt is %p\n",
1198 ctx->src_fmt, ctx->dst_fmt);
1199}
1200
1201