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