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