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