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-v4l2.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
 541        for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) {
 542                if (fourcc_to_dwngrd_schema_id[i] == fourcc)
 543                        return i;
 544        }
 545
 546        return -EINVAL;
 547}
 548
 549static int s5p_jpeg_adjust_fourcc_to_subsampling(
 550                                        enum v4l2_jpeg_chroma_subsampling subs,
 551                                        u32 in_fourcc,
 552                                        u32 *out_fourcc,
 553                                        struct s5p_jpeg_ctx *ctx)
 554{
 555        int dwngrd_sch_id;
 556
 557        if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
 558                dwngrd_sch_id =
 559                        s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc);
 560                if (dwngrd_sch_id < 0)
 561                        return -EINVAL;
 562        }
 563
 564        switch (ctx->subsampling) {
 565        case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
 566                *out_fourcc = V4L2_PIX_FMT_GREY;
 567                break;
 568        case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
 569                if (dwngrd_sch_id >
 570                                ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1)
 571                        return -EINVAL;
 572                *out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id];
 573                break;
 574        case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
 575                if (dwngrd_sch_id >
 576                                ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1)
 577                        return -EINVAL;
 578                *out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id];
 579                break;
 580        default:
 581                *out_fourcc = V4L2_PIX_FMT_GREY;
 582                break;
 583        }
 584
 585        return 0;
 586}
 587
 588static int exynos4x12_decoded_subsampling[] = {
 589        V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
 590        V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 591        V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 592        V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 593};
 594
 595static int exynos3250_decoded_subsampling[] = {
 596        V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 597        V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 598        V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 599        V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
 600        -1,
 601        -1,
 602        V4L2_JPEG_CHROMA_SUBSAMPLING_411,
 603};
 604
 605static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
 606{
 607        return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
 608}
 609
 610static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
 611{
 612        return container_of(fh, struct s5p_jpeg_ctx, fh);
 613}
 614
 615static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
 616{
 617        WARN_ON(ctx->subsampling > 3);
 618
 619        switch (ctx->jpeg->variant->version) {
 620        case SJPEG_S5P:
 621                if (ctx->subsampling > 2)
 622                        return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
 623                return ctx->subsampling;
 624        case SJPEG_EXYNOS3250:
 625        case SJPEG_EXYNOS5420:
 626                if (ctx->subsampling > 3)
 627                        return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
 628                return exynos3250_decoded_subsampling[ctx->subsampling];
 629        case SJPEG_EXYNOS4:
 630        case SJPEG_EXYNOS5433:
 631                if (ctx->subsampling > 2)
 632                        return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
 633                return exynos4x12_decoded_subsampling[ctx->subsampling];
 634        default:
 635                return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
 636        }
 637}
 638
 639static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
 640                                     const unsigned char *qtbl,
 641                                     unsigned long tab, int len)
 642{
 643        int i;
 644
 645        for (i = 0; i < len; i++)
 646                writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
 647}
 648
 649static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
 650{
 651        /* this driver fills quantisation table 0 with data for luma */
 652        s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
 653                          S5P_JPG_QTBL_CONTENT(0),
 654                          ARRAY_SIZE(qtbl_luminance[quality]));
 655}
 656
 657static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
 658{
 659        /* this driver fills quantisation table 1 with data for chroma */
 660        s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
 661                          S5P_JPG_QTBL_CONTENT(1),
 662                          ARRAY_SIZE(qtbl_chrominance[quality]));
 663}
 664
 665static inline void s5p_jpeg_set_htbl(void __iomem *regs,
 666                                     const unsigned char *htbl,
 667                                     unsigned long tab, int len)
 668{
 669        int i;
 670
 671        for (i = 0; i < len; i++)
 672                writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
 673}
 674
 675static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
 676{
 677        /* this driver fills table 0 for this component */
 678        s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
 679                                                ARRAY_SIZE(hdctbl0));
 680}
 681
 682static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
 683{
 684        /* this driver fills table 0 for this component */
 685        s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
 686                                                ARRAY_SIZE(hdctblg0));
 687}
 688
 689static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
 690{
 691        /* this driver fills table 0 for this component */
 692        s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
 693                                                ARRAY_SIZE(hactbl0));
 694}
 695
 696static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
 697{
 698        /* this driver fills table 0 for this component */
 699        s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
 700                                                ARRAY_SIZE(hactblg0));
 701}
 702
 703static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
 704                                        const unsigned char *tbl,
 705                                        unsigned long tab, int len)
 706{
 707        int i;
 708        unsigned int dword;
 709
 710        for (i = 0; i < len; i += 4) {
 711                dword = tbl[i] |
 712                        (tbl[i + 1] << 8) |
 713                        (tbl[i + 2] << 16) |
 714                        (tbl[i + 3] << 24);
 715                writel(dword, regs + tab + i);
 716        }
 717}
 718
 719static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
 720{
 721        /* this driver fills quantisation table 0 with data for luma */
 722        exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
 723                             EXYNOS4_QTBL_CONTENT(0),
 724                             ARRAY_SIZE(qtbl_luminance[quality]));
 725}
 726
 727static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
 728{
 729        /* this driver fills quantisation table 1 with data for chroma */
 730        exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
 731                             EXYNOS4_QTBL_CONTENT(1),
 732                             ARRAY_SIZE(qtbl_chrominance[quality]));
 733}
 734
 735static void exynos4_jpeg_set_huff_tbl(void __iomem *base)
 736{
 737        exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
 738                                                        ARRAY_SIZE(hdctbl0));
 739        exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
 740                                                        ARRAY_SIZE(hdctbl0));
 741        exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
 742                                                        ARRAY_SIZE(hdctblg0));
 743        exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
 744                                                        ARRAY_SIZE(hdctblg0));
 745        exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
 746                                                        ARRAY_SIZE(hactbl0));
 747        exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
 748                                                        ARRAY_SIZE(hactbl0));
 749        exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
 750                                                        ARRAY_SIZE(hactblg0));
 751        exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
 752                                                        ARRAY_SIZE(hactblg0));
 753}
 754
 755static inline int __exynos4_huff_tbl(int class, int id, bool lenval)
 756{
 757        /*
 758         * class: 0 - DC, 1 - AC
 759         * id: 0 - Y, 1 - Cb/Cr
 760         */
 761        if (class) {
 762                if (id)
 763                        return lenval ? EXYNOS4_HUFF_TBL_HACCL :
 764                                EXYNOS4_HUFF_TBL_HACCV;
 765                return lenval ? EXYNOS4_HUFF_TBL_HACLL : EXYNOS4_HUFF_TBL_HACLV;
 766
 767        }
 768        /* class == 0 */
 769        if (id)
 770                return lenval ? EXYNOS4_HUFF_TBL_HDCCL : EXYNOS4_HUFF_TBL_HDCCV;
 771
 772        return lenval ? EXYNOS4_HUFF_TBL_HDCLL : EXYNOS4_HUFF_TBL_HDCLV;
 773}
 774
 775static inline int exynos4_huff_tbl_len(int class, int id)
 776{
 777        return __exynos4_huff_tbl(class, id, true);
 778}
 779
 780static inline int exynos4_huff_tbl_val(int class, int id)
 781{
 782        return __exynos4_huff_tbl(class, id, false);
 783}
 784
 785static int get_byte(struct s5p_jpeg_buffer *buf);
 786static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word);
 787static void skip(struct s5p_jpeg_buffer *buf, long len);
 788
 789static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx *ctx)
 790{
 791        struct s5p_jpeg *jpeg = ctx->jpeg;
 792        struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 793        struct s5p_jpeg_buffer jpeg_buffer;
 794        unsigned int word;
 795        int c, x, components;
 796
 797        jpeg_buffer.size = 2; /* Ls */
 798        jpeg_buffer.data =
 799                (unsigned long)vb2_plane_vaddr(vb, 0) + ctx->out_q.sos + 2;
 800        jpeg_buffer.curr = 0;
 801
 802        word = 0;
 803
 804        if (get_word_be(&jpeg_buffer, &word))
 805                return;
 806        jpeg_buffer.size = (long)word - 2;
 807        jpeg_buffer.data += 2;
 808        jpeg_buffer.curr = 0;
 809
 810        components = get_byte(&jpeg_buffer);
 811        if (components == -1)
 812                return;
 813        while (components--) {
 814                c = get_byte(&jpeg_buffer);
 815                if (c == -1)
 816                        return;
 817                x = get_byte(&jpeg_buffer);
 818                if (x == -1)
 819                        return;
 820                exynos4_jpeg_select_dec_h_tbl(jpeg->regs, c,
 821                                        (((x >> 4) & 0x1) << 1) | (x & 0x1));
 822        }
 823
 824}
 825
 826static void exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx *ctx)
 827{
 828        struct s5p_jpeg *jpeg = ctx->jpeg;
 829        struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 830        struct s5p_jpeg_buffer jpeg_buffer;
 831        unsigned int word;
 832        int c, i, n, j;
 833
 834        for (j = 0; j < ctx->out_q.dht.n; ++j) {
 835                jpeg_buffer.size = ctx->out_q.dht.len[j];
 836                jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(vb, 0) +
 837                                   ctx->out_q.dht.marker[j];
 838                jpeg_buffer.curr = 0;
 839
 840                word = 0;
 841                while (jpeg_buffer.curr < jpeg_buffer.size) {
 842                        char id, class;
 843
 844                        c = get_byte(&jpeg_buffer);
 845                        if (c == -1)
 846                                return;
 847                        id = c & 0xf;
 848                        class = (c >> 4) & 0xf;
 849                        n = 0;
 850                        for (i = 0; i < 16; ++i) {
 851                                c = get_byte(&jpeg_buffer);
 852                                if (c == -1)
 853                                        return;
 854                                word |= c << ((i % 4) * 8);
 855                                if ((i + 1) % 4 == 0) {
 856                                        writel(word, jpeg->regs +
 857                                        exynos4_huff_tbl_len(class, id) +
 858                                        (i / 4) * 4);
 859                                        word = 0;
 860                                }
 861                                n += c;
 862                        }
 863                        word = 0;
 864                        for (i = 0; i < n; ++i) {
 865                                c = get_byte(&jpeg_buffer);
 866                                if (c == -1)
 867                                        return;
 868                                word |= c << ((i % 4) * 8);
 869                                if ((i + 1) % 4 == 0) {
 870                                        writel(word, jpeg->regs +
 871                                        exynos4_huff_tbl_val(class, id) +
 872                                        (i / 4) * 4);
 873                                        word = 0;
 874                                }
 875                        }
 876                        if (i % 4) {
 877                                writel(word, jpeg->regs +
 878                                exynos4_huff_tbl_val(class, id) + (i / 4) * 4);
 879                        }
 880                        word = 0;
 881                }
 882        }
 883}
 884
 885static void exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx *ctx)
 886{
 887        struct s5p_jpeg *jpeg = ctx->jpeg;
 888        struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 889        struct s5p_jpeg_buffer jpeg_buffer;
 890        int c, x, components;
 891
 892        jpeg_buffer.size = ctx->out_q.sof_len;
 893        jpeg_buffer.data =
 894                (unsigned long)vb2_plane_vaddr(vb, 0) + ctx->out_q.sof;
 895        jpeg_buffer.curr = 0;
 896
 897        skip(&jpeg_buffer, 5); /* P, Y, X */
 898        components = get_byte(&jpeg_buffer);
 899        if (components == -1)
 900                return;
 901
 902        exynos4_jpeg_set_dec_components(jpeg->regs, components);
 903
 904        while (components--) {
 905                c = get_byte(&jpeg_buffer);
 906                if (c == -1)
 907                        return;
 908                skip(&jpeg_buffer, 1);
 909                x = get_byte(&jpeg_buffer);
 910                if (x == -1)
 911                        return;
 912                exynos4_jpeg_select_dec_q_tbl(jpeg->regs, c, x);
 913        }
 914}
 915
 916static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx *ctx)
 917{
 918        struct s5p_jpeg *jpeg = ctx->jpeg;
 919        struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 920        struct s5p_jpeg_buffer jpeg_buffer;
 921        unsigned int word;
 922        int c, i, j;
 923
 924        for (j = 0; j < ctx->out_q.dqt.n; ++j) {
 925                jpeg_buffer.size = ctx->out_q.dqt.len[j];
 926                jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(vb, 0) +
 927                                   ctx->out_q.dqt.marker[j];
 928                jpeg_buffer.curr = 0;
 929
 930                word = 0;
 931                while (jpeg_buffer.size - jpeg_buffer.curr >= 65) {
 932                        char id;
 933
 934                        c = get_byte(&jpeg_buffer);
 935                        if (c == -1)
 936                                return;
 937                        id = c & 0xf;
 938                        /* nonzero means extended mode - not supported */
 939                        if ((c >> 4) & 0xf)
 940                                return;
 941                        for (i = 0; i < 64; ++i) {
 942                                c = get_byte(&jpeg_buffer);
 943                                if (c == -1)
 944                                        return;
 945                                word |= c << ((i % 4) * 8);
 946                                if ((i + 1) % 4 == 0) {
 947                                        writel(word, jpeg->regs +
 948                                        EXYNOS4_QTBL_CONTENT(id) + (i / 4) * 4);
 949                                        word = 0;
 950                                }
 951                        }
 952                        word = 0;
 953                }
 954        }
 955}
 956
 957/*
 958 * ============================================================================
 959 * Device file operations
 960 * ============================================================================
 961 */
 962
 963static int queue_init(void *priv, struct vb2_queue *src_vq,
 964                      struct vb2_queue *dst_vq);
 965static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
 966                                __u32 pixelformat, unsigned int fmt_type);
 967static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
 968
 969static int s5p_jpeg_open(struct file *file)
 970{
 971        struct s5p_jpeg *jpeg = video_drvdata(file);
 972        struct video_device *vfd = video_devdata(file);
 973        struct s5p_jpeg_ctx *ctx;
 974        struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
 975        int ret = 0;
 976
 977        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 978        if (!ctx)
 979                return -ENOMEM;
 980
 981        if (mutex_lock_interruptible(&jpeg->lock)) {
 982                ret = -ERESTARTSYS;
 983                goto free;
 984        }
 985
 986        v4l2_fh_init(&ctx->fh, vfd);
 987        /* Use separate control handler per file handle */
 988        ctx->fh.ctrl_handler = &ctx->ctrl_handler;
 989        file->private_data = &ctx->fh;
 990        v4l2_fh_add(&ctx->fh);
 991
 992        ctx->jpeg = jpeg;
 993        if (vfd == jpeg->vfd_encoder) {
 994                ctx->mode = S5P_JPEG_ENCODE;
 995                out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
 996                                                        FMT_TYPE_OUTPUT);
 997                cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
 998                                                        FMT_TYPE_CAPTURE);
 999        } else {
1000                ctx->mode = S5P_JPEG_DECODE;
1001                out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
1002                                                        FMT_TYPE_OUTPUT);
1003                cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
1004                                                        FMT_TYPE_CAPTURE);
1005                ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
1006        }
1007
1008        ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
1009        if (IS_ERR(ctx->fh.m2m_ctx)) {
1010                ret = PTR_ERR(ctx->fh.m2m_ctx);
1011                goto error;
1012        }
1013
1014        ctx->out_q.fmt = out_fmt;
1015        ctx->cap_q.fmt = cap_fmt;
1016
1017        ret = s5p_jpeg_controls_create(ctx);
1018        if (ret < 0)
1019                goto error;
1020
1021        mutex_unlock(&jpeg->lock);
1022        return 0;
1023
1024error:
1025        v4l2_fh_del(&ctx->fh);
1026        v4l2_fh_exit(&ctx->fh);
1027        mutex_unlock(&jpeg->lock);
1028free:
1029        kfree(ctx);
1030        return ret;
1031}
1032
1033static int s5p_jpeg_release(struct file *file)
1034{
1035        struct s5p_jpeg *jpeg = video_drvdata(file);
1036        struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1037
1038        mutex_lock(&jpeg->lock);
1039        v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1040        v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1041        v4l2_fh_del(&ctx->fh);
1042        v4l2_fh_exit(&ctx->fh);
1043        kfree(ctx);
1044        mutex_unlock(&jpeg->lock);
1045
1046        return 0;
1047}
1048
1049static const struct v4l2_file_operations s5p_jpeg_fops = {
1050        .owner          = THIS_MODULE,
1051        .open           = s5p_jpeg_open,
1052        .release        = s5p_jpeg_release,
1053        .poll           = v4l2_m2m_fop_poll,
1054        .unlocked_ioctl = video_ioctl2,
1055        .mmap           = v4l2_m2m_fop_mmap,
1056};
1057
1058/*
1059 * ============================================================================
1060 * video ioctl operations
1061 * ============================================================================
1062 */
1063
1064static int get_byte(struct s5p_jpeg_buffer *buf)
1065{
1066        if (buf->curr >= buf->size)
1067                return -1;
1068
1069        return ((unsigned char *)buf->data)[buf->curr++];
1070}
1071
1072static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
1073{
1074        unsigned int temp;
1075        int byte;
1076
1077        byte = get_byte(buf);
1078        if (byte == -1)
1079                return -1;
1080        temp = byte << 8;
1081        byte = get_byte(buf);
1082        if (byte == -1)
1083                return -1;
1084        *word = (unsigned int)byte | temp;
1085        return 0;
1086}
1087
1088static void skip(struct s5p_jpeg_buffer *buf, long len)
1089{
1090        if (len <= 0)
1091                return;
1092
1093        while (len--)
1094                get_byte(buf);
1095}
1096
1097static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
1098                               unsigned long buffer, unsigned long size,
1099                               struct s5p_jpeg_ctx *ctx)
1100{
1101        int c, components = 0, notfound, n_dht = 0, n_dqt = 0;
1102        unsigned int height, width, word, subsampling = 0, sos = 0, sof = 0,
1103                     sof_len = 0;
1104        unsigned int dht[S5P_JPEG_MAX_MARKER], dht_len[S5P_JPEG_MAX_MARKER],
1105                     dqt[S5P_JPEG_MAX_MARKER], dqt_len[S5P_JPEG_MAX_MARKER];
1106        long length;
1107        struct s5p_jpeg_buffer jpeg_buffer;
1108
1109        jpeg_buffer.size = size;
1110        jpeg_buffer.data = buffer;
1111        jpeg_buffer.curr = 0;
1112
1113        notfound = 1;
1114        while (notfound || !sos) {
1115                c = get_byte(&jpeg_buffer);
1116                if (c == -1)
1117                        return false;
1118                if (c != 0xff)
1119                        continue;
1120                do
1121                        c = get_byte(&jpeg_buffer);
1122                while (c == 0xff);
1123                if (c == -1)
1124                        return false;
1125                if (c == 0)
1126                        continue;
1127                length = 0;
1128                switch (c) {
1129                /* SOF0: baseline JPEG */
1130                case SOF0:
1131                        if (get_word_be(&jpeg_buffer, &word))
1132                                break;
1133                        length = (long)word - 2;
1134                        if (!length)
1135                                return false;
1136                        sof = jpeg_buffer.curr; /* after 0xffc0 */
1137                        sof_len = length;
1138                        if (get_byte(&jpeg_buffer) == -1)
1139                                break;
1140                        if (get_word_be(&jpeg_buffer, &height))
1141                                break;
1142                        if (get_word_be(&jpeg_buffer, &width))
1143                                break;
1144                        components = get_byte(&jpeg_buffer);
1145                        if (components == -1)
1146                                break;
1147
1148                        if (components == 1) {
1149                                subsampling = 0x33;
1150                        } else {
1151                                skip(&jpeg_buffer, 1);
1152                                subsampling = get_byte(&jpeg_buffer);
1153                                skip(&jpeg_buffer, 1);
1154                        }
1155                        if (components > 3)
1156                                return false;
1157                        skip(&jpeg_buffer, components * 2);
1158                        notfound = 0;
1159                        break;
1160
1161                case DQT:
1162                        if (get_word_be(&jpeg_buffer, &word))
1163                                break;
1164                        length = (long)word - 2;
1165                        if (!length)
1166                                return false;
1167                        if (n_dqt >= S5P_JPEG_MAX_MARKER)
1168                                return false;
1169                        dqt[n_dqt] = jpeg_buffer.curr; /* after 0xffdb */
1170                        dqt_len[n_dqt++] = length;
1171                        skip(&jpeg_buffer, length);
1172                        break;
1173
1174                case DHT:
1175                        if (get_word_be(&jpeg_buffer, &word))
1176                                break;
1177                        length = (long)word - 2;
1178                        if (!length)
1179                                return false;
1180                        if (n_dht >= S5P_JPEG_MAX_MARKER)
1181                                return false;
1182                        dht[n_dht] = jpeg_buffer.curr; /* after 0xffc4 */
1183                        dht_len[n_dht++] = length;
1184                        skip(&jpeg_buffer, length);
1185                        break;
1186
1187                case SOS:
1188                        sos = jpeg_buffer.curr - 2; /* 0xffda */
1189                        break;
1190
1191                /* skip payload-less markers */
1192                case RST ... RST + 7:
1193                case SOI:
1194                case EOI:
1195                case TEM:
1196                        break;
1197
1198                /* skip uninteresting payload markers */
1199                default:
1200                        if (get_word_be(&jpeg_buffer, &word))
1201                                break;
1202                        length = (long)word - 2;
1203                        skip(&jpeg_buffer, length);
1204                        break;
1205                }
1206        }
1207        result->w = width;
1208        result->h = height;
1209        result->sos = sos;
1210        result->dht.n = n_dht;
1211        while (n_dht--) {
1212                result->dht.marker[n_dht] = dht[n_dht];
1213                result->dht.len[n_dht] = dht_len[n_dht];
1214        }
1215        result->dqt.n = n_dqt;
1216        while (n_dqt--) {
1217                result->dqt.marker[n_dqt] = dqt[n_dqt];
1218                result->dqt.len[n_dqt] = dqt_len[n_dqt];
1219        }
1220        result->sof = sof;
1221        result->sof_len = sof_len;
1222        result->size = result->components = components;
1223
1224        switch (subsampling) {
1225        case 0x11:
1226                ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
1227                break;
1228        case 0x21:
1229                ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
1230                break;
1231        case 0x22:
1232                ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
1233                break;
1234        case 0x33:
1235                ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
1236                break;
1237        default:
1238                return false;
1239        }
1240
1241        return !notfound && sos;
1242}
1243
1244static int s5p_jpeg_querycap(struct file *file, void *priv,
1245                           struct v4l2_capability *cap)
1246{
1247        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1248
1249        if (ctx->mode == S5P_JPEG_ENCODE) {
1250                strlcpy(cap->driver, S5P_JPEG_M2M_NAME,
1251                        sizeof(cap->driver));
1252                strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
1253                        sizeof(cap->card));
1254        } else {
1255                strlcpy(cap->driver, S5P_JPEG_M2M_NAME,
1256                        sizeof(cap->driver));
1257                strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
1258                        sizeof(cap->card));
1259        }
1260        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
1261                 dev_name(ctx->jpeg->dev));
1262        cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
1263        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1264        return 0;
1265}
1266
1267static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
1268                    struct v4l2_fmtdesc *f, u32 type)
1269{
1270        int i, num = 0;
1271
1272        for (i = 0; i < n; ++i) {
1273                if (sjpeg_formats[i].flags & type) {
1274                        /* index-th format of type type found ? */
1275                        if (num == f->index)
1276                                break;
1277                        /* Correct type but haven't reached our index yet,
1278                         * just increment per-type index
1279                         */
1280                        ++num;
1281                }
1282        }
1283
1284        /* Format not found */
1285        if (i >= n)
1286                return -EINVAL;
1287
1288        strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
1289        f->pixelformat = sjpeg_formats[i].fourcc;
1290
1291        return 0;
1292}
1293
1294static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
1295                                   struct v4l2_fmtdesc *f)
1296{
1297        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1298
1299        if (ctx->mode == S5P_JPEG_ENCODE)
1300                return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1301                                SJPEG_FMT_FLAG_ENC_CAPTURE);
1302
1303        return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1304                                        SJPEG_FMT_FLAG_DEC_CAPTURE);
1305}
1306
1307static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
1308                                   struct v4l2_fmtdesc *f)
1309{
1310        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1311
1312        if (ctx->mode == S5P_JPEG_ENCODE)
1313                return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1314                                SJPEG_FMT_FLAG_ENC_OUTPUT);
1315
1316        return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1317                                        SJPEG_FMT_FLAG_DEC_OUTPUT);
1318}
1319
1320static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
1321                                          enum v4l2_buf_type type)
1322{
1323        if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1324                return &ctx->out_q;
1325        if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1326                return &ctx->cap_q;
1327
1328        return NULL;
1329}
1330
1331static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
1332{
1333        struct vb2_queue *vq;
1334        struct s5p_jpeg_q_data *q_data = NULL;
1335        struct v4l2_pix_format *pix = &f->fmt.pix;
1336        struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
1337
1338        vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1339        if (!vq)
1340                return -EINVAL;
1341
1342        if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1343            ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
1344                return -EINVAL;
1345        q_data = get_q_data(ct, f->type);
1346        BUG_ON(q_data == NULL);
1347
1348        pix->width = q_data->w;
1349        pix->height = q_data->h;
1350        pix->field = V4L2_FIELD_NONE;
1351        pix->pixelformat = q_data->fmt->fourcc;
1352        pix->bytesperline = 0;
1353        if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1354                u32 bpl = q_data->w;
1355
1356                if (q_data->fmt->colplanes == 1)
1357                        bpl = (bpl * q_data->fmt->depth) >> 3;
1358                pix->bytesperline = bpl;
1359        }
1360        pix->sizeimage = q_data->size;
1361
1362        return 0;
1363}
1364
1365static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
1366                                u32 pixelformat, unsigned int fmt_type)
1367{
1368        unsigned int k, fmt_flag;
1369
1370        if (ctx->mode == S5P_JPEG_ENCODE)
1371                fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1372                                SJPEG_FMT_FLAG_ENC_OUTPUT :
1373                                SJPEG_FMT_FLAG_ENC_CAPTURE;
1374        else
1375                fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1376                                SJPEG_FMT_FLAG_DEC_OUTPUT :
1377                                SJPEG_FMT_FLAG_DEC_CAPTURE;
1378
1379        for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
1380                struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
1381
1382                if (fmt->fourcc == pixelformat &&
1383                    fmt->flags & fmt_flag &&
1384                    fmt->flags & ctx->jpeg->variant->fmt_ver_flag) {
1385                        return fmt;
1386                }
1387        }
1388
1389        return NULL;
1390}
1391
1392static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx,
1393                                   u32 *w, unsigned int wmin, unsigned int wmax,
1394                                   unsigned int walign,
1395                                   u32 *h, unsigned int hmin, unsigned int hmax,
1396                                   unsigned int halign)
1397{
1398        int width, height, w_step, h_step;
1399
1400        width = *w;
1401        height = *h;
1402
1403        w_step = 1 << walign;
1404        h_step = 1 << halign;
1405
1406        if (ctx->jpeg->variant->hw3250_compat) {
1407                /*
1408                 * Rightmost and bottommost pixels are cropped by the
1409                 * Exynos3250/compatible JPEG IP for RGB formats, for the
1410                 * specific width and height values respectively. This
1411                 * assignment will result in v4l_bound_align_image returning
1412                 * dimensions reduced by 1 for the aforementioned cases.
1413                 */
1414                if (w_step == 4 && ((width & 3) == 1)) {
1415                        wmax = width;
1416                        hmax = height;
1417                }
1418        }
1419
1420        v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
1421
1422        if (*w < width && (*w + w_step) < wmax)
1423                *w += w_step;
1424        if (*h < height && (*h + h_step) < hmax)
1425                *h += h_step;
1426}
1427
1428static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
1429                          struct s5p_jpeg_ctx *ctx, int q_type)
1430{
1431        struct v4l2_pix_format *pix = &f->fmt.pix;
1432
1433        if (pix->field == V4L2_FIELD_ANY)
1434                pix->field = V4L2_FIELD_NONE;
1435        else if (pix->field != V4L2_FIELD_NONE)
1436                return -EINVAL;
1437
1438        /* V4L2 specification suggests the driver corrects the format struct
1439         * if any of the dimensions is unsupported
1440         */
1441        if (q_type == FMT_TYPE_OUTPUT)
1442                jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1443                                       S5P_JPEG_MAX_WIDTH, 0,
1444                                       &pix->height, S5P_JPEG_MIN_HEIGHT,
1445                                       S5P_JPEG_MAX_HEIGHT, 0);
1446        else
1447                jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1448                                       S5P_JPEG_MAX_WIDTH, fmt->h_align,
1449                                       &pix->height, S5P_JPEG_MIN_HEIGHT,
1450                                       S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1451
1452        if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1453                if (pix->sizeimage <= 0)
1454                        pix->sizeimage = PAGE_SIZE;
1455                pix->bytesperline = 0;
1456        } else {
1457                u32 bpl = pix->bytesperline;
1458
1459                if (fmt->colplanes > 1 && bpl < pix->width)
1460                        bpl = pix->width; /* planar */
1461
1462                if (fmt->colplanes == 1 && /* packed */
1463                    (bpl << 3) / fmt->depth < pix->width)
1464                        bpl = (pix->width * fmt->depth) >> 3;
1465
1466                pix->bytesperline = bpl;
1467                pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1468        }
1469
1470        return 0;
1471}
1472
1473static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1474                                  struct v4l2_format *f)
1475{
1476        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1477        struct v4l2_pix_format *pix = &f->fmt.pix;
1478        struct s5p_jpeg_fmt *fmt;
1479        int ret;
1480
1481        fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1482                                                FMT_TYPE_CAPTURE);
1483        if (!fmt) {
1484                v4l2_err(&ctx->jpeg->v4l2_dev,
1485                         "Fourcc format (0x%08x) invalid.\n",
1486                         f->fmt.pix.pixelformat);
1487                return -EINVAL;
1488        }
1489
1490        if (!ctx->jpeg->variant->hw_ex4_compat || ctx->mode != S5P_JPEG_DECODE)
1491                goto exit;
1492
1493        /*
1494         * The exynos4x12 device requires resulting YUV image
1495         * subsampling not to be lower than the input jpeg subsampling.
1496         * If this requirement is not met then downgrade the requested
1497         * capture format to the one with subsampling equal to the input jpeg.
1498         */
1499        if ((fmt->flags & SJPEG_FMT_NON_RGB) &&
1500            (fmt->subsampling < ctx->subsampling)) {
1501                ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1502                                                            fmt->fourcc,
1503                                                            &pix->pixelformat,
1504                                                            ctx);
1505                if (ret < 0)
1506                        pix->pixelformat = V4L2_PIX_FMT_GREY;
1507
1508                fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1509                                                        FMT_TYPE_CAPTURE);
1510        }
1511
1512        /*
1513         * Decompression of a JPEG file with 4:2:0 subsampling and odd
1514         * width to the YUV 4:2:0 compliant formats produces a raw image
1515         * with broken luma component. Adjust capture format to RGB565
1516         * in such a case.
1517         */
1518        if (ctx->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420 &&
1519            (ctx->out_q.w & 1) &&
1520            (pix->pixelformat == V4L2_PIX_FMT_NV12 ||
1521             pix->pixelformat == V4L2_PIX_FMT_NV21 ||
1522             pix->pixelformat == V4L2_PIX_FMT_YUV420)) {
1523                pix->pixelformat = V4L2_PIX_FMT_RGB565;
1524                fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1525                                                        FMT_TYPE_CAPTURE);
1526        }
1527
1528exit:
1529        return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
1530}
1531
1532static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1533                                  struct v4l2_format *f)
1534{
1535        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1536        struct s5p_jpeg_fmt *fmt;
1537
1538        fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1539                                                FMT_TYPE_OUTPUT);
1540        if (!fmt) {
1541                v4l2_err(&ctx->jpeg->v4l2_dev,
1542                         "Fourcc format (0x%08x) invalid.\n",
1543                         f->fmt.pix.pixelformat);
1544                return -EINVAL;
1545        }
1546
1547        return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
1548}
1549
1550static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx,
1551                                                struct v4l2_format *f,
1552                                                int fmt_depth)
1553{
1554        struct v4l2_pix_format *pix = &f->fmt.pix;
1555        u32 pix_fmt = f->fmt.pix.pixelformat;
1556        int w = pix->width, h = pix->height, wh_align;
1557        int padding = 0;
1558
1559        if (pix_fmt == V4L2_PIX_FMT_RGB32 ||
1560            pix_fmt == V4L2_PIX_FMT_RGB565 ||
1561            pix_fmt == V4L2_PIX_FMT_NV24 ||
1562            pix_fmt == V4L2_PIX_FMT_NV42 ||
1563            pix_fmt == V4L2_PIX_FMT_NV12 ||
1564            pix_fmt == V4L2_PIX_FMT_NV21 ||
1565            pix_fmt == V4L2_PIX_FMT_YUV420)
1566                wh_align = 4;
1567        else
1568                wh_align = 1;
1569
1570        jpeg_bound_align_image(ctx, &w, S5P_JPEG_MIN_WIDTH,
1571                               S5P_JPEG_MAX_WIDTH, wh_align,
1572                               &h, S5P_JPEG_MIN_HEIGHT,
1573                               S5P_JPEG_MAX_HEIGHT, wh_align);
1574
1575        if (ctx->jpeg->variant->version == SJPEG_EXYNOS4)
1576                padding = PAGE_SIZE;
1577
1578        return (w * h * fmt_depth >> 3) + padding;
1579}
1580
1581static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1582                                   struct v4l2_rect *r);
1583
1584static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1585{
1586        struct vb2_queue *vq;
1587        struct s5p_jpeg_q_data *q_data = NULL;
1588        struct v4l2_pix_format *pix = &f->fmt.pix;
1589        struct v4l2_ctrl *ctrl_subs;
1590        struct v4l2_rect scale_rect;
1591        unsigned int f_type;
1592
1593        vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1594        if (!vq)
1595                return -EINVAL;
1596
1597        q_data = get_q_data(ct, f->type);
1598        BUG_ON(q_data == NULL);
1599
1600        if (vb2_is_busy(vq)) {
1601                v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1602                return -EBUSY;
1603        }
1604
1605        f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1606                        FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1607
1608        q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
1609        q_data->w = pix->width;
1610        q_data->h = pix->height;
1611        if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1612                /*
1613                 * During encoding Exynos4x12 SoCs access wider memory area
1614                 * than it results from Image_x and Image_y values written to
1615                 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
1616                 * page fault calculate proper buffer size in such a case.
1617                 */
1618                if (ct->jpeg->variant->hw_ex4_compat &&
1619                    f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
1620                        q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
1621                                                        f,
1622                                                        q_data->fmt->depth);
1623                else
1624                        q_data->size = q_data->w * q_data->h *
1625                                                q_data->fmt->depth >> 3;
1626        } else {
1627                q_data->size = pix->sizeimage;
1628        }
1629
1630        if (f_type == FMT_TYPE_OUTPUT) {
1631                ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1632                                        V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1633                if (ctrl_subs)
1634                        v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
1635                ct->crop_altered = false;
1636        }
1637
1638        /*
1639         * For decoding init crop_rect with capture buffer dimmensions which
1640         * contain aligned dimensions of the input JPEG image and do it only
1641         * if crop rectangle hasn't been altered by the user space e.g. with
1642         * S_SELECTION ioctl. For encoding assign output buffer dimensions.
1643         */
1644        if (!ct->crop_altered &&
1645            ((ct->mode == S5P_JPEG_DECODE && f_type == FMT_TYPE_CAPTURE) ||
1646             (ct->mode == S5P_JPEG_ENCODE && f_type == FMT_TYPE_OUTPUT))) {
1647                ct->crop_rect.width = pix->width;
1648                ct->crop_rect.height = pix->height;
1649        }
1650
1651        /*
1652         * Prevent downscaling to YUV420 format by more than 2
1653         * for Exynos3250/compatible SoC as it produces broken raw image
1654         * in such cases.
1655         */
1656        if (ct->mode == S5P_JPEG_DECODE &&
1657            f_type == FMT_TYPE_CAPTURE &&
1658            ct->jpeg->variant->hw3250_compat &&
1659            pix->pixelformat == V4L2_PIX_FMT_YUV420 &&
1660            ct->scale_factor > 2) {
1661                scale_rect.width = ct->out_q.w / 2;
1662                scale_rect.height = ct->out_q.h / 2;
1663                exynos3250_jpeg_try_downscale(ct, &scale_rect);
1664        }
1665
1666        return 0;
1667}
1668
1669static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1670                                struct v4l2_format *f)
1671{
1672        int ret;
1673
1674        ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1675        if (ret)
1676                return ret;
1677
1678        return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1679}
1680
1681static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1682                                struct v4l2_format *f)
1683{
1684        int ret;
1685
1686        ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1687        if (ret)
1688                return ret;
1689
1690        return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1691}
1692
1693static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1694                                   struct v4l2_rect *r)
1695{
1696        int w_ratio, h_ratio, scale_factor, cur_ratio, i;
1697
1698        w_ratio = ctx->out_q.w / r->width;
1699        h_ratio = ctx->out_q.h / r->height;
1700
1701        scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio;
1702        scale_factor = clamp_val(scale_factor, 1, 8);
1703
1704        /* Align scale ratio to the nearest power of 2 */
1705        for (i = 0; i <= 3; ++i) {
1706                cur_ratio = 1 << i;
1707                if (scale_factor <= cur_ratio) {
1708                        ctx->scale_factor = cur_ratio;
1709                        break;
1710                }
1711        }
1712
1713        r->width = round_down(ctx->out_q.w / ctx->scale_factor, 2);
1714        r->height = round_down(ctx->out_q.h / ctx->scale_factor, 2);
1715
1716        ctx->crop_rect.width = r->width;
1717        ctx->crop_rect.height = r->height;
1718        ctx->crop_rect.left = 0;
1719        ctx->crop_rect.top = 0;
1720
1721        ctx->crop_altered = true;
1722
1723        return 0;
1724}
1725
1726/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1727static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1728{
1729        if (a->left < b->left || a->top < b->top)
1730                return 0;
1731        if (a->left + a->width > b->left + b->width)
1732                return 0;
1733        if (a->top + a->height > b->top + b->height)
1734                return 0;
1735
1736        return 1;
1737}
1738
1739static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,
1740                                   struct v4l2_rect *r)
1741{
1742        struct v4l2_rect base_rect;
1743        int w_step, h_step;
1744
1745        switch (ctx->cap_q.fmt->fourcc) {
1746        case V4L2_PIX_FMT_NV12:
1747        case V4L2_PIX_FMT_NV21:
1748                w_step = 1;
1749                h_step = 2;
1750                break;
1751        case V4L2_PIX_FMT_YUV420:
1752                w_step = 2;
1753                h_step = 2;
1754                break;
1755        default:
1756                w_step = 1;
1757                h_step = 1;
1758                break;
1759        }
1760
1761        base_rect.top = 0;
1762        base_rect.left = 0;
1763        base_rect.width = ctx->out_q.w;
1764        base_rect.height = ctx->out_q.h;
1765
1766        r->width = round_down(r->width, w_step);
1767        r->height = round_down(r->height, h_step);
1768        r->left = round_down(r->left, 2);
1769        r->top = round_down(r->top, 2);
1770
1771        if (!enclosed_rectangle(r, &base_rect))
1772                return -EINVAL;
1773
1774        ctx->crop_rect.left = r->left;
1775        ctx->crop_rect.top = r->top;
1776        ctx->crop_rect.width = r->width;
1777        ctx->crop_rect.height = r->height;
1778
1779        ctx->crop_altered = true;
1780
1781        return 0;
1782}
1783
1784/*
1785 * V4L2 controls
1786 */
1787
1788static int s5p_jpeg_g_selection(struct file *file, void *priv,
1789                         struct v4l2_selection *s)
1790{
1791        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1792
1793        if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
1794            s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1795                return -EINVAL;
1796
1797        /* For JPEG blob active == default == bounds */
1798        switch (s->target) {
1799        case V4L2_SEL_TGT_CROP:
1800        case V4L2_SEL_TGT_CROP_BOUNDS:
1801        case V4L2_SEL_TGT_CROP_DEFAULT:
1802        case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1803                s->r.width = ctx->out_q.w;
1804                s->r.height = ctx->out_q.h;
1805                s->r.left = 0;
1806                s->r.top = 0;
1807                break;
1808        case V4L2_SEL_TGT_COMPOSE:
1809        case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1810        case V4L2_SEL_TGT_COMPOSE_PADDED:
1811                s->r.width = ctx->crop_rect.width;
1812                s->r.height =  ctx->crop_rect.height;
1813                s->r.left = ctx->crop_rect.left;
1814                s->r.top = ctx->crop_rect.top;
1815                break;
1816        default:
1817                return -EINVAL;
1818        }
1819        return 0;
1820}
1821
1822/*
1823 * V4L2 controls
1824 */
1825static int s5p_jpeg_s_selection(struct file *file, void *fh,
1826                                  struct v4l2_selection *s)
1827{
1828        struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1829        struct v4l2_rect *rect = &s->r;
1830        int ret = -EINVAL;
1831
1832        if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1833                return -EINVAL;
1834
1835        if (s->target == V4L2_SEL_TGT_COMPOSE) {
1836                if (ctx->mode != S5P_JPEG_DECODE)
1837                        return -EINVAL;
1838                if (ctx->jpeg->variant->hw3250_compat)
1839                        ret = exynos3250_jpeg_try_downscale(ctx, rect);
1840        } else if (s->target == V4L2_SEL_TGT_CROP) {
1841                if (ctx->mode != S5P_JPEG_ENCODE)
1842                        return -EINVAL;
1843                if (ctx->jpeg->variant->hw3250_compat)
1844                        ret = exynos3250_jpeg_try_crop(ctx, rect);
1845        }
1846
1847        return ret;
1848}
1849
1850static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1851{
1852        struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1853        struct s5p_jpeg *jpeg = ctx->jpeg;
1854        unsigned long flags;
1855
1856        switch (ctrl->id) {
1857        case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1858                spin_lock_irqsave(&jpeg->slock, flags);
1859                ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
1860                spin_unlock_irqrestore(&jpeg->slock, flags);
1861                break;
1862        }
1863
1864        return 0;
1865}
1866
1867static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
1868{
1869        switch (ctx->jpeg->variant->version) {
1870        case SJPEG_S5P:
1871                return 0;
1872        case SJPEG_EXYNOS3250:
1873        case SJPEG_EXYNOS5420:
1874                /*
1875                 * The exynos3250/compatible device can produce JPEG image only
1876                 * of 4:4:4 subsampling when given RGB32 source image.
1877                 */
1878                if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
1879                        *ctrl_val = 0;
1880                break;
1881        case SJPEG_EXYNOS4:
1882                /*
1883                 * The exynos4x12 device requires input raw image fourcc
1884                 * to be V4L2_PIX_FMT_GREY if gray jpeg format
1885                 * is to be set.
1886                 */
1887                if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
1888                    *ctrl_val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY)
1889                        return -EINVAL;
1890                break;
1891        }
1892
1893        /*
1894         * The exynos4x12 and exynos3250/compatible devices require resulting
1895         * jpeg subsampling not to be lower than the input raw image
1896         * subsampling.
1897         */
1898        if (ctx->out_q.fmt->subsampling > *ctrl_val)
1899                *ctrl_val = ctx->out_q.fmt->subsampling;
1900
1901        return 0;
1902}
1903
1904static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1905{
1906        struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1907        unsigned long flags;
1908        int ret = 0;
1909
1910        spin_lock_irqsave(&ctx->jpeg->slock, flags);
1911
1912        if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING)
1913                ret = s5p_jpeg_adjust_subs_ctrl(ctx, &ctrl->val);
1914
1915        spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1916        return ret;
1917}
1918
1919static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
1920{
1921        struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1922        unsigned long flags;
1923
1924        spin_lock_irqsave(&ctx->jpeg->slock, flags);
1925
1926        switch (ctrl->id) {
1927        case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1928                ctx->compr_quality = ctrl->val;
1929                break;
1930        case V4L2_CID_JPEG_RESTART_INTERVAL:
1931                ctx->restart_interval = ctrl->val;
1932                break;
1933        case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1934                ctx->subsampling = ctrl->val;
1935                break;
1936        }
1937
1938        spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1939        return 0;
1940}
1941
1942static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1943        .g_volatile_ctrl        = s5p_jpeg_g_volatile_ctrl,
1944        .try_ctrl               = s5p_jpeg_try_ctrl,
1945        .s_ctrl                 = s5p_jpeg_s_ctrl,
1946};
1947
1948static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1949{
1950        unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1951        struct v4l2_ctrl *ctrl;
1952        int ret;
1953
1954        v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
1955
1956        if (ctx->mode == S5P_JPEG_ENCODE) {
1957                v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1958                                  V4L2_CID_JPEG_COMPRESSION_QUALITY,
1959                                  0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
1960
1961                v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1962                                  V4L2_CID_JPEG_RESTART_INTERVAL,
1963                                  0, 3, 0xffff, 0);
1964                if (ctx->jpeg->variant->version == SJPEG_S5P)
1965                        mask = ~0x06; /* 422, 420 */
1966        }
1967
1968        ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1969                                      V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1970                                      V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
1971                                      V4L2_JPEG_CHROMA_SUBSAMPLING_422);
1972
1973        if (ctx->ctrl_handler.error) {
1974                ret = ctx->ctrl_handler.error;
1975                goto error_free;
1976        }
1977
1978        if (ctx->mode == S5P_JPEG_DECODE)
1979                ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
1980                        V4L2_CTRL_FLAG_READ_ONLY;
1981
1982        ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1983        if (ret < 0)
1984                goto error_free;
1985
1986        return ret;
1987
1988error_free:
1989        v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1990        return ret;
1991}
1992
1993static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
1994        .vidioc_querycap                = s5p_jpeg_querycap,
1995
1996        .vidioc_enum_fmt_vid_cap        = s5p_jpeg_enum_fmt_vid_cap,
1997        .vidioc_enum_fmt_vid_out        = s5p_jpeg_enum_fmt_vid_out,
1998
1999        .vidioc_g_fmt_vid_cap           = s5p_jpeg_g_fmt,
2000        .vidioc_g_fmt_vid_out           = s5p_jpeg_g_fmt,
2001
2002        .vidioc_try_fmt_vid_cap         = s5p_jpeg_try_fmt_vid_cap,
2003        .vidioc_try_fmt_vid_out         = s5p_jpeg_try_fmt_vid_out,
2004
2005        .vidioc_s_fmt_vid_cap           = s5p_jpeg_s_fmt_vid_cap,
2006        .vidioc_s_fmt_vid_out           = s5p_jpeg_s_fmt_vid_out,
2007
2008        .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
2009        .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
2010        .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
2011        .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
2012
2013        .vidioc_streamon                = v4l2_m2m_ioctl_streamon,
2014        .vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
2015
2016        .vidioc_g_selection             = s5p_jpeg_g_selection,
2017        .vidioc_s_selection             = s5p_jpeg_s_selection,
2018};
2019
2020/*
2021 * ============================================================================
2022 * mem2mem callbacks
2023 * ============================================================================
2024 */
2025
2026static void s5p_jpeg_device_run(void *priv)
2027{
2028        struct s5p_jpeg_ctx *ctx = priv;
2029        struct s5p_jpeg *jpeg = ctx->jpeg;
2030        struct vb2_buffer *src_buf, *dst_buf;
2031        unsigned long src_addr, dst_addr, flags;
2032
2033        spin_lock_irqsave(&ctx->jpeg->slock, flags);
2034
2035        src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2036        dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2037        src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
2038        dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
2039
2040        s5p_jpeg_reset(jpeg->regs);
2041        s5p_jpeg_poweron(jpeg->regs);
2042        s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
2043        if (ctx->mode == S5P_JPEG_ENCODE) {
2044                if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
2045                        s5p_jpeg_input_raw_mode(jpeg->regs,
2046                                                        S5P_JPEG_RAW_IN_565);
2047                else
2048                        s5p_jpeg_input_raw_mode(jpeg->regs,
2049                                                        S5P_JPEG_RAW_IN_422);
2050                s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
2051                s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
2052                s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
2053                s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
2054                s5p_jpeg_imgadr(jpeg->regs, src_addr);
2055                s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
2056
2057                /* ultimately comes from sizeimage from userspace */
2058                s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
2059
2060                /* JPEG RGB to YCbCr conversion matrix */
2061                s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
2062                s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
2063                s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
2064                s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
2065                s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
2066                s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
2067                s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
2068                s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
2069                s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
2070
2071                /*
2072                 * JPEG IP allows storing 4 quantization tables
2073                 * We fill table 0 for luma and table 1 for chroma
2074                 */
2075                s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2076                s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2077                /* use table 0 for Y */
2078                s5p_jpeg_qtbl(jpeg->regs, 1, 0);
2079                /* use table 1 for Cb and Cr*/
2080                s5p_jpeg_qtbl(jpeg->regs, 2, 1);
2081                s5p_jpeg_qtbl(jpeg->regs, 3, 1);
2082
2083                /* Y, Cb, Cr use Huffman table 0 */
2084                s5p_jpeg_htbl_ac(jpeg->regs, 1);
2085                s5p_jpeg_htbl_dc(jpeg->regs, 1);
2086                s5p_jpeg_htbl_ac(jpeg->regs, 2);
2087                s5p_jpeg_htbl_dc(jpeg->regs, 2);
2088                s5p_jpeg_htbl_ac(jpeg->regs, 3);
2089                s5p_jpeg_htbl_dc(jpeg->regs, 3);
2090        } else { /* S5P_JPEG_DECODE */
2091                s5p_jpeg_rst_int_enable(jpeg->regs, true);
2092                s5p_jpeg_data_num_int_enable(jpeg->regs, true);
2093                s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
2094                if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
2095                        s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
2096                else
2097                        s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
2098                s5p_jpeg_jpgadr(jpeg->regs, src_addr);
2099                s5p_jpeg_imgadr(jpeg->regs, dst_addr);
2100        }
2101
2102        s5p_jpeg_start(jpeg->regs);
2103
2104        spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2105}
2106
2107static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
2108{
2109        struct s5p_jpeg *jpeg = ctx->jpeg;
2110        struct s5p_jpeg_fmt *fmt;
2111        struct vb2_buffer *vb;
2112        struct s5p_jpeg_addr jpeg_addr = {};
2113        u32 pix_size, padding_bytes = 0;
2114
2115        jpeg_addr.cb = 0;
2116        jpeg_addr.cr = 0;
2117
2118        pix_size = ctx->cap_q.w * ctx->cap_q.h;
2119
2120        if (ctx->mode == S5P_JPEG_ENCODE) {
2121                vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2122                fmt = ctx->out_q.fmt;
2123                if (ctx->out_q.w % 2 && fmt->h_align > 0)
2124                        padding_bytes = ctx->out_q.h;
2125        } else {
2126                fmt = ctx->cap_q.fmt;
2127                vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2128        }
2129
2130        jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
2131
2132        if (fmt->colplanes == 2) {
2133                jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
2134        } else if (fmt->colplanes == 3) {
2135                jpeg_addr.cb = jpeg_addr.y + pix_size;
2136                if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
2137                        jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
2138                else
2139                        jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
2140        }
2141
2142        exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
2143}
2144
2145static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
2146{
2147        struct s5p_jpeg *jpeg = ctx->jpeg;
2148        struct vb2_buffer *vb;
2149        unsigned int jpeg_addr = 0;
2150
2151        if (ctx->mode == S5P_JPEG_ENCODE)
2152                vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2153        else
2154                vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2155
2156        jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
2157        if (jpeg->variant->version == SJPEG_EXYNOS5433 &&
2158            ctx->mode == S5P_JPEG_DECODE)
2159                jpeg_addr += ctx->out_q.sos;
2160        exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
2161}
2162
2163static inline void exynos4_jpeg_set_img_fmt(void __iomem *base,
2164                                            unsigned int img_fmt)
2165{
2166        __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS4);
2167}
2168
2169static inline void exynos5433_jpeg_set_img_fmt(void __iomem *base,
2170                                               unsigned int img_fmt)
2171{
2172        __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS5433);
2173}
2174
2175static inline void exynos4_jpeg_set_enc_out_fmt(void __iomem *base,
2176                                                unsigned int out_fmt)
2177{
2178        __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS4);
2179}
2180
2181static inline void exynos5433_jpeg_set_enc_out_fmt(void __iomem *base,
2182                                                   unsigned int out_fmt)
2183{
2184        __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS5433);
2185}
2186
2187static void exynos4_jpeg_device_run(void *priv)
2188{
2189        struct s5p_jpeg_ctx *ctx = priv;
2190        struct s5p_jpeg *jpeg = ctx->jpeg;
2191        unsigned int bitstream_size;
2192        unsigned long flags;
2193
2194        spin_lock_irqsave(&jpeg->slock, flags);
2195
2196        if (ctx->mode == S5P_JPEG_ENCODE) {
2197                exynos4_jpeg_sw_reset(jpeg->regs);
2198                exynos4_jpeg_set_interrupt(jpeg->regs, jpeg->variant->version);
2199                exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
2200
2201                exynos4_jpeg_set_huff_tbl(jpeg->regs);
2202
2203                /*
2204                 * JPEG IP allows storing 4 quantization tables
2205                 * We fill table 0 for luma and table 1 for chroma
2206                 */
2207                exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2208                exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2209
2210                exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
2211                                                        ctx->compr_quality);
2212                exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
2213                                                        ctx->cap_q.h);
2214
2215                if (ctx->jpeg->variant->version == SJPEG_EXYNOS4) {
2216                        exynos4_jpeg_set_enc_out_fmt(jpeg->regs,
2217                                                     ctx->subsampling);
2218                        exynos4_jpeg_set_img_fmt(jpeg->regs,
2219                                                 ctx->out_q.fmt->fourcc);
2220                } else {
2221                        exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
2222                                                        ctx->subsampling);
2223                        exynos5433_jpeg_set_img_fmt(jpeg->regs,
2224                                                    ctx->out_q.fmt->fourcc);
2225                }
2226                exynos4_jpeg_set_img_addr(ctx);
2227                exynos4_jpeg_set_jpeg_addr(ctx);
2228                exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
2229                                                        ctx->out_q.fmt->fourcc);
2230        } else {
2231                exynos4_jpeg_sw_reset(jpeg->regs);
2232                exynos4_jpeg_set_interrupt(jpeg->regs,
2233                                           jpeg->variant->version);
2234                exynos4_jpeg_set_img_addr(ctx);
2235                exynos4_jpeg_set_jpeg_addr(ctx);
2236
2237                if (jpeg->variant->version == SJPEG_EXYNOS5433) {
2238                        exynos4_jpeg_parse_huff_tbl(ctx);
2239                        exynos4_jpeg_parse_decode_h_tbl(ctx);
2240
2241                        exynos4_jpeg_parse_q_tbl(ctx);
2242                        exynos4_jpeg_parse_decode_q_tbl(ctx);
2243
2244                        exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
2245
2246                        exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
2247                                        ctx->cap_q.h);
2248                        exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
2249                                                        ctx->subsampling);
2250                        exynos5433_jpeg_set_img_fmt(jpeg->regs,
2251                                                    ctx->cap_q.fmt->fourcc);
2252                        bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 16);
2253                } else {
2254                        exynos4_jpeg_set_img_fmt(jpeg->regs,
2255                                                 ctx->cap_q.fmt->fourcc);
2256                        bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
2257                }
2258
2259                exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
2260        }
2261
2262        exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
2263
2264        spin_unlock_irqrestore(&jpeg->slock, flags);
2265}
2266
2267static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
2268{
2269        struct s5p_jpeg *jpeg = ctx->jpeg;
2270        struct s5p_jpeg_fmt *fmt;
2271        struct vb2_buffer *vb;
2272        struct s5p_jpeg_addr jpeg_addr = {};
2273        u32 pix_size;
2274
2275        pix_size = ctx->cap_q.w * ctx->cap_q.h;
2276
2277        if (ctx->mode == S5P_JPEG_ENCODE) {
2278                vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2279                fmt = ctx->out_q.fmt;
2280        } else {
2281                vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2282                fmt = ctx->cap_q.fmt;
2283        }
2284
2285        jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
2286
2287        if (fmt->colplanes == 2) {
2288                jpeg_addr.cb = jpeg_addr.y + pix_size;
2289        } else if (fmt->colplanes == 3) {
2290                jpeg_addr.cb = jpeg_addr.y + pix_size;
2291                if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
2292                        jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
2293                else
2294                        jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
2295        }
2296
2297        exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr);
2298}
2299
2300static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
2301{
2302        struct s5p_jpeg *jpeg = ctx->jpeg;
2303        struct vb2_buffer *vb;
2304        unsigned int jpeg_addr = 0;
2305
2306        if (ctx->mode == S5P_JPEG_ENCODE)
2307                vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2308        else
2309                vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2310
2311        jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
2312        exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr);
2313}
2314
2315static void exynos3250_jpeg_device_run(void *priv)
2316{
2317        struct s5p_jpeg_ctx *ctx = priv;
2318        struct s5p_jpeg *jpeg = ctx->jpeg;
2319        unsigned long flags;
2320
2321        spin_lock_irqsave(&ctx->jpeg->slock, flags);
2322
2323        exynos3250_jpeg_reset(jpeg->regs);
2324        exynos3250_jpeg_set_dma_num(jpeg->regs);
2325        exynos3250_jpeg_poweron(jpeg->regs);
2326        exynos3250_jpeg_clk_set(jpeg->regs);
2327        exynos3250_jpeg_proc_mode(jpeg->regs, ctx->mode);
2328
2329        if (ctx->mode == S5P_JPEG_ENCODE) {
2330                exynos3250_jpeg_input_raw_fmt(jpeg->regs,
2331                                              ctx->out_q.fmt->fourcc);
2332                exynos3250_jpeg_dri(jpeg->regs, ctx->restart_interval);
2333
2334                /*
2335                 * JPEG IP allows storing 4 quantization tables
2336                 * We fill table 0 for luma and table 1 for chroma
2337                 */
2338                s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2339                s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2340                /* use table 0 for Y */
2341                exynos3250_jpeg_qtbl(jpeg->regs, 1, 0);
2342                /* use table 1 for Cb and Cr*/
2343                exynos3250_jpeg_qtbl(jpeg->regs, 2, 1);
2344                exynos3250_jpeg_qtbl(jpeg->regs, 3, 1);
2345
2346                /*
2347                 * Some SoCs require setting Huffman tables before each run
2348                 */
2349                if (jpeg->variant->htbl_reinit) {
2350                        s5p_jpeg_set_hdctbl(jpeg->regs);
2351                        s5p_jpeg_set_hdctblg(jpeg->regs);
2352                        s5p_jpeg_set_hactbl(jpeg->regs);
2353                        s5p_jpeg_set_hactblg(jpeg->regs);
2354                }
2355
2356                /* Y, Cb, Cr use Huffman table 0 */
2357                exynos3250_jpeg_htbl_ac(jpeg->regs, 1);
2358                exynos3250_jpeg_htbl_dc(jpeg->regs, 1);
2359                exynos3250_jpeg_htbl_ac(jpeg->regs, 2);
2360                exynos3250_jpeg_htbl_dc(jpeg->regs, 2);
2361                exynos3250_jpeg_htbl_ac(jpeg->regs, 3);
2362                exynos3250_jpeg_htbl_dc(jpeg->regs, 3);
2363
2364                exynos3250_jpeg_set_x(jpeg->regs, ctx->crop_rect.width);
2365                exynos3250_jpeg_set_y(jpeg->regs, ctx->crop_rect.height);
2366                exynos3250_jpeg_stride(jpeg->regs, ctx->out_q.fmt->fourcc,
2367                                                                ctx->out_q.w);
2368                exynos3250_jpeg_offset(jpeg->regs, ctx->crop_rect.left,
2369                                                        ctx->crop_rect.top);
2370                exynos3250_jpeg_set_img_addr(ctx);
2371                exynos3250_jpeg_set_jpeg_addr(ctx);
2372                exynos3250_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
2373
2374                /* ultimately comes from sizeimage from userspace */
2375                exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size);
2376
2377                if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565 ||
2378                    ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565X ||
2379                    ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
2380                        exynos3250_jpeg_set_y16(jpeg->regs, true);
2381        } else {
2382                exynos3250_jpeg_set_img_addr(ctx);
2383                exynos3250_jpeg_set_jpeg_addr(ctx);
2384                exynos3250_jpeg_stride(jpeg->regs, ctx->cap_q.fmt->fourcc,
2385                                                                ctx->cap_q.w);
2386                exynos3250_jpeg_offset(jpeg->regs, 0, 0);
2387                exynos3250_jpeg_dec_scaling_ratio(jpeg->regs,
2388                                                        ctx->scale_factor);
2389                exynos3250_jpeg_dec_stream_size(jpeg->regs, ctx->out_q.size);
2390                exynos3250_jpeg_output_raw_fmt(jpeg->regs,
2391                                                ctx->cap_q.fmt->fourcc);
2392        }
2393
2394        exynos3250_jpeg_interrupts_enable(jpeg->regs);
2395
2396        /* JPEG RGB to YCbCr conversion matrix */
2397        exynos3250_jpeg_coef(jpeg->regs, ctx->mode);
2398
2399        exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT);
2400        jpeg->irq_status = 0;
2401        exynos3250_jpeg_start(jpeg->regs);
2402
2403        spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2404}
2405
2406static int s5p_jpeg_job_ready(void *priv)
2407{
2408        struct s5p_jpeg_ctx *ctx = priv;
2409
2410        if (ctx->mode == S5P_JPEG_DECODE)
2411                return ctx->hdr_parsed;
2412        return 1;
2413}
2414
2415static void s5p_jpeg_job_abort(void *priv)
2416{
2417}
2418
2419static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
2420        .device_run     = s5p_jpeg_device_run,
2421        .job_ready      = s5p_jpeg_job_ready,
2422        .job_abort      = s5p_jpeg_job_abort,
2423};
2424
2425static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = {
2426        .device_run     = exynos3250_jpeg_device_run,
2427        .job_ready      = s5p_jpeg_job_ready,
2428        .job_abort      = s5p_jpeg_job_abort,
2429};
2430
2431static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
2432        .device_run     = exynos4_jpeg_device_run,
2433        .job_ready      = s5p_jpeg_job_ready,
2434        .job_abort      = s5p_jpeg_job_abort,
2435};
2436
2437/*
2438 * ============================================================================
2439 * Queue operations
2440 * ============================================================================
2441 */
2442
2443static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
2444                           unsigned int *nbuffers, unsigned int *nplanes,
2445                           unsigned int sizes[], struct device *alloc_devs[])
2446{
2447        struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
2448        struct s5p_jpeg_q_data *q_data = NULL;
2449        unsigned int size, count = *nbuffers;
2450
2451        q_data = get_q_data(ctx, vq->type);
2452        BUG_ON(q_data == NULL);
2453
2454        size = q_data->size;
2455
2456        /*
2457         * header is parsed during decoding and parsed information stored
2458         * in the context so we do not allow another buffer to overwrite it
2459         */
2460        if (ctx->mode == S5P_JPEG_DECODE)
2461                count = 1;
2462
2463        *nbuffers = count;
2464        *nplanes = 1;
2465        sizes[0] = size;
2466
2467        return 0;
2468}
2469
2470static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
2471{
2472        struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2473        struct s5p_jpeg_q_data *q_data = NULL;
2474
2475        q_data = get_q_data(ctx, vb->vb2_queue->type);
2476        BUG_ON(q_data == NULL);
2477
2478        if (vb2_plane_size(vb, 0) < q_data->size) {
2479                pr_err("%s data will not fit into plane (%lu < %lu)\n",
2480                                __func__, vb2_plane_size(vb, 0),
2481                                (long)q_data->size);
2482                return -EINVAL;
2483        }
2484
2485        vb2_set_plane_payload(vb, 0, q_data->size);
2486
2487        return 0;
2488}
2489
2490static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
2491{
2492        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
2493        struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2494
2495        if (ctx->mode == S5P_JPEG_DECODE &&
2496            vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
2497                struct s5p_jpeg_q_data tmp, *q_data;
2498
2499                ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
2500                     (unsigned long)vb2_plane_vaddr(vb, 0),
2501                     min((unsigned long)ctx->out_q.size,
2502                         vb2_get_plane_payload(vb, 0)), ctx);
2503                if (!ctx->hdr_parsed) {
2504                        vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
2505                        return;
2506                }
2507
2508                q_data = &ctx->out_q;
2509                q_data->w = tmp.w;
2510                q_data->h = tmp.h;
2511                q_data->sos = tmp.sos;
2512                memcpy(q_data->dht.marker, tmp.dht.marker,
2513                       sizeof(tmp.dht.marker));
2514                memcpy(q_data->dht.len, tmp.dht.len, sizeof(tmp.dht.len));
2515                q_data->dht.n = tmp.dht.n;
2516                memcpy(q_data->dqt.marker, tmp.dqt.marker,
2517                       sizeof(tmp.dqt.marker));
2518                memcpy(q_data->dqt.len, tmp.dqt.len, sizeof(tmp.dqt.len));
2519                q_data->dqt.n = tmp.dqt.n;
2520                q_data->sof = tmp.sof;
2521                q_data->sof_len = tmp.sof_len;
2522
2523                q_data = &ctx->cap_q;
2524                q_data->w = tmp.w;
2525                q_data->h = tmp.h;
2526        }
2527
2528        v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
2529}
2530
2531static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
2532{
2533        struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2534        int ret;
2535
2536        ret = pm_runtime_get_sync(ctx->jpeg->dev);
2537
2538        return ret > 0 ? 0 : ret;
2539}
2540
2541static void s5p_jpeg_stop_streaming(struct vb2_queue *q)
2542{
2543        struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2544
2545        pm_runtime_put(ctx->jpeg->dev);
2546}
2547
2548static const struct vb2_ops s5p_jpeg_qops = {
2549        .queue_setup            = s5p_jpeg_queue_setup,
2550        .buf_prepare            = s5p_jpeg_buf_prepare,
2551        .buf_queue              = s5p_jpeg_buf_queue,
2552        .wait_prepare           = vb2_ops_wait_prepare,
2553        .wait_finish            = vb2_ops_wait_finish,
2554        .start_streaming        = s5p_jpeg_start_streaming,
2555        .stop_streaming         = s5p_jpeg_stop_streaming,
2556};
2557
2558static int queue_init(void *priv, struct vb2_queue *src_vq,
2559                      struct vb2_queue *dst_vq)
2560{
2561        struct s5p_jpeg_ctx *ctx = priv;
2562        int ret;
2563
2564        src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2565        src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2566        src_vq->drv_priv = ctx;
2567        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2568        src_vq->ops = &s5p_jpeg_qops;
2569        src_vq->mem_ops = &vb2_dma_contig_memops;
2570        src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2571        src_vq->lock = &ctx->jpeg->lock;
2572        src_vq->dev = ctx->jpeg->dev;
2573
2574        ret = vb2_queue_init(src_vq);
2575        if (ret)
2576                return ret;
2577
2578        dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2579        dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2580        dst_vq->drv_priv = ctx;
2581        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2582        dst_vq->ops = &s5p_jpeg_qops;
2583        dst_vq->mem_ops = &vb2_dma_contig_memops;
2584        dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2585        dst_vq->lock = &ctx->jpeg->lock;
2586        dst_vq->dev = ctx->jpeg->dev;
2587
2588        return vb2_queue_init(dst_vq);
2589}
2590
2591/*
2592 * ============================================================================
2593 * ISR
2594 * ============================================================================
2595 */
2596
2597static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
2598{
2599        struct s5p_jpeg *jpeg = dev_id;
2600        struct s5p_jpeg_ctx *curr_ctx;
2601        struct vb2_v4l2_buffer *src_buf, *dst_buf;
2602        unsigned long payload_size = 0;
2603        enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2604        bool enc_jpeg_too_large = false;
2605        bool timer_elapsed = false;
2606        bool op_completed = false;
2607
2608        spin_lock(&jpeg->slock);
2609
2610        curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2611
2612        src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2613        dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2614
2615        if (curr_ctx->mode == S5P_JPEG_ENCODE)
2616                enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
2617        timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
2618        op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
2619        if (curr_ctx->mode == S5P_JPEG_DECODE)
2620                op_completed = op_completed &&
2621                                        s5p_jpeg_stream_stat_ok(jpeg->regs);
2622
2623        if (enc_jpeg_too_large) {
2624                state = VB2_BUF_STATE_ERROR;
2625                s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
2626        } else if (timer_elapsed) {
2627                state = VB2_BUF_STATE_ERROR;
2628                s5p_jpeg_clear_timer_stat(jpeg->regs);
2629        } else if (!op_completed) {
2630                state = VB2_BUF_STATE_ERROR;
2631        } else {
2632                payload_size = s5p_jpeg_compressed_size(jpeg->regs);
2633        }
2634
2635        dst_buf->timecode = src_buf->timecode;
2636        dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
2637        dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2638        dst_buf->flags |=
2639                src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2640
2641        v4l2_m2m_buf_done(src_buf, state);
2642        if (curr_ctx->mode == S5P_JPEG_ENCODE)
2643                vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
2644        v4l2_m2m_buf_done(dst_buf, state);
2645        v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2646
2647        curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
2648        spin_unlock(&jpeg->slock);
2649
2650        s5p_jpeg_clear_int(jpeg->regs);
2651
2652        return IRQ_HANDLED;
2653}
2654
2655static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
2656{
2657        unsigned int int_status;
2658        struct vb2_v4l2_buffer *src_vb, *dst_vb;
2659        struct s5p_jpeg *jpeg = priv;
2660        struct s5p_jpeg_ctx *curr_ctx;
2661        unsigned long payload_size = 0;
2662
2663        spin_lock(&jpeg->slock);
2664
2665        curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2666
2667        src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2668        dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2669
2670        int_status = exynos4_jpeg_get_int_status(jpeg->regs);
2671
2672        if (int_status) {
2673                switch (int_status & 0x1f) {
2674                case 0x1:
2675                        jpeg->irq_ret = ERR_PROT;
2676                        break;
2677                case 0x2:
2678                        jpeg->irq_ret = OK_ENC_OR_DEC;
2679                        break;
2680                case 0x4:
2681                        jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
2682                        break;
2683                case 0x8:
2684                        jpeg->irq_ret = ERR_MULTI_SCAN;
2685                        break;
2686                case 0x10:
2687                        jpeg->irq_ret = ERR_FRAME;
2688                        break;
2689                default:
2690                        jpeg->irq_ret = ERR_UNKNOWN;
2691                        break;
2692                }
2693        } else {
2694                jpeg->irq_ret = ERR_UNKNOWN;
2695        }
2696
2697        if (jpeg->irq_ret == OK_ENC_OR_DEC) {
2698                if (curr_ctx->mode == S5P_JPEG_ENCODE) {
2699                        payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
2700                        vb2_set_plane_payload(&dst_vb->vb2_buf,
2701                                        0, payload_size);
2702                }
2703                v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
2704                v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
2705        } else {
2706                v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
2707                v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
2708        }
2709
2710        v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2711        if (jpeg->variant->version == SJPEG_EXYNOS4)
2712                curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
2713
2714        spin_unlock(&jpeg->slock);
2715        return IRQ_HANDLED;
2716}
2717
2718static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
2719{
2720        struct s5p_jpeg *jpeg = dev_id;
2721        struct s5p_jpeg_ctx *curr_ctx;
2722        struct vb2_v4l2_buffer *src_buf, *dst_buf;
2723        unsigned long payload_size = 0;
2724        enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2725        bool interrupt_timeout = false;
2726        u32 irq_status;
2727
2728        spin_lock(&jpeg->slock);
2729
2730        irq_status = exynos3250_jpeg_get_timer_status(jpeg->regs);
2731        if (irq_status & EXYNOS3250_TIMER_INT_STAT) {
2732                exynos3250_jpeg_clear_timer_status(jpeg->regs);
2733                interrupt_timeout = true;
2734                dev_err(jpeg->dev, "Interrupt timeout occurred.\n");
2735        }
2736
2737        irq_status = exynos3250_jpeg_get_int_status(jpeg->regs);
2738        exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status);
2739
2740        jpeg->irq_status |= irq_status;
2741
2742        curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2743
2744        if (!curr_ctx)
2745                goto exit_unlock;
2746
2747        if ((irq_status & EXYNOS3250_HEADER_STAT) &&
2748            (curr_ctx->mode == S5P_JPEG_DECODE)) {
2749                exynos3250_jpeg_rstart(jpeg->regs);
2750                goto exit_unlock;
2751        }
2752
2753        if (jpeg->irq_status & (EXYNOS3250_JPEG_DONE |
2754                                EXYNOS3250_WDMA_DONE |
2755                                EXYNOS3250_RDMA_DONE |
2756                                EXYNOS3250_RESULT_STAT))
2757                payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
2758        else if (interrupt_timeout)
2759                state = VB2_BUF_STATE_ERROR;
2760        else
2761                goto exit_unlock;
2762
2763        src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2764        dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2765
2766        dst_buf->timecode = src_buf->timecode;
2767        dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
2768
2769        v4l2_m2m_buf_done(src_buf, state);
2770        if (curr_ctx->mode == S5P_JPEG_ENCODE)
2771                vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
2772        v4l2_m2m_buf_done(dst_buf, state);
2773        v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2774
2775        curr_ctx->subsampling =
2776                        exynos3250_jpeg_get_subsampling_mode(jpeg->regs);
2777exit_unlock:
2778        spin_unlock(&jpeg->slock);
2779        return IRQ_HANDLED;
2780}
2781
2782static void *jpeg_get_drv_data(struct device *dev);
2783
2784/*
2785 * ============================================================================
2786 * Driver basic infrastructure
2787 * ============================================================================
2788 */
2789
2790static int s5p_jpeg_probe(struct platform_device *pdev)
2791{
2792        struct s5p_jpeg *jpeg;
2793        struct resource *res;
2794        int i, ret;
2795
2796        /* JPEG IP abstraction struct */
2797        jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
2798        if (!jpeg)
2799                return -ENOMEM;
2800
2801        jpeg->variant = jpeg_get_drv_data(&pdev->dev);
2802
2803        mutex_init(&jpeg->lock);
2804        spin_lock_init(&jpeg->slock);
2805        jpeg->dev = &pdev->dev;
2806
2807        /* memory-mapped registers */
2808        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2809
2810        jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
2811        if (IS_ERR(jpeg->regs))
2812                return PTR_ERR(jpeg->regs);
2813
2814        /* interrupt service routine registration */
2815        jpeg->irq = ret = platform_get_irq(pdev, 0);
2816        if (ret < 0) {
2817                dev_err(&pdev->dev, "cannot find IRQ\n");
2818                return ret;
2819        }
2820
2821        ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
2822                                0, dev_name(&pdev->dev), jpeg);
2823        if (ret) {
2824                dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
2825                return ret;
2826        }
2827
2828        /* clocks */
2829        for (i = 0; i < jpeg->variant->num_clocks; i++) {
2830                jpeg->clocks[i] = devm_clk_get(&pdev->dev,
2831                                              jpeg->variant->clk_names[i]);
2832                if (IS_ERR(jpeg->clocks[i])) {
2833                        dev_err(&pdev->dev, "failed to get clock: %s\n",
2834                                jpeg->variant->clk_names[i]);
2835                        return PTR_ERR(jpeg->clocks[i]);
2836                }
2837        }
2838
2839        /* v4l2 device */
2840        ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
2841        if (ret) {
2842                dev_err(&pdev->dev, "Failed to register v4l2 device\n");
2843                return ret;
2844        }
2845
2846        /* mem2mem device */
2847        jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops);
2848        if (IS_ERR(jpeg->m2m_dev)) {
2849                v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
2850                ret = PTR_ERR(jpeg->m2m_dev);
2851                goto device_register_rollback;
2852        }
2853
2854        vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
2855
2856        /* JPEG encoder /dev/videoX node */
2857        jpeg->vfd_encoder = video_device_alloc();
2858        if (!jpeg->vfd_encoder) {
2859                v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
2860                ret = -ENOMEM;
2861                goto m2m_init_rollback;
2862        }
2863        snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
2864                                "%s-enc", S5P_JPEG_M2M_NAME);
2865        jpeg->vfd_encoder->fops         = &s5p_jpeg_fops;
2866        jpeg->vfd_encoder->ioctl_ops    = &s5p_jpeg_ioctl_ops;
2867        jpeg->vfd_encoder->minor        = -1;
2868        jpeg->vfd_encoder->release      = video_device_release;
2869        jpeg->vfd_encoder->lock         = &jpeg->lock;
2870        jpeg->vfd_encoder->v4l2_dev     = &jpeg->v4l2_dev;
2871        jpeg->vfd_encoder->vfl_dir      = VFL_DIR_M2M;
2872
2873        ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
2874        if (ret) {
2875                v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2876                video_device_release(jpeg->vfd_encoder);
2877                goto m2m_init_rollback;
2878        }
2879
2880        video_set_drvdata(jpeg->vfd_encoder, jpeg);
2881        v4l2_info(&jpeg->v4l2_dev,
2882                  "encoder device registered as /dev/video%d\n",
2883                  jpeg->vfd_encoder->num);
2884
2885        /* JPEG decoder /dev/videoX node */
2886        jpeg->vfd_decoder = video_device_alloc();
2887        if (!jpeg->vfd_decoder) {
2888                v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
2889                ret = -ENOMEM;
2890                goto enc_vdev_register_rollback;
2891        }
2892        snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
2893                                "%s-dec", S5P_JPEG_M2M_NAME);
2894        jpeg->vfd_decoder->fops         = &s5p_jpeg_fops;
2895        jpeg->vfd_decoder->ioctl_ops    = &s5p_jpeg_ioctl_ops;
2896        jpeg->vfd_decoder->minor        = -1;
2897        jpeg->vfd_decoder->release      = video_device_release;
2898        jpeg->vfd_decoder->lock         = &jpeg->lock;
2899        jpeg->vfd_decoder->v4l2_dev     = &jpeg->v4l2_dev;
2900        jpeg->vfd_decoder->vfl_dir      = VFL_DIR_M2M;
2901
2902        ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
2903        if (ret) {
2904                v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2905                video_device_release(jpeg->vfd_decoder);
2906                goto enc_vdev_register_rollback;
2907        }
2908
2909        video_set_drvdata(jpeg->vfd_decoder, jpeg);
2910        v4l2_info(&jpeg->v4l2_dev,
2911                  "decoder device registered as /dev/video%d\n",
2912                  jpeg->vfd_decoder->num);
2913
2914        /* final statements & power management */
2915        platform_set_drvdata(pdev, jpeg);
2916
2917        pm_runtime_enable(&pdev->dev);
2918
2919        v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
2920
2921        return 0;
2922
2923enc_vdev_register_rollback:
2924        video_unregister_device(jpeg->vfd_encoder);
2925
2926m2m_init_rollback:
2927        v4l2_m2m_release(jpeg->m2m_dev);
2928
2929device_register_rollback:
2930        v4l2_device_unregister(&jpeg->v4l2_dev);
2931
2932        return ret;
2933}
2934
2935static int s5p_jpeg_remove(struct platform_device *pdev)
2936{
2937        struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
2938        int i;
2939
2940        pm_runtime_disable(jpeg->dev);
2941
2942        video_unregister_device(jpeg->vfd_decoder);
2943        video_unregister_device(jpeg->vfd_encoder);
2944        vb2_dma_contig_clear_max_seg_size(&pdev->dev);
2945        v4l2_m2m_release(jpeg->m2m_dev);
2946        v4l2_device_unregister(&jpeg->v4l2_dev);
2947
2948        if (!pm_runtime_status_suspended(&pdev->dev)) {
2949                for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
2950                        clk_disable_unprepare(jpeg->clocks[i]);
2951        }
2952
2953        return 0;
2954}
2955
2956#ifdef CONFIG_PM
2957static int s5p_jpeg_runtime_suspend(struct device *dev)
2958{
2959        struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2960        int i;
2961
2962        for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
2963                clk_disable_unprepare(jpeg->clocks[i]);
2964
2965        return 0;
2966}
2967
2968static int s5p_jpeg_runtime_resume(struct device *dev)
2969{
2970        struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2971        unsigned long flags;
2972        int i, ret;
2973
2974        for (i = 0; i < jpeg->variant->num_clocks; i++) {
2975                ret = clk_prepare_enable(jpeg->clocks[i]);
2976                if (ret) {
2977                        while (--i > 0)
2978                                clk_disable_unprepare(jpeg->clocks[i]);
2979                        return ret;
2980                }
2981        }
2982
2983        spin_lock_irqsave(&jpeg->slock, flags);
2984
2985        /*
2986         * JPEG IP allows storing two Huffman tables for each component.
2987         * We fill table 0 for each component and do this here only
2988         * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC
2989         * require programming their Huffman tables each time the encoding
2990         * process is initialized, and thus it is accomplished in the
2991         * device_run callback of m2m_ops.
2992         */
2993        if (!jpeg->variant->htbl_reinit) {
2994                s5p_jpeg_set_hdctbl(jpeg->regs);
2995                s5p_jpeg_set_hdctblg(jpeg->regs);
2996                s5p_jpeg_set_hactbl(jpeg->regs);
2997                s5p_jpeg_set_hactblg(jpeg->regs);
2998        }
2999
3000        spin_unlock_irqrestore(&jpeg->slock, flags);
3001
3002        return 0;
3003}
3004#endif /* CONFIG_PM */
3005
3006static const struct dev_pm_ops s5p_jpeg_pm_ops = {
3007        SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
3008                                pm_runtime_force_resume)
3009        SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume,
3010                           NULL)
3011};
3012
3013static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
3014        .version        = SJPEG_S5P,
3015        .jpeg_irq       = s5p_jpeg_irq,
3016        .m2m_ops        = &s5p_jpeg_m2m_ops,
3017        .fmt_ver_flag   = SJPEG_FMT_FLAG_S5P,
3018        .clk_names      = {"jpeg"},
3019        .num_clocks     = 1,
3020};
3021
3022static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
3023        .version        = SJPEG_EXYNOS3250,
3024        .jpeg_irq       = exynos3250_jpeg_irq,
3025        .m2m_ops        = &exynos3250_jpeg_m2m_ops,
3026        .fmt_ver_flag   = SJPEG_FMT_FLAG_EXYNOS3250,
3027        .hw3250_compat  = 1,
3028        .clk_names      = {"jpeg", "sclk"},
3029        .num_clocks     = 2,
3030};
3031
3032static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
3033        .version        = SJPEG_EXYNOS4,
3034        .jpeg_irq       = exynos4_jpeg_irq,
3035        .m2m_ops        = &exynos4_jpeg_m2m_ops,
3036        .fmt_ver_flag   = SJPEG_FMT_FLAG_EXYNOS4,
3037        .htbl_reinit    = 1,
3038        .clk_names      = {"jpeg"},
3039        .num_clocks     = 1,
3040        .hw_ex4_compat  = 1,
3041};
3042
3043static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = {
3044        .version        = SJPEG_EXYNOS5420,
3045        .jpeg_irq       = exynos3250_jpeg_irq,          /* intentionally 3250 */
3046        .m2m_ops        = &exynos3250_jpeg_m2m_ops,     /* intentionally 3250 */
3047        .fmt_ver_flag   = SJPEG_FMT_FLAG_EXYNOS3250,    /* intentionally 3250 */
3048        .hw3250_compat  = 1,
3049        .htbl_reinit    = 1,
3050        .clk_names      = {"jpeg"},
3051        .num_clocks     = 1,
3052};
3053
3054static struct s5p_jpeg_variant exynos5433_jpeg_drvdata = {
3055        .version        = SJPEG_EXYNOS5433,
3056        .jpeg_irq       = exynos4_jpeg_irq,
3057        .m2m_ops        = &exynos4_jpeg_m2m_ops,
3058        .fmt_ver_flag   = SJPEG_FMT_FLAG_EXYNOS4,
3059        .htbl_reinit    = 1,
3060        .clk_names      = {"pclk", "aclk", "aclk_xiu", "sclk"},
3061        .num_clocks     = 4,
3062        .hw_ex4_compat  = 1,
3063};
3064
3065static const struct of_device_id samsung_jpeg_match[] = {
3066        {
3067                .compatible = "samsung,s5pv210-jpeg",
3068                .data = &s5p_jpeg_drvdata,
3069        }, {
3070                .compatible = "samsung,exynos3250-jpeg",
3071                .data = &exynos3250_jpeg_drvdata,
3072        }, {
3073                .compatible = "samsung,exynos4210-jpeg",
3074                .data = &exynos4_jpeg_drvdata,
3075        }, {
3076                .compatible = "samsung,exynos4212-jpeg",
3077                .data = &exynos4_jpeg_drvdata,
3078        }, {
3079                .compatible = "samsung,exynos5420-jpeg",
3080                .data = &exynos5420_jpeg_drvdata,
3081        }, {
3082                .compatible = "samsung,exynos5433-jpeg",
3083                .data = &exynos5433_jpeg_drvdata,
3084        },
3085        {},
3086};
3087
3088MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
3089
3090static void *jpeg_get_drv_data(struct device *dev)
3091{
3092        struct s5p_jpeg_variant *driver_data = NULL;
3093        const struct of_device_id *match;
3094
3095        if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
3096                return &s5p_jpeg_drvdata;
3097
3098        match = of_match_node(samsung_jpeg_match, dev->of_node);
3099
3100        if (match)
3101                driver_data = (struct s5p_jpeg_variant *)match->data;
3102
3103        return driver_data;
3104}
3105
3106static struct platform_driver s5p_jpeg_driver = {
3107        .probe = s5p_jpeg_probe,
3108        .remove = s5p_jpeg_remove,
3109        .driver = {
3110                .of_match_table = of_match_ptr(samsung_jpeg_match),
3111                .name           = S5P_JPEG_M2M_NAME,
3112                .pm             = &s5p_jpeg_pm_ops,
3113        },
3114};
3115
3116module_platform_driver(s5p_jpeg_driver);
3117
3118MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
3119MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
3120MODULE_DESCRIPTION("Samsung JPEG codec driver");
3121MODULE_LICENSE("GPL");
3122