[media] vb2: stop_streaming should return void
[deliverable/linux.git] / drivers / media / platform / s5p-jpeg / jpeg-core.c
CommitLineData
2c3fb08b 1/* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
bb677f3a 2 *
80529ae5 3 * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd.
bb677f3a
AP
4 * http://www.samsung.com
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
80529ae5 7 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
bb677f3a
AP
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/clk.h>
15#include <linux/err.h>
16#include <linux/gfp.h>
17#include <linux/interrupt.h>
18#include <linux/io.h>
19#include <linux/kernel.h>
20#include <linux/module.h>
f7074ab3 21#include <linux/of.h>
bb677f3a
AP
22#include <linux/platform_device.h>
23#include <linux/pm_runtime.h>
24#include <linux/slab.h>
25#include <linux/spinlock.h>
26#include <linux/string.h>
27#include <media/v4l2-mem2mem.h>
28#include <media/v4l2-ioctl.h>
29#include <media/videobuf2-core.h>
30#include <media/videobuf2-dma-contig.h>
31
32#include "jpeg-core.h"
9f7b62d9 33#include "jpeg-hw-s5p.h"
80529ae5
JA
34#include "jpeg-hw-exynos4.h"
35#include "jpeg-regs.h"
bb677f3a 36
80529ae5 37static struct s5p_jpeg_fmt sjpeg_formats[] = {
bb677f3a 38 {
fb6f8c02
AP
39 .name = "JPEG JFIF",
40 .fourcc = V4L2_PIX_FMT_JPEG,
80529ae5
JA
41 .flags = SJPEG_FMT_FLAG_ENC_CAPTURE |
42 SJPEG_FMT_FLAG_DEC_OUTPUT |
43 SJPEG_FMT_FLAG_S5P |
44 SJPEG_FMT_FLAG_EXYNOS4,
45 },
46 {
47 .name = "YUV 4:2:2 packed, YCbYCr",
48 .fourcc = V4L2_PIX_FMT_YUYV,
49 .depth = 16,
fb6f8c02 50 .colplanes = 1,
80529ae5
JA
51 .h_align = 4,
52 .v_align = 3,
53 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
54 SJPEG_FMT_FLAG_DEC_CAPTURE |
55 SJPEG_FMT_FLAG_S5P |
56 SJPEG_FMT_NON_RGB,
57 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
bb677f3a
AP
58 },
59 {
60 .name = "YUV 4:2:2 packed, YCbYCr",
61 .fourcc = V4L2_PIX_FMT_YUYV,
62 .depth = 16,
63 .colplanes = 1,
80529ae5
JA
64 .h_align = 1,
65 .v_align = 0,
66 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
67 SJPEG_FMT_FLAG_DEC_CAPTURE |
68 SJPEG_FMT_FLAG_EXYNOS4 |
69 SJPEG_FMT_NON_RGB,
70 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
71 },
72 {
73 .name = "YUV 4:2:2 packed, YCrYCb",
74 .fourcc = V4L2_PIX_FMT_YVYU,
75 .depth = 16,
76 .colplanes = 1,
77 .h_align = 1,
78 .v_align = 0,
79 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
80 SJPEG_FMT_FLAG_DEC_CAPTURE |
81 SJPEG_FMT_FLAG_EXYNOS4 |
82 SJPEG_FMT_NON_RGB,
83 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
bb677f3a
AP
84 },
85 {
86 .name = "RGB565",
87 .fourcc = V4L2_PIX_FMT_RGB565,
88 .depth = 16,
89 .colplanes = 1,
80529ae5
JA
90 .h_align = 0,
91 .v_align = 0,
92 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
93 SJPEG_FMT_FLAG_DEC_CAPTURE |
94 SJPEG_FMT_FLAG_EXYNOS4 |
95 SJPEG_FMT_RGB,
96 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
97 },
98 {
99 .name = "RGB565",
100 .fourcc = V4L2_PIX_FMT_RGB565,
101 .depth = 16,
102 .colplanes = 1,
103 .h_align = 0,
104 .v_align = 0,
105 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
106 SJPEG_FMT_FLAG_S5P |
107 SJPEG_FMT_RGB,
108 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
109 },
110 {
111 .name = "ARGB8888, 32 bpp",
112 .fourcc = V4L2_PIX_FMT_RGB32,
113 .depth = 32,
114 .colplanes = 1,
115 .h_align = 0,
116 .v_align = 0,
117 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
118 SJPEG_FMT_FLAG_DEC_CAPTURE |
119 SJPEG_FMT_FLAG_EXYNOS4 |
120 SJPEG_FMT_RGB,
121 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
122 },
123 {
124 .name = "YUV 4:4:4 planar, Y/CbCr",
125 .fourcc = V4L2_PIX_FMT_NV24,
126 .depth = 24,
127 .colplanes = 2,
128 .h_align = 0,
129 .v_align = 0,
130 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
131 SJPEG_FMT_FLAG_DEC_CAPTURE |
132 SJPEG_FMT_FLAG_EXYNOS4 |
133 SJPEG_FMT_NON_RGB,
134 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
135 },
136 {
137 .name = "YUV 4:4:4 planar, Y/CrCb",
138 .fourcc = V4L2_PIX_FMT_NV42,
139 .depth = 24,
140 .colplanes = 2,
141 .h_align = 0,
142 .v_align = 0,
143 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
144 SJPEG_FMT_FLAG_DEC_CAPTURE |
145 SJPEG_FMT_FLAG_EXYNOS4 |
146 SJPEG_FMT_NON_RGB,
147 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
148 },
149 {
150 .name = "YUV 4:2:2 planar, Y/CrCb",
151 .fourcc = V4L2_PIX_FMT_NV61,
152 .depth = 16,
153 .colplanes = 2,
154 .h_align = 1,
155 .v_align = 0,
156 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
157 SJPEG_FMT_FLAG_DEC_CAPTURE |
158 SJPEG_FMT_FLAG_EXYNOS4 |
159 SJPEG_FMT_NON_RGB,
160 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
bb677f3a 161 },
bb677f3a 162 {
80529ae5
JA
163 .name = "YUV 4:2:2 planar, Y/CbCr",
164 .fourcc = V4L2_PIX_FMT_NV16,
165 .depth = 16,
166 .colplanes = 2,
167 .h_align = 1,
168 .v_align = 0,
169 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
170 SJPEG_FMT_FLAG_DEC_CAPTURE |
171 SJPEG_FMT_FLAG_EXYNOS4 |
172 SJPEG_FMT_NON_RGB,
173 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
174 },
175 {
176 .name = "YUV 4:2:0 planar, Y/CbCr",
c97ba28b 177 .fourcc = V4L2_PIX_FMT_NV12,
a62cffef 178 .depth = 12,
80529ae5
JA
179 .colplanes = 2,
180 .h_align = 1,
181 .v_align = 1,
182 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
183 SJPEG_FMT_FLAG_DEC_CAPTURE |
184 SJPEG_FMT_FLAG_EXYNOS4 |
185 SJPEG_FMT_NON_RGB,
186 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
bb677f3a
AP
187 },
188 {
80529ae5
JA
189 .name = "YUV 4:2:0 planar, Y/CbCr",
190 .fourcc = V4L2_PIX_FMT_NV12,
a62cffef
JA
191 .depth = 12,
192 .colplanes = 2,
bb677f3a 193 .h_align = 4,
a62cffef 194 .v_align = 4,
80529ae5
JA
195 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
196 SJPEG_FMT_FLAG_DEC_CAPTURE |
197 SJPEG_FMT_FLAG_S5P |
198 SJPEG_FMT_NON_RGB,
199 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
bb677f3a
AP
200 },
201 {
80529ae5
JA
202 .name = "YUV 4:2:0 planar, Y/CrCb",
203 .fourcc = V4L2_PIX_FMT_NV21,
204 .depth = 12,
205 .colplanes = 2,
206 .h_align = 1,
207 .v_align = 1,
208 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
209 SJPEG_FMT_FLAG_DEC_CAPTURE |
210 SJPEG_FMT_FLAG_EXYNOS4 |
211 SJPEG_FMT_NON_RGB,
212 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
213 },
214 {
215 .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
216 .fourcc = V4L2_PIX_FMT_YUV420,
217 .depth = 12,
218 .colplanes = 3,
219 .h_align = 1,
220 .v_align = 1,
221 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
222 SJPEG_FMT_FLAG_DEC_CAPTURE |
223 SJPEG_FMT_FLAG_EXYNOS4 |
224 SJPEG_FMT_NON_RGB,
225 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
226 },
227 {
228 .name = "Gray",
229 .fourcc = V4L2_PIX_FMT_GREY,
230 .depth = 8,
bb677f3a 231 .colplanes = 1,
80529ae5
JA
232 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
233 SJPEG_FMT_FLAG_DEC_CAPTURE |
234 SJPEG_FMT_FLAG_EXYNOS4 |
235 SJPEG_FMT_NON_RGB,
236 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
bb677f3a
AP
237 },
238};
80529ae5 239#define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
bb677f3a
AP
240
241static const unsigned char qtbl_luminance[4][64] = {
78e5a3ce
JA
242 {/*level 0 - high compression quality */
243 20, 16, 25, 39, 50, 46, 62, 68,
244 16, 18, 23, 38, 38, 53, 65, 68,
245 25, 23, 31, 38, 53, 65, 68, 68,
246 39, 38, 38, 53, 65, 68, 68, 68,
247 50, 38, 53, 65, 68, 68, 68, 68,
248 46, 53, 65, 68, 68, 68, 68, 68,
249 62, 65, 68, 68, 68, 68, 68, 68,
250 68, 68, 68, 68, 68, 68, 68, 68
251 },
252 {/* level 1 */
253 16, 11, 11, 16, 23, 27, 31, 30,
254 11, 12, 12, 15, 20, 23, 23, 30,
255 11, 12, 13, 16, 23, 26, 35, 47,
256 16, 15, 16, 23, 26, 37, 47, 64,
257 23, 20, 23, 26, 39, 51, 64, 64,
258 27, 23, 26, 37, 51, 64, 64, 64,
259 31, 23, 35, 47, 64, 64, 64, 64,
260 30, 30, 47, 64, 64, 64, 64, 64
bb677f3a
AP
261 },
262 {/* level 2 */
263 12, 8, 8, 12, 17, 21, 24, 23,
264 8, 9, 9, 11, 15, 19, 18, 23,
265 8, 9, 10, 12, 19, 20, 27, 36,
266 12, 11, 12, 21, 20, 28, 36, 53,
267 17, 15, 19, 20, 30, 39, 51, 59,
268 21, 19, 20, 28, 39, 51, 59, 59,
269 24, 18, 27, 36, 51, 59, 59, 59,
270 23, 23, 36, 53, 59, 59, 59, 59
271 },
78e5a3ce
JA
272 {/* level 3 - low compression quality */
273 8, 6, 6, 8, 12, 14, 16, 17,
274 6, 6, 6, 8, 10, 13, 12, 15,
275 6, 6, 7, 8, 13, 14, 18, 24,
276 8, 8, 8, 14, 13, 19, 24, 35,
277 12, 10, 13, 13, 20, 26, 34, 39,
278 14, 13, 14, 19, 26, 34, 39, 39,
279 16, 12, 18, 24, 34, 39, 39, 39,
280 17, 15, 24, 35, 39, 39, 39, 39
bb677f3a
AP
281 }
282};
283
284static const unsigned char qtbl_chrominance[4][64] = {
78e5a3ce
JA
285 {/*level 0 - high compression quality */
286 21, 25, 32, 38, 54, 68, 68, 68,
287 25, 28, 24, 38, 54, 68, 68, 68,
288 32, 24, 32, 43, 66, 68, 68, 68,
289 38, 38, 43, 53, 68, 68, 68, 68,
290 54, 54, 66, 68, 68, 68, 68, 68,
291 68, 68, 68, 68, 68, 68, 68, 68,
292 68, 68, 68, 68, 68, 68, 68, 68,
293 68, 68, 68, 68, 68, 68, 68, 68
294 },
295 {/* level 1 */
296 17, 15, 17, 21, 20, 26, 38, 48,
297 15, 19, 18, 17, 20, 26, 35, 43,
298 17, 18, 20, 22, 26, 30, 46, 53,
299 21, 17, 22, 28, 30, 39, 53, 64,
300 20, 20, 26, 30, 39, 48, 64, 64,
301 26, 26, 30, 39, 48, 63, 64, 64,
302 38, 35, 46, 53, 64, 64, 64, 64,
303 48, 43, 53, 64, 64, 64, 64, 64
bb677f3a
AP
304 },
305 {/* level 2 */
306 13, 11, 13, 16, 20, 20, 29, 37,
307 11, 14, 14, 14, 16, 20, 26, 32,
308 13, 14, 15, 17, 20, 23, 35, 40,
309 16, 14, 17, 21, 23, 30, 40, 50,
310 20, 16, 20, 23, 30, 37, 50, 59,
311 20, 20, 23, 30, 37, 48, 59, 59,
312 29, 26, 35, 40, 50, 59, 59, 59,
313 37, 32, 40, 50, 59, 59, 59, 59
314 },
78e5a3ce
JA
315 {/* level 3 - low compression quality */
316 9, 8, 9, 11, 14, 17, 19, 24,
317 8, 10, 9, 11, 14, 13, 17, 22,
318 9, 9, 13, 14, 13, 15, 23, 26,
319 11, 11, 14, 14, 15, 20, 26, 33,
320 14, 14, 13, 15, 20, 24, 33, 39,
321 17, 13, 15, 20, 24, 32, 39, 39,
322 19, 17, 23, 26, 33, 39, 39, 39,
323 24, 22, 26, 33, 39, 39, 39, 39
bb677f3a
AP
324 }
325};
326
327static const unsigned char hdctbl0[16] = {
328 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
329};
330
331static const unsigned char hdctblg0[12] = {
332 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
333};
334static const unsigned char hactbl0[16] = {
335 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
336};
337static const unsigned char hactblg0[162] = {
338 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
339 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
340 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
341 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
342 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
343 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
344 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
345 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
346 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
347 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
348 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
349 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
350 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
351 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
352 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
353 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
354 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
355 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
356 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
357 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
358 0xf9, 0xfa
359};
360
337777a4
JA
361/*
362 * Fourcc downgrade schema lookup tables for 422 and 420
363 * chroma subsampling - fourcc on each position maps on the
364 * fourcc from the table fourcc_to_dwngrd_schema_id which allows
365 * to get the most suitable fourcc counterpart for the given
366 * downgraded subsampling property.
367 */
368static const u32 subs422_fourcc_dwngrd_schema[] = {
369 V4L2_PIX_FMT_NV16,
370 V4L2_PIX_FMT_NV61,
371};
372
373static const u32 subs420_fourcc_dwngrd_schema[] = {
374 V4L2_PIX_FMT_NV12,
375 V4L2_PIX_FMT_NV21,
376 V4L2_PIX_FMT_NV12,
377 V4L2_PIX_FMT_NV21,
378 V4L2_PIX_FMT_NV12,
379 V4L2_PIX_FMT_NV21,
380 V4L2_PIX_FMT_GREY,
381 V4L2_PIX_FMT_GREY,
382 V4L2_PIX_FMT_GREY,
383 V4L2_PIX_FMT_GREY,
384};
385
386/*
387 * Lookup table for translation of a fourcc to the position
388 * of its downgraded counterpart in the *fourcc_dwngrd_schema
389 * tables.
390 */
391static const u32 fourcc_to_dwngrd_schema_id[] = {
392 V4L2_PIX_FMT_NV24,
393 V4L2_PIX_FMT_NV42,
394 V4L2_PIX_FMT_NV16,
395 V4L2_PIX_FMT_NV61,
396 V4L2_PIX_FMT_YUYV,
397 V4L2_PIX_FMT_YVYU,
398 V4L2_PIX_FMT_NV12,
399 V4L2_PIX_FMT_NV21,
400 V4L2_PIX_FMT_YUV420,
401 V4L2_PIX_FMT_GREY,
402};
403
404static int s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)
405{
406 int i;
407 for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) {
408 if (fourcc_to_dwngrd_schema_id[i] == fourcc)
409 return i;
410 }
411
412 return -EINVAL;
413}
414
415static int s5p_jpeg_adjust_fourcc_to_subsampling(
416 enum v4l2_jpeg_chroma_subsampling subs,
417 u32 in_fourcc,
418 u32 *out_fourcc,
419 struct s5p_jpeg_ctx *ctx)
420{
421 int dwngrd_sch_id;
422
423 if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
424 dwngrd_sch_id =
425 s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc);
426 if (dwngrd_sch_id < 0)
427 return -EINVAL;
428 }
429
430 switch (ctx->subsampling) {
431 case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
432 *out_fourcc = V4L2_PIX_FMT_GREY;
433 break;
434 case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
435 if (dwngrd_sch_id >
436 ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1)
437 return -EINVAL;
438 *out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id];
439 break;
440 case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
441 if (dwngrd_sch_id >
442 ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1)
443 return -EINVAL;
444 *out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id];
445 break;
446 default:
447 *out_fourcc = V4L2_PIX_FMT_GREY;
448 break;
449 }
450
451 return 0;
452}
453
303b0a96
JA
454static int exynos4x12_decoded_subsampling[] = {
455 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
456 V4L2_JPEG_CHROMA_SUBSAMPLING_444,
457 V4L2_JPEG_CHROMA_SUBSAMPLING_422,
458 V4L2_JPEG_CHROMA_SUBSAMPLING_420,
459};
460
15f4bc3b
SN
461static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
462{
463 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
464}
465
275de24d
SN
466static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
467{
468 return container_of(fh, struct s5p_jpeg_ctx, fh);
469}
470
303b0a96
JA
471static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
472{
473 WARN_ON(ctx->subsampling > 3);
474
475 if (ctx->jpeg->variant->version == SJPEG_S5P) {
476 if (ctx->subsampling > 2)
477 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
478 return ctx->subsampling;
479 } else {
480 if (ctx->subsampling > 2)
481 return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
482 return exynos4x12_decoded_subsampling[ctx->subsampling];
483 }
484}
485
31dc0ac0
JA
486static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
487 const unsigned char *qtbl,
488 unsigned long tab, int len)
bb677f3a
AP
489{
490 int i;
491
492 for (i = 0; i < len; i++)
493 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
494}
495
31dc0ac0 496static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
bb677f3a
AP
497{
498 /* this driver fills quantisation table 0 with data for luma */
31dc0ac0
JA
499 s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
500 S5P_JPG_QTBL_CONTENT(0),
501 ARRAY_SIZE(qtbl_luminance[quality]));
bb677f3a
AP
502}
503
31dc0ac0 504static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
bb677f3a
AP
505{
506 /* this driver fills quantisation table 1 with data for chroma */
31dc0ac0
JA
507 s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
508 S5P_JPG_QTBL_CONTENT(1),
509 ARRAY_SIZE(qtbl_chrominance[quality]));
bb677f3a
AP
510}
511
31dc0ac0
JA
512static inline void s5p_jpeg_set_htbl(void __iomem *regs,
513 const unsigned char *htbl,
514 unsigned long tab, int len)
bb677f3a
AP
515{
516 int i;
517
518 for (i = 0; i < len; i++)
519 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
520}
521
31dc0ac0 522static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
bb677f3a
AP
523{
524 /* this driver fills table 0 for this component */
31dc0ac0
JA
525 s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
526 ARRAY_SIZE(hdctbl0));
bb677f3a
AP
527}
528
31dc0ac0 529static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
bb677f3a
AP
530{
531 /* this driver fills table 0 for this component */
31dc0ac0
JA
532 s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
533 ARRAY_SIZE(hdctblg0));
bb677f3a
AP
534}
535
31dc0ac0 536static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
bb677f3a
AP
537{
538 /* this driver fills table 0 for this component */
31dc0ac0
JA
539 s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
540 ARRAY_SIZE(hactbl0));
bb677f3a
AP
541}
542
31dc0ac0 543static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
bb677f3a
AP
544{
545 /* this driver fills table 0 for this component */
31dc0ac0
JA
546 s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
547 ARRAY_SIZE(hactblg0));
bb677f3a
AP
548}
549
80529ae5
JA
550static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
551 const unsigned char *tbl,
552 unsigned long tab, int len)
553{
554 int i;
555 unsigned int dword;
556
557 for (i = 0; i < len; i += 4) {
558 dword = tbl[i] |
559 (tbl[i + 1] << 8) |
560 (tbl[i + 2] << 16) |
561 (tbl[i + 3] << 24);
562 writel(dword, regs + tab + i);
563 }
564}
565
566static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
567{
568 /* this driver fills quantisation table 0 with data for luma */
569 exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
570 EXYNOS4_QTBL_CONTENT(0),
571 ARRAY_SIZE(qtbl_luminance[quality]));
572}
573
574static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
575{
576 /* this driver fills quantisation table 1 with data for chroma */
577 exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
578 EXYNOS4_QTBL_CONTENT(1),
579 ARRAY_SIZE(qtbl_chrominance[quality]));
580}
581
582void exynos4_jpeg_set_huff_tbl(void __iomem *base)
583{
584 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
585 ARRAY_SIZE(hdctbl0));
586 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
587 ARRAY_SIZE(hdctbl0));
588 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
589 ARRAY_SIZE(hdctblg0));
590 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
591 ARRAY_SIZE(hdctblg0));
592 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
593 ARRAY_SIZE(hactbl0));
594 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
595 ARRAY_SIZE(hactbl0));
596 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
597 ARRAY_SIZE(hactblg0));
598 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
599 ARRAY_SIZE(hactblg0));
600}
601
bb677f3a
AP
602/*
603 * ============================================================================
604 * Device file operations
605 * ============================================================================
606 */
607
608static int queue_init(void *priv, struct vb2_queue *src_vq,
609 struct vb2_queue *dst_vq);
80529ae5
JA
610static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
611 __u32 pixelformat, unsigned int fmt_type);
15f4bc3b 612static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
bb677f3a
AP
613
614static int s5p_jpeg_open(struct file *file)
615{
616 struct s5p_jpeg *jpeg = video_drvdata(file);
617 struct video_device *vfd = video_devdata(file);
618 struct s5p_jpeg_ctx *ctx;
80529ae5 619 struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
275de24d 620 int ret = 0;
bb677f3a 621
b5146c96 622 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
bb677f3a
AP
623 if (!ctx)
624 return -ENOMEM;
625
b0d5cd6b
HV
626 if (mutex_lock_interruptible(&jpeg->lock)) {
627 ret = -ERESTARTSYS;
628 goto free;
629 }
630
275de24d 631 v4l2_fh_init(&ctx->fh, vfd);
15f4bc3b
SN
632 /* Use separate control handler per file handle */
633 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
275de24d
SN
634 file->private_data = &ctx->fh;
635 v4l2_fh_add(&ctx->fh);
636
bb677f3a
AP
637 ctx->jpeg = jpeg;
638 if (vfd == jpeg->vfd_encoder) {
639 ctx->mode = S5P_JPEG_ENCODE;
80529ae5
JA
640 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
641 FMT_TYPE_OUTPUT);
642 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
643 FMT_TYPE_CAPTURE);
bb677f3a
AP
644 } else {
645 ctx->mode = S5P_JPEG_DECODE;
80529ae5
JA
646 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
647 FMT_TYPE_OUTPUT);
648 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
649 FMT_TYPE_CAPTURE);
bb677f3a
AP
650 }
651
718cf4a9
SN
652 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
653 if (IS_ERR(ctx->fh.m2m_ctx)) {
654 ret = PTR_ERR(ctx->fh.m2m_ctx);
275de24d 655 goto error;
bb677f3a
AP
656 }
657
658 ctx->out_q.fmt = out_fmt;
80529ae5
JA
659 ctx->cap_q.fmt = cap_fmt;
660
661 ret = s5p_jpeg_controls_create(ctx);
662 if (ret < 0)
663 goto error;
664
b0d5cd6b 665 mutex_unlock(&jpeg->lock);
bb677f3a 666 return 0;
275de24d
SN
667
668error:
669 v4l2_fh_del(&ctx->fh);
670 v4l2_fh_exit(&ctx->fh);
b0d5cd6b
HV
671 mutex_unlock(&jpeg->lock);
672free:
275de24d
SN
673 kfree(ctx);
674 return ret;
bb677f3a
AP
675}
676
677static int s5p_jpeg_release(struct file *file)
678{
b0d5cd6b 679 struct s5p_jpeg *jpeg = video_drvdata(file);
275de24d 680 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
bb677f3a 681
b0d5cd6b 682 mutex_lock(&jpeg->lock);
718cf4a9 683 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
15f4bc3b 684 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
275de24d
SN
685 v4l2_fh_del(&ctx->fh);
686 v4l2_fh_exit(&ctx->fh);
bb677f3a 687 kfree(ctx);
80529ae5 688 mutex_unlock(&jpeg->lock);
bb677f3a
AP
689
690 return 0;
691}
692
bb677f3a
AP
693static const struct v4l2_file_operations s5p_jpeg_fops = {
694 .owner = THIS_MODULE,
695 .open = s5p_jpeg_open,
696 .release = s5p_jpeg_release,
718cf4a9 697 .poll = v4l2_m2m_fop_poll,
bb677f3a 698 .unlocked_ioctl = video_ioctl2,
718cf4a9 699 .mmap = v4l2_m2m_fop_mmap,
bb677f3a
AP
700};
701
702/*
703 * ============================================================================
704 * video ioctl operations
705 * ============================================================================
706 */
707
708static int get_byte(struct s5p_jpeg_buffer *buf)
709{
710 if (buf->curr >= buf->size)
711 return -1;
712
713 return ((unsigned char *)buf->data)[buf->curr++];
714}
715
716static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
717{
718 unsigned int temp;
719 int byte;
720
721 byte = get_byte(buf);
722 if (byte == -1)
723 return -1;
724 temp = byte << 8;
725 byte = get_byte(buf);
726 if (byte == -1)
727 return -1;
728 *word = (unsigned int)byte | temp;
729 return 0;
730}
731
732static void skip(struct s5p_jpeg_buffer *buf, long len)
733{
734 if (len <= 0)
735 return;
736
737 while (len--)
738 get_byte(buf);
739}
740
741static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
f8433962
JA
742 unsigned long buffer, unsigned long size,
743 struct s5p_jpeg_ctx *ctx)
bb677f3a
AP
744{
745 int c, components, notfound;
f8433962 746 unsigned int height, width, word, subsampling = 0;
bb677f3a
AP
747 long length;
748 struct s5p_jpeg_buffer jpeg_buffer;
749
750 jpeg_buffer.size = size;
751 jpeg_buffer.data = buffer;
752 jpeg_buffer.curr = 0;
753
754 notfound = 1;
755 while (notfound) {
756 c = get_byte(&jpeg_buffer);
757 if (c == -1)
758 break;
759 if (c != 0xff)
760 continue;
761 do
762 c = get_byte(&jpeg_buffer);
763 while (c == 0xff);
764 if (c == -1)
765 break;
766 if (c == 0)
767 continue;
768 length = 0;
769 switch (c) {
770 /* SOF0: baseline JPEG */
771 case SOF0:
772 if (get_word_be(&jpeg_buffer, &word))
773 break;
774 if (get_byte(&jpeg_buffer) == -1)
775 break;
776 if (get_word_be(&jpeg_buffer, &height))
777 break;
778 if (get_word_be(&jpeg_buffer, &width))
779 break;
780 components = get_byte(&jpeg_buffer);
781 if (components == -1)
782 break;
783 notfound = 0;
784
f8433962
JA
785 if (components == 1) {
786 subsampling = 0x33;
787 } else {
788 skip(&jpeg_buffer, 1);
789 subsampling = get_byte(&jpeg_buffer);
790 skip(&jpeg_buffer, 1);
791 }
792
793 skip(&jpeg_buffer, components * 2);
bb677f3a
AP
794 break;
795
796 /* skip payload-less markers */
797 case RST ... RST + 7:
798 case SOI:
799 case EOI:
800 case TEM:
801 break;
802
803 /* skip uninteresting payload markers */
804 default:
805 if (get_word_be(&jpeg_buffer, &word))
806 break;
807 length = (long)word - 2;
808 skip(&jpeg_buffer, length);
809 break;
810 }
811 }
812 result->w = width;
813 result->h = height;
814 result->size = components;
f8433962
JA
815
816 switch (subsampling) {
817 case 0x11:
818 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
819 break;
820 case 0x21:
821 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
822 break;
823 case 0x22:
824 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
825 break;
826 case 0x33:
827 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
828 break;
829 default:
830 return false;
831 }
832
bb677f3a
AP
833 return !notfound;
834}
835
836static int s5p_jpeg_querycap(struct file *file, void *priv,
837 struct v4l2_capability *cap)
838{
275de24d 839 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a
AP
840
841 if (ctx->mode == S5P_JPEG_ENCODE) {
842 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
843 sizeof(cap->driver));
844 strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
845 sizeof(cap->card));
846 } else {
847 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
848 sizeof(cap->driver));
849 strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
850 sizeof(cap->card));
851 }
852 cap->bus_info[0] = 0;
f0476a83
SN
853 /*
854 * This is only a mem-to-mem video device. The capture and output
855 * device capability flags are left only for backward compatibility
856 * and are scheduled for removal.
857 */
858 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M |
859 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT;
bb677f3a
AP
860 return 0;
861}
862
80529ae5 863static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
bb677f3a
AP
864 struct v4l2_fmtdesc *f, u32 type)
865{
866 int i, num = 0;
867
868 for (i = 0; i < n; ++i) {
80529ae5 869 if (sjpeg_formats[i].flags & type) {
bb677f3a
AP
870 /* index-th format of type type found ? */
871 if (num == f->index)
872 break;
873 /* Correct type but haven't reached our index yet,
874 * just increment per-type index */
875 ++num;
876 }
877 }
878
879 /* Format not found */
880 if (i >= n)
881 return -EINVAL;
882
80529ae5
JA
883 strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
884 f->pixelformat = sjpeg_formats[i].fourcc;
bb677f3a
AP
885
886 return 0;
887}
888
889static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
890 struct v4l2_fmtdesc *f)
891{
275de24d 892 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a
AP
893
894 if (ctx->mode == S5P_JPEG_ENCODE)
80529ae5
JA
895 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
896 SJPEG_FMT_FLAG_ENC_CAPTURE);
bb677f3a 897
80529ae5
JA
898 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
899 SJPEG_FMT_FLAG_DEC_CAPTURE);
bb677f3a
AP
900}
901
902static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
903 struct v4l2_fmtdesc *f)
904{
275de24d 905 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a
AP
906
907 if (ctx->mode == S5P_JPEG_ENCODE)
80529ae5
JA
908 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
909 SJPEG_FMT_FLAG_ENC_OUTPUT);
bb677f3a 910
80529ae5
JA
911 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
912 SJPEG_FMT_FLAG_DEC_OUTPUT);
bb677f3a
AP
913}
914
915static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
916 enum v4l2_buf_type type)
917{
918 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
919 return &ctx->out_q;
920 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
921 return &ctx->cap_q;
922
923 return NULL;
924}
925
926static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
927{
928 struct vb2_queue *vq;
929 struct s5p_jpeg_q_data *q_data = NULL;
930 struct v4l2_pix_format *pix = &f->fmt.pix;
275de24d 931 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
bb677f3a 932
718cf4a9 933 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
bb677f3a
AP
934 if (!vq)
935 return -EINVAL;
936
937 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
938 ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
939 return -EINVAL;
940 q_data = get_q_data(ct, f->type);
941 BUG_ON(q_data == NULL);
942
943 pix->width = q_data->w;
944 pix->height = q_data->h;
945 pix->field = V4L2_FIELD_NONE;
946 pix->pixelformat = q_data->fmt->fourcc;
947 pix->bytesperline = 0;
948 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
949 u32 bpl = q_data->w;
950 if (q_data->fmt->colplanes == 1)
951 bpl = (bpl * q_data->fmt->depth) >> 3;
952 pix->bytesperline = bpl;
953 }
954 pix->sizeimage = q_data->size;
955
956 return 0;
957}
958
80529ae5
JA
959static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
960 u32 pixelformat, unsigned int fmt_type)
bb677f3a 961{
80529ae5 962 unsigned int k, fmt_flag, ver_flag;
bb677f3a 963
80529ae5
JA
964 if (ctx->mode == S5P_JPEG_ENCODE)
965 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
966 SJPEG_FMT_FLAG_ENC_OUTPUT :
967 SJPEG_FMT_FLAG_ENC_CAPTURE;
968 else
969 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
970 SJPEG_FMT_FLAG_DEC_OUTPUT :
971 SJPEG_FMT_FLAG_DEC_CAPTURE;
bb677f3a 972
80529ae5
JA
973 if (ctx->jpeg->variant->version == SJPEG_S5P)
974 ver_flag = SJPEG_FMT_FLAG_S5P;
975 else
976 ver_flag = SJPEG_FMT_FLAG_EXYNOS4;
977
978 for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
979 struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
980 if (fmt->fourcc == pixelformat &&
981 fmt->flags & fmt_flag &&
982 fmt->flags & ver_flag) {
bb677f3a 983 return fmt;
80529ae5 984 }
bb677f3a
AP
985 }
986
987 return NULL;
bb677f3a
AP
988}
989
990static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
991 unsigned int walign,
992 u32 *h, unsigned int hmin, unsigned int hmax,
993 unsigned int halign)
994{
995 int width, height, w_step, h_step;
996
997 width = *w;
998 height = *h;
999
1000 w_step = 1 << walign;
1001 h_step = 1 << halign;
1002 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
1003
1004 if (*w < width && (*w + w_step) < wmax)
1005 *w += w_step;
1006 if (*h < height && (*h + h_step) < hmax)
1007 *h += h_step;
1008
1009}
1010
1011static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
1012 struct s5p_jpeg_ctx *ctx, int q_type)
1013{
1014 struct v4l2_pix_format *pix = &f->fmt.pix;
1015
1016 if (pix->field == V4L2_FIELD_ANY)
1017 pix->field = V4L2_FIELD_NONE;
1018 else if (pix->field != V4L2_FIELD_NONE)
1019 return -EINVAL;
1020
1021 /* V4L2 specification suggests the driver corrects the format struct
1022 * if any of the dimensions is unsupported */
80529ae5 1023 if (q_type == FMT_TYPE_OUTPUT)
bb677f3a
AP
1024 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
1025 S5P_JPEG_MAX_WIDTH, 0,
1026 &pix->height, S5P_JPEG_MIN_HEIGHT,
1027 S5P_JPEG_MAX_HEIGHT, 0);
1028 else
1029 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
1030 S5P_JPEG_MAX_WIDTH, fmt->h_align,
1031 &pix->height, S5P_JPEG_MIN_HEIGHT,
1032 S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1033
1034 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1035 if (pix->sizeimage <= 0)
1036 pix->sizeimage = PAGE_SIZE;
1037 pix->bytesperline = 0;
1038 } else {
1039 u32 bpl = pix->bytesperline;
1040
1041 if (fmt->colplanes > 1 && bpl < pix->width)
1042 bpl = pix->width; /* planar */
1043
1044 if (fmt->colplanes == 1 && /* packed */
cc690904 1045 (bpl << 3) / fmt->depth < pix->width)
bb677f3a
AP
1046 bpl = (pix->width * fmt->depth) >> 3;
1047
1048 pix->bytesperline = bpl;
1049 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1050 }
1051
1052 return 0;
1053}
1054
1055static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1056 struct v4l2_format *f)
1057{
275de24d 1058 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
337777a4 1059 struct v4l2_pix_format *pix = &f->fmt.pix;
bb677f3a 1060 struct s5p_jpeg_fmt *fmt;
337777a4 1061 int ret;
bb677f3a 1062
80529ae5
JA
1063 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1064 FMT_TYPE_CAPTURE);
1065 if (!fmt) {
bb677f3a
AP
1066 v4l2_err(&ctx->jpeg->v4l2_dev,
1067 "Fourcc format (0x%08x) invalid.\n",
1068 f->fmt.pix.pixelformat);
1069 return -EINVAL;
1070 }
1071
337777a4
JA
1072 /*
1073 * The exynos4x12 device requires resulting YUV image
1074 * subsampling not to be lower than the input jpeg subsampling.
1075 * If this requirement is not met then downgrade the requested
1076 * capture format to the one with subsampling equal to the input jpeg.
1077 */
1078 if ((ctx->jpeg->variant->version != SJPEG_S5P) &&
1079 (ctx->mode == S5P_JPEG_DECODE) &&
1080 (fmt->flags & SJPEG_FMT_NON_RGB) &&
1081 (fmt->subsampling < ctx->subsampling)) {
1082 ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1083 fmt->fourcc,
1084 &pix->pixelformat,
1085 ctx);
1086 if (ret < 0)
1087 pix->pixelformat = V4L2_PIX_FMT_GREY;
1088
1089 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1090 FMT_TYPE_CAPTURE);
1091 }
1092
80529ae5 1093 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
bb677f3a
AP
1094}
1095
1096static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1097 struct v4l2_format *f)
1098{
275de24d 1099 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a 1100 struct s5p_jpeg_fmt *fmt;
bb677f3a 1101
80529ae5
JA
1102 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1103 FMT_TYPE_OUTPUT);
1104 if (!fmt) {
bb677f3a
AP
1105 v4l2_err(&ctx->jpeg->v4l2_dev,
1106 "Fourcc format (0x%08x) invalid.\n",
1107 f->fmt.pix.pixelformat);
1108 return -EINVAL;
1109 }
1110
80529ae5 1111 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
bb677f3a
AP
1112}
1113
1114static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1115{
1116 struct vb2_queue *vq;
1117 struct s5p_jpeg_q_data *q_data = NULL;
1118 struct v4l2_pix_format *pix = &f->fmt.pix;
4a30d30b 1119 struct v4l2_ctrl *ctrl_subs;
80529ae5 1120 unsigned int f_type;
bb677f3a 1121
718cf4a9 1122 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
bb677f3a
AP
1123 if (!vq)
1124 return -EINVAL;
1125
1126 q_data = get_q_data(ct, f->type);
1127 BUG_ON(q_data == NULL);
1128
1129 if (vb2_is_busy(vq)) {
1130 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1131 return -EBUSY;
1132 }
1133
80529ae5
JA
1134 f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1135 FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1136
1137 q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
bb677f3a
AP
1138 q_data->w = pix->width;
1139 q_data->h = pix->height;
1140 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
1141 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
1142 else
1143 q_data->size = pix->sizeimage;
1144
4a30d30b
JA
1145 if (f_type == FMT_TYPE_OUTPUT) {
1146 ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1147 V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1148 if (ctrl_subs)
1149 v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
1150 }
1151
bb677f3a
AP
1152 return 0;
1153}
1154
1155static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1156 struct v4l2_format *f)
1157{
1158 int ret;
1159
1160 ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1161 if (ret)
1162 return ret;
1163
275de24d 1164 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
bb677f3a
AP
1165}
1166
1167static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1168 struct v4l2_format *f)
1169{
1170 int ret;
1171
1172 ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1173 if (ret)
1174 return ret;
1175
275de24d 1176 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
bb677f3a
AP
1177}
1178
9f3bd320 1179static int s5p_jpeg_g_selection(struct file *file, void *priv,
bb677f3a
AP
1180 struct v4l2_selection *s)
1181{
275de24d 1182 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a
AP
1183
1184 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
80529ae5
JA
1185 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1186 ctx->jpeg->variant->version != SJPEG_S5P)
bb677f3a
AP
1187 return -EINVAL;
1188
1189 /* For JPEG blob active == default == bounds */
1190 switch (s->target) {
c1334823 1191 case V4L2_SEL_TGT_CROP:
bb677f3a
AP
1192 case V4L2_SEL_TGT_CROP_BOUNDS:
1193 case V4L2_SEL_TGT_CROP_DEFAULT:
c1334823 1194 case V4L2_SEL_TGT_COMPOSE:
bb677f3a
AP
1195 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1196 s->r.width = ctx->out_q.w;
1197 s->r.height = ctx->out_q.h;
1198 break;
1199 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1200 case V4L2_SEL_TGT_COMPOSE_PADDED:
1201 s->r.width = ctx->cap_q.w;
1202 s->r.height = ctx->cap_q.h;
1203 break;
1204 default:
1205 return -EINVAL;
1206 }
1207 s->r.left = 0;
1208 s->r.top = 0;
1209 return 0;
1210}
1211
15f4bc3b
SN
1212/*
1213 * V4L2 controls
1214 */
1215
1216static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
bb677f3a 1217{
15f4bc3b
SN
1218 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1219 struct s5p_jpeg *jpeg = ctx->jpeg;
1220 unsigned long flags;
bb677f3a 1221
15f4bc3b
SN
1222 switch (ctrl->id) {
1223 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1224 spin_lock_irqsave(&jpeg->slock, flags);
303b0a96 1225 ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
15f4bc3b
SN
1226 spin_unlock_irqrestore(&jpeg->slock, flags);
1227 break;
1228 }
bb677f3a
AP
1229
1230 return 0;
1231}
1232
11fbea3e
JA
1233static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1234{
1235 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1236 unsigned long flags;
1237 int ret = 0;
1238
1239 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1240
1241 if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING) {
1242 if (ctx->jpeg->variant->version == SJPEG_S5P)
1243 goto error_free;
1244 /*
1245 * The exynos4x12 device requires input raw image fourcc
1246 * to be V4L2_PIX_FMT_GREY if gray jpeg format
1247 * is to be set.
1248 */
1249 if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
1250 ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
1251 ret = -EINVAL;
1252 goto error_free;
1253 }
1254 /*
1255 * The exynos4x12 device requires resulting jpeg subsampling
1256 * not to be lower than the input raw image subsampling.
1257 */
1258 if (ctx->out_q.fmt->subsampling > ctrl->val)
1259 ctrl->val = ctx->out_q.fmt->subsampling;
1260 }
1261
1262error_free:
1263 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1264 return ret;
1265}
1266
15f4bc3b 1267static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
bb677f3a 1268{
15f4bc3b
SN
1269 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1270 unsigned long flags;
bb677f3a 1271
15f4bc3b 1272 spin_lock_irqsave(&ctx->jpeg->slock, flags);
bb677f3a 1273
15f4bc3b
SN
1274 switch (ctrl->id) {
1275 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
78e5a3ce 1276 ctx->compr_quality = ctrl->val;
15f4bc3b
SN
1277 break;
1278 case V4L2_CID_JPEG_RESTART_INTERVAL:
1279 ctx->restart_interval = ctrl->val;
1280 break;
1281 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1282 ctx->subsampling = ctrl->val;
1283 break;
1284 }
1285
1286 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1287 return 0;
1288}
1289
1290static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1291 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
11fbea3e 1292 .try_ctrl = s5p_jpeg_try_ctrl,
15f4bc3b
SN
1293 .s_ctrl = s5p_jpeg_s_ctrl,
1294};
1295
1296static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1297{
1298 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1299 struct v4l2_ctrl *ctrl;
088f8300 1300 int ret;
15f4bc3b
SN
1301
1302 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
bb677f3a 1303
15f4bc3b
SN
1304 if (ctx->mode == S5P_JPEG_ENCODE) {
1305 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1306 V4L2_CID_JPEG_COMPRESSION_QUALITY,
78e5a3ce 1307 0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
15f4bc3b
SN
1308
1309 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1310 V4L2_CID_JPEG_RESTART_INTERVAL,
1311 0, 3, 0xffff, 0);
fdf9e2bc
JA
1312 if (ctx->jpeg->variant->version == SJPEG_S5P)
1313 mask = ~0x06; /* 422, 420 */
15f4bc3b
SN
1314 }
1315
1316 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1317 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1318 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
1319 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
bb677f3a 1320
088f8300
JA
1321 if (ctx->ctrl_handler.error) {
1322 ret = ctx->ctrl_handler.error;
1323 goto error_free;
1324 }
15f4bc3b
SN
1325
1326 if (ctx->mode == S5P_JPEG_DECODE)
1327 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
1328 V4L2_CTRL_FLAG_READ_ONLY;
088f8300
JA
1329
1330 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1331 if (ret < 0)
1332 goto error_free;
1333
1334 return ret;
1335
1336error_free:
1337 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1338 return ret;
bb677f3a
AP
1339}
1340
1341static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
1342 .vidioc_querycap = s5p_jpeg_querycap,
1343
1344 .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
1345 .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
1346
1347 .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
1348 .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
1349
1350 .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
1351 .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
1352
1353 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
1354 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
1355
718cf4a9
SN
1356 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
1357 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
1358 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
1359 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
bb677f3a 1360
718cf4a9
SN
1361 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
1362 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
bb677f3a
AP
1363
1364 .vidioc_g_selection = s5p_jpeg_g_selection,
bb677f3a
AP
1365};
1366
1367/*
1368 * ============================================================================
1369 * mem2mem callbacks
1370 * ============================================================================
1371 */
1372
1373static void s5p_jpeg_device_run(void *priv)
1374{
1375 struct s5p_jpeg_ctx *ctx = priv;
1376 struct s5p_jpeg *jpeg = ctx->jpeg;
1377 struct vb2_buffer *src_buf, *dst_buf;
b3c932a9
JA
1378 unsigned long src_addr, dst_addr, flags;
1379
1380 spin_lock_irqsave(&ctx->jpeg->slock, flags);
bb677f3a 1381
718cf4a9
SN
1382 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1383 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
bb677f3a
AP
1384 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
1385 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
1386
9f7b62d9
JA
1387 s5p_jpeg_reset(jpeg->regs);
1388 s5p_jpeg_poweron(jpeg->regs);
1389 s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
bb677f3a
AP
1390 if (ctx->mode == S5P_JPEG_ENCODE) {
1391 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
9f7b62d9
JA
1392 s5p_jpeg_input_raw_mode(jpeg->regs,
1393 S5P_JPEG_RAW_IN_565);
bb677f3a 1394 else
9f7b62d9
JA
1395 s5p_jpeg_input_raw_mode(jpeg->regs,
1396 S5P_JPEG_RAW_IN_422);
1397 s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
1398 s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
1399 s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
1400 s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
1401 s5p_jpeg_imgadr(jpeg->regs, src_addr);
1402 s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
bb677f3a
AP
1403
1404 /* ultimately comes from sizeimage from userspace */
9f7b62d9 1405 s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
bb677f3a
AP
1406
1407 /* JPEG RGB to YCbCr conversion matrix */
9f7b62d9
JA
1408 s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
1409 s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1410 s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1411 s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1412 s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1413 s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1414 s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1415 s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1416 s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
bb677f3a
AP
1417
1418 /*
1419 * JPEG IP allows storing 4 quantization tables
1420 * We fill table 0 for luma and table 1 for chroma
1421 */
31dc0ac0
JA
1422 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1423 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
bb677f3a 1424 /* use table 0 for Y */
9f7b62d9 1425 s5p_jpeg_qtbl(jpeg->regs, 1, 0);
bb677f3a 1426 /* use table 1 for Cb and Cr*/
9f7b62d9
JA
1427 s5p_jpeg_qtbl(jpeg->regs, 2, 1);
1428 s5p_jpeg_qtbl(jpeg->regs, 3, 1);
bb677f3a
AP
1429
1430 /* Y, Cb, Cr use Huffman table 0 */
9f7b62d9
JA
1431 s5p_jpeg_htbl_ac(jpeg->regs, 1);
1432 s5p_jpeg_htbl_dc(jpeg->regs, 1);
1433 s5p_jpeg_htbl_ac(jpeg->regs, 2);
1434 s5p_jpeg_htbl_dc(jpeg->regs, 2);
1435 s5p_jpeg_htbl_ac(jpeg->regs, 3);
1436 s5p_jpeg_htbl_dc(jpeg->regs, 3);
fb6f8c02 1437 } else { /* S5P_JPEG_DECODE */
9f7b62d9
JA
1438 s5p_jpeg_rst_int_enable(jpeg->regs, true);
1439 s5p_jpeg_data_num_int_enable(jpeg->regs, true);
1440 s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
fb6f8c02 1441 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
9f7b62d9 1442 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
fb6f8c02 1443 else
9f7b62d9
JA
1444 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1445 s5p_jpeg_jpgadr(jpeg->regs, src_addr);
1446 s5p_jpeg_imgadr(jpeg->regs, dst_addr);
bb677f3a 1447 }
15f4bc3b 1448
9f7b62d9 1449 s5p_jpeg_start(jpeg->regs);
b3c932a9
JA
1450
1451 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
bb677f3a
AP
1452}
1453
80529ae5
JA
1454static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1455{
1456 struct s5p_jpeg *jpeg = ctx->jpeg;
1457 struct s5p_jpeg_fmt *fmt;
1458 struct vb2_buffer *vb;
1459 struct s5p_jpeg_addr jpeg_addr;
1460 u32 pix_size, padding_bytes = 0;
1461
1462 pix_size = ctx->cap_q.w * ctx->cap_q.h;
1463
1464 if (ctx->mode == S5P_JPEG_ENCODE) {
1465 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1466 fmt = ctx->out_q.fmt;
1467 if (ctx->out_q.w % 2 && fmt->h_align > 0)
1468 padding_bytes = ctx->out_q.h;
1469 } else {
1470 fmt = ctx->cap_q.fmt;
1471 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1472 }
1473
1474 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
1475
1476 if (fmt->colplanes == 2) {
1477 jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
1478 } else if (fmt->colplanes == 3) {
1479 jpeg_addr.cb = jpeg_addr.y + pix_size;
1480 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
1481 jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
1482 else
1483 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
1484 }
1485
1486 exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
1487}
1488
1489static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
1490{
1491 struct s5p_jpeg *jpeg = ctx->jpeg;
1492 struct vb2_buffer *vb;
1493 unsigned int jpeg_addr = 0;
1494
1495 if (ctx->mode == S5P_JPEG_ENCODE)
1496 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1497 else
1498 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1499
1500 jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1501 exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
1502}
1503
1504static void exynos4_jpeg_device_run(void *priv)
1505{
1506 struct s5p_jpeg_ctx *ctx = priv;
1507 struct s5p_jpeg *jpeg = ctx->jpeg;
1508 unsigned int bitstream_size;
1509 unsigned long flags;
1510
1511 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1512
1513 if (ctx->mode == S5P_JPEG_ENCODE) {
1514 exynos4_jpeg_sw_reset(jpeg->regs);
1515 exynos4_jpeg_set_interrupt(jpeg->regs);
1516 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
1517
1518 exynos4_jpeg_set_huff_tbl(jpeg->regs);
1519
1520 /*
1521 * JPEG IP allows storing 4 quantization tables
1522 * We fill table 0 for luma and table 1 for chroma
1523 */
1524 exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1525 exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1526
1527 exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
1528 ctx->compr_quality);
1529 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
1530 ctx->cap_q.h);
1531
1532 exynos4_jpeg_set_enc_out_fmt(jpeg->regs, ctx->subsampling);
1533 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->out_q.fmt->fourcc);
1534 exynos4_jpeg_set_img_addr(ctx);
1535 exynos4_jpeg_set_jpeg_addr(ctx);
1536 exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
1537 ctx->out_q.fmt->fourcc);
1538 } else {
1539 exynos4_jpeg_sw_reset(jpeg->regs);
1540 exynos4_jpeg_set_interrupt(jpeg->regs);
1541 exynos4_jpeg_set_img_addr(ctx);
1542 exynos4_jpeg_set_jpeg_addr(ctx);
1543 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->cap_q.fmt->fourcc);
1544
1545 bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
1546
1547 exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
1548 }
1549
1550 exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
1551
1552 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1553}
1554
bb677f3a
AP
1555static int s5p_jpeg_job_ready(void *priv)
1556{
1557 struct s5p_jpeg_ctx *ctx = priv;
1558
1559 if (ctx->mode == S5P_JPEG_DECODE)
1560 return ctx->hdr_parsed;
1561 return 1;
1562}
1563
1564static void s5p_jpeg_job_abort(void *priv)
1565{
1566}
1567
1568static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
1569 .device_run = s5p_jpeg_device_run,
1570 .job_ready = s5p_jpeg_job_ready,
1571 .job_abort = s5p_jpeg_job_abort,
80529ae5
JA
1572}
1573;
1574static struct v4l2_m2m_ops exynos_jpeg_m2m_ops = {
1575 .device_run = exynos4_jpeg_device_run,
1576 .job_ready = s5p_jpeg_job_ready,
1577 .job_abort = s5p_jpeg_job_abort,
bb677f3a
AP
1578};
1579
1580/*
1581 * ============================================================================
1582 * Queue operations
1583 * ============================================================================
1584 */
1585
719c174e
MS
1586static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
1587 const struct v4l2_format *fmt,
1588 unsigned int *nbuffers, unsigned int *nplanes,
1589 unsigned int sizes[], void *alloc_ctxs[])
bb677f3a
AP
1590{
1591 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1592 struct s5p_jpeg_q_data *q_data = NULL;
1593 unsigned int size, count = *nbuffers;
1594
1595 q_data = get_q_data(ctx, vq->type);
1596 BUG_ON(q_data == NULL);
1597
1598 size = q_data->size;
1599
1600 /*
1601 * header is parsed during decoding and parsed information stored
1602 * in the context so we do not allow another buffer to overwrite it
1603 */
1604 if (ctx->mode == S5P_JPEG_DECODE)
1605 count = 1;
1606
1607 *nbuffers = count;
1608 *nplanes = 1;
1609 sizes[0] = size;
1610 alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
1611
1612 return 0;
1613}
1614
1615static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
1616{
1617 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1618 struct s5p_jpeg_q_data *q_data = NULL;
1619
1620 q_data = get_q_data(ctx, vb->vb2_queue->type);
1621 BUG_ON(q_data == NULL);
1622
1623 if (vb2_plane_size(vb, 0) < q_data->size) {
1624 pr_err("%s data will not fit into plane (%lu < %lu)\n",
1625 __func__, vb2_plane_size(vb, 0),
1626 (long)q_data->size);
1627 return -EINVAL;
1628 }
1629
1630 vb2_set_plane_payload(vb, 0, q_data->size);
1631
1632 return 0;
1633}
1634
1635static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
1636{
1637 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1638
1639 if (ctx->mode == S5P_JPEG_DECODE &&
1640 vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1641 struct s5p_jpeg_q_data tmp, *q_data;
1642 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
1643 (unsigned long)vb2_plane_vaddr(vb, 0),
1644 min((unsigned long)ctx->out_q.size,
f8433962 1645 vb2_get_plane_payload(vb, 0)), ctx);
bb677f3a
AP
1646 if (!ctx->hdr_parsed) {
1647 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1648 return;
1649 }
1650
1651 q_data = &ctx->out_q;
1652 q_data->w = tmp.w;
1653 q_data->h = tmp.h;
1654
1655 q_data = &ctx->cap_q;
1656 q_data->w = tmp.w;
1657 q_data->h = tmp.h;
bb677f3a 1658 }
bb677f3a 1659
718cf4a9 1660 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
bb677f3a
AP
1661}
1662
1663static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1664{
1665 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1666 int ret;
1667
1668 ret = pm_runtime_get_sync(ctx->jpeg->dev);
1669
1670 return ret > 0 ? 0 : ret;
1671}
1672
e37559b2 1673static void s5p_jpeg_stop_streaming(struct vb2_queue *q)
bb677f3a
AP
1674{
1675 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1676
1677 pm_runtime_put(ctx->jpeg->dev);
bb677f3a
AP
1678}
1679
1680static struct vb2_ops s5p_jpeg_qops = {
1681 .queue_setup = s5p_jpeg_queue_setup,
1682 .buf_prepare = s5p_jpeg_buf_prepare,
1683 .buf_queue = s5p_jpeg_buf_queue,
718cf4a9
SN
1684 .wait_prepare = vb2_ops_wait_prepare,
1685 .wait_finish = vb2_ops_wait_finish,
bb677f3a
AP
1686 .start_streaming = s5p_jpeg_start_streaming,
1687 .stop_streaming = s5p_jpeg_stop_streaming,
1688};
1689
1690static int queue_init(void *priv, struct vb2_queue *src_vq,
1691 struct vb2_queue *dst_vq)
1692{
1693 struct s5p_jpeg_ctx *ctx = priv;
1694 int ret;
1695
bb677f3a
AP
1696 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1697 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1698 src_vq->drv_priv = ctx;
1699 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1700 src_vq->ops = &s5p_jpeg_qops;
1701 src_vq->mem_ops = &vb2_dma_contig_memops;
ade48681 1702 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
718cf4a9 1703 src_vq->lock = &ctx->jpeg->lock;
bb677f3a
AP
1704
1705 ret = vb2_queue_init(src_vq);
1706 if (ret)
1707 return ret;
1708
bb677f3a
AP
1709 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1710 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1711 dst_vq->drv_priv = ctx;
1712 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1713 dst_vq->ops = &s5p_jpeg_qops;
1714 dst_vq->mem_ops = &vb2_dma_contig_memops;
ade48681 1715 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
718cf4a9 1716 dst_vq->lock = &ctx->jpeg->lock;
bb677f3a
AP
1717
1718 return vb2_queue_init(dst_vq);
1719}
1720
1721/*
1722 * ============================================================================
1723 * ISR
1724 * ============================================================================
1725 */
1726
1727static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1728{
1729 struct s5p_jpeg *jpeg = dev_id;
1730 struct s5p_jpeg_ctx *curr_ctx;
1731 struct vb2_buffer *src_buf, *dst_buf;
1732 unsigned long payload_size = 0;
1733 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
1734 bool enc_jpeg_too_large = false;
1735 bool timer_elapsed = false;
1736 bool op_completed = false;
1737
15f4bc3b
SN
1738 spin_lock(&jpeg->slock);
1739
bb677f3a
AP
1740 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1741
718cf4a9
SN
1742 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1743 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
bb677f3a
AP
1744
1745 if (curr_ctx->mode == S5P_JPEG_ENCODE)
9f7b62d9
JA
1746 enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
1747 timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
1748 op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
bb677f3a 1749 if (curr_ctx->mode == S5P_JPEG_DECODE)
9f7b62d9
JA
1750 op_completed = op_completed &&
1751 s5p_jpeg_stream_stat_ok(jpeg->regs);
bb677f3a
AP
1752
1753 if (enc_jpeg_too_large) {
1754 state = VB2_BUF_STATE_ERROR;
9f7b62d9 1755 s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
bb677f3a
AP
1756 } else if (timer_elapsed) {
1757 state = VB2_BUF_STATE_ERROR;
9f7b62d9 1758 s5p_jpeg_clear_timer_stat(jpeg->regs);
bb677f3a
AP
1759 } else if (!op_completed) {
1760 state = VB2_BUF_STATE_ERROR;
1761 } else {
9f7b62d9 1762 payload_size = s5p_jpeg_compressed_size(jpeg->regs);
bb677f3a
AP
1763 }
1764
aca326ae
KD
1765 dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
1766 dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
309f4d62
SA
1767 dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
1768 dst_buf->v4l2_buf.flags |=
1769 src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
aca326ae 1770
bb677f3a
AP
1771 v4l2_m2m_buf_done(src_buf, state);
1772 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1773 vb2_set_plane_payload(dst_buf, 0, payload_size);
1774 v4l2_m2m_buf_done(dst_buf, state);
718cf4a9 1775 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
bb677f3a 1776
9f7b62d9 1777 curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
15f4bc3b 1778 spin_unlock(&jpeg->slock);
fb6f8c02 1779
9f7b62d9 1780 s5p_jpeg_clear_int(jpeg->regs);
bb677f3a
AP
1781
1782 return IRQ_HANDLED;
1783}
1784
80529ae5
JA
1785static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
1786{
1787 unsigned int int_status;
1788 struct vb2_buffer *src_vb, *dst_vb;
1789 struct s5p_jpeg *jpeg = priv;
1790 struct s5p_jpeg_ctx *curr_ctx;
1791 unsigned long payload_size = 0;
1792
1793 spin_lock(&jpeg->slock);
1794
1795 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1796
1797 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1798 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1799
1800 int_status = exynos4_jpeg_get_int_status(jpeg->regs);
1801
1802 if (int_status) {
1803 switch (int_status & 0x1f) {
1804 case 0x1:
1805 jpeg->irq_ret = ERR_PROT;
1806 break;
1807 case 0x2:
1808 jpeg->irq_ret = OK_ENC_OR_DEC;
1809 break;
1810 case 0x4:
1811 jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
1812 break;
1813 case 0x8:
1814 jpeg->irq_ret = ERR_MULTI_SCAN;
1815 break;
1816 case 0x10:
1817 jpeg->irq_ret = ERR_FRAME;
1818 break;
1819 default:
1820 jpeg->irq_ret = ERR_UNKNOWN;
1821 break;
1822 }
1823 } else {
1824 jpeg->irq_ret = ERR_UNKNOWN;
1825 }
1826
1827 if (jpeg->irq_ret == OK_ENC_OR_DEC) {
1828 if (curr_ctx->mode == S5P_JPEG_ENCODE) {
1829 payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
1830 vb2_set_plane_payload(dst_vb, 0, payload_size);
1831 }
1832 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
1833 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
1834 } else {
1835 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
1836 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
1837 }
1838
1839 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
1840 curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
1841
1842 spin_unlock(&jpeg->slock);
1843 return IRQ_HANDLED;
1844}
1845
1846static void *jpeg_get_drv_data(struct platform_device *pdev);
1847
bb677f3a
AP
1848/*
1849 * ============================================================================
1850 * Driver basic infrastructure
1851 * ============================================================================
1852 */
1853
1854static int s5p_jpeg_probe(struct platform_device *pdev)
1855{
1856 struct s5p_jpeg *jpeg;
1857 struct resource *res;
80529ae5 1858 struct v4l2_m2m_ops *samsung_jpeg_m2m_ops;
bb677f3a
AP
1859 int ret;
1860
80529ae5
JA
1861 if (!pdev->dev.of_node)
1862 return -ENODEV;
1863
bb677f3a 1864 /* JPEG IP abstraction struct */
5b58b954 1865 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
bb677f3a
AP
1866 if (!jpeg)
1867 return -ENOMEM;
1868
80529ae5
JA
1869 jpeg->variant = jpeg_get_drv_data(pdev);
1870
bb677f3a 1871 mutex_init(&jpeg->lock);
15f4bc3b 1872 spin_lock_init(&jpeg->slock);
bb677f3a
AP
1873 jpeg->dev = &pdev->dev;
1874
1875 /* memory-mapped registers */
1876 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bb677f3a 1877
f23999ec
TR
1878 jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
1879 if (IS_ERR(jpeg->regs))
1880 return PTR_ERR(jpeg->regs);
bb677f3a 1881
bb677f3a
AP
1882 /* interrupt service routine registration */
1883 jpeg->irq = ret = platform_get_irq(pdev, 0);
1884 if (ret < 0) {
1885 dev_err(&pdev->dev, "cannot find IRQ\n");
5b58b954 1886 return ret;
bb677f3a
AP
1887 }
1888
80529ae5
JA
1889 ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
1890 0, dev_name(&pdev->dev), jpeg);
bb677f3a
AP
1891 if (ret) {
1892 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
5b58b954 1893 return ret;
bb677f3a
AP
1894 }
1895
1896 /* clocks */
1897 jpeg->clk = clk_get(&pdev->dev, "jpeg");
1898 if (IS_ERR(jpeg->clk)) {
1899 dev_err(&pdev->dev, "cannot get clock\n");
1900 ret = PTR_ERR(jpeg->clk);
5b58b954 1901 return ret;
bb677f3a
AP
1902 }
1903 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
bb677f3a
AP
1904
1905 /* v4l2 device */
1906 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1907 if (ret) {
1908 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1909 goto clk_get_rollback;
1910 }
1911
80529ae5
JA
1912 if (jpeg->variant->version == SJPEG_S5P)
1913 samsung_jpeg_m2m_ops = &s5p_jpeg_m2m_ops;
1914 else
1915 samsung_jpeg_m2m_ops = &exynos_jpeg_m2m_ops;
1916
bb677f3a 1917 /* mem2mem device */
80529ae5 1918 jpeg->m2m_dev = v4l2_m2m_init(samsung_jpeg_m2m_ops);
bb677f3a
AP
1919 if (IS_ERR(jpeg->m2m_dev)) {
1920 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1921 ret = PTR_ERR(jpeg->m2m_dev);
1922 goto device_register_rollback;
1923 }
1924
1925 jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1926 if (IS_ERR(jpeg->alloc_ctx)) {
1927 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
1928 ret = PTR_ERR(jpeg->alloc_ctx);
1929 goto m2m_init_rollback;
1930 }
1931
1932 /* JPEG encoder /dev/videoX node */
1933 jpeg->vfd_encoder = video_device_alloc();
1934 if (!jpeg->vfd_encoder) {
1935 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1936 ret = -ENOMEM;
1937 goto vb2_allocator_rollback;
1938 }
baaf046d
SWK
1939 snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
1940 "%s-enc", S5P_JPEG_M2M_NAME);
bb677f3a
AP
1941 jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
1942 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1943 jpeg->vfd_encoder->minor = -1;
1944 jpeg->vfd_encoder->release = video_device_release;
1945 jpeg->vfd_encoder->lock = &jpeg->lock;
1946 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
954f340f 1947 jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M;
bb677f3a
AP
1948
1949 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
1950 if (ret) {
1951 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1952 goto enc_vdev_alloc_rollback;
1953 }
1954
1955 video_set_drvdata(jpeg->vfd_encoder, jpeg);
1956 v4l2_info(&jpeg->v4l2_dev,
1957 "encoder device registered as /dev/video%d\n",
1958 jpeg->vfd_encoder->num);
1959
1960 /* JPEG decoder /dev/videoX node */
1961 jpeg->vfd_decoder = video_device_alloc();
1962 if (!jpeg->vfd_decoder) {
1963 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1964 ret = -ENOMEM;
1965 goto enc_vdev_register_rollback;
1966 }
baaf046d
SWK
1967 snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
1968 "%s-dec", S5P_JPEG_M2M_NAME);
bb677f3a
AP
1969 jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
1970 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1971 jpeg->vfd_decoder->minor = -1;
1972 jpeg->vfd_decoder->release = video_device_release;
1973 jpeg->vfd_decoder->lock = &jpeg->lock;
1974 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
7f7d8fe2 1975 jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M;
bb677f3a
AP
1976
1977 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
1978 if (ret) {
1979 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1980 goto dec_vdev_alloc_rollback;
1981 }
1982
1983 video_set_drvdata(jpeg->vfd_decoder, jpeg);
1984 v4l2_info(&jpeg->v4l2_dev,
1985 "decoder device registered as /dev/video%d\n",
1986 jpeg->vfd_decoder->num);
1987
1988 /* final statements & power management */
1989 platform_set_drvdata(pdev, jpeg);
1990
1991 pm_runtime_enable(&pdev->dev);
1992
1993 v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
1994
1995 return 0;
1996
1997dec_vdev_alloc_rollback:
1998 video_device_release(jpeg->vfd_decoder);
1999
2000enc_vdev_register_rollback:
2001 video_unregister_device(jpeg->vfd_encoder);
2002
2003enc_vdev_alloc_rollback:
2004 video_device_release(jpeg->vfd_encoder);
2005
2006vb2_allocator_rollback:
2007 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2008
2009m2m_init_rollback:
2010 v4l2_m2m_release(jpeg->m2m_dev);
2011
2012device_register_rollback:
2013 v4l2_device_unregister(&jpeg->v4l2_dev);
2014
2015clk_get_rollback:
bb677f3a
AP
2016 clk_put(jpeg->clk);
2017
bb677f3a
AP
2018 return ret;
2019}
2020
2021static int s5p_jpeg_remove(struct platform_device *pdev)
2022{
2023 struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
2024
2025 pm_runtime_disable(jpeg->dev);
2026
2027 video_unregister_device(jpeg->vfd_decoder);
2028 video_device_release(jpeg->vfd_decoder);
2029 video_unregister_device(jpeg->vfd_encoder);
2030 video_device_release(jpeg->vfd_encoder);
2031 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2032 v4l2_m2m_release(jpeg->m2m_dev);
2033 v4l2_device_unregister(&jpeg->v4l2_dev);
2034
f1347132
JA
2035 if (!pm_runtime_status_suspended(&pdev->dev))
2036 clk_disable_unprepare(jpeg->clk);
2037
bb677f3a
AP
2038 clk_put(jpeg->clk);
2039
bb677f3a
AP
2040 return 0;
2041}
2042
2043static int s5p_jpeg_runtime_suspend(struct device *dev)
2044{
f1347132
JA
2045 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2046
2047 clk_disable_unprepare(jpeg->clk);
2048
bb677f3a
AP
2049 return 0;
2050}
2051
2052static int s5p_jpeg_runtime_resume(struct device *dev)
2053{
2054 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
b3c932a9 2055 unsigned long flags;
f1347132
JA
2056 int ret;
2057
2058 ret = clk_prepare_enable(jpeg->clk);
2059 if (ret < 0)
2060 return ret;
31dc0ac0 2061
b3c932a9
JA
2062 spin_lock_irqsave(&jpeg->slock, flags);
2063
bb677f3a
AP
2064 /*
2065 * JPEG IP allows storing two Huffman tables for each component
80529ae5
JA
2066 * We fill table 0 for each component and do this here only
2067 * for S5PC210 device as Exynos4x12 requires programming its
2068 * Huffman tables each time the encoding process is initialized.
bb677f3a 2069 */
80529ae5
JA
2070 if (jpeg->variant->version == SJPEG_S5P) {
2071 s5p_jpeg_set_hdctbl(jpeg->regs);
2072 s5p_jpeg_set_hdctblg(jpeg->regs);
2073 s5p_jpeg_set_hactbl(jpeg->regs);
2074 s5p_jpeg_set_hactblg(jpeg->regs);
2075 }
31dc0ac0 2076
b3c932a9
JA
2077 spin_unlock_irqrestore(&jpeg->slock, flags);
2078
bb677f3a
AP
2079 return 0;
2080}
2081
f1347132
JA
2082static int s5p_jpeg_suspend(struct device *dev)
2083{
2084 if (pm_runtime_suspended(dev))
2085 return 0;
2086
2087 return s5p_jpeg_runtime_suspend(dev);
2088}
2089
2090static int s5p_jpeg_resume(struct device *dev)
2091{
2092 if (pm_runtime_suspended(dev))
2093 return 0;
2094
2095 return s5p_jpeg_runtime_resume(dev);
2096}
2097
bb677f3a 2098static const struct dev_pm_ops s5p_jpeg_pm_ops = {
f1347132
JA
2099 SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
2100 SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL)
bb677f3a
AP
2101};
2102
f7074ab3 2103#ifdef CONFIG_OF
80529ae5
JA
2104static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
2105 .version = SJPEG_S5P,
2106 .jpeg_irq = s5p_jpeg_irq,
f7074ab3 2107};
80529ae5
JA
2108
2109static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
2110 .version = SJPEG_EXYNOS4,
2111 .jpeg_irq = exynos4_jpeg_irq,
2112};
2113
2114static const struct of_device_id samsung_jpeg_match[] = {
2115 {
2116 .compatible = "samsung,s5pv210-jpeg",
2117 .data = &s5p_jpeg_drvdata,
2118 }, {
2119 .compatible = "samsung,exynos4210-jpeg",
2120 .data = &s5p_jpeg_drvdata,
2121 }, {
2122 .compatible = "samsung,exynos4212-jpeg",
2123 .data = &exynos4_jpeg_drvdata,
2124 },
2125 {},
2126};
2127
2128MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
2129
2130static void *jpeg_get_drv_data(struct platform_device *pdev)
2131{
2132 struct s5p_jpeg_variant *driver_data = NULL;
2133 const struct of_device_id *match;
2134
2135 match = of_match_node(of_match_ptr(samsung_jpeg_match),
2136 pdev->dev.of_node);
2137 if (match)
2138 driver_data = (struct s5p_jpeg_variant *)match->data;
2139
2140 return driver_data;
2141}
f7074ab3
SN
2142#endif
2143
bb677f3a
AP
2144static struct platform_driver s5p_jpeg_driver = {
2145 .probe = s5p_jpeg_probe,
2146 .remove = s5p_jpeg_remove,
2147 .driver = {
80529ae5
JA
2148 .of_match_table = of_match_ptr(samsung_jpeg_match),
2149 .owner = THIS_MODULE,
2150 .name = S5P_JPEG_M2M_NAME,
2151 .pm = &s5p_jpeg_pm_ops,
bb677f3a
AP
2152 },
2153};
2154
87e94294 2155module_platform_driver(s5p_jpeg_driver);
bb677f3a
AP
2156
2157MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
80529ae5 2158MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
bb677f3a
AP
2159MODULE_DESCRIPTION("Samsung JPEG codec driver");
2160MODULE_LICENSE("GPL");
This page took 0.341448 seconds and 5 git commands to generate.