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