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