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