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