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
37 static 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
347 static 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
390 static 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
433 static const unsigned char hdctbl0[16] = {
434 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
435 };
436
437 static const unsigned char hdctblg0[12] = {
438 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
439 };
440 static const unsigned char hactbl0[16] = {
441 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
442 };
443 static 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 */
474 static const u32 subs422_fourcc_dwngrd_schema[] = {
475 V4L2_PIX_FMT_NV16,
476 V4L2_PIX_FMT_NV61,
477 };
478
479 static 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 */
497 static 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
s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)510 static 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
s5p_jpeg_adjust_fourcc_to_subsampling(enum v4l2_jpeg_chroma_subsampling subs,u32 in_fourcc,u32 * out_fourcc,struct s5p_jpeg_ctx * ctx)522 static 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
561 static 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
568 static 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
ctrl_to_ctx(struct v4l2_ctrl * c)578 static 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
file_to_ctx(struct file * filp)583 static 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
s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx * ctx)588 static 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
s5p_jpeg_set_qtbl(void __iomem * regs,const unsigned char * qtbl,unsigned long tab,int len)615 static 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
s5p_jpeg_set_qtbl_lum(void __iomem * regs,int quality)625 static 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
s5p_jpeg_set_qtbl_chr(void __iomem * regs,int quality)633 static 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
s5p_jpeg_set_htbl(void __iomem * regs,const unsigned char * htbl,unsigned long tab,int len)641 static 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
s5p_jpeg_set_hdctbl(void __iomem * regs)651 static 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
s5p_jpeg_set_hdctblg(void __iomem * regs)658 static 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
s5p_jpeg_set_hactbl(void __iomem * regs)665 static 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
s5p_jpeg_set_hactblg(void __iomem * regs)672 static 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
exynos4_jpeg_set_tbl(void __iomem * regs,const unsigned char * tbl,unsigned long tab,int len)679 static 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
exynos4_jpeg_set_qtbl_lum(void __iomem * regs,int quality)695 static 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
exynos4_jpeg_set_qtbl_chr(void __iomem * regs,int quality)703 static 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
exynos4_jpeg_set_huff_tbl(void __iomem * base)711 static 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
__exynos4_huff_tbl(int class,int id,bool lenval)731 static 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
exynos4_huff_tbl_len(int class,int id)751 static inline int exynos4_huff_tbl_len(int class, int id)
752 {
753 return __exynos4_huff_tbl(class, id, true);
754 }
755
exynos4_huff_tbl_val(int class,int id)756 static inline int exynos4_huff_tbl_val(int class, int id)
757 {
758 return __exynos4_huff_tbl(class, id, false);
759 }
760
761 static int get_byte(struct s5p_jpeg_buffer *buf);
762 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word);
763 static void skip(struct s5p_jpeg_buffer *buf, long len);
764
exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx * ctx)765 static 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
exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx * ctx)805 static 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
exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx * ctx)864 static 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
exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx * ctx)895 static 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
942 static int queue_init(void *priv, struct vb2_queue *src_vq,
943 struct vb2_queue *dst_vq);
944 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
945 __u32 pixelformat, unsigned int fmt_type);
946 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
947
s5p_jpeg_open(struct file * file)948 static 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_obj(*ctx);
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
1002 error:
1003 v4l2_fh_del(&ctx->fh, file);
1004 v4l2_fh_exit(&ctx->fh);
1005 mutex_unlock(&jpeg->lock);
1006 free:
1007 kfree(ctx);
1008 return ret;
1009 }
1010
s5p_jpeg_release(struct file * file)1011 static 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
1027 static 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
get_byte(struct s5p_jpeg_buffer * buf)1042 static 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
get_word_be(struct s5p_jpeg_buffer * buf,unsigned int * word)1050 static 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
skip(struct s5p_jpeg_buffer * buf,long len)1067 static 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
s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx * ctx,unsigned int subsampling)1076 static 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
s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data * result,unsigned long buffer,unsigned long size,struct s5p_jpeg_ctx * ctx)1114 static 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
s5p_jpeg_querycap(struct file * file,void * priv,struct v4l2_capability * cap)1248 static 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
enum_fmt(struct s5p_jpeg_ctx * ctx,struct s5p_jpeg_fmt * sjpeg_formats,int n,struct v4l2_fmtdesc * f,u32 type)1267 static 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
s5p_jpeg_enum_fmt_vid_cap(struct file * file,void * priv,struct v4l2_fmtdesc * f)1296 static 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
s5p_jpeg_enum_fmt_vid_out(struct file * file,void * priv,struct v4l2_fmtdesc * f)1309 static 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
get_q_data(struct s5p_jpeg_ctx * ctx,enum v4l2_buf_type type)1322 static 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
s5p_jpeg_g_fmt(struct file * file,void * priv,struct v4l2_format * f)1333 static 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
s5p_jpeg_find_format(struct s5p_jpeg_ctx * ctx,u32 pixelformat,unsigned int fmt_type)1362 static 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
jpeg_bound_align_image(struct s5p_jpeg_ctx * ctx,u32 * w,unsigned int wmin,unsigned int wmax,unsigned int walign,u32 * h,unsigned int hmin,unsigned int hmax,unsigned int halign)1389 static 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
vidioc_try_fmt(struct v4l2_format * f,struct s5p_jpeg_fmt * fmt,struct s5p_jpeg_ctx * ctx,int q_type)1425 static 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
s5p_jpeg_try_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * f)1470 static 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
1525 exit:
1526 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
1527 }
1528
s5p_jpeg_try_fmt_vid_out(struct file * file,void * priv,struct v4l2_format * f)1529 static 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
exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx * ctx,struct v4l2_format * f,int fmt_depth)1547 static 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
1578 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1579 struct v4l2_rect *r);
1580
s5p_jpeg_s_fmt(struct s5p_jpeg_ctx * ct,struct v4l2_format * f)1581 static 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
s5p_jpeg_s_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * f)1668 static 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
s5p_jpeg_s_fmt_vid_out(struct file * file,void * priv,struct v4l2_format * f)1680 static 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
s5p_jpeg_subscribe_event(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)1692 static 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
exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx * ctx,struct v4l2_rect * r)1701 static 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
exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx * ctx,struct v4l2_rect * r)1734 static 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
s5p_jpeg_g_selection(struct file * file,void * priv,struct v4l2_selection * s)1783 static 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 */
s5p_jpeg_s_selection(struct file * file,void * fh,struct v4l2_selection * s)1820 static 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
s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl * ctrl)1845 static 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
s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx * ctx,int * ctrl_val)1862 static 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
s5p_jpeg_try_ctrl(struct v4l2_ctrl * ctrl)1899 static 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
s5p_jpeg_s_ctrl(struct v4l2_ctrl * ctrl)1914 static 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
1937 static 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
s5p_jpeg_controls_create(struct s5p_jpeg_ctx * ctx)1943 static 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
1983 error_free:
1984 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1985 return ret;
1986 }
1987
1988 static 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
s5p_jpeg_device_run(void * priv)2024 static 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
exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx * ctx)2105 static 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
exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx * ctx)2143 static 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
exynos4_jpeg_set_img_fmt(void __iomem * base,unsigned int img_fmt)2161 static 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
exynos5433_jpeg_set_img_fmt(void __iomem * base,unsigned int img_fmt)2167 static 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
exynos4_jpeg_set_enc_out_fmt(void __iomem * base,unsigned int out_fmt)2173 static 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
exynos5433_jpeg_set_enc_out_fmt(void __iomem * base,unsigned int out_fmt)2179 static 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
exynos4_jpeg_device_run(void * priv)2185 static 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
exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx * ctx)2266 static 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
exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx * ctx)2299 static 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
exynos3250_jpeg_device_run(void * priv)2314 static 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
s5p_jpeg_job_ready(void * priv)2405 static 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
2423 static 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
2428 static 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
2433 static 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
s5p_jpeg_queue_setup(struct vb2_queue * vq,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],struct device * alloc_devs[])2444 static 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
s5p_jpeg_buf_prepare(struct vb2_buffer * vb)2471 static 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
s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx * ctx)2491 static 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
s5p_jpeg_buf_queue(struct vb2_buffer * vb)2515 static 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
s5p_jpeg_start_streaming(struct vb2_queue * q,unsigned int count)2561 static 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
s5p_jpeg_stop_streaming(struct vb2_queue * q)2568 static 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
2586 static 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
queue_init(void * priv,struct vb2_queue * src_vq,struct vb2_queue * dst_vq)2594 static 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
s5p_jpeg_irq(int irq,void * dev_id)2633 static 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
exynos4_jpeg_irq(int irq,void * priv)2691 static 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
exynos3250_jpeg_irq(int irq,void * dev_id)2759 static 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
2830 exit_unlock:
2831 spin_unlock(&jpeg->slock);
2832 return IRQ_HANDLED;
2833 }
2834
2835 static void *jpeg_get_drv_data(struct device *dev);
2836
2837 /*
2838 * ============================================================================
2839 * Driver basic infrastructure
2840 * ============================================================================
2841 */
2842
s5p_jpeg_probe(struct platform_device * pdev)2843 static 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
2975 enc_vdev_register_rollback:
2976 video_unregister_device(jpeg->vfd_encoder);
2977
2978 m2m_init_rollback:
2979 v4l2_m2m_release(jpeg->m2m_dev);
2980
2981 device_register_rollback:
2982 v4l2_device_unregister(&jpeg->v4l2_dev);
2983
2984 return ret;
2985 }
2986
s5p_jpeg_remove(struct platform_device * pdev)2987 static 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
s5p_jpeg_runtime_suspend(struct device * dev)3007 static 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
s5p_jpeg_runtime_resume(struct device * dev)3018 static 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
3056 static 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
3063 static 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
3072 static 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
3082 static 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
3093 static 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
3104 static 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
3115 static 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
3138 MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
3139
jpeg_get_drv_data(struct device * dev)3140 static 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
3156 static 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
3166 module_platform_driver(s5p_jpeg_driver);
3167
3168 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>");
3169 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
3170 MODULE_DESCRIPTION("Samsung JPEG codec driver");
3171 MODULE_LICENSE("GPL");
3172