linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
<<
>>
Prefs
   1/* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
   2 *
   3 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
   4 *              http://www.samsung.com
   5 *
   6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
   7 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13
  14#include <linux/clk.h>
  15#include <linux/err.h>
  16#include <linux/gfp.h>
  17#include <linux/interrupt.h>
  18#include <linux/io.h>
  19#include <linux/kernel.h>
  20#include <linux/module.h>
  21#include <linux/of.h>
  22#include <linux/platform_device.h>
  23#include <linux/pm_runtime.h>
  24#include <linux/slab.h>
  25#include <linux/spinlock.h>
  26#include <linux/string.h>
  27#include <media/v4l2-event.h>
  28#include <media/v4l2-mem2mem.h>
  29#include <media/v4l2-ioctl.h>
  30#include <media/videobuf2-v4l2.h>
  31#include <media/videobuf2-dma-contig.h>
  32
  33#include "jpeg-core.h"
  34#include "jpeg-hw-s5p.h"
  35#include "jpeg-hw-exynos4.h"
  36#include "jpeg-hw-exynos3250.h"
  37#include "jpeg-regs.h"
  38
  39static struct s5p_jpeg_fmt sjpeg_formats[] = {
  40        {
  41                .name           = "JPEG JFIF",
  42                .fourcc         = V4L2_PIX_FMT_JPEG,
  43                .flags          = SJPEG_FMT_FLAG_ENC_CAPTURE |
  44                                  SJPEG_FMT_FLAG_DEC_OUTPUT |
  45                                  SJPEG_FMT_FLAG_S5P |
  46                                  SJPEG_FMT_FLAG_EXYNOS3250 |
  47                                  SJPEG_FMT_FLAG_EXYNOS4,
  48        },
  49        {
  50                .name           = "YUV 4:2:2 packed, YCbYCr",
  51                .fourcc         = V4L2_PIX_FMT_YUYV,
  52                .depth          = 16,
  53                .colplanes      = 1,
  54                .h_align        = 4,
  55                .v_align        = 3,
  56                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
  57                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
  58                                  SJPEG_FMT_FLAG_S5P |
  59                                  SJPEG_FMT_NON_RGB,
  60                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
  61        },
  62        {
  63                .name           = "YUV 4:2:2 packed, YCbYCr",
  64                .fourcc         = V4L2_PIX_FMT_YUYV,
  65                .depth          = 16,
  66                .colplanes      = 1,
  67                .h_align        = 1,
  68                .v_align        = 0,
  69                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
  70                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
  71                                  SJPEG_FMT_FLAG_EXYNOS4 |
  72                                  SJPEG_FMT_NON_RGB,
  73                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
  74        },
  75        {
  76                .name           = "YUV 4:2:2 packed, YCbYCr",
  77                .fourcc         = V4L2_PIX_FMT_YUYV,
  78                .depth          = 16,
  79                .colplanes      = 1,
  80                .h_align        = 2,
  81                .v_align        = 0,
  82                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
  83                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
  84                                  SJPEG_FMT_FLAG_EXYNOS3250 |
  85                                  SJPEG_FMT_NON_RGB,
  86                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
  87        },
  88        {
  89                .name           = "YUV 4:2:2 packed, YCrYCb",
  90                .fourcc         = V4L2_PIX_FMT_YVYU,
  91                .depth          = 16,
  92                .colplanes      = 1,
  93                .h_align        = 1,
  94                .v_align        = 0,
  95                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
  96                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
  97                                  SJPEG_FMT_FLAG_EXYNOS4 |
  98                                  SJPEG_FMT_NON_RGB,
  99                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 100        },
 101        {
 102                .name           = "YUV 4:2:2 packed, YCrYCb",
 103                .fourcc         = V4L2_PIX_FMT_YVYU,
 104                .depth          = 16,
 105                .colplanes      = 1,
 106                .h_align        = 2,
 107                .v_align        = 0,
 108                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 109                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 110                                  SJPEG_FMT_FLAG_EXYNOS3250 |
 111                                  SJPEG_FMT_NON_RGB,
 112                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 113        },
 114        {
 115                .name           = "YUV 4:2:2 packed, YCrYCb",
 116                .fourcc         = V4L2_PIX_FMT_UYVY,
 117                .depth          = 16,
 118                .colplanes      = 1,
 119                .h_align        = 2,
 120                .v_align        = 0,
 121                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 122                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 123                                  SJPEG_FMT_FLAG_EXYNOS3250 |
 124                                  SJPEG_FMT_NON_RGB,
 125                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 126        },
 127        {
 128                .name           = "YUV 4:2:2 packed, YCrYCb",
 129                .fourcc         = V4L2_PIX_FMT_VYUY,
 130                .depth          = 16,
 131                .colplanes      = 1,
 132                .h_align        = 2,
 133                .v_align        = 0,
 134                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 135                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 136                                  SJPEG_FMT_FLAG_EXYNOS3250 |
 137                                  SJPEG_FMT_NON_RGB,
 138                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 139        },
 140        {
 141                .name           = "RGB565",
 142                .fourcc         = V4L2_PIX_FMT_RGB565,
 143                .depth          = 16,
 144                .colplanes      = 1,
 145                .h_align        = 0,
 146                .v_align        = 0,
 147                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 148                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 149                                  SJPEG_FMT_FLAG_EXYNOS4 |
 150                                  SJPEG_FMT_RGB,
 151                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 152        },
 153        {
 154                .name           = "RGB565",
 155                .fourcc         = V4L2_PIX_FMT_RGB565,
 156                .depth          = 16,
 157                .colplanes      = 1,
 158                .h_align        = 2,
 159                .v_align        = 0,
 160                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 161                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 162                                  SJPEG_FMT_FLAG_EXYNOS3250 |
 163                                  SJPEG_FMT_RGB,
 164                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 165        },
 166        {
 167                .name           = "RGB565X",
 168                .fourcc         = V4L2_PIX_FMT_RGB565X,
 169                .depth          = 16,
 170                .colplanes      = 1,
 171                .h_align        = 2,
 172                .v_align        = 0,
 173                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 174                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 175                                  SJPEG_FMT_FLAG_EXYNOS3250 |
 176                                  SJPEG_FMT_RGB,
 177                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 178        },
 179        {
 180                .name           = "RGB565",
 181                .fourcc         = V4L2_PIX_FMT_RGB565,
 182                .depth          = 16,
 183                .colplanes      = 1,
 184                .h_align        = 0,
 185                .v_align        = 0,
 186                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 187                                  SJPEG_FMT_FLAG_S5P |
 188                                  SJPEG_FMT_RGB,
 189                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 190        },
 191        {
 192                .name           = "ARGB8888, 32 bpp",
 193                .fourcc         = V4L2_PIX_FMT_RGB32,
 194                .depth          = 32,
 195                .colplanes      = 1,
 196                .h_align        = 0,
 197                .v_align        = 0,
 198                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 199                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 200                                  SJPEG_FMT_FLAG_EXYNOS4 |
 201                                  SJPEG_FMT_RGB,
 202                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 203        },
 204        {
 205                .name           = "ARGB8888, 32 bpp",
 206                .fourcc         = V4L2_PIX_FMT_RGB32,
 207                .depth          = 32,
 208                .colplanes      = 1,
 209                .h_align        = 2,
 210                .v_align        = 0,
 211                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 212                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 213                                  SJPEG_FMT_FLAG_EXYNOS3250 |
 214                                  SJPEG_FMT_RGB,
 215                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 216        },
 217        {
 218                .name           = "YUV 4:4:4 planar, Y/CbCr",
 219                .fourcc         = V4L2_PIX_FMT_NV24,
 220                .depth          = 24,
 221                .colplanes      = 2,
 222                .h_align        = 0,
 223                .v_align        = 0,
 224                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 225                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 226                                  SJPEG_FMT_FLAG_EXYNOS4 |
 227                                  SJPEG_FMT_NON_RGB,
 228                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 229        },
 230        {
 231                .name           = "YUV 4:4:4 planar, Y/CrCb",
 232                .fourcc         = V4L2_PIX_FMT_NV42,
 233                .depth          = 24,
 234                .colplanes      = 2,
 235                .h_align        = 0,
 236                .v_align        = 0,
 237                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 238                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 239                                  SJPEG_FMT_FLAG_EXYNOS4 |
 240                                  SJPEG_FMT_NON_RGB,
 241                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 242        },
 243        {
 244                .name           = "YUV 4:2:2 planar, Y/CrCb",
 245                .fourcc         = V4L2_PIX_FMT_NV61,
 246                .depth          = 16,
 247                .colplanes      = 2,
 248                .h_align        = 1,
 249                .v_align        = 0,
 250                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 251                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 252                                  SJPEG_FMT_FLAG_EXYNOS4 |
 253                                  SJPEG_FMT_NON_RGB,
 254                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 255        },
 256        {
 257                .name           = "YUV 4:2:2 planar, Y/CbCr",
 258                .fourcc         = V4L2_PIX_FMT_NV16,
 259                .depth          = 16,
 260                .colplanes      = 2,
 261                .h_align        = 1,
 262                .v_align        = 0,
 263                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 264                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 265                                  SJPEG_FMT_FLAG_EXYNOS4 |
 266                                  SJPEG_FMT_NON_RGB,
 267                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 268        },
 269        {
 270                .name           = "YUV 4:2:0 planar, Y/CbCr",
 271                .fourcc         = V4L2_PIX_FMT_NV12,
 272                .depth          = 12,
 273                .colplanes      = 2,
 274                .h_align        = 1,
 275                .v_align        = 1,
 276                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 277                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 278                                  SJPEG_FMT_FLAG_EXYNOS4 |
 279                                  SJPEG_FMT_NON_RGB,
 280                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 281        },
 282        {
 283                .name           = "YUV 4:2:0 planar, Y/CbCr",
 284                .fourcc         = V4L2_PIX_FMT_NV12,
 285                .depth          = 12,
 286                .colplanes      = 2,
 287                .h_align        = 3,
 288                .v_align        = 3,
 289                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 290                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 291                                  SJPEG_FMT_FLAG_EXYNOS3250 |
 292                                  SJPEG_FMT_NON_RGB,
 293                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 294        },
 295        {
 296                .name           = "YUV 4:2:0 planar, Y/CbCr",
 297                .fourcc         = V4L2_PIX_FMT_NV12,
 298                .depth          = 12,
 299                .colplanes      = 2,
 300                .h_align        = 4,
 301                .v_align        = 4,
 302                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 303                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 304                                  SJPEG_FMT_FLAG_S5P |
 305                                  SJPEG_FMT_NON_RGB,
 306                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 307        },
 308        {
 309                .name           = "YUV 4:2:0 planar, Y/CrCb",
 310                .fourcc         = V4L2_PIX_FMT_NV21,
 311                .depth          = 12,
 312                .colplanes      = 2,
 313                .h_align        = 3,
 314                .v_align        = 3,
 315                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 316                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 317                                  SJPEG_FMT_FLAG_EXYNOS3250 |
 318                                  SJPEG_FMT_NON_RGB,
 319                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 320        },
 321        {
 322                .name           = "YUV 4:2:0 planar, Y/CrCb",
 323                .fourcc         = V4L2_PIX_FMT_NV21,
 324                .depth          = 12,
 325                .colplanes      = 2,
 326                .h_align        = 1,
 327                .v_align        = 1,
 328                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 329                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 330                                  SJPEG_FMT_FLAG_EXYNOS3250 |
 331                                  SJPEG_FMT_FLAG_EXYNOS4 |
 332                                  SJPEG_FMT_NON_RGB,
 333                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 334        },
 335        {
 336                .name           = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
 337                .fourcc         = V4L2_PIX_FMT_YUV420,
 338                .depth          = 12,
 339                .colplanes      = 3,
 340                .h_align        = 1,
 341                .v_align        = 1,
 342                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 343                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 344                                  SJPEG_FMT_FLAG_EXYNOS4 |
 345                                  SJPEG_FMT_NON_RGB,
 346                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 347        },
 348        {
 349                .name           = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
 350                .fourcc         = V4L2_PIX_FMT_YUV420,
 351                .depth          = 12,
 352                .colplanes      = 3,
 353                .h_align        = 4,
 354                .v_align        = 4,
 355                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 356                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 357                                  SJPEG_FMT_FLAG_EXYNOS3250 |
 358                                  SJPEG_FMT_NON_RGB,
 359                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 360        },
 361        {
 362                .name           = "Gray",
 363                .fourcc         = V4L2_PIX_FMT_GREY,
 364                .depth          = 8,
 365                .colplanes      = 1,
 366                .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
 367                                  SJPEG_FMT_FLAG_DEC_CAPTURE |
 368                                  SJPEG_FMT_FLAG_EXYNOS4 |
 369                                  SJPEG_FMT_NON_RGB,
 370                .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
 371        },
 372};
 373#define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
 374
 375static const unsigned char qtbl_luminance[4][64] = {
 376        {/*level 0 - high compression quality */
 377                20, 16, 25, 39, 50, 46, 62, 68,
 378                16, 18, 23, 38, 38, 53, 65, 68,
 379                25, 23, 31, 38, 53, 65, 68, 68,
 380                39, 38, 38, 53, 65, 68, 68, 68,
 381                50, 38, 53, 65, 68, 68, 68, 68,
 382                46, 53, 65, 68, 68, 68, 68, 68,
 383                62, 65, 68, 68, 68, 68, 68, 68,
 384                68, 68, 68, 68, 68, 68, 68, 68
 385        },
 386        {/* level 1 */
 387                16, 11, 11, 16, 23, 27, 31, 30,
 388                11, 12, 12, 15, 20, 23, 23, 30,
 389                11, 12, 13, 16, 23, 26, 35, 47,
 390                16, 15, 16, 23, 26, 37, 47, 64,
 391                23, 20, 23, 26, 39, 51, 64, 64,
 392                27, 23, 26, 37, 51, 64, 64, 64,
 393                31, 23, 35, 47, 64, 64, 64, 64,
 394                30, 30, 47, 64, 64, 64, 64, 64
 395        },
 396        {/* level 2 */
 397                12,  8,  8, 12, 17, 21, 24, 23,
 398                 8,  9,  9, 11, 15, 19, 18, 23,
 399                 8,  9, 10, 12, 19, 20, 27, 36,
 400                12, 11, 12, 21, 20, 28, 36, 53,
 401                17, 15, 19, 20, 30, 39, 51, 59,
 402                21, 19, 20, 28, 39, 51, 59, 59,
 403                24, 18, 27, 36, 51, 59, 59, 59,
 404                23, 23, 36, 53, 59, 59, 59, 59
 405        },
 406        {/* level 3 - low compression quality */
 407                 8,  6,  6,  8, 12, 14, 16, 17,
 408                 6,  6,  6,  8, 10, 13, 12, 15,
 409                 6,  6,  7,  8, 13, 14, 18, 24,
 410                 8,  8,  8, 14, 13, 19, 24, 35,
 411                12, 10, 13, 13, 20, 26, 34, 39,
 412                14, 13, 14, 19, 26, 34, 39, 39,
 413                16, 12, 18, 24, 34, 39, 39, 39,
 414                17, 15, 24, 35, 39, 39, 39, 39
 415        }
 416};
 417
 418static const unsigned char qtbl_chrominance[4][64] = {
 419        {/*level 0 - high compression quality */
 420                21, 25, 32, 38, 54, 68, 68, 68,
 421                25, 28, 24, 38, 54, 68, 68, 68,
 422                32, 24, 32, 43, 66, 68, 68, 68,
 423                38, 38, 43, 53, 68, 68, 68, 68,
 424                54, 54, 66, 68, 68, 68, 68, 68,
 425                68, 68, 68, 68, 68, 68, 68, 68,
 426                68, 68, 68, 68, 68, 68, 68, 68,
 427                68, 68, 68, 68, 68, 68, 68, 68
 428        },
 429        {/* level 1 */
 430                17, 15, 17, 21, 20, 26, 38, 48,
 431                15, 19, 18, 17, 20, 26, 35, 43,
 432                17, 18, 20, 22, 26, 30, 46, 53,
 433                21, 17, 22, 28, 30, 39, 53, 64,
 434                20, 20, 26, 30, 39, 48, 64, 64,
 435                26, 26, 30, 39, 48, 63, 64, 64,
 436                38, 35, 46, 53, 64, 64, 64, 64,
 437                48, 43, 53, 64, 64, 64, 64, 64
 438        },
 439        {/* level 2 */
 440                13, 11, 13, 16, 20, 20, 29, 37,
 441                11, 14, 14, 14, 16, 20, 26, 32,
 442                13, 14, 15, 17, 20, 23, 35, 40,
 443                16, 14, 17, 21, 23, 30, 40, 50,
 444                20, 16, 20, 23, 30, 37, 50, 59,
 445                20, 20, 23, 30, 37, 48, 59, 59,
 446                29, 26, 35, 40, 50, 59, 59, 59,
 447                37, 32, 40, 50, 59, 59, 59, 59
 448        },
 449        {/* level 3 - low compression quality */
 450                 9,  8,  9, 11, 14, 17, 19, 24,
 451                 8, 10,  9, 11, 14, 13, 17, 22,
 452                 9,  9, 13, 14, 13, 15, 23, 26,
 453                11, 11, 14, 14, 15, 20, 26, 33,
 454                14, 14, 13, 15, 20, 24, 33, 39,
 455                17, 13, 15, 20, 24, 32, 39, 39,
 456                19, 17, 23, 26, 33, 39, 39, 39,
 457                24, 22, 26, 33, 39, 39, 39, 39
 458        }
 459};
 460
 461static const unsigned char hdctbl0[16] = {
 462        0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
 463};
 464
 465static const unsigned char hdctblg0[12] = {
 466        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
 467};
 468static const unsigned char hactbl0[16] = {
 469        0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
 470};
 471static const unsigned char hactblg0[162] = {
 472        0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
 473        0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
 474        0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
 475        0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
 476        0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
 477        0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
 478        0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
 479        0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
 480        0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
 481        0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
 482        0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
 483        0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
 484        0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
 485        0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
 486        0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
 487        0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
 488        0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
 489        0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
 490        0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
 491        0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
 492        0xf9, 0xfa
 493};
 494
 495/*
 496 * Fourcc downgrade schema lookup tables for 422 and 420
 497 * chroma subsampling - fourcc on each position maps on the
 498 * fourcc from the table fourcc_to_dwngrd_schema_id which allows
 499 * to get the most suitable fourcc counterpart for the given
 500 * downgraded subsampling property.
 501 */
 502static const u32 subs422_fourcc_dwngrd_schema[] = {
 503        V4L2_PIX_FMT_NV16,
 504        V4L2_PIX_FMT_NV61,
 505};
 506
 507static const u32 subs420_fourcc_dwngrd_schema[] = {
 508        V4L2_PIX_FMT_NV12,
 509        V4L2_PIX_FMT_NV21,
 510        V4L2_PIX_FMT_NV12,
 511        V4L2_PIX_FMT_NV21,
 512        V4L2_PIX_FMT_NV12,
 513        V4L2_PIX_FMT_NV21,
 514        V4L2_PIX_FMT_GREY,
 515        V4L2_PIX_FMT_GREY,
 516        V4L2_PIX_FMT_GREY,
 517        V4L2_PIX_FMT_GREY,
 518};
 519
 520/*
 521 * Lookup table for translation of a fourcc to the position
 522 * of its downgraded counterpart in the *fourcc_dwngrd_schema
 523 * tables.
 524 */
 525static const u32 fourcc_to_dwngrd_schema_id[] = {
 526        V4L2_PIX_FMT_NV24,
 527        V4L2_PIX_FMT_NV42,
 528        V4L2_PIX_FMT_NV16,
 529        V4L2_PIX_FMT_NV61,
 530        V4L2_PIX_FMT_YUYV,
 531        V4L2_PIX_FMT_YVYU,
 532        V4L2_PIX_FMT_NV12,
 533        V4L2_PIX_FMT_NV21,
 534        V4L2_PIX_FMT_YUV420,
 535        V4L2_PIX_FMT_GREY,
 536};
 537
 538static int s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)
 539{
 540        int i;
 541
 542        for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) {
 543                if (fourcc_to_dwngrd_schema_id[i] == fourcc)
 544                        return i;
 545        }
 546
 547        return -EINVAL;
 548}
 549
 550static int s5p_jpeg_adjust_fourcc_to_subsampling(
 551                                        enum v4l2_jpeg_chroma_subsampling subs,
 552                                        u32 in_fourcc,
 553                                        u32 *out_fourcc,
 554                                        struct s5p_jpeg_ctx *ctx)
 555{
 556        int dwngrd_sch_id;
 557
 558        if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
 559                dwngrd_sch_id =
 560                        s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc);
 561                if (dwngrd_sch_id < 0)
 562                        return -EINVAL;
 563        }
 564
 565        switch (ctx->subsampling) {
 566        case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
 567                *out_fourcc = V4L2_PIX_FMT_GREY;
 568                break;
 569        case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
 570                if (dwngrd_sch_id >
 571                                ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1)
 572                        return -EINVAL;
 573                *out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id];
 574                break;
 575        case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
 576                if (dwngrd_sch_id >
 577                                ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1)
 578                        return -EINVAL;
 579                *out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id];
 580                break;
 581        default:
 582                *out_fourcc = V4L2_PIX_FMT_GREY;
 583                break;
 584        }
 585
 586        return 0;
 587}
 588
 589static int exynos4x12_decoded_subsampling[] = {
 590        V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
 591        V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 592        V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 593        V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 594};
 595
 596static int exynos3250_decoded_subsampling[] = {
 597        V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 598        V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 599        V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 600        V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
 601        -1,
 602        -1,
 603        V4L2_JPEG_CHROMA_SUBSAMPLING_411,
 604};
 605
 606static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
 607{
 608        return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
 609}
 610
 611static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
 612{
 613        return container_of(fh, struct s5p_jpeg_ctx, fh);
 614}
 615
 616static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
 617{
 618        switch (ctx->jpeg->variant->version) {
 619        case SJPEG_S5P:
 620                WARN_ON(ctx->subsampling > 3);
 621                if (ctx->subsampling > 2)
 622                        return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
 623                return ctx->subsampling;
 624        case SJPEG_EXYNOS3250:
 625        case SJPEG_EXYNOS5420:
 626                WARN_ON(ctx->subsampling > 6);
 627                if (ctx->subsampling > 3)
 628                        return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
 629                return exynos3250_decoded_subsampling[ctx->subsampling];
 630        case SJPEG_EXYNOS4:
 631                WARN_ON(ctx->subsampling > 3);
 632                if (ctx->subsampling > 2)
 633                        return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
 634                return exynos4x12_decoded_subsampling[ctx->subsampling];
 635        case SJPEG_EXYNOS5433:
 636                return ctx->subsampling; /* parsed from header */
 637        default:
 638                WARN_ON(ctx->subsampling > 3);
 639                return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
 640        }
 641}
 642
 643static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
 644                                     const unsigned char *qtbl,
 645                                     unsigned long tab, int len)
 646{
 647        int i;
 648
 649        for (i = 0; i < len; i++)
 650                writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
 651}
 652
 653static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
 654{
 655        /* this driver fills quantisation table 0 with data for luma */
 656        s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
 657                          S5P_JPG_QTBL_CONTENT(0),
 658                          ARRAY_SIZE(qtbl_luminance[quality]));
 659}
 660
 661static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
 662{
 663        /* this driver fills quantisation table 1 with data for chroma */
 664        s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
 665                          S5P_JPG_QTBL_CONTENT(1),
 666                          ARRAY_SIZE(qtbl_chrominance[quality]));
 667}
 668
 669static inline void s5p_jpeg_set_htbl(void __iomem *regs,
 670                                     const unsigned char *htbl,
 671                                     unsigned long tab, int len)
 672{
 673        int i;
 674
 675        for (i = 0; i < len; i++)
 676                writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
 677}
 678
 679static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
 680{
 681        /* this driver fills table 0 for this component */
 682        s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
 683                                                ARRAY_SIZE(hdctbl0));
 684}
 685
 686static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
 687{
 688        /* this driver fills table 0 for this component */
 689        s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
 690                                                ARRAY_SIZE(hdctblg0));
 691}
 692
 693static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
 694{
 695        /* this driver fills table 0 for this component */
 696        s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
 697                                                ARRAY_SIZE(hactbl0));
 698}
 699
 700static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
 701{
 702        /* this driver fills table 0 for this component */
 703        s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
 704                                                ARRAY_SIZE(hactblg0));
 705}
 706
 707static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
 708                                        const unsigned char *tbl,
 709                                        unsigned long tab, int len)
 710{
 711        int i;
 712        unsigned int dword;
 713
 714        for (i = 0; i < len; i += 4) {
 715                dword = tbl[i] |
 716                        (tbl[i + 1] << 8) |
 717                        (tbl[i + 2] << 16) |
 718                        (tbl[i + 3] << 24);
 719                writel(dword, regs + tab + i);
 720        }
 721}
 722
 723static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
 724{
 725        /* this driver fills quantisation table 0 with data for luma */
 726        exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
 727                             EXYNOS4_QTBL_CONTENT(0),
 728                             ARRAY_SIZE(qtbl_luminance[quality]));
 729}
 730
 731static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
 732{
 733        /* this driver fills quantisation table 1 with data for chroma */
 734        exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
 735                             EXYNOS4_QTBL_CONTENT(1),
 736                             ARRAY_SIZE(qtbl_chrominance[quality]));
 737}
 738
 739static void exynos4_jpeg_set_huff_tbl(void __iomem *base)
 740{
 741        exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
 742                                                        ARRAY_SIZE(hdctbl0));
 743        exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
 744                                                        ARRAY_SIZE(hdctbl0));
 745        exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
 746                                                        ARRAY_SIZE(hdctblg0));
 747        exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
 748                                                        ARRAY_SIZE(hdctblg0));
 749        exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
 750                                                        ARRAY_SIZE(hactbl0));
 751        exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
 752                                                        ARRAY_SIZE(hactbl0));
 753        exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
 754                                                        ARRAY_SIZE(hactblg0));
 755        exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
 756                                                        ARRAY_SIZE(hactblg0));
 757}
 758
 759static inline int __exynos4_huff_tbl(int class, int id, bool lenval)
 760{
 761        /*
 762         * class: 0 - DC, 1 - AC
 763         * id: 0 - Y, 1 - Cb/Cr
 764         */
 765        if (class) {
 766                if (id)
 767                        return lenval ? EXYNOS4_HUFF_TBL_HACCL :
 768                                EXYNOS4_HUFF_TBL_HACCV;
 769                return lenval ? EXYNOS4_HUFF_TBL_HACLL : EXYNOS4_HUFF_TBL_HACLV;
 770
 771        }
 772        /* class == 0 */
 773        if (id)
 774                return lenval ? EXYNOS4_HUFF_TBL_HDCCL : EXYNOS4_HUFF_TBL_HDCCV;
 775
 776        return lenval ? EXYNOS4_HUFF_TBL_HDCLL : EXYNOS4_HUFF_TBL_HDCLV;
 777}
 778
 779static inline int exynos4_huff_tbl_len(int class, int id)
 780{
 781        return __exynos4_huff_tbl(class, id, true);
 782}
 783
 784static inline int exynos4_huff_tbl_val(int class, int id)
 785{
 786        return __exynos4_huff_tbl(class, id, false);
 787}
 788
 789static int get_byte(struct s5p_jpeg_buffer *buf);
 790static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word);
 791static void skip(struct s5p_jpeg_buffer *buf, long len);
 792
 793static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx *ctx)
 794{
 795        struct s5p_jpeg *jpeg = ctx->jpeg;
 796        struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 797        struct s5p_jpeg_buffer jpeg_buffer;
 798        unsigned int word;
 799        int c, x, components;
 800
 801        jpeg_buffer.size = 2; /* Ls */
 802        jpeg_buffer.data =
 803                (unsigned long)vb2_plane_vaddr(vb, 0) + ctx->out_q.sos + 2;
 804        jpeg_buffer.curr = 0;
 805
 806        word = 0;
 807
 808        if (get_word_be(&jpeg_buffer, &word))
 809                return;
 810        jpeg_buffer.size = (long)word - 2;
 811        jpeg_buffer.data += 2;
 812        jpeg_buffer.curr = 0;
 813
 814        components = get_byte(&jpeg_buffer);
 815        if (components == -1)
 816                return;
 817        while (components--) {
 818                c = get_byte(&jpeg_buffer);
 819                if (c == -1)
 820                        return;
 821                x = get_byte(&jpeg_buffer);
 822                if (x == -1)
 823                        return;
 824                exynos4_jpeg_select_dec_h_tbl(jpeg->regs, c,
 825                                        (((x >> 4) & 0x1) << 1) | (x & 0x1));
 826        }
 827
 828}
 829
 830static void exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx *ctx)
 831{
 832        struct s5p_jpeg *jpeg = ctx->jpeg;
 833        struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 834        struct s5p_jpeg_buffer jpeg_buffer;
 835        unsigned int word;
 836        int c, i, n, j;
 837
 838        for (j = 0; j < ctx->out_q.dht.n; ++j) {
 839                jpeg_buffer.size = ctx->out_q.dht.len[j];
 840                jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(vb, 0) +
 841                                   ctx->out_q.dht.marker[j];
 842                jpeg_buffer.curr = 0;
 843
 844                word = 0;
 845                while (jpeg_buffer.curr < jpeg_buffer.size) {
 846                        char id, class;
 847
 848                        c = get_byte(&jpeg_buffer);
 849                        if (c == -1)
 850                                return;
 851                        id = c & 0xf;
 852                        class = (c >> 4) & 0xf;
 853                        n = 0;
 854                        for (i = 0; i < 16; ++i) {
 855                                c = get_byte(&jpeg_buffer);
 856                                if (c == -1)
 857                                        return;
 858                                word |= c << ((i % 4) * 8);
 859                                if ((i + 1) % 4 == 0) {
 860                                        writel(word, jpeg->regs +
 861                                        exynos4_huff_tbl_len(class, id) +
 862                                        (i / 4) * 4);
 863                                        word = 0;
 864                                }
 865                                n += c;
 866                        }
 867                        word = 0;
 868                        for (i = 0; i < n; ++i) {
 869                                c = get_byte(&jpeg_buffer);
 870                                if (c == -1)
 871                                        return;
 872                                word |= c << ((i % 4) * 8);
 873                                if ((i + 1) % 4 == 0) {
 874                                        writel(word, jpeg->regs +
 875                                        exynos4_huff_tbl_val(class, id) +
 876                                        (i / 4) * 4);
 877                                        word = 0;
 878                                }
 879                        }
 880                        if (i % 4) {
 881                                writel(word, jpeg->regs +
 882                                exynos4_huff_tbl_val(class, id) + (i / 4) * 4);
 883                        }
 884                        word = 0;
 885                }
 886        }
 887}
 888
 889static void exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx *ctx)
 890{
 891        struct s5p_jpeg *jpeg = ctx->jpeg;
 892        struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 893        struct s5p_jpeg_buffer jpeg_buffer;
 894        int c, x, components;
 895
 896        jpeg_buffer.size = ctx->out_q.sof_len;
 897        jpeg_buffer.data =
 898                (unsigned long)vb2_plane_vaddr(vb, 0) + ctx->out_q.sof;
 899        jpeg_buffer.curr = 0;
 900
 901        skip(&jpeg_buffer, 5); /* P, Y, X */
 902        components = get_byte(&jpeg_buffer);
 903        if (components == -1)
 904                return;
 905
 906        exynos4_jpeg_set_dec_components(jpeg->regs, components);
 907
 908        while (components--) {
 909                c = get_byte(&jpeg_buffer);
 910                if (c == -1)
 911                        return;
 912                skip(&jpeg_buffer, 1);
 913                x = get_byte(&jpeg_buffer);
 914                if (x == -1)
 915                        return;
 916                exynos4_jpeg_select_dec_q_tbl(jpeg->regs, c, x);
 917        }
 918}
 919
 920static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx *ctx)
 921{
 922        struct s5p_jpeg *jpeg = ctx->jpeg;
 923        struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 924        struct s5p_jpeg_buffer jpeg_buffer;
 925        unsigned int word;
 926        int c, i, j;
 927
 928        for (j = 0; j < ctx->out_q.dqt.n; ++j) {
 929                jpeg_buffer.size = ctx->out_q.dqt.len[j];
 930                jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(vb, 0) +
 931                                   ctx->out_q.dqt.marker[j];
 932                jpeg_buffer.curr = 0;
 933
 934                word = 0;
 935                while (jpeg_buffer.size - jpeg_buffer.curr >= 65) {
 936                        char id;
 937
 938                        c = get_byte(&jpeg_buffer);
 939                        if (c == -1)
 940                                return;
 941                        id = c & 0xf;
 942                        /* nonzero means extended mode - not supported */
 943                        if ((c >> 4) & 0xf)
 944                                return;
 945                        for (i = 0; i < 64; ++i) {
 946                                c = get_byte(&jpeg_buffer);
 947                                if (c == -1)
 948                                        return;
 949                                word |= c << ((i % 4) * 8);
 950                                if ((i + 1) % 4 == 0) {
 951                                        writel(word, jpeg->regs +
 952                                        EXYNOS4_QTBL_CONTENT(id) + (i / 4) * 4);
 953                                        word = 0;
 954                                }
 955                        }
 956                        word = 0;
 957                }
 958        }
 959}
 960
 961/*
 962 * ============================================================================
 963 * Device file operations
 964 * ============================================================================
 965 */
 966
 967static int queue_init(void *priv, struct vb2_queue *src_vq,
 968                      struct vb2_queue *dst_vq);
 969static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
 970                                __u32 pixelformat, unsigned int fmt_type);
 971static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
 972
 973static int s5p_jpeg_open(struct file *file)
 974{
 975        struct s5p_jpeg *jpeg = video_drvdata(file);
 976        struct video_device *vfd = video_devdata(file);
 977        struct s5p_jpeg_ctx *ctx;
 978        struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
 979        int ret = 0;
 980
 981        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 982        if (!ctx)
 983                return -ENOMEM;
 984
 985        if (mutex_lock_interruptible(&jpeg->lock)) {
 986                ret = -ERESTARTSYS;
 987                goto free;
 988        }
 989
 990        v4l2_fh_init(&ctx->fh, vfd);
 991        /* Use separate control handler per file handle */
 992        ctx->fh.ctrl_handler = &ctx->ctrl_handler;
 993        file->private_data = &ctx->fh;
 994        v4l2_fh_add(&ctx->fh);
 995
 996        ctx->jpeg = jpeg;
 997        if (vfd == jpeg->vfd_encoder) {
 998                ctx->mode = S5P_JPEG_ENCODE;
 999                out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
1000                                                        FMT_TYPE_OUTPUT);
1001                cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
1002                                                        FMT_TYPE_CAPTURE);
1003        } else {
1004                ctx->mode = S5P_JPEG_DECODE;
1005                out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
1006                                                        FMT_TYPE_OUTPUT);
1007                cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
1008                                                        FMT_TYPE_CAPTURE);
1009                ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
1010        }
1011
1012        ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
1013        if (IS_ERR(ctx->fh.m2m_ctx)) {
1014                ret = PTR_ERR(ctx->fh.m2m_ctx);
1015                goto error;
1016        }
1017
1018        ctx->out_q.fmt = out_fmt;
1019        ctx->cap_q.fmt = cap_fmt;
1020
1021        ret = s5p_jpeg_controls_create(ctx);
1022        if (ret < 0)
1023                goto error;
1024
1025        mutex_unlock(&jpeg->lock);
1026        return 0;
1027
1028error:
1029        v4l2_fh_del(&ctx->fh);
1030        v4l2_fh_exit(&ctx->fh);
1031        mutex_unlock(&jpeg->lock);
1032free:
1033        kfree(ctx);
1034        return ret;
1035}
1036
1037static int s5p_jpeg_release(struct file *file)
1038{
1039        struct s5p_jpeg *jpeg = video_drvdata(file);
1040        struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1041
1042        mutex_lock(&jpeg->lock);
1043        v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1044        v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1045        v4l2_fh_del(&ctx->fh);
1046        v4l2_fh_exit(&ctx->fh);
1047        kfree(ctx);
1048        mutex_unlock(&jpeg->lock);
1049
1050        return 0;
1051}
1052
1053static const struct v4l2_file_operations s5p_jpeg_fops = {
1054        .owner          = THIS_MODULE,
1055        .open           = s5p_jpeg_open,
1056        .release        = s5p_jpeg_release,
1057        .poll           = v4l2_m2m_fop_poll,
1058        .unlocked_ioctl = video_ioctl2,
1059        .mmap           = v4l2_m2m_fop_mmap,
1060};
1061
1062/*
1063 * ============================================================================
1064 * video ioctl operations
1065 * ============================================================================
1066 */
1067
1068static int get_byte(struct s5p_jpeg_buffer *buf)
1069{
1070        if (buf->curr >= buf->size)
1071                return -1;
1072
1073        return ((unsigned char *)buf->data)[buf->curr++];
1074}
1075
1076static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
1077{
1078        unsigned int temp;
1079        int byte;
1080
1081        byte = get_byte(buf);
1082        if (byte == -1)
1083                return -1;
1084        temp = byte << 8;
1085        byte = get_byte(buf);
1086        if (byte == -1)
1087                return -1;
1088        *word = (unsigned int)byte | temp;
1089        return 0;
1090}
1091
1092static void skip(struct s5p_jpeg_buffer *buf, long len)
1093{
1094        if (len <= 0)
1095                return;
1096
1097        while (len--)
1098                get_byte(buf);
1099}
1100
1101static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx,
1102                                        unsigned int subsampling)
1103{
1104        unsigned int version;
1105
1106        switch (subsampling) {
1107        case 0x11:
1108                ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
1109                break;
1110        case 0x21:
1111                ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
1112                break;
1113        case 0x22:
1114                ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
1115                break;
1116        case 0x33:
1117                ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
1118                break;
1119        case 0x41:
1120                /*
1121                 * 4:1:1 subsampling only supported by 3250, 5420, and 5433
1122                 * variants
1123                 */
1124                version = ctx->jpeg->variant->version;
1125                if (version != SJPEG_EXYNOS3250 &&
1126                    version != SJPEG_EXYNOS5420 &&
1127                    version != SJPEG_EXYNOS5433)
1128                        return false;
1129
1130                ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_411;
1131                break;
1132        default:
1133                return false;
1134        }
1135
1136        return true;
1137}
1138
1139static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
1140                               unsigned long buffer, unsigned long size,
1141                               struct s5p_jpeg_ctx *ctx)
1142{
1143        int c, components = 0, notfound, n_dht = 0, n_dqt = 0;
1144        unsigned int height = 0, width = 0, word, subsampling = 0;
1145        unsigned int sos = 0, sof = 0, sof_len = 0;
1146        unsigned int dht[S5P_JPEG_MAX_MARKER], dht_len[S5P_JPEG_MAX_MARKER];
1147        unsigned int dqt[S5P_JPEG_MAX_MARKER], dqt_len[S5P_JPEG_MAX_MARKER];
1148        long length;
1149        struct s5p_jpeg_buffer jpeg_buffer;
1150
1151        jpeg_buffer.size = size;
1152        jpeg_buffer.data = buffer;
1153        jpeg_buffer.curr = 0;
1154
1155        notfound = 1;
1156        while (notfound || !sos) {
1157                c = get_byte(&jpeg_buffer);
1158                if (c == -1)
1159                        return false;
1160                if (c != 0xff)
1161                        continue;
1162                do
1163                        c = get_byte(&jpeg_buffer);
1164                while (c == 0xff);
1165                if (c == -1)
1166                        return false;
1167                if (c == 0)
1168                        continue;
1169                length = 0;
1170                switch (c) {
1171                /* SOF0: baseline JPEG */
1172                case SOF0:
1173                        if (get_word_be(&jpeg_buffer, &word))
1174                                break;
1175                        length = (long)word - 2;
1176                        if (!length)
1177                                return false;
1178                        sof = jpeg_buffer.curr; /* after 0xffc0 */
1179                        sof_len = length;
1180                        if (get_byte(&jpeg_buffer) == -1)
1181                                break;
1182                        if (get_word_be(&jpeg_buffer, &height))
1183                                break;
1184                        if (get_word_be(&jpeg_buffer, &width))
1185                                break;
1186                        components = get_byte(&jpeg_buffer);
1187                        if (components == -1)
1188                                break;
1189
1190                        if (components == 1) {
1191                                subsampling = 0x33;
1192                        } else {
1193                                skip(&jpeg_buffer, 1);
1194                                subsampling = get_byte(&jpeg_buffer);
1195                                skip(&jpeg_buffer, 1);
1196                        }
1197                        if (components > 3)
1198                                return false;
1199                        skip(&jpeg_buffer, components * 2);
1200                        notfound = 0;
1201                        break;
1202
1203                case DQT:
1204                        if (get_word_be(&jpeg_buffer, &word))
1205                                break;
1206                        length = (long)word - 2;
1207                        if (!length)
1208                                return false;
1209                        if (n_dqt >= S5P_JPEG_MAX_MARKER)
1210                                return false;
1211                        dqt[n_dqt] = jpeg_buffer.curr; /* after 0xffdb */
1212                        dqt_len[n_dqt++] = length;
1213                        skip(&jpeg_buffer, length);
1214                        break;
1215
1216                case DHT:
1217                        if (get_word_be(&jpeg_buffer, &word))
1218                                break;
1219                        length = (long)word - 2;
1220                        if (!length)
1221                                return false;
1222                        if (n_dht >= S5P_JPEG_MAX_MARKER)
1223                                return false;
1224                        dht[n_dht] = jpeg_buffer.curr; /* after 0xffc4 */
1225                        dht_len[n_dht++] = length;
1226                        skip(&jpeg_buffer, length);
1227                        break;
1228
1229                case SOS:
1230                        sos = jpeg_buffer.curr - 2; /* 0xffda */
1231                        break;
1232
1233                /* skip payload-less markers */
1234                case RST ... RST + 7:
1235                case SOI:
1236                case EOI:
1237                case TEM:
1238                        break;
1239
1240                /* skip uninteresting payload markers */
1241                default:
1242                        if (get_word_be(&jpeg_buffer, &word))
1243                                break;
1244                        length = (long)word - 2;
1245                        skip(&jpeg_buffer, length);
1246                        break;
1247                }
1248        }
1249
1250        if (notfound || !sos || !s5p_jpeg_subsampling_decode(ctx, subsampling))
1251                return false;
1252
1253        result->w = width;
1254        result->h = height;
1255        result->sos = sos;
1256        result->dht.n = n_dht;
1257        while (n_dht--) {
1258                result->dht.marker[n_dht] = dht[n_dht];
1259                result->dht.len[n_dht] = dht_len[n_dht];
1260        }
1261        result->dqt.n = n_dqt;
1262        while (n_dqt--) {
1263                result->dqt.marker[n_dqt] = dqt[n_dqt];
1264                result->dqt.len[n_dqt] = dqt_len[n_dqt];
1265        }
1266        result->sof = sof;
1267        result->sof_len = sof_len;
1268        result->components = components;
1269
1270        return true;
1271}
1272
1273static int s5p_jpeg_querycap(struct file *file, void *priv,
1274                           struct v4l2_capability *cap)
1275{
1276        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1277
1278        if (ctx->mode == S5P_JPEG_ENCODE) {
1279                strlcpy(cap->driver, S5P_JPEG_M2M_NAME,
1280                        sizeof(cap->driver));
1281                strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
1282                        sizeof(cap->card));
1283        } else {
1284                strlcpy(cap->driver, S5P_JPEG_M2M_NAME,
1285                        sizeof(cap->driver));
1286                strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
1287                        sizeof(cap->card));
1288        }
1289        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
1290                 dev_name(ctx->jpeg->dev));
1291        cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
1292        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1293        return 0;
1294}
1295
1296static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
1297                    struct v4l2_fmtdesc *f, u32 type)
1298{
1299        int i, num = 0;
1300
1301        for (i = 0; i < n; ++i) {
1302                if (sjpeg_formats[i].flags & type) {
1303                        /* index-th format of type type found ? */
1304                        if (num == f->index)
1305                                break;
1306                        /* Correct type but haven't reached our index yet,
1307                         * just increment per-type index
1308                         */
1309                        ++num;
1310                }
1311        }
1312
1313        /* Format not found */
1314        if (i >= n)
1315                return -EINVAL;
1316
1317        strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
1318        f->pixelformat = sjpeg_formats[i].fourcc;
1319
1320        return 0;
1321}
1322
1323static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
1324                                   struct v4l2_fmtdesc *f)
1325{
1326        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1327
1328        if (ctx->mode == S5P_JPEG_ENCODE)
1329                return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1330                                SJPEG_FMT_FLAG_ENC_CAPTURE);
1331
1332        return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1333                                        SJPEG_FMT_FLAG_DEC_CAPTURE);
1334}
1335
1336static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
1337                                   struct v4l2_fmtdesc *f)
1338{
1339        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1340
1341        if (ctx->mode == S5P_JPEG_ENCODE)
1342                return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1343                                SJPEG_FMT_FLAG_ENC_OUTPUT);
1344
1345        return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1346                                        SJPEG_FMT_FLAG_DEC_OUTPUT);
1347}
1348
1349static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
1350                                          enum v4l2_buf_type type)
1351{
1352        if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1353                return &ctx->out_q;
1354        if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1355                return &ctx->cap_q;
1356
1357        return NULL;
1358}
1359
1360static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
1361{
1362        struct vb2_queue *vq;
1363        struct s5p_jpeg_q_data *q_data = NULL;
1364        struct v4l2_pix_format *pix = &f->fmt.pix;
1365        struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
1366
1367        vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1368        if (!vq)
1369                return -EINVAL;
1370
1371        if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1372            ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
1373                return -EINVAL;
1374        q_data = get_q_data(ct, f->type);
1375        BUG_ON(q_data == NULL);
1376
1377        pix->width = q_data->w;
1378        pix->height = q_data->h;
1379        pix->field = V4L2_FIELD_NONE;
1380        pix->pixelformat = q_data->fmt->fourcc;
1381        pix->bytesperline = 0;
1382        if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1383                u32 bpl = q_data->w;
1384
1385                if (q_data->fmt->colplanes == 1)
1386                        bpl = (bpl * q_data->fmt->depth) >> 3;
1387                pix->bytesperline = bpl;
1388        }
1389        pix->sizeimage = q_data->size;
1390
1391        return 0;
1392}
1393
1394static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
1395                                u32 pixelformat, unsigned int fmt_type)
1396{
1397        unsigned int k, fmt_flag;
1398
1399        if (ctx->mode == S5P_JPEG_ENCODE)
1400                fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1401                                SJPEG_FMT_FLAG_ENC_OUTPUT :
1402                                SJPEG_FMT_FLAG_ENC_CAPTURE;
1403        else
1404                fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1405                                SJPEG_FMT_FLAG_DEC_OUTPUT :
1406                                SJPEG_FMT_FLAG_DEC_CAPTURE;
1407
1408        for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
1409                struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
1410
1411                if (fmt->fourcc == pixelformat &&
1412                    fmt->flags & fmt_flag &&
1413                    fmt->flags & ctx->jpeg->variant->fmt_ver_flag) {
1414                        return fmt;
1415                }
1416        }
1417
1418        return NULL;
1419}
1420
1421static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx,
1422                                   u32 *w, unsigned int wmin, unsigned int wmax,
1423                                   unsigned int walign,
1424                                   u32 *h, unsigned int hmin, unsigned int hmax,
1425                                   unsigned int halign)
1426{
1427        int width, height, w_step, h_step;
1428
1429        width = *w;
1430        height = *h;
1431
1432        w_step = 1 << walign;
1433        h_step = 1 << halign;
1434
1435        if (ctx->jpeg->variant->hw3250_compat) {
1436                /*
1437                 * Rightmost and bottommost pixels are cropped by the
1438                 * Exynos3250/compatible JPEG IP for RGB formats, for the
1439                 * specific width and height values respectively. This
1440                 * assignment will result in v4l_bound_align_image returning
1441                 * dimensions reduced by 1 for the aforementioned cases.
1442                 */
1443                if (w_step == 4 && ((width & 3) == 1)) {
1444                        wmax = width;
1445                        hmax = height;
1446                }
1447        }
1448
1449        v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
1450
1451        if (*w < width && (*w + w_step) < wmax)
1452                *w += w_step;
1453        if (*h < height && (*h + h_step) < hmax)
1454                *h += h_step;
1455}
1456
1457static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
1458                          struct s5p_jpeg_ctx *ctx, int q_type)
1459{
1460        struct v4l2_pix_format *pix = &f->fmt.pix;
1461
1462        if (pix->field == V4L2_FIELD_ANY)
1463                pix->field = V4L2_FIELD_NONE;
1464        else if (pix->field != V4L2_FIELD_NONE)
1465                return -EINVAL;
1466
1467        /* V4L2 specification suggests the driver corrects the format struct
1468         * if any of the dimensions is unsupported
1469         */
1470        if (q_type == FMT_TYPE_OUTPUT)
1471                jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1472                                       S5P_JPEG_MAX_WIDTH, 0,
1473                                       &pix->height, S5P_JPEG_MIN_HEIGHT,
1474                                       S5P_JPEG_MAX_HEIGHT, 0);
1475        else
1476                jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1477                                       S5P_JPEG_MAX_WIDTH, fmt->h_align,
1478                                       &pix->height, S5P_JPEG_MIN_HEIGHT,
1479                                       S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1480
1481        if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1482                if (pix->sizeimage <= 0)
1483                        pix->sizeimage = PAGE_SIZE;
1484                pix->bytesperline = 0;
1485        } else {
1486                u32 bpl = pix->bytesperline;
1487
1488                if (fmt->colplanes > 1 && bpl < pix->width)
1489                        bpl = pix->width; /* planar */
1490
1491                if (fmt->colplanes == 1 && /* packed */
1492                    (bpl << 3) / fmt->depth < pix->width)
1493                        bpl = (pix->width * fmt->depth) >> 3;
1494
1495                pix->bytesperline = bpl;
1496                pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1497        }
1498
1499        return 0;
1500}
1501
1502static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1503                                  struct v4l2_format *f)
1504{
1505        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1506        struct v4l2_pix_format *pix = &f->fmt.pix;
1507        struct s5p_jpeg_fmt *fmt;
1508        int ret;
1509
1510        fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1511                                                FMT_TYPE_CAPTURE);
1512        if (!fmt) {
1513                v4l2_err(&ctx->jpeg->v4l2_dev,
1514                         "Fourcc format (0x%08x) invalid.\n",
1515                         f->fmt.pix.pixelformat);
1516                return -EINVAL;
1517        }
1518
1519        if (!ctx->jpeg->variant->hw_ex4_compat || ctx->mode != S5P_JPEG_DECODE)
1520                goto exit;
1521
1522        /*
1523         * The exynos4x12 device requires resulting YUV image
1524         * subsampling not to be lower than the input jpeg subsampling.
1525         * If this requirement is not met then downgrade the requested
1526         * capture format to the one with subsampling equal to the input jpeg.
1527         */
1528        if ((fmt->flags & SJPEG_FMT_NON_RGB) &&
1529            (fmt->subsampling < ctx->subsampling)) {
1530                ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1531                                                            fmt->fourcc,
1532                                                            &pix->pixelformat,
1533                                                            ctx);
1534                if (ret < 0)
1535                        pix->pixelformat = V4L2_PIX_FMT_GREY;
1536
1537                fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1538                                                        FMT_TYPE_CAPTURE);
1539        }
1540
1541        /*
1542         * Decompression of a JPEG file with 4:2:0 subsampling and odd
1543         * width to the YUV 4:2:0 compliant formats produces a raw image
1544         * with broken luma component. Adjust capture format to RGB565
1545         * in such a case.
1546         */
1547        if (ctx->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420 &&
1548            (ctx->out_q.w & 1) &&
1549            (pix->pixelformat == V4L2_PIX_FMT_NV12 ||
1550             pix->pixelformat == V4L2_PIX_FMT_NV21 ||
1551             pix->pixelformat == V4L2_PIX_FMT_YUV420)) {
1552                pix->pixelformat = V4L2_PIX_FMT_RGB565;
1553                fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1554                                                        FMT_TYPE_CAPTURE);
1555        }
1556
1557exit:
1558        return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
1559}
1560
1561static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1562                                  struct v4l2_format *f)
1563{
1564        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1565        struct s5p_jpeg_fmt *fmt;
1566
1567        fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1568                                                FMT_TYPE_OUTPUT);
1569        if (!fmt) {
1570                v4l2_err(&ctx->jpeg->v4l2_dev,
1571                         "Fourcc format (0x%08x) invalid.\n",
1572                         f->fmt.pix.pixelformat);
1573                return -EINVAL;
1574        }
1575
1576        return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
1577}
1578
1579static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx,
1580                                                struct v4l2_format *f,
1581                                                int fmt_depth)
1582{
1583        struct v4l2_pix_format *pix = &f->fmt.pix;
1584        u32 pix_fmt = f->fmt.pix.pixelformat;
1585        int w = pix->width, h = pix->height, wh_align;
1586        int padding = 0;
1587
1588        if (pix_fmt == V4L2_PIX_FMT_RGB32 ||
1589            pix_fmt == V4L2_PIX_FMT_RGB565 ||
1590            pix_fmt == V4L2_PIX_FMT_NV24 ||
1591            pix_fmt == V4L2_PIX_FMT_NV42 ||
1592            pix_fmt == V4L2_PIX_FMT_NV12 ||
1593            pix_fmt == V4L2_PIX_FMT_NV21 ||
1594            pix_fmt == V4L2_PIX_FMT_YUV420)
1595                wh_align = 4;
1596        else
1597                wh_align = 1;
1598
1599        jpeg_bound_align_image(ctx, &w, S5P_JPEG_MIN_WIDTH,
1600                               S5P_JPEG_MAX_WIDTH, wh_align,
1601                               &h, S5P_JPEG_MIN_HEIGHT,
1602                               S5P_JPEG_MAX_HEIGHT, wh_align);
1603
1604        if (ctx->jpeg->variant->version == SJPEG_EXYNOS4)
1605                padding = PAGE_SIZE;
1606
1607        return (w * h * fmt_depth >> 3) + padding;
1608}
1609
1610static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1611                                   struct v4l2_rect *r);
1612
1613static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1614{
1615        struct vb2_queue *vq;
1616        struct s5p_jpeg_q_data *q_data = NULL;
1617        struct v4l2_pix_format *pix = &f->fmt.pix;
1618        struct v4l2_ctrl *ctrl_subs;
1619        struct v4l2_rect scale_rect;
1620        unsigned int f_type;
1621
1622        vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1623        if (!vq)
1624                return -EINVAL;
1625
1626        q_data = get_q_data(ct, f->type);
1627        BUG_ON(q_data == NULL);
1628
1629        if (vb2_is_busy(vq)) {
1630                v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1631                return -EBUSY;
1632        }
1633
1634        f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1635                        FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1636
1637        q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
1638        if (ct->mode == S5P_JPEG_ENCODE ||
1639                (ct->mode == S5P_JPEG_DECODE &&
1640                q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)) {
1641                q_data->w = pix->width;
1642                q_data->h = pix->height;
1643        }
1644        if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1645                /*
1646                 * During encoding Exynos4x12 SoCs access wider memory area
1647                 * than it results from Image_x and Image_y values written to
1648                 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
1649                 * page fault calculate proper buffer size in such a case.
1650                 */
1651                if (ct->jpeg->variant->hw_ex4_compat &&
1652                    f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
1653                        q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
1654                                                        f,
1655                                                        q_data->fmt->depth);
1656                else
1657                        q_data->size = q_data->w * q_data->h *
1658                                                q_data->fmt->depth >> 3;
1659        } else {
1660                q_data->size = pix->sizeimage;
1661        }
1662
1663        if (f_type == FMT_TYPE_OUTPUT) {
1664                ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1665                                        V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1666                if (ctrl_subs)
1667                        v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
1668                ct->crop_altered = false;
1669        }
1670
1671        /*
1672         * For decoding init crop_rect with capture buffer dimmensions which
1673         * contain aligned dimensions of the input JPEG image and do it only
1674         * if crop rectangle hasn't been altered by the user space e.g. with
1675         * S_SELECTION ioctl. For encoding assign output buffer dimensions.
1676         */
1677        if (!ct->crop_altered &&
1678            ((ct->mode == S5P_JPEG_DECODE && f_type == FMT_TYPE_CAPTURE) ||
1679             (ct->mode == S5P_JPEG_ENCODE && f_type == FMT_TYPE_OUTPUT))) {
1680                ct->crop_rect.width = pix->width;
1681                ct->crop_rect.height = pix->height;
1682        }
1683
1684        /*
1685         * Prevent downscaling to YUV420 format by more than 2
1686         * for Exynos3250/compatible SoC as it produces broken raw image
1687         * in such cases.
1688         */
1689        if (ct->mode == S5P_JPEG_DECODE &&
1690            f_type == FMT_TYPE_CAPTURE &&
1691            ct->jpeg->variant->hw3250_compat &&
1692            pix->pixelformat == V4L2_PIX_FMT_YUV420 &&
1693            ct->scale_factor > 2) {
1694                scale_rect.width = ct->out_q.w / 2;
1695                scale_rect.height = ct->out_q.h / 2;
1696                exynos3250_jpeg_try_downscale(ct, &scale_rect);
1697        }
1698
1699        return 0;
1700}
1701
1702static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1703                                struct v4l2_format *f)
1704{
1705        int ret;
1706
1707        ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1708        if (ret)
1709                return ret;
1710
1711        return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1712}
1713
1714static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1715                                struct v4l2_format *f)
1716{
1717        int ret;
1718
1719        ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1720        if (ret)
1721                return ret;
1722
1723        return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1724}
1725
1726static int s5p_jpeg_subscribe_event(struct v4l2_fh *fh,
1727                                    const struct v4l2_event_subscription *sub)
1728{
1729        if (sub->type == V4L2_EVENT_SOURCE_CHANGE)
1730                return v4l2_src_change_event_subscribe(fh, sub);
1731
1732        return -EINVAL;
1733}
1734
1735static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1736                                   struct v4l2_rect *r)
1737{
1738        int w_ratio, h_ratio, scale_factor, cur_ratio, i;
1739
1740        w_ratio = ctx->out_q.w / r->width;
1741        h_ratio = ctx->out_q.h / r->height;
1742
1743        scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio;
1744        scale_factor = clamp_val(scale_factor, 1, 8);
1745
1746        /* Align scale ratio to the nearest power of 2 */
1747        for (i = 0; i <= 3; ++i) {
1748                cur_ratio = 1 << i;
1749                if (scale_factor <= cur_ratio) {
1750                        ctx->scale_factor = cur_ratio;
1751                        break;
1752                }
1753        }
1754
1755        r->width = round_down(ctx->out_q.w / ctx->scale_factor, 2);
1756        r->height = round_down(ctx->out_q.h / ctx->scale_factor, 2);
1757
1758        ctx->crop_rect.width = r->width;
1759        ctx->crop_rect.height = r->height;
1760        ctx->crop_rect.left = 0;
1761        ctx->crop_rect.top = 0;
1762
1763        ctx->crop_altered = true;
1764
1765        return 0;
1766}
1767
1768/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1769static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1770{
1771        if (a->left < b->left || a->top < b->top)
1772                return 0;
1773        if (a->left + a->width > b->left + b->width)
1774                return 0;
1775        if (a->top + a->height > b->top + b->height)
1776                return 0;
1777
1778        return 1;
1779}
1780
1781static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,
1782                                   struct v4l2_rect *r)
1783{
1784        struct v4l2_rect base_rect;
1785        int w_step, h_step;
1786
1787        switch (ctx->cap_q.fmt->fourcc) {
1788        case V4L2_PIX_FMT_NV12:
1789        case V4L2_PIX_FMT_NV21:
1790                w_step = 1;
1791                h_step = 2;
1792                break;
1793        case V4L2_PIX_FMT_YUV420:
1794                w_step = 2;
1795                h_step = 2;
1796                break;
1797        default:
1798                w_step = 1;
1799                h_step = 1;
1800                break;
1801        }
1802
1803        base_rect.top = 0;
1804        base_rect.left = 0;
1805        base_rect.width = ctx->out_q.w;
1806        base_rect.height = ctx->out_q.h;
1807
1808        r->width = round_down(r->width, w_step);
1809        r->height = round_down(r->height, h_step);
1810        r->left = round_down(r->left, 2);
1811        r->top = round_down(r->top, 2);
1812
1813        if (!enclosed_rectangle(r, &base_rect))
1814                return -EINVAL;
1815
1816        ctx->crop_rect.left = r->left;
1817        ctx->crop_rect.top = r->top;
1818        ctx->crop_rect.width = r->width;
1819        ctx->crop_rect.height = r->height;
1820
1821        ctx->crop_altered = true;
1822
1823        return 0;
1824}
1825
1826/*
1827 * V4L2 controls
1828 */
1829
1830static int s5p_jpeg_g_selection(struct file *file, void *priv,
1831                         struct v4l2_selection *s)
1832{
1833        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1834
1835        if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
1836            s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1837                return -EINVAL;
1838
1839        /* For JPEG blob active == default == bounds */
1840        switch (s->target) {
1841        case V4L2_SEL_TGT_CROP:
1842        case V4L2_SEL_TGT_CROP_BOUNDS:
1843        case V4L2_SEL_TGT_CROP_DEFAULT:
1844        case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1845                s->r.width = ctx->out_q.w;
1846                s->r.height = ctx->out_q.h;
1847                s->r.left = 0;
1848                s->r.top = 0;
1849                break;
1850        case V4L2_SEL_TGT_COMPOSE:
1851        case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1852        case V4L2_SEL_TGT_COMPOSE_PADDED:
1853                s->r.width = ctx->crop_rect.width;
1854                s->r.height =  ctx->crop_rect.height;
1855                s->r.left = ctx->crop_rect.left;
1856                s->r.top = ctx->crop_rect.top;
1857                break;
1858        default:
1859                return -EINVAL;
1860        }
1861        return 0;
1862}
1863
1864/*
1865 * V4L2 controls
1866 */
1867static int s5p_jpeg_s_selection(struct file *file, void *fh,
1868                                  struct v4l2_selection *s)
1869{
1870        struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1871        struct v4l2_rect *rect = &s->r;
1872        int ret = -EINVAL;
1873
1874        if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1875                return -EINVAL;
1876
1877        if (s->target == V4L2_SEL_TGT_COMPOSE) {
1878                if (ctx->mode != S5P_JPEG_DECODE)
1879                        return -EINVAL;
1880                if (ctx->jpeg->variant->hw3250_compat)
1881                        ret = exynos3250_jpeg_try_downscale(ctx, rect);
1882        } else if (s->target == V4L2_SEL_TGT_CROP) {
1883                if (ctx->mode != S5P_JPEG_ENCODE)
1884                        return -EINVAL;
1885                if (ctx->jpeg->variant->hw3250_compat)
1886                        ret = exynos3250_jpeg_try_crop(ctx, rect);
1887        }
1888
1889        return ret;
1890}
1891
1892static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1893{
1894        struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1895        struct s5p_jpeg *jpeg = ctx->jpeg;
1896        unsigned long flags;
1897
1898        switch (ctrl->id) {
1899        case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1900                spin_lock_irqsave(&jpeg->slock, flags);
1901                ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
1902                spin_unlock_irqrestore(&jpeg->slock, flags);
1903                break;
1904        }
1905
1906        return 0;
1907}
1908
1909static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
1910{
1911        switch (ctx->jpeg->variant->version) {
1912        case SJPEG_S5P:
1913                return 0;
1914        case SJPEG_EXYNOS3250:
1915        case SJPEG_EXYNOS5420:
1916                /*
1917                 * The exynos3250/compatible device can produce JPEG image only
1918                 * of 4:4:4 subsampling when given RGB32 source image.
1919                 */
1920                if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
1921                        *ctrl_val = 0;
1922                break;
1923        case SJPEG_EXYNOS4:
1924                /*
1925                 * The exynos4x12 device requires input raw image fourcc
1926                 * to be V4L2_PIX_FMT_GREY if gray jpeg format
1927                 * is to be set.
1928                 */
1929                if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
1930                    *ctrl_val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY)
1931                        return -EINVAL;
1932                break;
1933        }
1934
1935        /*
1936         * The exynos4x12 and exynos3250/compatible devices require resulting
1937         * jpeg subsampling not to be lower than the input raw image
1938         * subsampling.
1939         */
1940        if (ctx->out_q.fmt->subsampling > *ctrl_val)
1941                *ctrl_val = ctx->out_q.fmt->subsampling;
1942
1943        return 0;
1944}
1945
1946static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1947{
1948        struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1949        unsigned long flags;
1950        int ret = 0;
1951
1952        spin_lock_irqsave(&ctx->jpeg->slock, flags);
1953
1954        if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING)
1955                ret = s5p_jpeg_adjust_subs_ctrl(ctx, &ctrl->val);
1956
1957        spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1958        return ret;
1959}
1960
1961static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
1962{
1963        struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1964        unsigned long flags;
1965
1966        spin_lock_irqsave(&ctx->jpeg->slock, flags);
1967
1968        switch (ctrl->id) {
1969        case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1970                ctx->compr_quality = ctrl->val;
1971                break;
1972        case V4L2_CID_JPEG_RESTART_INTERVAL:
1973                ctx->restart_interval = ctrl->val;
1974                break;
1975        case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1976                ctx->subsampling = ctrl->val;
1977                break;
1978        }
1979
1980        spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1981        return 0;
1982}
1983
1984static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1985        .g_volatile_ctrl        = s5p_jpeg_g_volatile_ctrl,
1986        .try_ctrl               = s5p_jpeg_try_ctrl,
1987        .s_ctrl                 = s5p_jpeg_s_ctrl,
1988};
1989
1990static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1991{
1992        unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1993        struct v4l2_ctrl *ctrl;
1994        int ret;
1995
1996        v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
1997
1998        if (ctx->mode == S5P_JPEG_ENCODE) {
1999                v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
2000                                  V4L2_CID_JPEG_COMPRESSION_QUALITY,
2001                                  0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
2002
2003                v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
2004                                  V4L2_CID_JPEG_RESTART_INTERVAL,
2005                                  0, 3, 0xffff, 0);
2006                if (ctx->jpeg->variant->version == SJPEG_S5P)
2007                        mask = ~0x06; /* 422, 420 */
2008        }
2009
2010        ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
2011                                      V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
2012                                      V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
2013                                      V4L2_JPEG_CHROMA_SUBSAMPLING_422);
2014
2015        if (ctx->ctrl_handler.error) {
2016                ret = ctx->ctrl_handler.error;
2017                goto error_free;
2018        }
2019
2020        if (ctx->mode == S5P_JPEG_DECODE)
2021                ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
2022                        V4L2_CTRL_FLAG_READ_ONLY;
2023
2024        ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
2025        if (ret < 0)
2026                goto error_free;
2027
2028        return ret;
2029
2030error_free:
2031        v4l2_ctrl_handler_free(&ctx->ctrl_handler);
2032        return ret;
2033}
2034
2035static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
2036        .vidioc_querycap                = s5p_jpeg_querycap,
2037
2038        .vidioc_enum_fmt_vid_cap        = s5p_jpeg_enum_fmt_vid_cap,
2039        .vidioc_enum_fmt_vid_out        = s5p_jpeg_enum_fmt_vid_out,
2040
2041        .vidioc_g_fmt_vid_cap           = s5p_jpeg_g_fmt,
2042        .vidioc_g_fmt_vid_out           = s5p_jpeg_g_fmt,
2043
2044        .vidioc_try_fmt_vid_cap         = s5p_jpeg_try_fmt_vid_cap,
2045        .vidioc_try_fmt_vid_out         = s5p_jpeg_try_fmt_vid_out,
2046
2047        .vidioc_s_fmt_vid_cap           = s5p_jpeg_s_fmt_vid_cap,
2048        .vidioc_s_fmt_vid_out           = s5p_jpeg_s_fmt_vid_out,
2049
2050        .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
2051        .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
2052        .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
2053        .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
2054
2055        .vidioc_streamon                = v4l2_m2m_ioctl_streamon,
2056        .vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
2057
2058        .vidioc_g_selection             = s5p_jpeg_g_selection,
2059        .vidioc_s_selection             = s5p_jpeg_s_selection,
2060
2061        .vidioc_subscribe_event         = s5p_jpeg_subscribe_event,
2062        .vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
2063};
2064
2065/*
2066 * ============================================================================
2067 * mem2mem callbacks
2068 * ============================================================================
2069 */
2070
2071static void s5p_jpeg_device_run(void *priv)
2072{
2073        struct s5p_jpeg_ctx *ctx = priv;
2074        struct s5p_jpeg *jpeg = ctx->jpeg;
2075        struct vb2_buffer *src_buf, *dst_buf;
2076        unsigned long src_addr, dst_addr, flags;
2077
2078        spin_lock_irqsave(&ctx->jpeg->slock, flags);
2079
2080        src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2081        dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2082        src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
2083        dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
2084
2085        s5p_jpeg_reset(jpeg->regs);
2086        s5p_jpeg_poweron(jpeg->regs);
2087        s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
2088        if (ctx->mode == S5P_JPEG_ENCODE) {
2089                if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
2090                        s5p_jpeg_input_raw_mode(jpeg->regs,
2091                                                        S5P_JPEG_RAW_IN_565);
2092                else
2093                        s5p_jpeg_input_raw_mode(jpeg->regs,
2094                                                        S5P_JPEG_RAW_IN_422);
2095                s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
2096                s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
2097                s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
2098                s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
2099                s5p_jpeg_imgadr(jpeg->regs, src_addr);
2100                s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
2101
2102                /* ultimately comes from sizeimage from userspace */
2103                s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
2104
2105                /* JPEG RGB to YCbCr conversion matrix */
2106                s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
2107                s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
2108                s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
2109                s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
2110                s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
2111                s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
2112                s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
2113                s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
2114                s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
2115
2116                /*
2117                 * JPEG IP allows storing 4 quantization tables
2118                 * We fill table 0 for luma and table 1 for chroma
2119                 */
2120                s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2121                s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2122                /* use table 0 for Y */
2123                s5p_jpeg_qtbl(jpeg->regs, 1, 0);
2124                /* use table 1 for Cb and Cr*/
2125                s5p_jpeg_qtbl(jpeg->regs, 2, 1);
2126                s5p_jpeg_qtbl(jpeg->regs, 3, 1);
2127
2128                /* Y, Cb, Cr use Huffman table 0 */
2129                s5p_jpeg_htbl_ac(jpeg->regs, 1);
2130                s5p_jpeg_htbl_dc(jpeg->regs, 1);
2131                s5p_jpeg_htbl_ac(jpeg->regs, 2);
2132                s5p_jpeg_htbl_dc(jpeg->regs, 2);
2133                s5p_jpeg_htbl_ac(jpeg->regs, 3);
2134                s5p_jpeg_htbl_dc(jpeg->regs, 3);
2135        } else { /* S5P_JPEG_DECODE */
2136                s5p_jpeg_rst_int_enable(jpeg->regs, true);
2137                s5p_jpeg_data_num_int_enable(jpeg->regs, true);
2138                s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
2139                if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
2140                        s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
2141                else
2142                        s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
2143                s5p_jpeg_jpgadr(jpeg->regs, src_addr);
2144                s5p_jpeg_imgadr(jpeg->regs, dst_addr);
2145        }
2146
2147        s5p_jpeg_start(jpeg->regs);
2148
2149        spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2150}
2151
2152static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
2153{
2154        struct s5p_jpeg *jpeg = ctx->jpeg;
2155        struct s5p_jpeg_fmt *fmt;
2156        struct vb2_buffer *vb;
2157        struct s5p_jpeg_addr jpeg_addr = {};
2158        u32 pix_size, padding_bytes = 0;
2159
2160        jpeg_addr.cb = 0;
2161        jpeg_addr.cr = 0;
2162
2163        pix_size = ctx->cap_q.w * ctx->cap_q.h;
2164
2165        if (ctx->mode == S5P_JPEG_ENCODE) {
2166                vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2167                fmt = ctx->out_q.fmt;
2168                if (ctx->out_q.w % 2 && fmt->h_align > 0)
2169                        padding_bytes = ctx->out_q.h;
2170        } else {
2171                fmt = ctx->cap_q.fmt;
2172                vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2173        }
2174
2175        jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
2176
2177        if (fmt->colplanes == 2) {
2178                jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
2179        } else if (fmt->colplanes == 3) {
2180                jpeg_addr.cb = jpeg_addr.y + pix_size;
2181                if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
2182                        jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
2183                else
2184                        jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
2185        }
2186
2187        exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
2188}
2189
2190static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
2191{
2192        struct s5p_jpeg *jpeg = ctx->jpeg;
2193        struct vb2_buffer *vb;
2194        unsigned int jpeg_addr = 0;
2195
2196        if (ctx->mode == S5P_JPEG_ENCODE)
2197                vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2198        else
2199                vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2200
2201        jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
2202        if (jpeg->variant->version == SJPEG_EXYNOS5433 &&
2203            ctx->mode == S5P_JPEG_DECODE)
2204                jpeg_addr += ctx->out_q.sos;
2205        exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
2206}
2207
2208static inline void exynos4_jpeg_set_img_fmt(void __iomem *base,
2209                                            unsigned int img_fmt)
2210{
2211        __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS4);
2212}
2213
2214static inline void exynos5433_jpeg_set_img_fmt(void __iomem *base,
2215                                               unsigned int img_fmt)
2216{
2217        __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS5433);
2218}
2219
2220static inline void exynos4_jpeg_set_enc_out_fmt(void __iomem *base,
2221                                                unsigned int out_fmt)
2222{
2223        __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS4);
2224}
2225
2226static inline void exynos5433_jpeg_set_enc_out_fmt(void __iomem *base,
2227                                                   unsigned int out_fmt)
2228{
2229        __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS5433);
2230}
2231
2232static void exynos4_jpeg_device_run(void *priv)
2233{
2234        struct s5p_jpeg_ctx *ctx = priv;
2235        struct s5p_jpeg *jpeg = ctx->jpeg;
2236        unsigned int bitstream_size;
2237        unsigned long flags;
2238
2239        spin_lock_irqsave(&jpeg->slock, flags);
2240
2241        if (ctx->mode == S5P_JPEG_ENCODE) {
2242                exynos4_jpeg_sw_reset(jpeg->regs);
2243                exynos4_jpeg_set_interrupt(jpeg->regs, jpeg->variant->version);
2244                exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
2245
2246                exynos4_jpeg_set_huff_tbl(jpeg->regs);
2247
2248                /*
2249                 * JPEG IP allows storing 4 quantization tables
2250                 * We fill table 0 for luma and table 1 for chroma
2251                 */
2252                exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2253                exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2254
2255                exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
2256                                                        ctx->compr_quality);
2257                exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
2258                                                        ctx->cap_q.h);
2259
2260                if (ctx->jpeg->variant->version == SJPEG_EXYNOS4) {
2261                        exynos4_jpeg_set_enc_out_fmt(jpeg->regs,
2262                                                     ctx->subsampling);
2263                        exynos4_jpeg_set_img_fmt(jpeg->regs,
2264                                                 ctx->out_q.fmt->fourcc);
2265                } else {
2266                        exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
2267                                                        ctx->subsampling);
2268                        exynos5433_jpeg_set_img_fmt(jpeg->regs,
2269                                                    ctx->out_q.fmt->fourcc);
2270                }
2271                exynos4_jpeg_set_img_addr(ctx);
2272                exynos4_jpeg_set_jpeg_addr(ctx);
2273                exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
2274                                                        ctx->out_q.fmt->fourcc);
2275        } else {
2276                exynos4_jpeg_sw_reset(jpeg->regs);
2277                exynos4_jpeg_set_interrupt(jpeg->regs,
2278                                           jpeg->variant->version);
2279                exynos4_jpeg_set_img_addr(ctx);
2280                exynos4_jpeg_set_jpeg_addr(ctx);
2281
2282                if (jpeg->variant->version == SJPEG_EXYNOS5433) {
2283                        exynos4_jpeg_parse_huff_tbl(ctx);
2284                        exynos4_jpeg_parse_decode_h_tbl(ctx);
2285
2286                        exynos4_jpeg_parse_q_tbl(ctx);
2287                        exynos4_jpeg_parse_decode_q_tbl(ctx);
2288
2289                        exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
2290
2291                        exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
2292                                        ctx->cap_q.h);
2293                        exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
2294                                                        ctx->subsampling);
2295                        exynos5433_jpeg_set_img_fmt(jpeg->regs,
2296                                                    ctx->cap_q.fmt->fourcc);
2297                        bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 16);
2298                } else {
2299                        exynos4_jpeg_set_img_fmt(jpeg->regs,
2300                                                 ctx->cap_q.fmt->fourcc);
2301                        bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
2302                }
2303
2304                exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
2305        }
2306
2307        exynos4_jpeg_set_sys_int_enable(jpeg->regs, 1);
2308        exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
2309
2310        spin_unlock_irqrestore(&jpeg->slock, flags);
2311}
2312
2313static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
2314{
2315        struct s5p_jpeg *jpeg = ctx->jpeg;
2316        struct s5p_jpeg_fmt *fmt;
2317        struct vb2_buffer *vb;
2318        struct s5p_jpeg_addr jpeg_addr = {};
2319        u32 pix_size;
2320
2321        pix_size = ctx->cap_q.w * ctx->cap_q.h;
2322
2323        if (ctx->mode == S5P_JPEG_ENCODE) {
2324                vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2325                fmt = ctx->out_q.fmt;
2326        } else {
2327                vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2328                fmt = ctx->cap_q.fmt;
2329        }
2330
2331        jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
2332
2333        if (fmt->colplanes == 2) {
2334                jpeg_addr.cb = jpeg_addr.y + pix_size;
2335        } else if (fmt->colplanes == 3) {
2336                jpeg_addr.cb = jpeg_addr.y + pix_size;
2337                if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
2338                        jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
2339                else
2340                        jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
2341        }
2342
2343        exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr);
2344}
2345
2346static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
2347{
2348        struct s5p_jpeg *jpeg = ctx->jpeg;
2349        struct vb2_buffer *vb;
2350        unsigned int jpeg_addr = 0;
2351
2352        if (ctx->mode == S5P_JPEG_ENCODE)
2353                vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2354        else
2355                vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2356
2357        jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
2358        exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr);
2359}
2360
2361static void exynos3250_jpeg_device_run(void *priv)
2362{
2363        struct s5p_jpeg_ctx *ctx = priv;
2364        struct s5p_jpeg *jpeg = ctx->jpeg;
2365        unsigned long flags;
2366
2367        spin_lock_irqsave(&ctx->jpeg->slock, flags);
2368
2369        exynos3250_jpeg_reset(jpeg->regs);
2370        exynos3250_jpeg_set_dma_num(jpeg->regs);
2371        exynos3250_jpeg_poweron(jpeg->regs);
2372        exynos3250_jpeg_clk_set(jpeg->regs);
2373        exynos3250_jpeg_proc_mode(jpeg->regs, ctx->mode);
2374
2375        if (ctx->mode == S5P_JPEG_ENCODE) {
2376                exynos3250_jpeg_input_raw_fmt(jpeg->regs,
2377                                              ctx->out_q.fmt->fourcc);
2378                exynos3250_jpeg_dri(jpeg->regs, ctx->restart_interval);
2379
2380                /*
2381                 * JPEG IP allows storing 4 quantization tables
2382                 * We fill table 0 for luma and table 1 for chroma
2383                 */
2384                s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2385                s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2386                /* use table 0 for Y */
2387                exynos3250_jpeg_qtbl(jpeg->regs, 1, 0);
2388                /* use table 1 for Cb and Cr*/
2389                exynos3250_jpeg_qtbl(jpeg->regs, 2, 1);
2390                exynos3250_jpeg_qtbl(jpeg->regs, 3, 1);
2391
2392                /*
2393                 * Some SoCs require setting Huffman tables before each run
2394                 */
2395                if (jpeg->variant->htbl_reinit) {
2396                        s5p_jpeg_set_hdctbl(jpeg->regs);
2397                        s5p_jpeg_set_hdctblg(jpeg->regs);
2398                        s5p_jpeg_set_hactbl(jpeg->regs);
2399                        s5p_jpeg_set_hactblg(jpeg->regs);
2400                }
2401
2402                /* Y, Cb, Cr use Huffman table 0 */
2403                exynos3250_jpeg_htbl_ac(jpeg->regs, 1);
2404                exynos3250_jpeg_htbl_dc(jpeg->regs, 1);
2405                exynos3250_jpeg_htbl_ac(jpeg->regs, 2);
2406                exynos3250_jpeg_htbl_dc(jpeg->regs, 2);
2407                exynos3250_jpeg_htbl_ac(jpeg->regs, 3);
2408                exynos3250_jpeg_htbl_dc(jpeg->regs, 3);
2409
2410                exynos3250_jpeg_set_x(jpeg->regs, ctx->crop_rect.width);
2411                exynos3250_jpeg_set_y(jpeg->regs, ctx->crop_rect.height);
2412                exynos3250_jpeg_stride(jpeg->regs, ctx->out_q.fmt->fourcc,
2413                                                                ctx->out_q.w);
2414                exynos3250_jpeg_offset(jpeg->regs, ctx->crop_rect.left,
2415                                                        ctx->crop_rect.top);
2416                exynos3250_jpeg_set_img_addr(ctx);
2417                exynos3250_jpeg_set_jpeg_addr(ctx);
2418                exynos3250_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
2419
2420                /* ultimately comes from sizeimage from userspace */
2421                exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size);
2422
2423                if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565 ||
2424                    ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565X ||
2425                    ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
2426                        exynos3250_jpeg_set_y16(jpeg->regs, true);
2427        } else {
2428                exynos3250_jpeg_set_img_addr(ctx);
2429                exynos3250_jpeg_set_jpeg_addr(ctx);
2430                exynos3250_jpeg_stride(jpeg->regs, ctx->cap_q.fmt->fourcc,
2431                                                                ctx->cap_q.w);
2432                exynos3250_jpeg_offset(jpeg->regs, 0, 0);
2433                exynos3250_jpeg_dec_scaling_ratio(jpeg->regs,
2434                                                        ctx->scale_factor);
2435                exynos3250_jpeg_dec_stream_size(jpeg->regs, ctx->out_q.size);
2436                exynos3250_jpeg_output_raw_fmt(jpeg->regs,
2437                                                ctx->cap_q.fmt->fourcc);
2438        }
2439
2440        exynos3250_jpeg_interrupts_enable(jpeg->regs);
2441
2442        /* JPEG RGB to YCbCr conversion matrix */
2443        exynos3250_jpeg_coef(jpeg->regs, ctx->mode);
2444
2445        exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT);
2446        jpeg->irq_status = 0;
2447        exynos3250_jpeg_start(jpeg->regs);
2448
2449        spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2450}
2451
2452static int s5p_jpeg_job_ready(void *priv)
2453{
2454        struct s5p_jpeg_ctx *ctx = priv;
2455
2456        if (ctx->mode == S5P_JPEG_DECODE) {
2457                /*
2458                 * We have only one input buffer and one output buffer. If there
2459                 * is a resolution change event, no need to continue decoding.
2460                 */
2461                if (ctx->state == JPEGCTX_RESOLUTION_CHANGE)
2462                        return 0;
2463
2464                return ctx->hdr_parsed;
2465        }
2466
2467        return 1;
2468}
2469
2470static void s5p_jpeg_job_abort(void *priv)
2471{
2472}
2473
2474static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
2475        .device_run     = s5p_jpeg_device_run,
2476        .job_ready      = s5p_jpeg_job_ready,
2477        .job_abort      = s5p_jpeg_job_abort,
2478};
2479
2480static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = {
2481        .device_run     = exynos3250_jpeg_device_run,
2482        .job_ready      = s5p_jpeg_job_ready,
2483        .job_abort      = s5p_jpeg_job_abort,
2484};
2485
2486static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
2487        .device_run     = exynos4_jpeg_device_run,
2488        .job_ready      = s5p_jpeg_job_ready,
2489        .job_abort      = s5p_jpeg_job_abort,
2490};
2491
2492/*
2493 * ============================================================================
2494 * Queue operations
2495 * ============================================================================
2496 */
2497
2498static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
2499                           unsigned int *nbuffers, unsigned int *nplanes,
2500                           unsigned int sizes[], struct device *alloc_devs[])
2501{
2502        struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
2503        struct s5p_jpeg_q_data *q_data = NULL;
2504        unsigned int size, count = *nbuffers;
2505
2506        q_data = get_q_data(ctx, vq->type);
2507        BUG_ON(q_data == NULL);
2508
2509        size = q_data->size;
2510
2511        /*
2512         * header is parsed during decoding and parsed information stored
2513         * in the context so we do not allow another buffer to overwrite it
2514         */
2515        if (ctx->mode == S5P_JPEG_DECODE)
2516                count = 1;
2517
2518        *nbuffers = count;
2519        *nplanes = 1;
2520        sizes[0] = size;
2521
2522        return 0;
2523}
2524
2525static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
2526{
2527        struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2528        struct s5p_jpeg_q_data *q_data = NULL;
2529
2530        q_data = get_q_data(ctx, vb->vb2_queue->type);
2531        BUG_ON(q_data == NULL);
2532
2533        if (vb2_plane_size(vb, 0) < q_data->size) {
2534                pr_err("%s data will not fit into plane (%lu < %lu)\n",
2535                                __func__, vb2_plane_size(vb, 0),
2536                                (long)q_data->size);
2537                return -EINVAL;
2538        }
2539
2540        vb2_set_plane_payload(vb, 0, q_data->size);
2541
2542        return 0;
2543}
2544
2545static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx *ctx)
2546{
2547        struct s5p_jpeg_q_data *q_data = &ctx->cap_q;
2548
2549        q_data->w = ctx->out_q.w;
2550        q_data->h = ctx->out_q.h;
2551
2552        /*
2553         * This call to jpeg_bound_align_image() takes care of width and
2554         * height values alignment when user space calls the QBUF of
2555         * OUTPUT buffer after the S_FMT of CAPTURE buffer.
2556         * Please note that on Exynos4x12 SoCs, resigning from executing
2557         * S_FMT on capture buffer for each JPEG image can result in a
2558         * hardware hangup if subsampling is lower than the one of input
2559         * JPEG.
2560         */
2561        jpeg_bound_align_image(ctx, &q_data->w, S5P_JPEG_MIN_WIDTH,
2562                               S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
2563                               &q_data->h, S5P_JPEG_MIN_HEIGHT,
2564                               S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align);
2565
2566        q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
2567}
2568
2569static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
2570{
2571        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
2572        struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2573
2574        if (ctx->mode == S5P_JPEG_DECODE &&
2575            vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
2576                static const struct v4l2_event ev_src_ch = {
2577                        .type = V4L2_EVENT_SOURCE_CHANGE,
2578                        .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
2579                };
2580                struct vb2_queue *dst_vq;
2581                u32 ori_w;
2582                u32 ori_h;
2583
2584                dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
2585                                         V4L2_BUF_TYPE_VIDEO_CAPTURE);
2586                ori_w = ctx->out_q.w;
2587                ori_h = ctx->out_q.h;
2588
2589                ctx->hdr_parsed = s5p_jpeg_parse_hdr(&ctx->out_q,
2590                     (unsigned long)vb2_plane_vaddr(vb, 0),
2591                     min((unsigned long)ctx->out_q.size,
2592                         vb2_get_plane_payload(vb, 0)), ctx);
2593                if (!ctx->hdr_parsed) {
2594                        vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
2595                        return;
2596                }
2597
2598                /*
2599                 * If there is a resolution change event, only update capture
2600                 * queue when it is not streaming. Otherwise, update it in
2601                 * STREAMOFF. See s5p_jpeg_stop_streaming for detail.
2602                 */
2603                if (ctx->out_q.w != ori_w || ctx->out_q.h != ori_h) {
2604                        v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
2605                        if (vb2_is_streaming(dst_vq))
2606                                ctx->state = JPEGCTX_RESOLUTION_CHANGE;
2607                        else
2608                                s5p_jpeg_set_capture_queue_data(ctx);
2609                }
2610        }
2611
2612        v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
2613}
2614
2615static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
2616{
2617        struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2618        int ret;
2619
2620        ret = pm_runtime_get_sync(ctx->jpeg->dev);
2621
2622        return ret > 0 ? 0 : ret;
2623}
2624
2625static void s5p_jpeg_stop_streaming(struct vb2_queue *q)
2626{
2627        struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2628
2629        /*
2630         * STREAMOFF is an acknowledgment for resolution change event.
2631         * Before STREAMOFF, we still have to return the old resolution and
2632         * subsampling. Update capture queue when the stream is off.
2633         */
2634        if (ctx->state == JPEGCTX_RESOLUTION_CHANGE &&
2635            q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2636                s5p_jpeg_set_capture_queue_data(ctx);
2637                ctx->state = JPEGCTX_RUNNING;
2638        }
2639
2640        pm_runtime_put(ctx->jpeg->dev);
2641}
2642
2643static const struct vb2_ops s5p_jpeg_qops = {
2644        .queue_setup            = s5p_jpeg_queue_setup,
2645        .buf_prepare            = s5p_jpeg_buf_prepare,
2646        .buf_queue              = s5p_jpeg_buf_queue,
2647        .wait_prepare           = vb2_ops_wait_prepare,
2648        .wait_finish            = vb2_ops_wait_finish,
2649        .start_streaming        = s5p_jpeg_start_streaming,
2650        .stop_streaming         = s5p_jpeg_stop_streaming,
2651};
2652
2653static int queue_init(void *priv, struct vb2_queue *src_vq,
2654                      struct vb2_queue *dst_vq)
2655{
2656        struct s5p_jpeg_ctx *ctx = priv;
2657        int ret;
2658
2659        src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2660        src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2661        src_vq->drv_priv = ctx;
2662        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2663        src_vq->ops = &s5p_jpeg_qops;
2664        src_vq->mem_ops = &vb2_dma_contig_memops;
2665        src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2666        src_vq->lock = &ctx->jpeg->lock;
2667        src_vq->dev = ctx->jpeg->dev;
2668
2669        ret = vb2_queue_init(src_vq);
2670        if (ret)
2671                return ret;
2672
2673        dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2674        dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2675        dst_vq->drv_priv = ctx;
2676        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2677        dst_vq->ops = &s5p_jpeg_qops;
2678        dst_vq->mem_ops = &vb2_dma_contig_memops;
2679        dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2680        dst_vq->lock = &ctx->jpeg->lock;
2681        dst_vq->dev = ctx->jpeg->dev;
2682
2683        return vb2_queue_init(dst_vq);
2684}
2685
2686/*
2687 * ============================================================================
2688 * ISR
2689 * ============================================================================
2690 */
2691
2692static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
2693{
2694        struct s5p_jpeg *jpeg = dev_id;
2695        struct s5p_jpeg_ctx *curr_ctx;
2696        struct vb2_v4l2_buffer *src_buf, *dst_buf;
2697        unsigned long payload_size = 0;
2698        enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2699        bool enc_jpeg_too_large = false;
2700        bool timer_elapsed = false;
2701        bool op_completed = false;
2702
2703        spin_lock(&jpeg->slock);
2704
2705        curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2706
2707        src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2708        dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2709
2710        if (curr_ctx->mode == S5P_JPEG_ENCODE)
2711                enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
2712        timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
2713        op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
2714        if (curr_ctx->mode == S5P_JPEG_DECODE)
2715                op_completed = op_completed &&
2716                                        s5p_jpeg_stream_stat_ok(jpeg->regs);
2717
2718        if (enc_jpeg_too_large) {
2719                state = VB2_BUF_STATE_ERROR;
2720                s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
2721        } else if (timer_elapsed) {
2722                state = VB2_BUF_STATE_ERROR;
2723                s5p_jpeg_clear_timer_stat(jpeg->regs);
2724        } else if (!op_completed) {
2725                state = VB2_BUF_STATE_ERROR;
2726        } else {
2727                payload_size = s5p_jpeg_compressed_size(jpeg->regs);
2728        }
2729
2730        dst_buf->timecode = src_buf->timecode;
2731        dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
2732        dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2733        dst_buf->flags |=
2734                src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2735
2736        v4l2_m2m_buf_done(src_buf, state);
2737        if (curr_ctx->mode == S5P_JPEG_ENCODE)
2738                vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
2739        v4l2_m2m_buf_done(dst_buf, state);
2740
2741        curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
2742        spin_unlock(&jpeg->slock);
2743
2744        s5p_jpeg_clear_int(jpeg->regs);
2745
2746        v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2747        return IRQ_HANDLED;
2748}
2749
2750static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
2751{
2752        unsigned int int_status;
2753        struct vb2_v4l2_buffer *src_vb, *dst_vb;
2754        struct s5p_jpeg *jpeg = priv;
2755        struct s5p_jpeg_ctx *curr_ctx;
2756        unsigned long payload_size = 0;
2757
2758        spin_lock(&jpeg->slock);
2759
2760        exynos4_jpeg_set_sys_int_enable(jpeg->regs, 0);
2761
2762        curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2763
2764        src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2765        dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2766
2767        int_status = exynos4_jpeg_get_int_status(jpeg->regs);
2768
2769        if (int_status) {
2770                switch (int_status & 0x1f) {
2771                case 0x1:
2772                        jpeg->irq_ret = ERR_PROT;
2773                        break;
2774                case 0x2:
2775                        jpeg->irq_ret = OK_ENC_OR_DEC;
2776                        break;
2777                case 0x4:
2778                        jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
2779                        break;
2780                case 0x8:
2781                        jpeg->irq_ret = ERR_MULTI_SCAN;
2782                        break;
2783                case 0x10:
2784                        jpeg->irq_ret = ERR_FRAME;
2785                        break;
2786                default:
2787                        jpeg->irq_ret = ERR_UNKNOWN;
2788                        break;
2789                }
2790        } else {
2791                jpeg->irq_ret = ERR_UNKNOWN;
2792        }
2793
2794        if (jpeg->irq_ret == OK_ENC_OR_DEC) {
2795                if (curr_ctx->mode == S5P_JPEG_ENCODE) {
2796                        payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
2797                        vb2_set_plane_payload(&dst_vb->vb2_buf,
2798                                        0, payload_size);
2799                }
2800                v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
2801                v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
2802        } else {
2803                v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
2804                v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
2805        }
2806
2807        if (jpeg->variant->version == SJPEG_EXYNOS4)
2808                curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
2809
2810        exynos4_jpeg_set_enc_dec_mode(jpeg->regs, S5P_JPEG_DISABLE);
2811
2812        spin_unlock(&jpeg->slock);
2813
2814        v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2815        return IRQ_HANDLED;
2816}
2817
2818static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
2819{
2820        struct s5p_jpeg *jpeg = dev_id;
2821        struct s5p_jpeg_ctx *curr_ctx;
2822        struct vb2_v4l2_buffer *src_buf, *dst_buf;
2823        unsigned long payload_size = 0;
2824        enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2825        bool interrupt_timeout = false;
2826        bool stream_error = false;
2827        u32 irq_status;
2828
2829        spin_lock(&jpeg->slock);
2830
2831        irq_status = exynos3250_jpeg_get_timer_status(jpeg->regs);
2832        if (irq_status & EXYNOS3250_TIMER_INT_STAT) {
2833                exynos3250_jpeg_clear_timer_status(jpeg->regs);
2834                interrupt_timeout = true;
2835                dev_err(jpeg->dev, "Interrupt timeout occurred.\n");
2836        }
2837
2838        irq_status = exynos3250_jpeg_get_int_status(jpeg->regs);
2839        exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status);
2840
2841        jpeg->irq_status |= irq_status;
2842
2843        if (jpeg->variant->version == SJPEG_EXYNOS5420 &&
2844            irq_status & EXYNOS3250_STREAM_STAT) {
2845                stream_error = true;
2846                dev_err(jpeg->dev, "Syntax error or unrecoverable error occurred.\n");
2847        }
2848
2849        curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2850
2851        if (!curr_ctx)
2852                goto exit_unlock;
2853
2854        if ((irq_status & EXYNOS3250_HEADER_STAT) &&
2855            (curr_ctx->mode == S5P_JPEG_DECODE)) {
2856                exynos3250_jpeg_rstart(jpeg->regs);
2857                goto exit_unlock;
2858        }
2859
2860        if (jpeg->irq_status & (EXYNOS3250_JPEG_DONE |
2861                                EXYNOS3250_WDMA_DONE |
2862                                EXYNOS3250_RDMA_DONE |
2863                                EXYNOS3250_RESULT_STAT))
2864                payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
2865        else if (interrupt_timeout || stream_error)
2866                state = VB2_BUF_STATE_ERROR;
2867        else
2868                goto exit_unlock;
2869
2870        src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2871        dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2872
2873        dst_buf->timecode = src_buf->timecode;
2874        dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
2875
2876        v4l2_m2m_buf_done(src_buf, state);
2877        if (curr_ctx->mode == S5P_JPEG_ENCODE)
2878                vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
2879        v4l2_m2m_buf_done(dst_buf, state);
2880
2881        curr_ctx->subsampling =
2882                        exynos3250_jpeg_get_subsampling_mode(jpeg->regs);
2883
2884        spin_unlock(&jpeg->slock);
2885
2886        v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2887        return IRQ_HANDLED;
2888
2889exit_unlock:
2890        spin_unlock(&jpeg->slock);
2891        return IRQ_HANDLED;
2892}
2893
2894static void *jpeg_get_drv_data(struct device *dev);
2895
2896/*
2897 * ============================================================================
2898 * Driver basic infrastructure
2899 * ============================================================================
2900 */
2901
2902static int s5p_jpeg_probe(struct platform_device *pdev)
2903{
2904        struct s5p_jpeg *jpeg;
2905        struct resource *res;
2906        int i, ret;
2907
2908        /* JPEG IP abstraction struct */
2909        jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
2910        if (!jpeg)
2911                return -ENOMEM;
2912
2913        jpeg->variant = jpeg_get_drv_data(&pdev->dev);
2914
2915        mutex_init(&jpeg->lock);
2916        spin_lock_init(&jpeg->slock);
2917        jpeg->dev = &pdev->dev;
2918
2919        /* memory-mapped registers */
2920        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2921
2922        jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
2923        if (IS_ERR(jpeg->regs))
2924                return PTR_ERR(jpeg->regs);
2925
2926        /* interrupt service routine registration */
2927        jpeg->irq = ret = platform_get_irq(pdev, 0);
2928        if (ret < 0) {
2929                dev_err(&pdev->dev, "cannot find IRQ\n");
2930                return ret;
2931        }
2932
2933        ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
2934                                0, dev_name(&pdev->dev), jpeg);
2935        if (ret) {
2936                dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
2937                return ret;
2938        }
2939
2940        /* clocks */
2941        for (i = 0; i < jpeg->variant->num_clocks; i++) {
2942                jpeg->clocks[i] = devm_clk_get(&pdev->dev,
2943                                              jpeg->variant->clk_names[i]);
2944                if (IS_ERR(jpeg->clocks[i])) {
2945                        dev_err(&pdev->dev, "failed to get clock: %s\n",
2946                                jpeg->variant->clk_names[i]);
2947                        return PTR_ERR(jpeg->clocks[i]);
2948                }
2949        }
2950
2951        /* v4l2 device */
2952        ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
2953        if (ret) {
2954                dev_err(&pdev->dev, "Failed to register v4l2 device\n");
2955                return ret;
2956        }
2957
2958        /* mem2mem device */
2959        jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops);
2960        if (IS_ERR(jpeg->m2m_dev)) {
2961                v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
2962                ret = PTR_ERR(jpeg->m2m_dev);
2963                goto device_register_rollback;
2964        }
2965
2966        vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
2967
2968        /* JPEG encoder /dev/videoX node */
2969        jpeg->vfd_encoder = video_device_alloc();
2970        if (!jpeg->vfd_encoder) {
2971                v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
2972                ret = -ENOMEM;
2973                goto m2m_init_rollback;
2974        }
2975        snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
2976                                "%s-enc", S5P_JPEG_M2M_NAME);
2977        jpeg->vfd_encoder->fops         = &s5p_jpeg_fops;
2978        jpeg->vfd_encoder->ioctl_ops    = &s5p_jpeg_ioctl_ops;
2979        jpeg->vfd_encoder->minor        = -1;
2980        jpeg->vfd_encoder->release      = video_device_release;
2981        jpeg->vfd_encoder->lock         = &jpeg->lock;
2982        jpeg->vfd_encoder->v4l2_dev     = &jpeg->v4l2_dev;
2983        jpeg->vfd_encoder->vfl_dir      = VFL_DIR_M2M;
2984
2985        ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
2986        if (ret) {
2987                v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2988                video_device_release(jpeg->vfd_encoder);
2989                goto m2m_init_rollback;
2990        }
2991
2992        video_set_drvdata(jpeg->vfd_encoder, jpeg);
2993        v4l2_info(&jpeg->v4l2_dev,
2994                  "encoder device registered as /dev/video%d\n",
2995                  jpeg->vfd_encoder->num);
2996
2997        /* JPEG decoder /dev/videoX node */
2998        jpeg->vfd_decoder = video_device_alloc();
2999        if (!jpeg->vfd_decoder) {
3000                v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
3001                ret = -ENOMEM;
3002                goto enc_vdev_register_rollback;
3003        }
3004        snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
3005                                "%s-dec", S5P_JPEG_M2M_NAME);
3006        jpeg->vfd_decoder->fops         = &s5p_jpeg_fops;
3007        jpeg->vfd_decoder->ioctl_ops    = &s5p_jpeg_ioctl_ops;
3008        jpeg->vfd_decoder->minor        = -1;
3009        jpeg->vfd_decoder->release      = video_device_release;
3010        jpeg->vfd_decoder->lock         = &jpeg->lock;
3011        jpeg->vfd_decoder->v4l2_dev     = &jpeg->v4l2_dev;
3012        jpeg->vfd_decoder->vfl_dir      = VFL_DIR_M2M;
3013
3014        ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
3015        if (ret) {
3016                v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
3017                video_device_release(jpeg->vfd_decoder);
3018                goto enc_vdev_register_rollback;
3019        }
3020
3021        video_set_drvdata(jpeg->vfd_decoder, jpeg);
3022        v4l2_info(&jpeg->v4l2_dev,
3023                  "decoder device registered as /dev/video%d\n",
3024                  jpeg->vfd_decoder->num);
3025
3026        /* final statements & power management */
3027        platform_set_drvdata(pdev, jpeg);
3028
3029        pm_runtime_enable(&pdev->dev);
3030
3031        v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
3032
3033        return 0;
3034
3035enc_vdev_register_rollback:
3036        video_unregister_device(jpeg->vfd_encoder);
3037
3038m2m_init_rollback:
3039        v4l2_m2m_release(jpeg->m2m_dev);
3040
3041device_register_rollback:
3042        v4l2_device_unregister(&jpeg->v4l2_dev);
3043
3044        return ret;
3045}
3046
3047static int s5p_jpeg_remove(struct platform_device *pdev)
3048{
3049        struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
3050        int i;
3051
3052        pm_runtime_disable(jpeg->dev);
3053
3054        video_unregister_device(jpeg->vfd_decoder);
3055        video_unregister_device(jpeg->vfd_encoder);
3056        vb2_dma_contig_clear_max_seg_size(&pdev->dev);
3057        v4l2_m2m_release(jpeg->m2m_dev);
3058        v4l2_device_unregister(&jpeg->v4l2_dev);
3059
3060        if (!pm_runtime_status_suspended(&pdev->dev)) {
3061                for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
3062                        clk_disable_unprepare(jpeg->clocks[i]);
3063        }
3064
3065        return 0;
3066}
3067
3068#ifdef CONFIG_PM
3069static int s5p_jpeg_runtime_suspend(struct device *dev)
3070{
3071        struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
3072        int i;
3073
3074        for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
3075                clk_disable_unprepare(jpeg->clocks[i]);
3076
3077        return 0;
3078}
3079
3080static int s5p_jpeg_runtime_resume(struct device *dev)
3081{
3082        struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
3083        unsigned long flags;
3084        int i, ret;
3085
3086        for (i = 0; i < jpeg->variant->num_clocks; i++) {
3087                ret = clk_prepare_enable(jpeg->clocks[i]);
3088                if (ret) {
3089                        while (--i >= 0)
3090                                clk_disable_unprepare(jpeg->clocks[i]);
3091                        return ret;
3092                }
3093        }
3094
3095        spin_lock_irqsave(&jpeg->slock, flags);
3096
3097        /*
3098         * JPEG IP allows storing two Huffman tables for each component.
3099         * We fill table 0 for each component and do this here only
3100         * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC
3101         * require programming their Huffman tables each time the encoding
3102         * process is initialized, and thus it is accomplished in the
3103         * device_run callback of m2m_ops.
3104         */
3105        if (!jpeg->variant->htbl_reinit) {
3106                s5p_jpeg_set_hdctbl(jpeg->regs);
3107                s5p_jpeg_set_hdctblg(jpeg->regs);
3108                s5p_jpeg_set_hactbl(jpeg->regs);
3109                s5p_jpeg_set_hactblg(jpeg->regs);
3110        }
3111
3112        spin_unlock_irqrestore(&jpeg->slock, flags);
3113
3114        return 0;
3115}
3116#endif /* CONFIG_PM */
3117
3118static const struct dev_pm_ops s5p_jpeg_pm_ops = {
3119        SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
3120                                pm_runtime_force_resume)
3121        SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume,
3122                           NULL)
3123};
3124
3125static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
3126        .version        = SJPEG_S5P,
3127        .jpeg_irq       = s5p_jpeg_irq,
3128        .m2m_ops        = &s5p_jpeg_m2m_ops,
3129        .fmt_ver_flag   = SJPEG_FMT_FLAG_S5P,
3130        .clk_names      = {"jpeg"},
3131        .num_clocks     = 1,
3132};
3133
3134static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
3135        .version        = SJPEG_EXYNOS3250,
3136        .jpeg_irq       = exynos3250_jpeg_irq,
3137        .m2m_ops        = &exynos3250_jpeg_m2m_ops,
3138        .fmt_ver_flag   = SJPEG_FMT_FLAG_EXYNOS3250,
3139        .hw3250_compat  = 1,
3140        .clk_names      = {"jpeg", "sclk"},
3141        .num_clocks     = 2,
3142};
3143
3144static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
3145        .version        = SJPEG_EXYNOS4,
3146        .jpeg_irq       = exynos4_jpeg_irq,
3147        .m2m_ops        = &exynos4_jpeg_m2m_ops,
3148        .fmt_ver_flag   = SJPEG_FMT_FLAG_EXYNOS4,
3149        .htbl_reinit    = 1,
3150        .clk_names      = {"jpeg"},
3151        .num_clocks     = 1,
3152        .hw_ex4_compat  = 1,
3153};
3154
3155static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = {
3156        .version        = SJPEG_EXYNOS5420,
3157        .jpeg_irq       = exynos3250_jpeg_irq,          /* intentionally 3250 */
3158        .m2m_ops        = &exynos3250_jpeg_m2m_ops,     /* intentionally 3250 */
3159        .fmt_ver_flag   = SJPEG_FMT_FLAG_EXYNOS3250,    /* intentionally 3250 */
3160        .hw3250_compat  = 1,
3161        .htbl_reinit    = 1,
3162        .clk_names      = {"jpeg"},
3163        .num_clocks     = 1,
3164};
3165
3166static struct s5p_jpeg_variant exynos5433_jpeg_drvdata = {
3167        .version        = SJPEG_EXYNOS5433,
3168        .jpeg_irq       = exynos4_jpeg_irq,
3169        .m2m_ops        = &exynos4_jpeg_m2m_ops,
3170        .fmt_ver_flag   = SJPEG_FMT_FLAG_EXYNOS4,
3171        .htbl_reinit    = 1,
3172        .clk_names      = {"pclk", "aclk", "aclk_xiu", "sclk"},
3173        .num_clocks     = 4,
3174        .hw_ex4_compat  = 1,
3175};
3176
3177static const struct of_device_id samsung_jpeg_match[] = {
3178        {
3179                .compatible = "samsung,s5pv210-jpeg",
3180                .data = &s5p_jpeg_drvdata,
3181        }, {
3182                .compatible = "samsung,exynos3250-jpeg",
3183                .data = &exynos3250_jpeg_drvdata,
3184        }, {
3185                .compatible = "samsung,exynos4210-jpeg",
3186                .data = &exynos4_jpeg_drvdata,
3187        }, {
3188                .compatible = "samsung,exynos4212-jpeg",
3189                .data = &exynos4_jpeg_drvdata,
3190        }, {
3191                .compatible = "samsung,exynos5420-jpeg",
3192                .data = &exynos5420_jpeg_drvdata,
3193        }, {
3194                .compatible = "samsung,exynos5433-jpeg",
3195                .data = &exynos5433_jpeg_drvdata,
3196        },
3197        {},
3198};
3199
3200MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
3201
3202static void *jpeg_get_drv_data(struct device *dev)
3203{
3204        struct s5p_jpeg_variant *driver_data = NULL;
3205        const struct of_device_id *match;
3206
3207        if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
3208                return &s5p_jpeg_drvdata;
3209
3210        match = of_match_node(samsung_jpeg_match, dev->of_node);
3211
3212        if (match)
3213                driver_data = (struct s5p_jpeg_variant *)match->data;
3214
3215        return driver_data;
3216}
3217
3218static struct platform_driver s5p_jpeg_driver = {
3219        .probe = s5p_jpeg_probe,
3220        .remove = s5p_jpeg_remove,
3221        .driver = {
3222                .of_match_table = of_match_ptr(samsung_jpeg_match),
3223                .name           = S5P_JPEG_M2M_NAME,
3224                .pm             = &s5p_jpeg_pm_ops,
3225        },
3226};
3227
3228module_platform_driver(s5p_jpeg_driver);
3229
3230MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
3231MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
3232MODULE_DESCRIPTION("Samsung JPEG codec driver");
3233MODULE_LICENSE("GPL");
3234