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