linux/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2016 MediaTek Inc.
   4 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
   5 *         Rick Chang <rick.chang@mediatek.com>
   6 *         Xia Jiang <xia.jiang@mediatek.com>
   7 */
   8
   9#include <linux/clk.h>
  10#include <linux/err.h>
  11#include <linux/interrupt.h>
  12#include <linux/io.h>
  13#include <linux/kernel.h>
  14#include <linux/module.h>
  15#include <linux/of_platform.h>
  16#include <linux/platform_device.h>
  17#include <linux/pm_runtime.h>
  18#include <linux/slab.h>
  19#include <linux/spinlock.h>
  20#include <media/v4l2-event.h>
  21#include <media/v4l2-mem2mem.h>
  22#include <media/v4l2-ioctl.h>
  23#include <media/videobuf2-core.h>
  24#include <media/videobuf2-dma-contig.h>
  25#include <soc/mediatek/smi.h>
  26
  27#include "mtk_jpeg_enc_hw.h"
  28#include "mtk_jpeg_dec_hw.h"
  29#include "mtk_jpeg_core.h"
  30#include "mtk_jpeg_dec_parse.h"
  31
  32static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = {
  33        {
  34                .fourcc         = V4L2_PIX_FMT_JPEG,
  35                .colplanes      = 1,
  36                .flags          = MTK_JPEG_FMT_FLAG_CAPTURE,
  37        },
  38        {
  39                .fourcc         = V4L2_PIX_FMT_NV12M,
  40                .hw_format      = JPEG_ENC_YUV_FORMAT_NV12,
  41                .h_sample       = {4, 4},
  42                .v_sample       = {4, 2},
  43                .colplanes      = 2,
  44                .h_align        = 4,
  45                .v_align        = 4,
  46                .flags          = MTK_JPEG_FMT_FLAG_OUTPUT,
  47        },
  48        {
  49                .fourcc         = V4L2_PIX_FMT_NV21M,
  50                .hw_format      = JEPG_ENC_YUV_FORMAT_NV21,
  51                .h_sample       = {4, 4},
  52                .v_sample       = {4, 2},
  53                .colplanes      = 2,
  54                .h_align        = 4,
  55                .v_align        = 4,
  56                .flags          = MTK_JPEG_FMT_FLAG_OUTPUT,
  57        },
  58        {
  59                .fourcc         = V4L2_PIX_FMT_YUYV,
  60                .hw_format      = JPEG_ENC_YUV_FORMAT_YUYV,
  61                .h_sample       = {8},
  62                .v_sample       = {4},
  63                .colplanes      = 1,
  64                .h_align        = 5,
  65                .v_align        = 3,
  66                .flags          = MTK_JPEG_FMT_FLAG_OUTPUT,
  67        },
  68        {
  69                .fourcc         = V4L2_PIX_FMT_YVYU,
  70                .hw_format      = JPEG_ENC_YUV_FORMAT_YVYU,
  71                .h_sample       = {8},
  72                .v_sample       = {4},
  73                .colplanes      = 1,
  74                .h_align        = 5,
  75                .v_align        = 3,
  76                .flags          = MTK_JPEG_FMT_FLAG_OUTPUT,
  77        },
  78};
  79
  80static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = {
  81        {
  82                .fourcc         = V4L2_PIX_FMT_JPEG,
  83                .colplanes      = 1,
  84                .flags          = MTK_JPEG_FMT_FLAG_OUTPUT,
  85        },
  86        {
  87                .fourcc         = V4L2_PIX_FMT_YUV420M,
  88                .h_sample       = {4, 2, 2},
  89                .v_sample       = {4, 2, 2},
  90                .colplanes      = 3,
  91                .h_align        = 5,
  92                .v_align        = 4,
  93                .flags          = MTK_JPEG_FMT_FLAG_CAPTURE,
  94        },
  95        {
  96                .fourcc         = V4L2_PIX_FMT_YUV422M,
  97                .h_sample       = {4, 2, 2},
  98                .v_sample       = {4, 4, 4},
  99                .colplanes      = 3,
 100                .h_align        = 5,
 101                .v_align        = 3,
 102                .flags          = MTK_JPEG_FMT_FLAG_CAPTURE,
 103        },
 104};
 105
 106#define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats)
 107#define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats)
 108
 109struct mtk_jpeg_src_buf {
 110        struct vb2_v4l2_buffer b;
 111        struct list_head list;
 112        struct mtk_jpeg_dec_param dec_param;
 113};
 114
 115static int debug;
 116module_param(debug, int, 0644);
 117
 118static inline struct mtk_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
 119{
 120        return container_of(ctrl->handler, struct mtk_jpeg_ctx, ctrl_hdl);
 121}
 122
 123static inline struct mtk_jpeg_ctx *mtk_jpeg_fh_to_ctx(struct v4l2_fh *fh)
 124{
 125        return container_of(fh, struct mtk_jpeg_ctx, fh);
 126}
 127
 128static inline struct mtk_jpeg_src_buf *mtk_jpeg_vb2_to_srcbuf(
 129                                                        struct vb2_buffer *vb)
 130{
 131        return container_of(to_vb2_v4l2_buffer(vb), struct mtk_jpeg_src_buf, b);
 132}
 133
 134static int mtk_jpeg_querycap(struct file *file, void *priv,
 135                             struct v4l2_capability *cap)
 136{
 137        struct mtk_jpeg_dev *jpeg = video_drvdata(file);
 138
 139        strscpy(cap->driver, jpeg->variant->dev_name, sizeof(cap->driver));
 140        strscpy(cap->card, jpeg->variant->dev_name, sizeof(cap->card));
 141        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
 142                 dev_name(jpeg->dev));
 143
 144        return 0;
 145}
 146
 147static int vidioc_jpeg_enc_s_ctrl(struct v4l2_ctrl *ctrl)
 148{
 149        struct mtk_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
 150
 151        switch (ctrl->id) {
 152        case V4L2_CID_JPEG_RESTART_INTERVAL:
 153                ctx->restart_interval = ctrl->val;
 154                break;
 155        case V4L2_CID_JPEG_COMPRESSION_QUALITY:
 156                ctx->enc_quality = ctrl->val;
 157                break;
 158        case V4L2_CID_JPEG_ACTIVE_MARKER:
 159                ctx->enable_exif = ctrl->val & V4L2_JPEG_ACTIVE_MARKER_APP1;
 160                break;
 161        }
 162
 163        return 0;
 164}
 165
 166static const struct v4l2_ctrl_ops mtk_jpeg_enc_ctrl_ops = {
 167        .s_ctrl = vidioc_jpeg_enc_s_ctrl,
 168};
 169
 170static int mtk_jpeg_enc_ctrls_setup(struct mtk_jpeg_ctx *ctx)
 171{
 172        const struct v4l2_ctrl_ops *ops = &mtk_jpeg_enc_ctrl_ops;
 173        struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl;
 174
 175        v4l2_ctrl_handler_init(handler, 3);
 176
 177        v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_RESTART_INTERVAL, 0, 100,
 178                          1, 0);
 179        v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_COMPRESSION_QUALITY, 48,
 180                          100, 1, 90);
 181        v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_ACTIVE_MARKER, 0,
 182                          V4L2_JPEG_ACTIVE_MARKER_APP1, 0, 0);
 183
 184        if (handler->error) {
 185                v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 186                return handler->error;
 187        }
 188
 189        v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
 190
 191        return 0;
 192}
 193
 194static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n,
 195                             struct v4l2_fmtdesc *f, u32 type)
 196{
 197        int i, num = 0;
 198
 199        for (i = 0; i < n; ++i) {
 200                if (mtk_jpeg_formats[i].flags & type) {
 201                        if (num == f->index)
 202                                break;
 203                        ++num;
 204                }
 205        }
 206
 207        if (i >= n)
 208                return -EINVAL;
 209
 210        f->pixelformat = mtk_jpeg_formats[i].fourcc;
 211
 212        return 0;
 213}
 214
 215static int mtk_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
 216                                     struct v4l2_fmtdesc *f)
 217{
 218        struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
 219        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 220
 221        return mtk_jpeg_enum_fmt(jpeg->variant->formats,
 222                                 jpeg->variant->num_formats, f,
 223                                 MTK_JPEG_FMT_FLAG_CAPTURE);
 224}
 225
 226static int mtk_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
 227                                     struct v4l2_fmtdesc *f)
 228{
 229        struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
 230        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 231
 232        return mtk_jpeg_enum_fmt(jpeg->variant->formats,
 233                                 jpeg->variant->num_formats, f,
 234                                 MTK_JPEG_FMT_FLAG_OUTPUT);
 235}
 236
 237static struct mtk_jpeg_q_data *mtk_jpeg_get_q_data(struct mtk_jpeg_ctx *ctx,
 238                                                   enum v4l2_buf_type type)
 239{
 240        if (V4L2_TYPE_IS_OUTPUT(type))
 241                return &ctx->out_q;
 242        return &ctx->cap_q;
 243}
 244
 245static struct mtk_jpeg_fmt *
 246mtk_jpeg_find_format(struct mtk_jpeg_fmt *mtk_jpeg_formats, int num_formats,
 247                     u32 pixelformat, unsigned int fmt_type)
 248{
 249        unsigned int k;
 250        struct mtk_jpeg_fmt *fmt;
 251
 252        for (k = 0; k < num_formats; k++) {
 253                fmt = &mtk_jpeg_formats[k];
 254
 255                if (fmt->fourcc == pixelformat && fmt->flags & fmt_type)
 256                        return fmt;
 257        }
 258
 259        return NULL;
 260}
 261
 262static int mtk_jpeg_try_fmt_mplane(struct v4l2_pix_format_mplane *pix_mp,
 263                                   struct mtk_jpeg_fmt *fmt)
 264{
 265        int i;
 266
 267        pix_mp->field = V4L2_FIELD_NONE;
 268
 269        pix_mp->num_planes = fmt->colplanes;
 270        pix_mp->pixelformat = fmt->fourcc;
 271
 272        if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
 273                struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[0];
 274
 275                pix_mp->height = clamp(pix_mp->height, MTK_JPEG_MIN_HEIGHT,
 276                                       MTK_JPEG_MAX_HEIGHT);
 277                pix_mp->width = clamp(pix_mp->width, MTK_JPEG_MIN_WIDTH,
 278                                      MTK_JPEG_MAX_WIDTH);
 279
 280                pfmt->bytesperline = 0;
 281                /* Source size must be aligned to 128 */
 282                pfmt->sizeimage = round_up(pfmt->sizeimage, 128);
 283                if (pfmt->sizeimage == 0)
 284                        pfmt->sizeimage = MTK_JPEG_DEFAULT_SIZEIMAGE;
 285                return 0;
 286        }
 287
 288        /* other fourcc */
 289        pix_mp->height = clamp(round_up(pix_mp->height, fmt->v_align),
 290                               MTK_JPEG_MIN_HEIGHT, MTK_JPEG_MAX_HEIGHT);
 291        pix_mp->width = clamp(round_up(pix_mp->width, fmt->h_align),
 292                              MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH);
 293
 294        for (i = 0; i < fmt->colplanes; i++) {
 295                struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i];
 296                u32 stride = pix_mp->width * fmt->h_sample[i] / 4;
 297                u32 h = pix_mp->height * fmt->v_sample[i] / 4;
 298
 299                pfmt->bytesperline = stride;
 300                pfmt->sizeimage = stride * h;
 301        }
 302        return 0;
 303}
 304
 305static int mtk_jpeg_g_fmt_vid_mplane(struct file *file, void *priv,
 306                                     struct v4l2_format *f)
 307{
 308        struct vb2_queue *vq;
 309        struct mtk_jpeg_q_data *q_data = NULL;
 310        struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
 311        struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
 312        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 313        int i;
 314
 315        vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
 316        if (!vq)
 317                return -EINVAL;
 318
 319        q_data = mtk_jpeg_get_q_data(ctx, f->type);
 320
 321        pix_mp->width = q_data->pix_mp.width;
 322        pix_mp->height = q_data->pix_mp.height;
 323        pix_mp->field = V4L2_FIELD_NONE;
 324        pix_mp->pixelformat = q_data->fmt->fourcc;
 325        pix_mp->num_planes = q_data->fmt->colplanes;
 326        pix_mp->colorspace = q_data->pix_mp.colorspace;
 327        pix_mp->ycbcr_enc = q_data->pix_mp.ycbcr_enc;
 328        pix_mp->xfer_func = q_data->pix_mp.xfer_func;
 329        pix_mp->quantization = q_data->pix_mp.quantization;
 330
 331        v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) g_fmt:%c%c%c%c wxh:%ux%u\n",
 332                 f->type,
 333                 (pix_mp->pixelformat & 0xff),
 334                 (pix_mp->pixelformat >>  8 & 0xff),
 335                 (pix_mp->pixelformat >> 16 & 0xff),
 336                 (pix_mp->pixelformat >> 24 & 0xff),
 337                 pix_mp->width, pix_mp->height);
 338
 339        for (i = 0; i < pix_mp->num_planes; i++) {
 340                struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i];
 341
 342                pfmt->bytesperline = q_data->pix_mp.plane_fmt[i].bytesperline;
 343                pfmt->sizeimage = q_data->pix_mp.plane_fmt[i].sizeimage;
 344
 345                v4l2_dbg(1, debug, &jpeg->v4l2_dev,
 346                         "plane[%d] bpl=%u, size=%u\n",
 347                         i,
 348                         pfmt->bytesperline,
 349                         pfmt->sizeimage);
 350        }
 351        return 0;
 352}
 353
 354static int mtk_jpeg_try_fmt_vid_cap_mplane(struct file *file, void *priv,
 355                                           struct v4l2_format *f)
 356{
 357        struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
 358        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 359        struct mtk_jpeg_fmt *fmt;
 360
 361        fmt = mtk_jpeg_find_format(jpeg->variant->formats,
 362                                   jpeg->variant->num_formats,
 363                                   f->fmt.pix_mp.pixelformat,
 364                                   MTK_JPEG_FMT_FLAG_CAPTURE);
 365        if (!fmt)
 366                fmt = ctx->cap_q.fmt;
 367
 368        v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n",
 369                 f->type,
 370                 (fmt->fourcc & 0xff),
 371                 (fmt->fourcc >>  8 & 0xff),
 372                 (fmt->fourcc >> 16 & 0xff),
 373                 (fmt->fourcc >> 24 & 0xff));
 374
 375        if (ctx->state != MTK_JPEG_INIT) {
 376                mtk_jpeg_g_fmt_vid_mplane(file, priv, f);
 377                return 0;
 378        }
 379
 380        return mtk_jpeg_try_fmt_mplane(&f->fmt.pix_mp, fmt);
 381}
 382
 383static int mtk_jpeg_try_fmt_vid_out_mplane(struct file *file, void *priv,
 384                                           struct v4l2_format *f)
 385{
 386        struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
 387        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 388        struct mtk_jpeg_fmt *fmt;
 389
 390        fmt = mtk_jpeg_find_format(jpeg->variant->formats,
 391                                   jpeg->variant->num_formats,
 392                                   f->fmt.pix_mp.pixelformat,
 393                                   MTK_JPEG_FMT_FLAG_OUTPUT);
 394        if (!fmt)
 395                fmt = ctx->out_q.fmt;
 396
 397        v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n",
 398                 f->type,
 399                 (fmt->fourcc & 0xff),
 400                 (fmt->fourcc >>  8 & 0xff),
 401                 (fmt->fourcc >> 16 & 0xff),
 402                 (fmt->fourcc >> 24 & 0xff));
 403
 404        if (ctx->state != MTK_JPEG_INIT) {
 405                mtk_jpeg_g_fmt_vid_mplane(file, priv, f);
 406                return 0;
 407        }
 408
 409        return mtk_jpeg_try_fmt_mplane(&f->fmt.pix_mp, fmt);
 410}
 411
 412static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx,
 413                                 struct v4l2_format *f, unsigned int fmt_type)
 414{
 415        struct vb2_queue *vq;
 416        struct mtk_jpeg_q_data *q_data = NULL;
 417        struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
 418        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 419        int i;
 420
 421        vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
 422        if (!vq)
 423                return -EINVAL;
 424
 425        q_data = mtk_jpeg_get_q_data(ctx, f->type);
 426
 427        if (vb2_is_busy(vq)) {
 428                v4l2_err(&jpeg->v4l2_dev, "queue busy\n");
 429                return -EBUSY;
 430        }
 431
 432        q_data->fmt = mtk_jpeg_find_format(jpeg->variant->formats,
 433                                           jpeg->variant->num_formats,
 434                                           pix_mp->pixelformat, fmt_type);
 435        q_data->pix_mp.width = pix_mp->width;
 436        q_data->pix_mp.height = pix_mp->height;
 437        q_data->enc_crop_rect.width = pix_mp->width;
 438        q_data->enc_crop_rect.height = pix_mp->height;
 439        q_data->pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
 440        q_data->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601;
 441        q_data->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
 442        q_data->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
 443
 444        v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) s_fmt:%c%c%c%c wxh:%ux%u\n",
 445                 f->type,
 446                 (q_data->fmt->fourcc & 0xff),
 447                 (q_data->fmt->fourcc >>  8 & 0xff),
 448                 (q_data->fmt->fourcc >> 16 & 0xff),
 449                 (q_data->fmt->fourcc >> 24 & 0xff),
 450                 q_data->pix_mp.width, q_data->pix_mp.height);
 451
 452        for (i = 0; i < q_data->fmt->colplanes; i++) {
 453                q_data->pix_mp.plane_fmt[i].bytesperline =
 454                                        pix_mp->plane_fmt[i].bytesperline;
 455                q_data->pix_mp.plane_fmt[i].sizeimage =
 456                                        pix_mp->plane_fmt[i].sizeimage;
 457
 458                v4l2_dbg(1, debug, &jpeg->v4l2_dev,
 459                         "plane[%d] bpl=%u, size=%u\n",
 460                         i, q_data->pix_mp.plane_fmt[i].bytesperline,
 461                         q_data->pix_mp.plane_fmt[i].sizeimage);
 462        }
 463
 464        return 0;
 465}
 466
 467static int mtk_jpeg_s_fmt_vid_out_mplane(struct file *file, void *priv,
 468                                         struct v4l2_format *f)
 469{
 470        int ret;
 471
 472        ret = mtk_jpeg_try_fmt_vid_out_mplane(file, priv, f);
 473        if (ret)
 474                return ret;
 475
 476        return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f,
 477                                     MTK_JPEG_FMT_FLAG_OUTPUT);
 478}
 479
 480static int mtk_jpeg_s_fmt_vid_cap_mplane(struct file *file, void *priv,
 481                                         struct v4l2_format *f)
 482{
 483        int ret;
 484
 485        ret = mtk_jpeg_try_fmt_vid_cap_mplane(file, priv, f);
 486        if (ret)
 487                return ret;
 488
 489        return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f,
 490                                     MTK_JPEG_FMT_FLAG_CAPTURE);
 491}
 492
 493static void mtk_jpeg_queue_src_chg_event(struct mtk_jpeg_ctx *ctx)
 494{
 495        static const struct v4l2_event ev_src_ch = {
 496                .type = V4L2_EVENT_SOURCE_CHANGE,
 497                .u.src_change.changes =
 498                V4L2_EVENT_SRC_CH_RESOLUTION,
 499        };
 500
 501        v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
 502}
 503
 504static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh,
 505                                    const struct v4l2_event_subscription *sub)
 506{
 507        switch (sub->type) {
 508        case V4L2_EVENT_SOURCE_CHANGE:
 509                return v4l2_src_change_event_subscribe(fh, sub);
 510        }
 511
 512        return v4l2_ctrl_subscribe_event(fh, sub);
 513}
 514
 515static int mtk_jpeg_enc_g_selection(struct file *file, void *priv,
 516                                    struct v4l2_selection *s)
 517{
 518        struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
 519
 520        if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
 521                return -EINVAL;
 522
 523        switch (s->target) {
 524        case V4L2_SEL_TGT_CROP:
 525                s->r = ctx->out_q.enc_crop_rect;
 526                break;
 527        case V4L2_SEL_TGT_CROP_BOUNDS:
 528        case V4L2_SEL_TGT_CROP_DEFAULT:
 529                s->r.width = ctx->out_q.pix_mp.width;
 530                s->r.height = ctx->out_q.pix_mp.height;
 531                s->r.left = 0;
 532                s->r.top = 0;
 533                break;
 534        default:
 535                return -EINVAL;
 536        }
 537        return 0;
 538}
 539
 540static int mtk_jpeg_dec_g_selection(struct file *file, void *priv,
 541                                    struct v4l2_selection *s)
 542{
 543        struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
 544
 545        if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 546                return -EINVAL;
 547
 548        switch (s->target) {
 549        case V4L2_SEL_TGT_COMPOSE:
 550        case V4L2_SEL_TGT_COMPOSE_DEFAULT:
 551                s->r.width = ctx->out_q.pix_mp.width;
 552                s->r.height = ctx->out_q.pix_mp.height;
 553                s->r.left = 0;
 554                s->r.top = 0;
 555                break;
 556        case V4L2_SEL_TGT_COMPOSE_BOUNDS:
 557        case V4L2_SEL_TGT_COMPOSE_PADDED:
 558                s->r.width = ctx->cap_q.pix_mp.width;
 559                s->r.height = ctx->cap_q.pix_mp.height;
 560                s->r.left = 0;
 561                s->r.top = 0;
 562                break;
 563        default:
 564                return -EINVAL;
 565        }
 566        return 0;
 567}
 568
 569static int mtk_jpeg_enc_s_selection(struct file *file, void *priv,
 570                                    struct v4l2_selection *s)
 571{
 572        struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
 573
 574        if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
 575                return -EINVAL;
 576
 577        switch (s->target) {
 578        case V4L2_SEL_TGT_CROP:
 579                s->r.left = 0;
 580                s->r.top = 0;
 581                s->r.width = min(s->r.width, ctx->out_q.pix_mp.width);
 582                s->r.height = min(s->r.height, ctx->out_q.pix_mp.height);
 583                ctx->out_q.enc_crop_rect = s->r;
 584                break;
 585        default:
 586                return -EINVAL;
 587        }
 588
 589        return 0;
 590}
 591
 592static const struct v4l2_ioctl_ops mtk_jpeg_enc_ioctl_ops = {
 593        .vidioc_querycap                = mtk_jpeg_querycap,
 594        .vidioc_enum_fmt_vid_cap        = mtk_jpeg_enum_fmt_vid_cap,
 595        .vidioc_enum_fmt_vid_out        = mtk_jpeg_enum_fmt_vid_out,
 596        .vidioc_try_fmt_vid_cap_mplane  = mtk_jpeg_try_fmt_vid_cap_mplane,
 597        .vidioc_try_fmt_vid_out_mplane  = mtk_jpeg_try_fmt_vid_out_mplane,
 598        .vidioc_g_fmt_vid_cap_mplane    = mtk_jpeg_g_fmt_vid_mplane,
 599        .vidioc_g_fmt_vid_out_mplane    = mtk_jpeg_g_fmt_vid_mplane,
 600        .vidioc_s_fmt_vid_cap_mplane    = mtk_jpeg_s_fmt_vid_cap_mplane,
 601        .vidioc_s_fmt_vid_out_mplane    = mtk_jpeg_s_fmt_vid_out_mplane,
 602        .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
 603        .vidioc_subscribe_event         = mtk_jpeg_subscribe_event,
 604        .vidioc_g_selection             = mtk_jpeg_enc_g_selection,
 605        .vidioc_s_selection             = mtk_jpeg_enc_s_selection,
 606
 607        .vidioc_create_bufs             = v4l2_m2m_ioctl_create_bufs,
 608        .vidioc_prepare_buf             = v4l2_m2m_ioctl_prepare_buf,
 609        .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
 610        .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
 611        .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
 612        .vidioc_expbuf                  = v4l2_m2m_ioctl_expbuf,
 613        .vidioc_streamon                = v4l2_m2m_ioctl_streamon,
 614        .vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
 615
 616        .vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
 617};
 618
 619static const struct v4l2_ioctl_ops mtk_jpeg_dec_ioctl_ops = {
 620        .vidioc_querycap                = mtk_jpeg_querycap,
 621        .vidioc_enum_fmt_vid_cap        = mtk_jpeg_enum_fmt_vid_cap,
 622        .vidioc_enum_fmt_vid_out        = mtk_jpeg_enum_fmt_vid_out,
 623        .vidioc_try_fmt_vid_cap_mplane  = mtk_jpeg_try_fmt_vid_cap_mplane,
 624        .vidioc_try_fmt_vid_out_mplane  = mtk_jpeg_try_fmt_vid_out_mplane,
 625        .vidioc_g_fmt_vid_cap_mplane    = mtk_jpeg_g_fmt_vid_mplane,
 626        .vidioc_g_fmt_vid_out_mplane    = mtk_jpeg_g_fmt_vid_mplane,
 627        .vidioc_s_fmt_vid_cap_mplane    = mtk_jpeg_s_fmt_vid_cap_mplane,
 628        .vidioc_s_fmt_vid_out_mplane    = mtk_jpeg_s_fmt_vid_out_mplane,
 629        .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
 630        .vidioc_subscribe_event         = mtk_jpeg_subscribe_event,
 631        .vidioc_g_selection             = mtk_jpeg_dec_g_selection,
 632
 633        .vidioc_create_bufs             = v4l2_m2m_ioctl_create_bufs,
 634        .vidioc_prepare_buf             = v4l2_m2m_ioctl_prepare_buf,
 635        .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
 636        .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
 637        .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
 638        .vidioc_expbuf                  = v4l2_m2m_ioctl_expbuf,
 639        .vidioc_streamon                = v4l2_m2m_ioctl_streamon,
 640        .vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
 641
 642        .vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
 643};
 644
 645static int mtk_jpeg_queue_setup(struct vb2_queue *q,
 646                                unsigned int *num_buffers,
 647                                unsigned int *num_planes,
 648                                unsigned int sizes[],
 649                                struct device *alloc_ctxs[])
 650{
 651        struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
 652        struct mtk_jpeg_q_data *q_data = NULL;
 653        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 654        int i;
 655
 656        v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) buf_req count=%u\n",
 657                 q->type, *num_buffers);
 658
 659        q_data = mtk_jpeg_get_q_data(ctx, q->type);
 660        if (!q_data)
 661                return -EINVAL;
 662
 663        if (*num_planes) {
 664                for (i = 0; i < *num_planes; i++)
 665                        if (sizes[i] < q_data->pix_mp.plane_fmt[i].sizeimage)
 666                                return -EINVAL;
 667                return 0;
 668        }
 669
 670        *num_planes = q_data->fmt->colplanes;
 671        for (i = 0; i < q_data->fmt->colplanes; i++) {
 672                sizes[i] =  q_data->pix_mp.plane_fmt[i].sizeimage;
 673                v4l2_dbg(1, debug, &jpeg->v4l2_dev, "sizeimage[%d]=%u\n",
 674                         i, sizes[i]);
 675        }
 676
 677        return 0;
 678}
 679
 680static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb)
 681{
 682        struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 683        struct mtk_jpeg_q_data *q_data = NULL;
 684        struct v4l2_plane_pix_format plane_fmt = {};
 685        int i;
 686
 687        q_data = mtk_jpeg_get_q_data(ctx, vb->vb2_queue->type);
 688        if (!q_data)
 689                return -EINVAL;
 690
 691        for (i = 0; i < q_data->fmt->colplanes; i++) {
 692                plane_fmt = q_data->pix_mp.plane_fmt[i];
 693                if (ctx->enable_exif &&
 694                    q_data->fmt->fourcc == V4L2_PIX_FMT_JPEG)
 695                        vb2_set_plane_payload(vb, i, plane_fmt.sizeimage +
 696                                              MTK_JPEG_MAX_EXIF_SIZE);
 697                else
 698                        vb2_set_plane_payload(vb, i,  plane_fmt.sizeimage);
 699        }
 700
 701        return 0;
 702}
 703
 704static bool mtk_jpeg_check_resolution_change(struct mtk_jpeg_ctx *ctx,
 705                                             struct mtk_jpeg_dec_param *param)
 706{
 707        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 708        struct mtk_jpeg_q_data *q_data;
 709
 710        q_data = &ctx->out_q;
 711        if (q_data->pix_mp.width != param->pic_w ||
 712            q_data->pix_mp.height != param->pic_h) {
 713                v4l2_dbg(1, debug, &jpeg->v4l2_dev, "Picture size change\n");
 714                return true;
 715        }
 716
 717        q_data = &ctx->cap_q;
 718        if (q_data->fmt !=
 719            mtk_jpeg_find_format(jpeg->variant->formats,
 720                                 jpeg->variant->num_formats, param->dst_fourcc,
 721                                 MTK_JPEG_FMT_FLAG_CAPTURE)) {
 722                v4l2_dbg(1, debug, &jpeg->v4l2_dev, "format change\n");
 723                return true;
 724        }
 725        return false;
 726}
 727
 728static void mtk_jpeg_set_queue_data(struct mtk_jpeg_ctx *ctx,
 729                                    struct mtk_jpeg_dec_param *param)
 730{
 731        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 732        struct mtk_jpeg_q_data *q_data;
 733        int i;
 734
 735        q_data = &ctx->out_q;
 736        q_data->pix_mp.width = param->pic_w;
 737        q_data->pix_mp.height = param->pic_h;
 738
 739        q_data = &ctx->cap_q;
 740        q_data->pix_mp.width = param->dec_w;
 741        q_data->pix_mp.height = param->dec_h;
 742        q_data->fmt = mtk_jpeg_find_format(jpeg->variant->formats,
 743                                           jpeg->variant->num_formats,
 744                                           param->dst_fourcc,
 745                                           MTK_JPEG_FMT_FLAG_CAPTURE);
 746
 747        for (i = 0; i < q_data->fmt->colplanes; i++) {
 748                q_data->pix_mp.plane_fmt[i].bytesperline = param->mem_stride[i];
 749                q_data->pix_mp.plane_fmt[i].sizeimage = param->comp_size[i];
 750        }
 751
 752        v4l2_dbg(1, debug, &jpeg->v4l2_dev,
 753                 "set_parse cap:%c%c%c%c pic(%u, %u), buf(%u, %u)\n",
 754                 (param->dst_fourcc & 0xff),
 755                 (param->dst_fourcc >>  8 & 0xff),
 756                 (param->dst_fourcc >> 16 & 0xff),
 757                 (param->dst_fourcc >> 24 & 0xff),
 758                 param->pic_w, param->pic_h,
 759                 param->dec_w, param->dec_h);
 760}
 761
 762static void mtk_jpeg_enc_buf_queue(struct vb2_buffer *vb)
 763{
 764        struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 765        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 766
 767        v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n",
 768                 vb->vb2_queue->type, vb->index, vb);
 769
 770        v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb));
 771}
 772
 773static void mtk_jpeg_dec_buf_queue(struct vb2_buffer *vb)
 774{
 775        struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 776        struct mtk_jpeg_dec_param *param;
 777        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 778        struct mtk_jpeg_src_buf *jpeg_src_buf;
 779        bool header_valid;
 780
 781        v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n",
 782                 vb->vb2_queue->type, vb->index, vb);
 783
 784        if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
 785                goto end;
 786
 787        jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb);
 788        param = &jpeg_src_buf->dec_param;
 789        memset(param, 0, sizeof(*param));
 790
 791        header_valid = mtk_jpeg_parse(param, (u8 *)vb2_plane_vaddr(vb, 0),
 792                                      vb2_get_plane_payload(vb, 0));
 793        if (!header_valid) {
 794                v4l2_err(&jpeg->v4l2_dev, "Header invalid.\n");
 795                vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
 796                return;
 797        }
 798
 799        if (ctx->state == MTK_JPEG_INIT) {
 800                struct vb2_queue *dst_vq = v4l2_m2m_get_vq(
 801                        ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
 802
 803                mtk_jpeg_queue_src_chg_event(ctx);
 804                mtk_jpeg_set_queue_data(ctx, param);
 805                ctx->state = vb2_is_streaming(dst_vq) ?
 806                                MTK_JPEG_SOURCE_CHANGE : MTK_JPEG_RUNNING;
 807        }
 808end:
 809        v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb));
 810}
 811
 812static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx,
 813                                 enum v4l2_buf_type type)
 814{
 815        if (V4L2_TYPE_IS_OUTPUT(type))
 816                return v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
 817        else
 818                return v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 819}
 820
 821static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q)
 822{
 823        struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
 824        struct vb2_v4l2_buffer *vb;
 825
 826        while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
 827                v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
 828}
 829
 830static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q)
 831{
 832        struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
 833        struct vb2_v4l2_buffer *vb;
 834
 835        /*
 836         * STREAMOFF is an acknowledgment for source change event.
 837         * Before STREAMOFF, we still have to return the old resolution and
 838         * subsampling. Update capture queue when the stream is off.
 839         */
 840        if (ctx->state == MTK_JPEG_SOURCE_CHANGE &&
 841            V4L2_TYPE_IS_CAPTURE(q->type)) {
 842                struct mtk_jpeg_src_buf *src_buf;
 843
 844                vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 845                src_buf = mtk_jpeg_vb2_to_srcbuf(&vb->vb2_buf);
 846                mtk_jpeg_set_queue_data(ctx, &src_buf->dec_param);
 847                ctx->state = MTK_JPEG_RUNNING;
 848        } else if (V4L2_TYPE_IS_OUTPUT(q->type)) {
 849                ctx->state = MTK_JPEG_INIT;
 850        }
 851
 852        while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
 853                v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
 854}
 855
 856static const struct vb2_ops mtk_jpeg_dec_qops = {
 857        .queue_setup        = mtk_jpeg_queue_setup,
 858        .buf_prepare        = mtk_jpeg_buf_prepare,
 859        .buf_queue          = mtk_jpeg_dec_buf_queue,
 860        .wait_prepare       = vb2_ops_wait_prepare,
 861        .wait_finish        = vb2_ops_wait_finish,
 862        .stop_streaming     = mtk_jpeg_dec_stop_streaming,
 863};
 864
 865static const struct vb2_ops mtk_jpeg_enc_qops = {
 866        .queue_setup        = mtk_jpeg_queue_setup,
 867        .buf_prepare        = mtk_jpeg_buf_prepare,
 868        .buf_queue          = mtk_jpeg_enc_buf_queue,
 869        .wait_prepare       = vb2_ops_wait_prepare,
 870        .wait_finish        = vb2_ops_wait_finish,
 871        .stop_streaming     = mtk_jpeg_enc_stop_streaming,
 872};
 873
 874static void mtk_jpeg_set_dec_src(struct mtk_jpeg_ctx *ctx,
 875                                 struct vb2_buffer *src_buf,
 876                                 struct mtk_jpeg_bs *bs)
 877{
 878        bs->str_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
 879        bs->end_addr = bs->str_addr +
 880                       round_up(vb2_get_plane_payload(src_buf, 0), 16);
 881        bs->size = round_up(vb2_plane_size(src_buf, 0), 128);
 882}
 883
 884static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx,
 885                                struct mtk_jpeg_dec_param *param,
 886                                struct vb2_buffer *dst_buf,
 887                                struct mtk_jpeg_fb *fb)
 888{
 889        int i;
 890
 891        if (param->comp_num != dst_buf->num_planes) {
 892                dev_err(ctx->jpeg->dev, "plane number mismatch (%u != %u)\n",
 893                        param->comp_num, dst_buf->num_planes);
 894                return -EINVAL;
 895        }
 896
 897        for (i = 0; i < dst_buf->num_planes; i++) {
 898                if (vb2_plane_size(dst_buf, i) < param->comp_size[i]) {
 899                        dev_err(ctx->jpeg->dev,
 900                                "buffer size is underflow (%lu < %u)\n",
 901                                vb2_plane_size(dst_buf, 0),
 902                                param->comp_size[i]);
 903                        return -EINVAL;
 904                }
 905                fb->plane_addr[i] = vb2_dma_contig_plane_dma_addr(dst_buf, i);
 906        }
 907
 908        return 0;
 909}
 910
 911static void mtk_jpeg_enc_device_run(void *priv)
 912{
 913        struct mtk_jpeg_ctx *ctx = priv;
 914        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 915        struct vb2_v4l2_buffer *src_buf, *dst_buf;
 916        enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
 917        unsigned long flags;
 918        int ret;
 919
 920        src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 921        dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
 922
 923        ret = pm_runtime_resume_and_get(jpeg->dev);
 924        if (ret < 0)
 925                goto enc_end;
 926
 927        schedule_delayed_work(&jpeg->job_timeout_work,
 928                              msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
 929
 930        spin_lock_irqsave(&jpeg->hw_lock, flags);
 931
 932        /*
 933         * Resetting the hardware every frame is to ensure that all the
 934         * registers are cleared. This is a hardware requirement.
 935         */
 936        mtk_jpeg_enc_reset(jpeg->reg_base);
 937
 938        mtk_jpeg_set_enc_src(ctx, jpeg->reg_base, &src_buf->vb2_buf);
 939        mtk_jpeg_set_enc_dst(ctx, jpeg->reg_base, &dst_buf->vb2_buf);
 940        mtk_jpeg_set_enc_params(ctx, jpeg->reg_base);
 941        mtk_jpeg_enc_start(jpeg->reg_base);
 942        spin_unlock_irqrestore(&jpeg->hw_lock, flags);
 943        return;
 944
 945enc_end:
 946        v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
 947        v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 948        v4l2_m2m_buf_done(src_buf, buf_state);
 949        v4l2_m2m_buf_done(dst_buf, buf_state);
 950        v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
 951}
 952
 953static void mtk_jpeg_dec_device_run(void *priv)
 954{
 955        struct mtk_jpeg_ctx *ctx = priv;
 956        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
 957        struct vb2_v4l2_buffer *src_buf, *dst_buf;
 958        enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
 959        unsigned long flags;
 960        struct mtk_jpeg_src_buf *jpeg_src_buf;
 961        struct mtk_jpeg_bs bs;
 962        struct mtk_jpeg_fb fb;
 963        int ret;
 964
 965        src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 966        dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
 967        jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
 968
 969        if (mtk_jpeg_check_resolution_change(ctx, &jpeg_src_buf->dec_param)) {
 970                mtk_jpeg_queue_src_chg_event(ctx);
 971                ctx->state = MTK_JPEG_SOURCE_CHANGE;
 972                v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
 973                return;
 974        }
 975
 976        ret = pm_runtime_resume_and_get(jpeg->dev);
 977        if (ret < 0)
 978                goto dec_end;
 979
 980        schedule_delayed_work(&jpeg->job_timeout_work,
 981                              msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
 982
 983        mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs);
 984        if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, &dst_buf->vb2_buf, &fb))
 985                goto dec_end;
 986
 987        spin_lock_irqsave(&jpeg->hw_lock, flags);
 988        mtk_jpeg_dec_reset(jpeg->reg_base);
 989        mtk_jpeg_dec_set_config(jpeg->reg_base,
 990                                &jpeg_src_buf->dec_param, &bs, &fb);
 991
 992        mtk_jpeg_dec_start(jpeg->reg_base);
 993        spin_unlock_irqrestore(&jpeg->hw_lock, flags);
 994        return;
 995
 996dec_end:
 997        v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
 998        v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 999        v4l2_m2m_buf_done(src_buf, buf_state);
1000        v4l2_m2m_buf_done(dst_buf, buf_state);
1001        v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1002}
1003
1004static int mtk_jpeg_dec_job_ready(void *priv)
1005{
1006        struct mtk_jpeg_ctx *ctx = priv;
1007
1008        return (ctx->state == MTK_JPEG_RUNNING) ? 1 : 0;
1009}
1010
1011static const struct v4l2_m2m_ops mtk_jpeg_enc_m2m_ops = {
1012        .device_run = mtk_jpeg_enc_device_run,
1013};
1014
1015static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = {
1016        .device_run = mtk_jpeg_dec_device_run,
1017        .job_ready  = mtk_jpeg_dec_job_ready,
1018};
1019
1020static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
1021                               struct vb2_queue *dst_vq)
1022{
1023        struct mtk_jpeg_ctx *ctx = priv;
1024        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1025        int ret;
1026
1027        src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1028        src_vq->io_modes = VB2_DMABUF | VB2_MMAP;
1029        src_vq->drv_priv = ctx;
1030        src_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf);
1031        src_vq->ops = jpeg->variant->qops;
1032        src_vq->mem_ops = &vb2_dma_contig_memops;
1033        src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1034        src_vq->lock = &ctx->jpeg->lock;
1035        src_vq->dev = ctx->jpeg->dev;
1036        ret = vb2_queue_init(src_vq);
1037        if (ret)
1038                return ret;
1039
1040        dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1041        dst_vq->io_modes = VB2_DMABUF | VB2_MMAP;
1042        dst_vq->drv_priv = ctx;
1043        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1044        dst_vq->ops = jpeg->variant->qops;
1045        dst_vq->mem_ops = &vb2_dma_contig_memops;
1046        dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1047        dst_vq->lock = &ctx->jpeg->lock;
1048        dst_vq->dev = ctx->jpeg->dev;
1049        ret = vb2_queue_init(dst_vq);
1050
1051        return ret;
1052}
1053
1054static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
1055{
1056        int ret;
1057
1058        ret = mtk_smi_larb_get(jpeg->larb);
1059        if (ret)
1060                dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret);
1061
1062        ret = clk_bulk_prepare_enable(jpeg->variant->num_clks,
1063                                      jpeg->variant->clks);
1064        if (ret)
1065                dev_err(jpeg->dev, "Failed to open jpeg clk: %d\n", ret);
1066}
1067
1068static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
1069{
1070        clk_bulk_disable_unprepare(jpeg->variant->num_clks,
1071                                   jpeg->variant->clks);
1072        mtk_smi_larb_put(jpeg->larb);
1073}
1074
1075static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg)
1076{
1077        struct mtk_jpeg_ctx *ctx;
1078        struct vb2_v4l2_buffer *src_buf, *dst_buf;
1079        enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1080        u32 result_size;
1081
1082        ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1083        if (!ctx) {
1084                v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n");
1085                return IRQ_HANDLED;
1086        }
1087
1088        src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1089        dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1090
1091        result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base);
1092        vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size);
1093
1094        buf_state = VB2_BUF_STATE_DONE;
1095
1096        v4l2_m2m_buf_done(src_buf, buf_state);
1097        v4l2_m2m_buf_done(dst_buf, buf_state);
1098        v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1099        pm_runtime_put(ctx->jpeg->dev);
1100        return IRQ_HANDLED;
1101}
1102
1103static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv)
1104{
1105        struct mtk_jpeg_dev *jpeg = priv;
1106        u32 irq_status;
1107        irqreturn_t ret = IRQ_NONE;
1108
1109        cancel_delayed_work(&jpeg->job_timeout_work);
1110
1111        irq_status = readl(jpeg->reg_base + JPEG_ENC_INT_STS) &
1112                     JPEG_ENC_INT_STATUS_MASK_ALLIRQ;
1113        if (irq_status)
1114                writel(0, jpeg->reg_base + JPEG_ENC_INT_STS);
1115
1116        if (!(irq_status & JPEG_ENC_INT_STATUS_DONE))
1117                return ret;
1118
1119        ret = mtk_jpeg_enc_done(jpeg);
1120        return ret;
1121}
1122
1123static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv)
1124{
1125        struct mtk_jpeg_dev *jpeg = priv;
1126        struct mtk_jpeg_ctx *ctx;
1127        struct vb2_v4l2_buffer *src_buf, *dst_buf;
1128        struct mtk_jpeg_src_buf *jpeg_src_buf;
1129        enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
1130        u32     dec_irq_ret;
1131        u32 dec_ret;
1132        int i;
1133
1134        cancel_delayed_work(&jpeg->job_timeout_work);
1135
1136        dec_ret = mtk_jpeg_dec_get_int_status(jpeg->reg_base);
1137        dec_irq_ret = mtk_jpeg_dec_enum_result(dec_ret);
1138        ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1139        if (!ctx) {
1140                v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n");
1141                return IRQ_HANDLED;
1142        }
1143
1144        src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1145        dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1146        jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
1147
1148        if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW)
1149                mtk_jpeg_dec_reset(jpeg->reg_base);
1150
1151        if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE) {
1152                dev_err(jpeg->dev, "decode failed\n");
1153                goto dec_end;
1154        }
1155
1156        for (i = 0; i < dst_buf->vb2_buf.num_planes; i++)
1157                vb2_set_plane_payload(&dst_buf->vb2_buf, i,
1158                                      jpeg_src_buf->dec_param.comp_size[i]);
1159
1160        buf_state = VB2_BUF_STATE_DONE;
1161
1162dec_end:
1163        v4l2_m2m_buf_done(src_buf, buf_state);
1164        v4l2_m2m_buf_done(dst_buf, buf_state);
1165        v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1166        pm_runtime_put(ctx->jpeg->dev);
1167        return IRQ_HANDLED;
1168}
1169
1170static void mtk_jpeg_set_default_params(struct mtk_jpeg_ctx *ctx)
1171{
1172        struct mtk_jpeg_q_data *q = &ctx->out_q;
1173        struct mtk_jpeg_dev *jpeg = ctx->jpeg;
1174
1175        ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
1176        q->pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
1177        q->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601;
1178        q->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1179        q->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
1180
1181        q->fmt = mtk_jpeg_find_format(jpeg->variant->formats,
1182                                      jpeg->variant->num_formats,
1183                                      jpeg->variant->out_q_default_fourcc,
1184                                      MTK_JPEG_FMT_FLAG_OUTPUT);
1185        q->pix_mp.width = MTK_JPEG_MIN_WIDTH;
1186        q->pix_mp.height = MTK_JPEG_MIN_HEIGHT;
1187        mtk_jpeg_try_fmt_mplane(&q->pix_mp, q->fmt);
1188
1189        q = &ctx->cap_q;
1190        q->fmt = mtk_jpeg_find_format(jpeg->variant->formats,
1191                                      jpeg->variant->num_formats,
1192                                      jpeg->variant->cap_q_default_fourcc,
1193                                      MTK_JPEG_FMT_FLAG_CAPTURE);
1194        q->pix_mp.colorspace = V4L2_COLORSPACE_SRGB;
1195        q->pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_601;
1196        q->pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1197        q->pix_mp.xfer_func = V4L2_XFER_FUNC_SRGB;
1198        q->pix_mp.width = MTK_JPEG_MIN_WIDTH;
1199        q->pix_mp.height = MTK_JPEG_MIN_HEIGHT;
1200
1201        mtk_jpeg_try_fmt_mplane(&q->pix_mp, q->fmt);
1202}
1203
1204static int mtk_jpeg_open(struct file *file)
1205{
1206        struct mtk_jpeg_dev *jpeg = video_drvdata(file);
1207        struct video_device *vfd = video_devdata(file);
1208        struct mtk_jpeg_ctx *ctx;
1209        int ret = 0;
1210
1211        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1212        if (!ctx)
1213                return -ENOMEM;
1214
1215        if (mutex_lock_interruptible(&jpeg->lock)) {
1216                ret = -ERESTARTSYS;
1217                goto free;
1218        }
1219
1220        v4l2_fh_init(&ctx->fh, vfd);
1221        file->private_data = &ctx->fh;
1222        v4l2_fh_add(&ctx->fh);
1223
1224        ctx->jpeg = jpeg;
1225        ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx,
1226                                            mtk_jpeg_queue_init);
1227        if (IS_ERR(ctx->fh.m2m_ctx)) {
1228                ret = PTR_ERR(ctx->fh.m2m_ctx);
1229                goto error;
1230        }
1231
1232        if (jpeg->variant->cap_q_default_fourcc == V4L2_PIX_FMT_JPEG) {
1233                ret = mtk_jpeg_enc_ctrls_setup(ctx);
1234                if (ret) {
1235                        v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg enc controls\n");
1236                        goto error;
1237                }
1238        } else {
1239                v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 0);
1240        }
1241        mtk_jpeg_set_default_params(ctx);
1242        mutex_unlock(&jpeg->lock);
1243        return 0;
1244
1245error:
1246        v4l2_fh_del(&ctx->fh);
1247        v4l2_fh_exit(&ctx->fh);
1248        mutex_unlock(&jpeg->lock);
1249free:
1250        kfree(ctx);
1251        return ret;
1252}
1253
1254static int mtk_jpeg_release(struct file *file)
1255{
1256        struct mtk_jpeg_dev *jpeg = video_drvdata(file);
1257        struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(file->private_data);
1258
1259        mutex_lock(&jpeg->lock);
1260        v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1261        v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
1262        v4l2_fh_del(&ctx->fh);
1263        v4l2_fh_exit(&ctx->fh);
1264        kfree(ctx);
1265        mutex_unlock(&jpeg->lock);
1266        return 0;
1267}
1268
1269static const struct v4l2_file_operations mtk_jpeg_fops = {
1270        .owner          = THIS_MODULE,
1271        .open           = mtk_jpeg_open,
1272        .release        = mtk_jpeg_release,
1273        .poll           = v4l2_m2m_fop_poll,
1274        .unlocked_ioctl = video_ioctl2,
1275        .mmap           = v4l2_m2m_fop_mmap,
1276};
1277
1278static struct clk_bulk_data mt8173_jpeg_dec_clocks[] = {
1279        { .id = "jpgdec-smi" },
1280        { .id = "jpgdec" },
1281};
1282
1283static struct clk_bulk_data mtk_jpeg_clocks[] = {
1284        { .id = "jpgenc" },
1285};
1286
1287static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg)
1288{
1289        struct device_node *node;
1290        struct platform_device *pdev;
1291        int ret;
1292
1293        node = of_parse_phandle(jpeg->dev->of_node, "mediatek,larb", 0);
1294        if (!node)
1295                return -EINVAL;
1296        pdev = of_find_device_by_node(node);
1297        if (WARN_ON(!pdev)) {
1298                of_node_put(node);
1299                return -EINVAL;
1300        }
1301        of_node_put(node);
1302
1303        jpeg->larb = &pdev->dev;
1304
1305        ret = devm_clk_bulk_get(jpeg->dev, jpeg->variant->num_clks,
1306                                jpeg->variant->clks);
1307        if (ret) {
1308                dev_err(&pdev->dev, "failed to get jpeg clock:%d\n", ret);
1309                put_device(&pdev->dev);
1310                return ret;
1311        }
1312
1313        return 0;
1314}
1315
1316static void mtk_jpeg_job_timeout_work(struct work_struct *work)
1317{
1318        struct mtk_jpeg_dev *jpeg = container_of(work, struct mtk_jpeg_dev,
1319                                                 job_timeout_work.work);
1320        struct mtk_jpeg_ctx *ctx;
1321        struct vb2_v4l2_buffer *src_buf, *dst_buf;
1322
1323        ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1324        src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1325        dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1326
1327        jpeg->variant->hw_reset(jpeg->reg_base);
1328
1329        pm_runtime_put(jpeg->dev);
1330
1331        v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
1332        v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
1333        v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1334}
1335
1336static inline void mtk_jpeg_clk_release(struct mtk_jpeg_dev *jpeg)
1337{
1338        put_device(jpeg->larb);
1339}
1340
1341static int mtk_jpeg_probe(struct platform_device *pdev)
1342{
1343        struct mtk_jpeg_dev *jpeg;
1344        struct resource *res;
1345        int jpeg_irq;
1346        int ret;
1347
1348        jpeg = devm_kzalloc(&pdev->dev, sizeof(*jpeg), GFP_KERNEL);
1349        if (!jpeg)
1350                return -ENOMEM;
1351
1352        mutex_init(&jpeg->lock);
1353        spin_lock_init(&jpeg->hw_lock);
1354        jpeg->dev = &pdev->dev;
1355        jpeg->variant = of_device_get_match_data(jpeg->dev);
1356        INIT_DELAYED_WORK(&jpeg->job_timeout_work, mtk_jpeg_job_timeout_work);
1357
1358        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1359        jpeg->reg_base = devm_ioremap_resource(&pdev->dev, res);
1360        if (IS_ERR(jpeg->reg_base)) {
1361                ret = PTR_ERR(jpeg->reg_base);
1362                return ret;
1363        }
1364
1365        jpeg_irq = platform_get_irq(pdev, 0);
1366        if (jpeg_irq < 0) {
1367                dev_err(&pdev->dev, "Failed to get jpeg_irq %d.\n", jpeg_irq);
1368                return jpeg_irq;
1369        }
1370
1371        ret = devm_request_irq(&pdev->dev, jpeg_irq,
1372                               jpeg->variant->irq_handler, 0, pdev->name, jpeg);
1373        if (ret) {
1374                dev_err(&pdev->dev, "Failed to request jpeg_irq %d (%d)\n",
1375                        jpeg_irq, ret);
1376                goto err_req_irq;
1377        }
1378
1379        ret = mtk_jpeg_clk_init(jpeg);
1380        if (ret) {
1381                dev_err(&pdev->dev, "Failed to init clk, err %d\n", ret);
1382                goto err_clk_init;
1383        }
1384
1385        ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1386        if (ret) {
1387                dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1388                ret = -EINVAL;
1389                goto err_dev_register;
1390        }
1391
1392        jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops);
1393
1394        if (IS_ERR(jpeg->m2m_dev)) {
1395                v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1396                ret = PTR_ERR(jpeg->m2m_dev);
1397                goto err_m2m_init;
1398        }
1399
1400        jpeg->vdev = video_device_alloc();
1401        if (!jpeg->vdev) {
1402                ret = -ENOMEM;
1403                goto err_vfd_jpeg_alloc;
1404        }
1405        snprintf(jpeg->vdev->name, sizeof(jpeg->vdev->name),
1406                 "%s", jpeg->variant->dev_name);
1407        jpeg->vdev->fops = &mtk_jpeg_fops;
1408        jpeg->vdev->ioctl_ops = jpeg->variant->ioctl_ops;
1409        jpeg->vdev->minor = -1;
1410        jpeg->vdev->release = video_device_release;
1411        jpeg->vdev->lock = &jpeg->lock;
1412        jpeg->vdev->v4l2_dev = &jpeg->v4l2_dev;
1413        jpeg->vdev->vfl_dir = VFL_DIR_M2M;
1414        jpeg->vdev->device_caps = V4L2_CAP_STREAMING |
1415                                  V4L2_CAP_VIDEO_M2M_MPLANE;
1416
1417        ret = video_register_device(jpeg->vdev, VFL_TYPE_VIDEO, -1);
1418        if (ret) {
1419                v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1420                goto err_vfd_jpeg_register;
1421        }
1422
1423        video_set_drvdata(jpeg->vdev, jpeg);
1424        v4l2_info(&jpeg->v4l2_dev,
1425                  "%s device registered as /dev/video%d (%d,%d)\n",
1426                  jpeg->variant->dev_name, jpeg->vdev->num,
1427                  VIDEO_MAJOR, jpeg->vdev->minor);
1428
1429        platform_set_drvdata(pdev, jpeg);
1430
1431        pm_runtime_enable(&pdev->dev);
1432
1433        return 0;
1434
1435err_vfd_jpeg_register:
1436        video_device_release(jpeg->vdev);
1437
1438err_vfd_jpeg_alloc:
1439        v4l2_m2m_release(jpeg->m2m_dev);
1440
1441err_m2m_init:
1442        v4l2_device_unregister(&jpeg->v4l2_dev);
1443
1444err_dev_register:
1445        mtk_jpeg_clk_release(jpeg);
1446
1447err_clk_init:
1448
1449err_req_irq:
1450
1451        return ret;
1452}
1453
1454static int mtk_jpeg_remove(struct platform_device *pdev)
1455{
1456        struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev);
1457
1458        pm_runtime_disable(&pdev->dev);
1459        video_unregister_device(jpeg->vdev);
1460        video_device_release(jpeg->vdev);
1461        v4l2_m2m_release(jpeg->m2m_dev);
1462        v4l2_device_unregister(&jpeg->v4l2_dev);
1463        mtk_jpeg_clk_release(jpeg);
1464
1465        return 0;
1466}
1467
1468static __maybe_unused int mtk_jpeg_pm_suspend(struct device *dev)
1469{
1470        struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1471
1472        mtk_jpeg_clk_off(jpeg);
1473
1474        return 0;
1475}
1476
1477static __maybe_unused int mtk_jpeg_pm_resume(struct device *dev)
1478{
1479        struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1480
1481        mtk_jpeg_clk_on(jpeg);
1482
1483        return 0;
1484}
1485
1486static __maybe_unused int mtk_jpeg_suspend(struct device *dev)
1487{
1488        struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1489
1490        v4l2_m2m_suspend(jpeg->m2m_dev);
1491        return pm_runtime_force_suspend(dev);
1492}
1493
1494static __maybe_unused int mtk_jpeg_resume(struct device *dev)
1495{
1496        struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1497        int ret;
1498
1499        ret = pm_runtime_force_resume(dev);
1500        if (ret < 0)
1501                return ret;
1502
1503        v4l2_m2m_resume(jpeg->m2m_dev);
1504        return ret;
1505}
1506
1507static const struct dev_pm_ops mtk_jpeg_pm_ops = {
1508        SET_SYSTEM_SLEEP_PM_OPS(mtk_jpeg_suspend, mtk_jpeg_resume)
1509        SET_RUNTIME_PM_OPS(mtk_jpeg_pm_suspend, mtk_jpeg_pm_resume, NULL)
1510};
1511
1512static const struct mtk_jpeg_variant mt8173_jpeg_drvdata = {
1513        .clks = mt8173_jpeg_dec_clocks,
1514        .num_clks = ARRAY_SIZE(mt8173_jpeg_dec_clocks),
1515        .formats = mtk_jpeg_dec_formats,
1516        .num_formats = MTK_JPEG_DEC_NUM_FORMATS,
1517        .qops = &mtk_jpeg_dec_qops,
1518        .irq_handler = mtk_jpeg_dec_irq,
1519        .hw_reset = mtk_jpeg_dec_reset,
1520        .m2m_ops = &mtk_jpeg_dec_m2m_ops,
1521        .dev_name = "mtk-jpeg-dec",
1522        .ioctl_ops = &mtk_jpeg_dec_ioctl_ops,
1523        .out_q_default_fourcc = V4L2_PIX_FMT_JPEG,
1524        .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M,
1525};
1526
1527static const struct mtk_jpeg_variant mtk_jpeg_drvdata = {
1528        .clks = mtk_jpeg_clocks,
1529        .num_clks = ARRAY_SIZE(mtk_jpeg_clocks),
1530        .formats = mtk_jpeg_enc_formats,
1531        .num_formats = MTK_JPEG_ENC_NUM_FORMATS,
1532        .qops = &mtk_jpeg_enc_qops,
1533        .irq_handler = mtk_jpeg_enc_irq,
1534        .hw_reset = mtk_jpeg_enc_reset,
1535        .m2m_ops = &mtk_jpeg_enc_m2m_ops,
1536        .dev_name = "mtk-jpeg-enc",
1537        .ioctl_ops = &mtk_jpeg_enc_ioctl_ops,
1538        .out_q_default_fourcc = V4L2_PIX_FMT_YUYV,
1539        .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
1540};
1541
1542static const struct of_device_id mtk_jpeg_match[] = {
1543        {
1544                .compatible = "mediatek,mt8173-jpgdec",
1545                .data = &mt8173_jpeg_drvdata,
1546        },
1547        {
1548                .compatible = "mediatek,mt2701-jpgdec",
1549                .data = &mt8173_jpeg_drvdata,
1550        },
1551        {
1552                .compatible = "mediatek,mtk-jpgenc",
1553                .data = &mtk_jpeg_drvdata,
1554        },
1555        {},
1556};
1557
1558MODULE_DEVICE_TABLE(of, mtk_jpeg_match);
1559
1560static struct platform_driver mtk_jpeg_driver = {
1561        .probe = mtk_jpeg_probe,
1562        .remove = mtk_jpeg_remove,
1563        .driver = {
1564                .name           = MTK_JPEG_NAME,
1565                .of_match_table = mtk_jpeg_match,
1566                .pm             = &mtk_jpeg_pm_ops,
1567        },
1568};
1569
1570module_platform_driver(mtk_jpeg_driver);
1571
1572MODULE_DESCRIPTION("MediaTek JPEG codec driver");
1573MODULE_LICENSE("GPL v2");
1574