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