1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * V4L2 driver for the JPEG encoder/decoder from i.MX8QXP/i.MX8QM application
4 * processors.
5 *
6 * The multi-planar buffers API is used.
7 *
8 * Baseline and extended sequential jpeg decoding is supported.
9 * Progressive jpeg decoding is not supported by the IP.
10 * Supports encode and decode of various formats:
11 * YUV444, YUV422, YUV420, BGR, ABGR, Gray
12 * YUV420 is the only multi-planar format supported.
13 * Minimum resolution is 64 x 64, maximum 8192 x 8192.
14 * To achieve 8192 x 8192, modify in defconfig: CONFIG_CMA_SIZE_MBYTES=320
15 * The alignment requirements for the resolution depend on the format,
16 * multiple of 16 resolutions should work for all formats.
17 * Special workarounds are made in the driver to support NV12 1080p.
18 * When decoding, the driver detects image resolution and pixel format
19 * from the jpeg stream, by parsing the jpeg markers.
20 *
21 * The IP has 4 slots available for context switching, but only slot 0
22 * was fully tested to work. Context switching is not used by the driver.
23 * Each driver instance (context) allocates a slot for itself, but this
24 * is postponed until device_run, to allow unlimited opens.
25 *
26 * The driver submits jobs to the IP by setting up a descriptor for the
27 * used slot, and then validating it. The encoder has an additional descriptor
28 * for the configuration phase. The driver expects FRM_DONE interrupt from
29 * IP to mark the job as finished.
30 *
31 * The decoder IP has some limitations regarding the component ID's,
32 * but the driver works around this by replacing them in the jpeg stream.
33 *
34 * A module parameter is available for debug purpose (jpeg_tracing), to enable
35 * it, enable dynamic debug for this module and:
36 * echo 1 > /sys/module/mxc_jpeg_encdec/parameters/jpeg_tracing
37 *
38 * This is inspired by the drivers/media/platform/samsung/s5p-jpeg driver
39 *
40 * Copyright 2018-2019 NXP
41 */
42
43 #include <linux/kernel.h>
44 #include <linux/module.h>
45 #include <linux/io.h>
46 #include <linux/clk.h>
47 #include <linux/of_platform.h>
48 #include <linux/platform_device.h>
49 #include <linux/slab.h>
50 #include <linux/irqreturn.h>
51 #include <linux/interrupt.h>
52 #include <linux/pm_runtime.h>
53 #include <linux/pm_domain.h>
54 #include <linux/string.h>
55
56 #include <media/v4l2-jpeg.h>
57 #include <media/v4l2-mem2mem.h>
58 #include <media/v4l2-ioctl.h>
59 #include <media/v4l2-common.h>
60 #include <media/v4l2-event.h>
61 #include <media/videobuf2-dma-contig.h>
62
63 #include "mxc-jpeg-hw.h"
64 #include "mxc-jpeg.h"
65
66 static const struct mxc_jpeg_fmt mxc_formats[] = {
67 {
68 .name = "JPEG",
69 .fourcc = V4L2_PIX_FMT_JPEG,
70 .subsampling = -1,
71 .nc = -1,
72 .mem_planes = 1,
73 .comp_planes = 1,
74 .flags = MXC_JPEG_FMT_TYPE_ENC,
75 },
76 {
77 .name = "BGR", /*BGR packed format*/
78 .fourcc = V4L2_PIX_FMT_BGR24,
79 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
80 .nc = 3,
81 .depth = 24,
82 .mem_planes = 1,
83 .comp_planes = 1,
84 .h_align = 3,
85 .v_align = 3,
86 .flags = MXC_JPEG_FMT_TYPE_RAW,
87 .precision = 8,
88 .is_rgb = 1,
89 },
90 {
91 .name = "BGR 12bit", /*12-bit BGR packed format*/
92 .fourcc = V4L2_PIX_FMT_BGR48_12,
93 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
94 .nc = 3,
95 .depth = 36,
96 .mem_planes = 1,
97 .comp_planes = 1,
98 .h_align = 3,
99 .v_align = 3,
100 .flags = MXC_JPEG_FMT_TYPE_RAW,
101 .precision = 12,
102 .is_rgb = 1,
103 },
104 {
105 .name = "ABGR", /* ABGR packed format */
106 .fourcc = V4L2_PIX_FMT_ABGR32,
107 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
108 .nc = 4,
109 .depth = 32,
110 .mem_planes = 1,
111 .comp_planes = 1,
112 .h_align = 3,
113 .v_align = 3,
114 .flags = MXC_JPEG_FMT_TYPE_RAW,
115 .precision = 8,
116 .is_rgb = 1,
117 },
118 {
119 .name = "ABGR 12bit", /* 12-bit ABGR packed format */
120 .fourcc = V4L2_PIX_FMT_ABGR64_12,
121 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
122 .nc = 4,
123 .depth = 48,
124 .mem_planes = 1,
125 .comp_planes = 1,
126 .h_align = 3,
127 .v_align = 3,
128 .flags = MXC_JPEG_FMT_TYPE_RAW,
129 .precision = 12,
130 .is_rgb = 1,
131 },
132 {
133 .name = "YUV420", /* 1st plane = Y, 2nd plane = UV */
134 .fourcc = V4L2_PIX_FMT_NV12M,
135 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
136 .nc = 3,
137 .depth = 12, /* 6 bytes (4Y + UV) for 4 pixels */
138 .mem_planes = 2,
139 .comp_planes = 2, /* 1 plane Y, 1 plane UV interleaved */
140 .h_align = 4,
141 .v_align = 4,
142 .flags = MXC_JPEG_FMT_TYPE_RAW,
143 .precision = 8,
144 },
145 {
146 .name = "YUV420", /* 1st plane = Y, 2nd plane = UV */
147 .fourcc = V4L2_PIX_FMT_NV12,
148 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
149 .nc = 3,
150 .depth = 12, /* 6 bytes (4Y + UV) for 4 pixels */
151 .mem_planes = 1,
152 .comp_planes = 2, /* 1 plane Y, 1 plane UV interleaved */
153 .h_align = 4,
154 .v_align = 4,
155 .flags = MXC_JPEG_FMT_TYPE_RAW,
156 .precision = 8,
157 },
158 {
159 .name = "YUV420 12bit", /* 1st plane = Y, 2nd plane = UV */
160 .fourcc = V4L2_PIX_FMT_P012M,
161 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
162 .nc = 3,
163 .depth = 18, /* 6 x 12 bits (4Y + UV) for 4 pixels */
164 .mem_planes = 2,
165 .comp_planes = 2, /* 1 plane Y, 1 plane UV interleaved */
166 .h_align = 4,
167 .v_align = 4,
168 .flags = MXC_JPEG_FMT_TYPE_RAW,
169 .precision = 12,
170 },
171 {
172 .name = "YUV420 12bit", /* 1st plane = Y, 2nd plane = UV */
173 .fourcc = V4L2_PIX_FMT_P012,
174 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
175 .nc = 3,
176 .depth = 18, /* 6 x 12 bits (4Y + UV) for 4 pixels */
177 .mem_planes = 1,
178 .comp_planes = 2, /* 1 plane Y, 1 plane UV interleaved */
179 .h_align = 4,
180 .v_align = 4,
181 .flags = MXC_JPEG_FMT_TYPE_RAW,
182 .precision = 12,
183 },
184 {
185 .name = "YUV422", /* YUYV */
186 .fourcc = V4L2_PIX_FMT_YUYV,
187 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
188 .nc = 3,
189 .depth = 16,
190 .mem_planes = 1,
191 .comp_planes = 1,
192 .h_align = 4,
193 .v_align = 3,
194 .flags = MXC_JPEG_FMT_TYPE_RAW,
195 .precision = 8,
196 },
197 {
198 .name = "YUV422 12bit", /* YUYV */
199 .fourcc = V4L2_PIX_FMT_Y212,
200 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
201 .nc = 3,
202 .depth = 24,
203 .mem_planes = 1,
204 .comp_planes = 1,
205 .h_align = 4,
206 .v_align = 3,
207 .flags = MXC_JPEG_FMT_TYPE_RAW,
208 .precision = 12,
209 },
210 {
211 .name = "YUV444", /* YUVYUV */
212 .fourcc = V4L2_PIX_FMT_YUV24,
213 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
214 .nc = 3,
215 .depth = 24,
216 .mem_planes = 1,
217 .comp_planes = 1,
218 .h_align = 3,
219 .v_align = 3,
220 .flags = MXC_JPEG_FMT_TYPE_RAW,
221 .precision = 8,
222 },
223 {
224 .name = "YUV444 12bit", /* YUVYUV */
225 .fourcc = V4L2_PIX_FMT_YUV48_12,
226 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
227 .nc = 3,
228 .depth = 36,
229 .mem_planes = 1,
230 .comp_planes = 1,
231 .h_align = 3,
232 .v_align = 3,
233 .flags = MXC_JPEG_FMT_TYPE_RAW,
234 .precision = 12,
235 },
236 {
237 .name = "Gray", /* Gray (Y8/Y12) or Single Comp */
238 .fourcc = V4L2_PIX_FMT_GREY,
239 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
240 .nc = 1,
241 .depth = 8,
242 .mem_planes = 1,
243 .comp_planes = 1,
244 .h_align = 3,
245 .v_align = 3,
246 .flags = MXC_JPEG_FMT_TYPE_RAW,
247 .precision = 8,
248 },
249 {
250 .name = "Gray 12bit", /* Gray (Y8/Y12) or Single Comp */
251 .fourcc = V4L2_PIX_FMT_Y012,
252 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
253 .nc = 1,
254 .depth = 12,
255 .mem_planes = 1,
256 .comp_planes = 1,
257 .h_align = 3,
258 .v_align = 3,
259 .flags = MXC_JPEG_FMT_TYPE_RAW,
260 .precision = 12,
261 },
262 };
263
264 #define MXC_JPEG_NUM_FORMATS ARRAY_SIZE(mxc_formats)
265
266 static const int mxc_decode_mode = MXC_JPEG_DECODE;
267 static const int mxc_encode_mode = MXC_JPEG_ENCODE;
268
269 static const struct of_device_id mxc_jpeg_match[] = {
270 {
271 .compatible = "nxp,imx8qxp-jpgdec",
272 .data = &mxc_decode_mode,
273 },
274 {
275 .compatible = "nxp,imx8qxp-jpgenc",
276 .data = &mxc_encode_mode,
277 },
278 { },
279 };
280
281 /*
282 * default configuration stream, 64x64 yuv422
283 * split by JPEG marker, so it's easier to modify & use
284 */
285 static const unsigned char jpeg_soi[] = {
286 0xFF, 0xD8
287 };
288
289 static const unsigned char jpeg_app0[] = {
290 0xFF, 0xE0,
291 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00,
292 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
293 0x00, 0x00
294 };
295
296 static const unsigned char jpeg_app14[] = {
297 0xFF, 0xEE,
298 0x00, 0x0E, 0x41, 0x64, 0x6F, 0x62, 0x65,
299 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00
300 };
301
302 static const unsigned char jpeg_dqt[] = {
303 0xFF, 0xDB,
304 0x00, 0x84, 0x00, 0x10, 0x0B, 0x0C, 0x0E,
305 0x0C, 0x0A, 0x10, 0x0E, 0x0D, 0x0E, 0x12,
306 0x11, 0x10, 0x13, 0x18, 0x28, 0x1A, 0x18,
307 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1D,
308 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33,
309 0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40,
310 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6D,
311 0x51, 0x57, 0x5F, 0x62, 0x67, 0x68, 0x67,
312 0x3E, 0x4D, 0x71, 0x79, 0x70, 0x64, 0x78,
313 0x5C, 0x65, 0x67, 0x63, 0x01, 0x11, 0x12,
314 0x12, 0x18, 0x15, 0x18, 0x2F, 0x1A, 0x1A,
315 0x2F, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
316 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
317 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
318 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
319 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
320 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
321 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
322 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
323 };
324
325 static const unsigned char jpeg_dqt_extseq[] = {
326 0xFF, 0xDB,
327 0x01, 0x04,
328 0x10,
329 0x00, 0x80, 0x00, 0x58, 0x00, 0x60, 0x00, 0x70,
330 0x00, 0x60, 0x00, 0x50, 0x00, 0x80, 0x00, 0x70,
331 0x00, 0x68, 0x00, 0x70, 0x00, 0x90, 0x00, 0x88,
332 0x00, 0x80, 0x00, 0x98, 0x00, 0xC0, 0x01, 0x40,
333 0x00, 0xD0, 0x00, 0xC0, 0x00, 0xB0, 0x00, 0xB0,
334 0x00, 0xC0, 0x01, 0x88, 0x01, 0x18, 0x01, 0x28,
335 0x00, 0xE8, 0x01, 0x40, 0x01, 0xD0, 0x01, 0x98,
336 0x01, 0xE8, 0x01, 0xE0, 0x01, 0xC8, 0x01, 0x98,
337 0x01, 0xC0, 0x01, 0xB8, 0x02, 0x00, 0x02, 0x40,
338 0x02, 0xE0, 0x02, 0x70, 0x02, 0x00, 0x02, 0x20,
339 0x02, 0xB8, 0x02, 0x28, 0x01, 0xB8, 0x01, 0xC0,
340 0x02, 0x80, 0x03, 0x68, 0x02, 0x88, 0x02, 0xB8,
341 0x02, 0xF8, 0x03, 0x10, 0x03, 0x38, 0x03, 0x40,
342 0x03, 0x38, 0x01, 0xF0, 0x02, 0x68, 0x03, 0x88,
343 0x03, 0xC8, 0x03, 0x80, 0x03, 0x20, 0x03, 0xC0,
344 0x02, 0xE0, 0x03, 0x28, 0x03, 0x38, 0x03, 0x18,
345 0x11,
346 0x00, 0x88, 0x00, 0x90, 0x00, 0x90, 0x00, 0xC0,
347 0x00, 0xA8, 0x00, 0xC0, 0x01, 0x78, 0x00, 0xD0,
348 0x00, 0xD0, 0x01, 0x78, 0x03, 0x18, 0x02, 0x10,
349 0x01, 0xC0, 0x02, 0x10, 0x03, 0x18, 0x03, 0x18,
350 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18,
351 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18,
352 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18,
353 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18,
354 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18,
355 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18,
356 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18,
357 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18,
358 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18,
359 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18,
360 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18,
361 0x03, 0x18, 0x03, 0x18, 0x03, 0x18, 0x03, 0x18,
362 };
363
364 static const unsigned char jpeg_sof_maximal[] = {
365 0xFF, 0xC0,
366 0x00, 0x14, 0x08, 0x00, 0x40, 0x00, 0x40,
367 0x04, 0x01, 0x11, 0x00, 0x02, 0x11, 0x01,
368 0x03, 0x11, 0x01, 0x04, 0x11, 0x01
369 };
370
371 static const unsigned char jpeg_sof_extseq[] = {
372 0xFF, 0xC1,
373 0x00, 0x14, 0x08, 0x00, 0x40, 0x00, 0x40,
374 0x04, 0x01, 0x11, 0x00, 0x02, 0x11, 0x01,
375 0x03, 0x11, 0x01, 0x04, 0x11, 0x01
376 };
377
378 static const unsigned char jpeg_dht[] = {
379 0xFF, 0xC4,
380 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05, 0x01,
381 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
383 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
384 0x09, 0x0A, 0x0B, 0x10, 0x00, 0x02, 0x01,
385 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05,
386 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01,
387 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
388 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
389 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91,
390 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15,
391 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72,
392 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19,
393 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
394 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
395 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
396 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
397 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67,
398 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76,
399 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85,
400 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93,
401 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
402 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
403 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
404 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4,
405 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2,
406 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
407 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
408 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
409 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
410 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01,
411 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
412 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
413 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
414 0x0B, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04,
415 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04,
416 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02,
417 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06,
418 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13,
419 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
420 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52,
421 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16,
422 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18,
423 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
424 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43,
425 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A,
426 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
427 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
428 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77,
429 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85,
430 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93,
431 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
432 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
433 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
434 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4,
435 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2,
436 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
437 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
438 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5,
439 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
440 };
441
442 static const unsigned char jpeg_dht_extseq[] = {
443 0xFF, 0xC4,
444 0x02, 0x2a, 0x00, 0x00, 0x01, 0x05, 0x01,
445 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
446 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
447 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
448 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
449 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02,
450 0x04, 0x03, 0x05, 0x05, 0x02, 0x03, 0x02,
451 0x00, 0x00, 0xbf, 0x01, 0x02, 0x03, 0x00,
452 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41,
453 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71,
454 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23,
455 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
456 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a,
457 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26,
458 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36,
459 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
460 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54,
461 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63,
462 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
463 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
464 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
465 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
466 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4,
467 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2,
468 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
469 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
470 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5,
471 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
472 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
473 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
474 0xf7, 0xf8, 0xf9, 0xfa, 0x0b, 0x0c, 0x0d,
475 0x0e, 0x1b, 0x1c, 0x1d, 0x1e, 0x2b, 0x2c,
476 0x2d, 0x2e, 0x3b, 0x3c, 0x3d, 0x3e, 0x4b,
477 0x4c, 0x4d, 0x4e, 0x5b, 0x5c, 0x5d, 0x5e,
478 0x6b, 0x6c, 0x6d, 0x6e, 0x7b, 0x7c, 0x7d,
479 0x7e, 0x8b, 0x8c, 0x8d, 0x8e, 0x9b, 0x9c,
480 0x9d, 0x9e, 0xab, 0xac, 0xad, 0xae, 0xbb,
481 0xbc, 0xbd, 0xbe, 0xcb, 0xcc, 0xcd, 0xce,
482 0xdb, 0xdc, 0xdd, 0xde, 0xeb, 0xec, 0xed,
483 0xee, 0xfb, 0xfc, 0xfd, 0xfe, 0x01, 0x00,
484 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
485 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
486 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
487 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
488 0x0d, 0x0e, 0x0f, 0x11, 0x00, 0x02, 0x01,
489 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05,
490 0x02, 0x03, 0x02, 0x00, 0x00, 0xbf, 0x01,
491 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
492 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
493 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91,
494 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15,
495 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
496 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19,
497 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
498 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
499 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
500 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
501 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67,
502 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
503 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85,
504 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93,
505 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
506 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
507 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
508 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4,
509 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
510 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
511 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
512 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3,
513 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
514 0x0b, 0x0c, 0x0d, 0x0e, 0x1b, 0x1c, 0x1d,
515 0x1e, 0x2b, 0x2c, 0x2d, 0x2e, 0x3b, 0x3c,
516 0x3d, 0x3e, 0x4b, 0x4c, 0x4d, 0x4e, 0x5b,
517 0x5c, 0x5d, 0x5e, 0x6b, 0x6c, 0x6d, 0x6e,
518 0x7b, 0x7c, 0x7d, 0x7e, 0x8b, 0x8c, 0x8d,
519 0x8e, 0x9b, 0x9c, 0x9d, 0x9e, 0xab, 0xac,
520 0xad, 0xae, 0xbb, 0xbc, 0xbd, 0xbe, 0xcb,
521 0xcc, 0xcd, 0xce, 0xdb, 0xdc, 0xdd, 0xde,
522 0xeb, 0xec, 0xed, 0xee, 0xfb, 0xfc, 0xfd,
523 0xfe,
524 };
525
526 static const unsigned char jpeg_dri[] = {
527 0xFF, 0xDD,
528 0x00, 0x04, 0x00, 0x20
529 };
530
531 static const unsigned char jpeg_sos_maximal[] = {
532 0xFF, 0xDA,
533 0x00, 0x0C, 0x04, 0x01, 0x00, 0x02, 0x11, 0x03,
534 0x11, 0x04, 0x11, 0x00, 0x3F, 0x00
535 };
536
537 static const unsigned char jpeg_image_red[] = {
538 0xF9, 0xFE, 0x8A, 0xFC, 0x34, 0xFD, 0xC4, 0x28,
539 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A,
540 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0,
541 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00,
542 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02,
543 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28,
544 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A,
545 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0,
546 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00,
547 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02,
548 0x8A, 0x00, 0x28, 0xA0, 0x0F, 0xFF, 0xD0, 0xF9,
549 0xFE, 0x8A, 0xFC, 0x34, 0xFD, 0xC4, 0x28, 0xA0,
550 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00,
551 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02,
552 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28,
553 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A,
554 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0,
555 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00,
556 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02,
557 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A, 0x00, 0x28,
558 0xA0, 0x02, 0x8A, 0x00, 0x28, 0xA0, 0x02, 0x8A,
559 0x00, 0x28, 0xA0, 0x0F
560 };
561
562 static const unsigned char jpeg_eoi[] = {
563 0xFF, 0xD9
564 };
565
566 struct mxc_jpeg_src_buf {
567 /* common v4l buffer stuff -- must be first */
568 struct vb2_v4l2_buffer b;
569 struct list_head list;
570
571 /* mxc-jpeg specific */
572 bool dht_needed;
573 bool jpeg_parse_error;
574 const struct mxc_jpeg_fmt *fmt;
575 int w;
576 int h;
577 };
578
vb2_to_mxc_buf(struct vb2_buffer * vb)579 static inline struct mxc_jpeg_src_buf *vb2_to_mxc_buf(struct vb2_buffer *vb)
580 {
581 return container_of(to_vb2_v4l2_buffer(vb),
582 struct mxc_jpeg_src_buf, b);
583 }
584
585 static unsigned int debug;
586 module_param(debug, int, 0644);
587 MODULE_PARM_DESC(debug, "Debug level (0-3)");
588
589 static unsigned int hw_timeout = 2000;
590 module_param(hw_timeout, int, 0644);
591 MODULE_PARM_DESC(hw_timeout, "MXC JPEG hw timeout, the number of milliseconds");
592
593 static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision);
594 static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q);
595
_bswap16(u16 * a)596 static void _bswap16(u16 *a)
597 {
598 *a = ((*a & 0x00FF) << 8) | ((*a & 0xFF00) >> 8);
599 }
600
mxc_jpeg_get_plane_dma_addr(struct vb2_buffer * buf,unsigned int plane_no)601 static dma_addr_t mxc_jpeg_get_plane_dma_addr(struct vb2_buffer *buf, unsigned int plane_no)
602 {
603 if (plane_no >= buf->num_planes)
604 return 0;
605 return vb2_dma_contig_plane_dma_addr(buf, plane_no) + buf->planes[plane_no].data_offset;
606 }
607
mxc_jpeg_get_plane_vaddr(struct vb2_buffer * buf,unsigned int plane_no)608 static void *mxc_jpeg_get_plane_vaddr(struct vb2_buffer *buf, unsigned int plane_no)
609 {
610 if (plane_no >= buf->num_planes)
611 return NULL;
612 return vb2_plane_vaddr(buf, plane_no) + buf->planes[plane_no].data_offset;
613 }
614
mxc_jpeg_get_plane_payload(struct vb2_buffer * buf,unsigned int plane_no)615 static unsigned long mxc_jpeg_get_plane_payload(struct vb2_buffer *buf, unsigned int plane_no)
616 {
617 if (plane_no >= buf->num_planes)
618 return 0;
619 return vb2_get_plane_payload(buf, plane_no) - buf->planes[plane_no].data_offset;
620 }
621
print_mxc_buf(struct mxc_jpeg_dev * jpeg,struct vb2_buffer * buf,unsigned long len)622 static void print_mxc_buf(struct mxc_jpeg_dev *jpeg, struct vb2_buffer *buf,
623 unsigned long len)
624 {
625 unsigned int plane_no;
626 u32 dma_addr;
627 void *vaddr;
628 unsigned long payload;
629
630 if (debug < 3)
631 return;
632
633 for (plane_no = 0; plane_no < buf->num_planes; plane_no++) {
634 payload = mxc_jpeg_get_plane_payload(buf, plane_no);
635 if (len == 0)
636 len = payload;
637 dma_addr = mxc_jpeg_get_plane_dma_addr(buf, plane_no);
638 vaddr = mxc_jpeg_get_plane_vaddr(buf, plane_no);
639 v4l2_dbg(3, debug, &jpeg->v4l2_dev,
640 "plane %d (vaddr=%p dma_addr=%x payload=%ld):",
641 plane_no, vaddr, dma_addr, payload);
642 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
643 vaddr, len, false);
644 }
645 }
646
mxc_jpeg_fh_to_ctx(struct v4l2_fh * fh)647 static inline struct mxc_jpeg_ctx *mxc_jpeg_fh_to_ctx(struct v4l2_fh *fh)
648 {
649 return container_of(fh, struct mxc_jpeg_ctx, fh);
650 }
651
enum_fmt(const struct mxc_jpeg_fmt * mxc_formats,int n,struct v4l2_fmtdesc * f,u32 type)652 static int enum_fmt(const struct mxc_jpeg_fmt *mxc_formats, int n,
653 struct v4l2_fmtdesc *f, u32 type)
654 {
655 int i, num = 0;
656
657 for (i = 0; i < n; ++i) {
658 if (mxc_formats[i].flags == type) {
659 /* index-th format of searched type found ? */
660 if (num == f->index)
661 break;
662 /* Correct type but haven't reached our index yet,
663 * just increment per-type index
664 */
665 ++num;
666 }
667 }
668
669 /* Format not found */
670 if (i >= n)
671 return -EINVAL;
672
673 f->pixelformat = mxc_formats[i].fourcc;
674
675 return 0;
676 }
677
mxc_jpeg_find_format(u32 pixelformat)678 static const struct mxc_jpeg_fmt *mxc_jpeg_find_format(u32 pixelformat)
679 {
680 unsigned int k;
681
682 for (k = 0; k < MXC_JPEG_NUM_FORMATS; k++) {
683 const struct mxc_jpeg_fmt *fmt = &mxc_formats[k];
684
685 if (fmt->fourcc == pixelformat)
686 return fmt;
687 }
688 return NULL;
689 }
690
mxc_jpeg_fourcc_to_imgfmt(u32 fourcc)691 static enum mxc_jpeg_image_format mxc_jpeg_fourcc_to_imgfmt(u32 fourcc)
692 {
693 switch (fourcc) {
694 case V4L2_PIX_FMT_GREY:
695 case V4L2_PIX_FMT_Y012:
696 return MXC_JPEG_GRAY;
697 case V4L2_PIX_FMT_YUYV:
698 case V4L2_PIX_FMT_Y212:
699 return MXC_JPEG_YUV422;
700 case V4L2_PIX_FMT_NV12:
701 case V4L2_PIX_FMT_NV12M:
702 case V4L2_PIX_FMT_P012:
703 case V4L2_PIX_FMT_P012M:
704 return MXC_JPEG_YUV420;
705 case V4L2_PIX_FMT_YUV24:
706 case V4L2_PIX_FMT_YUV48_12:
707 return MXC_JPEG_YUV444;
708 case V4L2_PIX_FMT_BGR24:
709 case V4L2_PIX_FMT_BGR48_12:
710 return MXC_JPEG_BGR;
711 case V4L2_PIX_FMT_ABGR32:
712 case V4L2_PIX_FMT_ABGR64_12:
713 return MXC_JPEG_ABGR;
714 default:
715 return MXC_JPEG_INVALID;
716 }
717 }
718
mxc_jpeg_get_q_data(struct mxc_jpeg_ctx * ctx,enum v4l2_buf_type type)719 static struct mxc_jpeg_q_data *mxc_jpeg_get_q_data(struct mxc_jpeg_ctx *ctx,
720 enum v4l2_buf_type type)
721 {
722 if (V4L2_TYPE_IS_OUTPUT(type))
723 return &ctx->out_q;
724 return &ctx->cap_q;
725 }
726
mxc_jpeg_addrs(struct mxc_jpeg_desc * desc,struct vb2_buffer * raw_buf,struct vb2_buffer * jpeg_buf,int offset)727 static void mxc_jpeg_addrs(struct mxc_jpeg_desc *desc,
728 struct vb2_buffer *raw_buf,
729 struct vb2_buffer *jpeg_buf, int offset)
730 {
731 int img_fmt = desc->stm_ctrl & STM_CTRL_IMAGE_FORMAT_MASK;
732 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(raw_buf->vb2_queue);
733 struct mxc_jpeg_q_data *q_data;
734
735 q_data = mxc_jpeg_get_q_data(ctx, raw_buf->type);
736 desc->buf_base0 = mxc_jpeg_get_plane_dma_addr(raw_buf, 0);
737 desc->buf_base1 = 0;
738 if (img_fmt == STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV420)) {
739 if (raw_buf->num_planes == 2)
740 desc->buf_base1 = mxc_jpeg_get_plane_dma_addr(raw_buf, 1);
741 else
742 desc->buf_base1 = desc->buf_base0 + q_data->sizeimage[0];
743 }
744 desc->stm_bufbase = mxc_jpeg_get_plane_dma_addr(jpeg_buf, 0) + offset;
745 }
746
mxc_jpeg_is_extended_sequential(const struct mxc_jpeg_fmt * fmt)747 static bool mxc_jpeg_is_extended_sequential(const struct mxc_jpeg_fmt *fmt)
748 {
749 if (!fmt || !(fmt->flags & MXC_JPEG_FMT_TYPE_RAW))
750 return false;
751
752 if (fmt->precision > 8)
753 return true;
754
755 return false;
756 }
757
notify_eos(struct mxc_jpeg_ctx * ctx)758 static void notify_eos(struct mxc_jpeg_ctx *ctx)
759 {
760 const struct v4l2_event ev = {
761 .type = V4L2_EVENT_EOS
762 };
763
764 dev_dbg(ctx->mxc_jpeg->dev, "Notify app event EOS reached");
765 v4l2_event_queue_fh(&ctx->fh, &ev);
766 }
767
notify_src_chg(struct mxc_jpeg_ctx * ctx)768 static void notify_src_chg(struct mxc_jpeg_ctx *ctx)
769 {
770 const struct v4l2_event ev = {
771 .type = V4L2_EVENT_SOURCE_CHANGE,
772 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
773 };
774
775 dev_dbg(ctx->mxc_jpeg->dev, "Notify app event SRC_CH_RESOLUTION");
776 v4l2_event_queue_fh(&ctx->fh, &ev);
777 }
778
mxc_get_free_slot(struct mxc_jpeg_slot_data * slot_data)779 static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data)
780 {
781 if (!slot_data->used)
782 return slot_data->slot;
783 return -1;
784 }
785
mxc_jpeg_free_slot_data(struct mxc_jpeg_dev * jpeg)786 static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
787 {
788 /* free descriptor for decoding/encoding phase */
789 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
790 jpeg->slot_data.desc,
791 jpeg->slot_data.desc_handle);
792 jpeg->slot_data.desc = NULL;
793 jpeg->slot_data.desc_handle = 0;
794
795 /* free descriptor for encoder configuration phase / decoder DHT */
796 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
797 jpeg->slot_data.cfg_desc,
798 jpeg->slot_data.cfg_desc_handle);
799 jpeg->slot_data.cfg_desc_handle = 0;
800 jpeg->slot_data.cfg_desc = NULL;
801
802 /* free configuration stream */
803 dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
804 jpeg->slot_data.cfg_stream_vaddr,
805 jpeg->slot_data.cfg_stream_handle);
806 jpeg->slot_data.cfg_stream_vaddr = NULL;
807 jpeg->slot_data.cfg_stream_handle = 0;
808
809 dma_free_coherent(jpeg->dev, jpeg->slot_data.cfg_dec_size,
810 jpeg->slot_data.cfg_dec_vaddr,
811 jpeg->slot_data.cfg_dec_daddr);
812 jpeg->slot_data.cfg_dec_size = 0;
813 jpeg->slot_data.cfg_dec_vaddr = NULL;
814 jpeg->slot_data.cfg_dec_daddr = 0;
815
816 jpeg->slot_data.used = false;
817 }
818
mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev * jpeg)819 static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
820 {
821 struct mxc_jpeg_desc *desc;
822 struct mxc_jpeg_desc *cfg_desc;
823 void *cfg_stm;
824
825 if (jpeg->slot_data.desc)
826 goto skip_alloc; /* already allocated, reuse it */
827
828 /* allocate descriptor for decoding/encoding phase */
829 desc = dma_alloc_coherent(jpeg->dev,
830 sizeof(struct mxc_jpeg_desc),
831 &jpeg->slot_data.desc_handle,
832 GFP_ATOMIC);
833 if (!desc)
834 goto err;
835 jpeg->slot_data.desc = desc;
836
837 /* allocate descriptor for configuration phase (encoder only) */
838 cfg_desc = dma_alloc_coherent(jpeg->dev,
839 sizeof(struct mxc_jpeg_desc),
840 &jpeg->slot_data.cfg_desc_handle,
841 GFP_ATOMIC);
842 if (!cfg_desc)
843 goto err;
844 jpeg->slot_data.cfg_desc = cfg_desc;
845
846 /* allocate configuration stream */
847 cfg_stm = dma_alloc_coherent(jpeg->dev,
848 MXC_JPEG_MAX_CFG_STREAM,
849 &jpeg->slot_data.cfg_stream_handle,
850 GFP_ATOMIC);
851 if (!cfg_stm)
852 goto err;
853 jpeg->slot_data.cfg_stream_vaddr = cfg_stm;
854
855 jpeg->slot_data.cfg_dec_size = MXC_JPEG_PATTERN_WIDTH * MXC_JPEG_PATTERN_HEIGHT * 2;
856 jpeg->slot_data.cfg_dec_vaddr = dma_alloc_coherent(jpeg->dev,
857 jpeg->slot_data.cfg_dec_size,
858 &jpeg->slot_data.cfg_dec_daddr,
859 GFP_ATOMIC);
860 if (!jpeg->slot_data.cfg_dec_vaddr)
861 goto err;
862
863 skip_alloc:
864 jpeg->slot_data.used = true;
865
866 return true;
867 err:
868 dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot);
869 mxc_jpeg_free_slot_data(jpeg);
870
871 return false;
872 }
873
mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx * ctx,struct vb2_v4l2_buffer * src_buf,struct vb2_v4l2_buffer * dst_buf)874 static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx,
875 struct vb2_v4l2_buffer *src_buf,
876 struct vb2_v4l2_buffer *dst_buf)
877 {
878 if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) {
879 dst_buf->flags |= V4L2_BUF_FLAG_LAST;
880 v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx);
881 notify_eos(ctx);
882 ctx->header_parsed = false;
883 }
884 }
885
mxc_jpeg_job_finish(struct mxc_jpeg_ctx * ctx,enum vb2_buffer_state state,bool reset)886 static void mxc_jpeg_job_finish(struct mxc_jpeg_ctx *ctx, enum vb2_buffer_state state, bool reset)
887 {
888 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
889 void __iomem *reg = jpeg->base_reg;
890 struct vb2_v4l2_buffer *src_buf, *dst_buf;
891
892 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
893 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
894 mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf);
895 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
896 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
897 v4l2_m2m_buf_done(src_buf, state);
898 v4l2_m2m_buf_done(dst_buf, state);
899
900 mxc_jpeg_disable_irq(reg, ctx->slot);
901 jpeg->slot_data.used = false;
902 if (reset)
903 mxc_jpeg_sw_reset(reg);
904 }
905
mxc_jpeg_get_plane_size(struct mxc_jpeg_q_data * q_data,u32 plane_no)906 static u32 mxc_jpeg_get_plane_size(struct mxc_jpeg_q_data *q_data, u32 plane_no)
907 {
908 const struct mxc_jpeg_fmt *fmt = q_data->fmt;
909 u32 size;
910 int i;
911
912 if (plane_no >= fmt->mem_planes)
913 return 0;
914
915 if (fmt->mem_planes == fmt->comp_planes)
916 return q_data->sizeimage[plane_no];
917
918 if (plane_no < fmt->mem_planes - 1)
919 return q_data->sizeimage[plane_no];
920
921 size = q_data->sizeimage[fmt->mem_planes - 1];
922
923 /* Should be impossible given mxc_formats. */
924 if (WARN_ON_ONCE(fmt->comp_planes > ARRAY_SIZE(q_data->sizeimage)))
925 return size;
926
927 for (i = fmt->mem_planes; i < fmt->comp_planes; i++)
928 size += q_data->sizeimage[i];
929
930 return size;
931 }
932
mxc_dec_is_ongoing(struct mxc_jpeg_ctx * ctx)933 static bool mxc_dec_is_ongoing(struct mxc_jpeg_ctx *ctx)
934 {
935 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
936 u32 curr_desc;
937 u32 slot_status;
938
939 curr_desc = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_CUR_DESCPT_PTR));
940 if (curr_desc == jpeg->slot_data.cfg_desc_handle)
941 return true;
942
943 slot_status = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_STATUS));
944 if (slot_status & SLOT_STATUS_ONGOING)
945 return true;
946
947 /*
948 * The curr_desc register is updated when next_descpt_ptr is loaded,
949 * the ongoing bit of slot_status is set when the 32 bytes descriptor is loaded.
950 * So there will be a short time interval in between, which may cause fake false.
951 * Consider read register is quite slow compared with IP read 32byte from memory,
952 * read twice slot_status can avoid this situation.
953 */
954 slot_status = readl(jpeg->base_reg + MXC_SLOT_OFFSET(ctx->slot, SLOT_STATUS));
955 if (slot_status & SLOT_STATUS_ONGOING)
956 return true;
957
958 return false;
959 }
960
mxc_jpeg_dec_irq(int irq,void * priv)961 static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
962 {
963 struct mxc_jpeg_dev *jpeg = priv;
964 struct mxc_jpeg_ctx *ctx;
965 void __iomem *reg = jpeg->base_reg;
966 struct device *dev = jpeg->dev;
967 struct vb2_v4l2_buffer *src_buf, *dst_buf;
968 struct mxc_jpeg_src_buf *jpeg_src_buf;
969 enum vb2_buffer_state buf_state;
970 u32 dec_ret, com_status;
971 unsigned long payload;
972 struct mxc_jpeg_q_data *q_data;
973 enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
974 unsigned int slot;
975
976 spin_lock(&jpeg->hw_lock);
977
978 com_status = readl(reg + COM_STATUS);
979 slot = COM_STATUS_CUR_SLOT(com_status);
980 dev_dbg(dev, "Irq %d on slot %d.\n", irq, slot);
981
982 ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
983 if (WARN_ON(!ctx))
984 goto job_unlock;
985
986 if (slot != ctx->slot) {
987 /* TODO investigate when adding multi-instance support */
988 dev_warn(dev, "IRQ slot %d != context slot %d.\n",
989 slot, ctx->slot);
990 goto job_unlock;
991 }
992
993 if (!jpeg->slot_data.used)
994 goto job_unlock;
995
996 dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
997 writel(dec_ret, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); /* w1c */
998
999 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1000 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1001 if (!dst_buf || !src_buf) {
1002 dev_err(dev, "No source or destination buffer.\n");
1003 goto job_unlock;
1004 }
1005 jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf);
1006
1007 if (dec_ret & SLOT_STATUS_ENC_CONFIG_ERR) {
1008 u32 ret = readl(reg + CAST_STATUS12);
1009
1010 dev_err(dev, "Encoder/decoder error, dec_ret = 0x%08x, status=0x%08x",
1011 dec_ret, ret);
1012 mxc_jpeg_clr_desc(reg, slot);
1013 mxc_jpeg_sw_reset(reg);
1014 buf_state = VB2_BUF_STATE_ERROR;
1015 goto buffers_done;
1016 }
1017
1018 if (!(dec_ret & SLOT_STATUS_FRMDONE))
1019 goto job_unlock;
1020
1021 if (jpeg->mode == MXC_JPEG_ENCODE &&
1022 ctx->enc_state == MXC_JPEG_ENC_CONF) {
1023 q_data = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
1024 ctx->enc_state = MXC_JPEG_ENCODING;
1025 dev_dbg(dev, "Encoder config finished. Start encoding...\n");
1026 mxc_jpeg_enc_set_quality(dev, reg, ctx->jpeg_quality);
1027 mxc_jpeg_enc_mode_go(dev, reg, mxc_jpeg_is_extended_sequential(q_data->fmt));
1028 goto job_unlock;
1029 }
1030 if (jpeg->mode == MXC_JPEG_DECODE && jpeg_src_buf->dht_needed &&
1031 mxc_dec_is_ongoing(ctx)) {
1032 jpeg_src_buf->dht_needed = false;
1033 dev_dbg(dev, "Decoder DHT cfg finished. Start decoding...\n");
1034 goto job_unlock;
1035 }
1036
1037 if (jpeg->mode == MXC_JPEG_ENCODE) {
1038 payload = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR));
1039 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload);
1040 dev_dbg(dev, "Encoding finished, payload size: %ld\n",
1041 payload);
1042 } else {
1043 q_data = mxc_jpeg_get_q_data(ctx, cap_type);
1044 payload = mxc_jpeg_get_plane_size(q_data, 0);
1045 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload);
1046 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0);
1047 if (q_data->fmt->mem_planes == 2) {
1048 payload = mxc_jpeg_get_plane_size(q_data, 1);
1049 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, payload);
1050 }
1051 dev_dbg(dev, "Decoding finished, payload size: %ld + %ld\n",
1052 mxc_jpeg_get_plane_payload(&dst_buf->vb2_buf, 0),
1053 mxc_jpeg_get_plane_payload(&dst_buf->vb2_buf, 1));
1054 }
1055
1056 /* short preview of the results */
1057 dev_dbg(dev, "src_buf preview: ");
1058 print_mxc_buf(jpeg, &src_buf->vb2_buf, 32);
1059 dev_dbg(dev, "dst_buf preview: ");
1060 print_mxc_buf(jpeg, &dst_buf->vb2_buf, 32);
1061 buf_state = VB2_BUF_STATE_DONE;
1062
1063 buffers_done:
1064 mxc_jpeg_job_finish(ctx, buf_state, false);
1065 spin_unlock(&jpeg->hw_lock);
1066 cancel_delayed_work(&ctx->task_timer);
1067 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1068 return IRQ_HANDLED;
1069 job_unlock:
1070 spin_unlock(&jpeg->hw_lock);
1071 return IRQ_HANDLED;
1072 }
1073
mxc_jpeg_fixup_sof(struct mxc_jpeg_sof * sof,u32 fourcc,u16 w,u16 h)1074 static int mxc_jpeg_fixup_sof(struct mxc_jpeg_sof *sof,
1075 u32 fourcc,
1076 u16 w, u16 h)
1077 {
1078 int sof_length;
1079 const struct mxc_jpeg_fmt *fmt = mxc_jpeg_find_format(fourcc);
1080
1081 if (fmt)
1082 sof->precision = fmt->precision;
1083 else
1084 sof->precision = 8; /* TODO allow 8/12 bit precision*/
1085 sof->height = h;
1086 _bswap16(&sof->height);
1087 sof->width = w;
1088 _bswap16(&sof->width);
1089
1090 switch (fourcc) {
1091 case V4L2_PIX_FMT_NV12:
1092 case V4L2_PIX_FMT_NV12M:
1093 case V4L2_PIX_FMT_P012:
1094 case V4L2_PIX_FMT_P012M:
1095 sof->components_no = 3;
1096 sof->comp[0].v = 0x2;
1097 sof->comp[0].h = 0x2;
1098 break;
1099 case V4L2_PIX_FMT_YUYV:
1100 case V4L2_PIX_FMT_Y212:
1101 sof->components_no = 3;
1102 sof->comp[0].v = 0x1;
1103 sof->comp[0].h = 0x2;
1104 break;
1105 case V4L2_PIX_FMT_YUV24:
1106 case V4L2_PIX_FMT_YUV48_12:
1107 case V4L2_PIX_FMT_BGR24:
1108 case V4L2_PIX_FMT_BGR48_12:
1109 default:
1110 sof->components_no = 3;
1111 break;
1112 case V4L2_PIX_FMT_ABGR32:
1113 case V4L2_PIX_FMT_ABGR64_12:
1114 sof->components_no = 4;
1115 break;
1116 case V4L2_PIX_FMT_GREY:
1117 case V4L2_PIX_FMT_Y012:
1118 sof->components_no = 1;
1119 break;
1120 }
1121 sof_length = 8 + 3 * sof->components_no;
1122 sof->length = sof_length;
1123 _bswap16(&sof->length);
1124
1125 return sof_length; /* not swaped */
1126 }
1127
mxc_jpeg_fixup_sos(struct mxc_jpeg_sos * sos,u32 fourcc)1128 static int mxc_jpeg_fixup_sos(struct mxc_jpeg_sos *sos,
1129 u32 fourcc)
1130 {
1131 int sos_length;
1132 u8 *sof_u8 = (u8 *)sos;
1133
1134 switch (fourcc) {
1135 case V4L2_PIX_FMT_NV12:
1136 case V4L2_PIX_FMT_NV12M:
1137 case V4L2_PIX_FMT_P012:
1138 case V4L2_PIX_FMT_P012M:
1139 sos->components_no = 3;
1140 break;
1141 case V4L2_PIX_FMT_YUYV:
1142 case V4L2_PIX_FMT_Y212:
1143 sos->components_no = 3;
1144 break;
1145 case V4L2_PIX_FMT_YUV24:
1146 case V4L2_PIX_FMT_YUV48_12:
1147 case V4L2_PIX_FMT_BGR24:
1148 case V4L2_PIX_FMT_BGR48_12:
1149 default:
1150 sos->components_no = 3;
1151 break;
1152 case V4L2_PIX_FMT_ABGR32:
1153 case V4L2_PIX_FMT_ABGR64_12:
1154 sos->components_no = 4;
1155 break;
1156 case V4L2_PIX_FMT_GREY:
1157 case V4L2_PIX_FMT_Y012:
1158 sos->components_no = 1;
1159 break;
1160 }
1161 sos_length = 6 + 2 * sos->components_no;
1162 sos->length = sos_length;
1163 _bswap16(&sos->length);
1164
1165 /* SOS ignorable bytes, not so ignorable after all */
1166 sof_u8[sos_length - 1] = 0x0;
1167 sof_u8[sos_length - 2] = 0x3f;
1168 sof_u8[sos_length - 3] = 0x0;
1169
1170 return sos_length; /* not swaped */
1171 }
1172
mxc_jpeg_setup_cfg_stream(void * cfg_stream_vaddr,u32 fourcc,u16 w,u16 h)1173 static unsigned int mxc_jpeg_setup_cfg_stream(void *cfg_stream_vaddr,
1174 u32 fourcc,
1175 u16 w, u16 h)
1176 {
1177 /*
1178 * There is a hardware issue that first 128 bytes of configuration data
1179 * can't be loaded correctly.
1180 * To avoid this issue, we need to write the configuration from
1181 * an offset which should be no less than 0x80 (128 bytes).
1182 */
1183 unsigned int offset = 0x80;
1184 u8 *cfg = (u8 *)cfg_stream_vaddr;
1185 struct mxc_jpeg_sof *sof;
1186 struct mxc_jpeg_sos *sos;
1187 const struct mxc_jpeg_fmt *fmt = mxc_jpeg_find_format(fourcc);
1188
1189 if (!fmt)
1190 return 0;
1191
1192 memcpy(cfg + offset, jpeg_soi, ARRAY_SIZE(jpeg_soi));
1193 offset += ARRAY_SIZE(jpeg_soi);
1194
1195 if (fmt->is_rgb) {
1196 memcpy(cfg + offset, jpeg_app14, sizeof(jpeg_app14));
1197 offset += sizeof(jpeg_app14);
1198 } else {
1199 memcpy(cfg + offset, jpeg_app0, sizeof(jpeg_app0));
1200 offset += sizeof(jpeg_app0);
1201 }
1202
1203 if (mxc_jpeg_is_extended_sequential(fmt)) {
1204 memcpy(cfg + offset, jpeg_dqt_extseq, sizeof(jpeg_dqt_extseq));
1205 offset += sizeof(jpeg_dqt_extseq);
1206
1207 memcpy(cfg + offset, jpeg_sof_extseq, sizeof(jpeg_sof_extseq));
1208 } else {
1209 memcpy(cfg + offset, jpeg_dqt, sizeof(jpeg_dqt));
1210 offset += sizeof(jpeg_dqt);
1211
1212 memcpy(cfg + offset, jpeg_sof_maximal, sizeof(jpeg_sof_maximal));
1213 }
1214 offset += 2; /* skip marker ID */
1215 sof = (struct mxc_jpeg_sof *)(cfg + offset);
1216 offset += mxc_jpeg_fixup_sof(sof, fourcc, w, h);
1217
1218 if (mxc_jpeg_is_extended_sequential(fmt)) {
1219 memcpy(cfg + offset, jpeg_dht_extseq, sizeof(jpeg_dht_extseq));
1220 offset += sizeof(jpeg_dht_extseq);
1221 } else {
1222 memcpy(cfg + offset, jpeg_dht, sizeof(jpeg_dht));
1223 offset += sizeof(jpeg_dht);
1224 }
1225
1226 memcpy(cfg + offset, jpeg_dri, sizeof(jpeg_dri));
1227 offset += sizeof(jpeg_dri);
1228
1229 memcpy(cfg + offset, jpeg_sos_maximal, sizeof(jpeg_sos_maximal));
1230 offset += 2; /* skip marker ID */
1231 sos = (struct mxc_jpeg_sos *)(cfg + offset);
1232 offset += mxc_jpeg_fixup_sos(sos, fourcc);
1233
1234 memcpy(cfg + offset, jpeg_image_red, sizeof(jpeg_image_red));
1235 offset += sizeof(jpeg_image_red);
1236
1237 memcpy(cfg + offset, jpeg_eoi, sizeof(jpeg_eoi));
1238 offset += sizeof(jpeg_eoi);
1239
1240 return offset;
1241 }
1242
mxc_jpeg_config_dec_desc(struct vb2_buffer * out_buf,struct mxc_jpeg_ctx * ctx,struct vb2_buffer * src_buf,struct vb2_buffer * dst_buf)1243 static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf,
1244 struct mxc_jpeg_ctx *ctx,
1245 struct vb2_buffer *src_buf,
1246 struct vb2_buffer *dst_buf)
1247 {
1248 enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1249 struct mxc_jpeg_q_data *q_data_cap;
1250 enum mxc_jpeg_image_format img_fmt;
1251 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
1252 void __iomem *reg = jpeg->base_reg;
1253 unsigned int slot = ctx->slot;
1254 struct mxc_jpeg_desc *desc = jpeg->slot_data.desc;
1255 struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc;
1256 dma_addr_t desc_handle = jpeg->slot_data.desc_handle;
1257 dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle;
1258 dma_addr_t cfg_stream_handle = jpeg->slot_data.cfg_stream_handle;
1259 unsigned int *cfg_size = &jpeg->slot_data.cfg_stream_size;
1260 void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr;
1261 struct mxc_jpeg_src_buf *jpeg_src_buf;
1262
1263 jpeg_src_buf = vb2_to_mxc_buf(src_buf);
1264
1265 /* setup the decoding descriptor */
1266 desc->next_descpt_ptr = 0; /* end of chain */
1267 q_data_cap = mxc_jpeg_get_q_data(ctx, cap_type);
1268 desc->imgsize = q_data_cap->w_adjusted << 16 | q_data_cap->h_adjusted;
1269 img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data_cap->fmt->fourcc);
1270 desc->stm_ctrl &= ~STM_CTRL_IMAGE_FORMAT(0xF); /* clear image format */
1271 desc->stm_ctrl |= STM_CTRL_IMAGE_FORMAT(img_fmt);
1272 desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1);
1273 if (mxc_jpeg_is_extended_sequential(jpeg_src_buf->fmt))
1274 desc->stm_ctrl |= STM_CTRL_PIXEL_PRECISION;
1275 else
1276 desc->stm_ctrl &= ~STM_CTRL_PIXEL_PRECISION;
1277 desc->line_pitch = q_data_cap->bytesperline[0];
1278 mxc_jpeg_addrs(desc, dst_buf, src_buf, 0);
1279 mxc_jpeg_set_bufsize(desc, ALIGN(vb2_plane_size(src_buf, 0), 1024));
1280 print_descriptor_info(jpeg->dev, desc);
1281
1282 if (!jpeg_src_buf->dht_needed) {
1283 /* validate the decoding descriptor */
1284 mxc_jpeg_set_desc(desc_handle, reg, slot);
1285 return;
1286 }
1287
1288 /*
1289 * if a default huffman table is needed, use the config descriptor to
1290 * inject a DHT, by chaining it before the decoding descriptor
1291 */
1292 *cfg_size = mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr,
1293 V4L2_PIX_FMT_YUYV,
1294 MXC_JPEG_PATTERN_WIDTH,
1295 MXC_JPEG_PATTERN_HEIGHT);
1296 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN;
1297 cfg_desc->buf_base0 = jpeg->slot_data.cfg_dec_daddr;
1298 cfg_desc->buf_base1 = 0;
1299 cfg_desc->imgsize = MXC_JPEG_PATTERN_WIDTH << 16;
1300 cfg_desc->imgsize |= MXC_JPEG_PATTERN_HEIGHT;
1301 cfg_desc->line_pitch = MXC_JPEG_PATTERN_WIDTH * 2;
1302 cfg_desc->stm_ctrl = STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV422);
1303 cfg_desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1);
1304 cfg_desc->stm_bufbase = cfg_stream_handle;
1305 cfg_desc->stm_bufsize = ALIGN(*cfg_size, 1024);
1306 print_descriptor_info(jpeg->dev, cfg_desc);
1307
1308 /* validate the configuration descriptor */
1309 mxc_jpeg_set_desc(cfg_desc_handle, reg, slot);
1310 }
1311
mxc_jpeg_config_enc_desc(struct vb2_buffer * out_buf,struct mxc_jpeg_ctx * ctx,struct vb2_buffer * src_buf,struct vb2_buffer * dst_buf)1312 static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,
1313 struct mxc_jpeg_ctx *ctx,
1314 struct vb2_buffer *src_buf,
1315 struct vb2_buffer *dst_buf)
1316 {
1317 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
1318 void __iomem *reg = jpeg->base_reg;
1319 unsigned int slot = ctx->slot;
1320 struct mxc_jpeg_desc *desc = jpeg->slot_data.desc;
1321 struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc;
1322 dma_addr_t desc_handle = jpeg->slot_data.desc_handle;
1323 dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle;
1324 void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr;
1325 struct mxc_jpeg_q_data *q_data;
1326 enum mxc_jpeg_image_format img_fmt;
1327 int w, h;
1328
1329 q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type);
1330
1331 jpeg->slot_data.cfg_stream_size =
1332 mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr,
1333 q_data->fmt->fourcc,
1334 q_data->crop.width,
1335 q_data->crop.height);
1336
1337 /* chain the config descriptor with the encoding descriptor */
1338 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN;
1339
1340 cfg_desc->buf_base0 = jpeg->slot_data.cfg_stream_handle;
1341 cfg_desc->buf_base1 = 0;
1342 cfg_desc->line_pitch = 0;
1343 cfg_desc->stm_bufbase = 0; /* no output expected */
1344 cfg_desc->stm_bufsize = 0x0;
1345 cfg_desc->imgsize = 0;
1346 cfg_desc->stm_ctrl = STM_CTRL_CONFIG_MOD(1);
1347 cfg_desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1);
1348
1349 desc->next_descpt_ptr = 0; /* end of chain */
1350
1351 /* use adjusted resolution for CAST IP job */
1352 w = q_data->crop.width;
1353 h = q_data->crop.height;
1354 v4l_bound_align_image(&w, w, MXC_JPEG_MAX_WIDTH, q_data->fmt->h_align,
1355 &h, h, MXC_JPEG_MAX_HEIGHT, q_data->fmt->v_align, 0);
1356 mxc_jpeg_set_res(desc, w, h);
1357 mxc_jpeg_set_line_pitch(desc, q_data->bytesperline[0]);
1358 mxc_jpeg_set_bufsize(desc, ALIGN(vb2_plane_size(dst_buf, 0), 1024));
1359 img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data->fmt->fourcc);
1360 if (img_fmt == MXC_JPEG_INVALID)
1361 dev_err(jpeg->dev, "No valid image format detected\n");
1362 desc->stm_ctrl = STM_CTRL_CONFIG_MOD(0) |
1363 STM_CTRL_IMAGE_FORMAT(img_fmt);
1364 desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1);
1365 if (mxc_jpeg_is_extended_sequential(q_data->fmt))
1366 desc->stm_ctrl |= STM_CTRL_PIXEL_PRECISION;
1367 else
1368 desc->stm_ctrl &= ~STM_CTRL_PIXEL_PRECISION;
1369 mxc_jpeg_addrs(desc, src_buf, dst_buf, 0);
1370 dev_dbg(jpeg->dev, "cfg_desc:\n");
1371 print_descriptor_info(jpeg->dev, cfg_desc);
1372 dev_dbg(jpeg->dev, "enc desc:\n");
1373 print_descriptor_info(jpeg->dev, desc);
1374 print_wrapper_info(jpeg->dev, reg);
1375 print_cast_status(jpeg->dev, reg, MXC_JPEG_ENCODE);
1376
1377 /* validate the configuration descriptor */
1378 mxc_jpeg_set_desc(cfg_desc_handle, reg, slot);
1379 }
1380
mxc_jpeg_get_sibling_format(const struct mxc_jpeg_fmt * fmt)1381 static const struct mxc_jpeg_fmt *mxc_jpeg_get_sibling_format(const struct mxc_jpeg_fmt *fmt)
1382 {
1383 int i;
1384
1385 for (i = 0; i < MXC_JPEG_NUM_FORMATS; i++) {
1386 if (mxc_formats[i].subsampling == fmt->subsampling &&
1387 mxc_formats[i].nc == fmt->nc &&
1388 mxc_formats[i].precision == fmt->precision &&
1389 mxc_formats[i].is_rgb == fmt->is_rgb &&
1390 mxc_formats[i].fourcc != fmt->fourcc)
1391 return &mxc_formats[i];
1392 }
1393
1394 return NULL;
1395 }
1396
mxc_jpeg_compare_format(const struct mxc_jpeg_fmt * fmt1,const struct mxc_jpeg_fmt * fmt2)1397 static bool mxc_jpeg_compare_format(const struct mxc_jpeg_fmt *fmt1,
1398 const struct mxc_jpeg_fmt *fmt2)
1399 {
1400 if (fmt1 == fmt2)
1401 return true;
1402 if (mxc_jpeg_get_sibling_format(fmt1) == fmt2)
1403 return true;
1404 return false;
1405 }
1406
mxc_jpeg_set_last_buffer(struct mxc_jpeg_ctx * ctx)1407 static void mxc_jpeg_set_last_buffer(struct mxc_jpeg_ctx *ctx)
1408 {
1409 struct vb2_v4l2_buffer *next_dst_buf;
1410
1411 next_dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1412 if (!next_dst_buf) {
1413 ctx->fh.m2m_ctx->is_draining = true;
1414 ctx->fh.m2m_ctx->next_buf_last = true;
1415 return;
1416 }
1417
1418 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, next_dst_buf);
1419 }
1420
mxc_jpeg_source_change(struct mxc_jpeg_ctx * ctx,struct mxc_jpeg_src_buf * jpeg_src_buf)1421 static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
1422 struct mxc_jpeg_src_buf *jpeg_src_buf)
1423 {
1424 struct device *dev = ctx->mxc_jpeg->dev;
1425 struct mxc_jpeg_q_data *q_data_cap;
1426
1427 if (!jpeg_src_buf->fmt)
1428 return false;
1429
1430 q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1431 if (mxc_jpeg_compare_format(q_data_cap->fmt, jpeg_src_buf->fmt))
1432 jpeg_src_buf->fmt = q_data_cap->fmt;
1433 if (ctx->need_initial_source_change_evt ||
1434 q_data_cap->fmt != jpeg_src_buf->fmt ||
1435 q_data_cap->w != jpeg_src_buf->w ||
1436 q_data_cap->h != jpeg_src_buf->h) {
1437 dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n",
1438 q_data_cap->w, q_data_cap->h,
1439 jpeg_src_buf->w, jpeg_src_buf->h,
1440 (jpeg_src_buf->fmt->fourcc & 0xff),
1441 (jpeg_src_buf->fmt->fourcc >> 8) & 0xff,
1442 (jpeg_src_buf->fmt->fourcc >> 16) & 0xff,
1443 (jpeg_src_buf->fmt->fourcc >> 24) & 0xff);
1444
1445 /*
1446 * set-up the capture queue with the pixelformat and resolution
1447 * detected from the jpeg output stream
1448 */
1449 q_data_cap->w = jpeg_src_buf->w;
1450 q_data_cap->h = jpeg_src_buf->h;
1451 q_data_cap->fmt = jpeg_src_buf->fmt;
1452 q_data_cap->w_adjusted = q_data_cap->w;
1453 q_data_cap->h_adjusted = q_data_cap->h;
1454 q_data_cap->crop.left = 0;
1455 q_data_cap->crop.top = 0;
1456 q_data_cap->crop.width = jpeg_src_buf->w;
1457 q_data_cap->crop.height = jpeg_src_buf->h;
1458 q_data_cap->bytesperline[0] = 0;
1459 q_data_cap->bytesperline[1] = 0;
1460
1461 /*
1462 * align up the resolution for CAST IP,
1463 * but leave the buffer resolution unchanged
1464 */
1465 v4l_bound_align_image(&q_data_cap->w_adjusted,
1466 q_data_cap->w_adjusted, /* adjust up */
1467 MXC_JPEG_MAX_WIDTH,
1468 q_data_cap->fmt->h_align,
1469 &q_data_cap->h_adjusted,
1470 q_data_cap->h_adjusted, /* adjust up */
1471 MXC_JPEG_MAX_HEIGHT,
1472 q_data_cap->fmt->v_align,
1473 0);
1474
1475 /* setup bytesperline/sizeimage for capture queue */
1476 mxc_jpeg_bytesperline(q_data_cap, jpeg_src_buf->fmt->precision);
1477 mxc_jpeg_sizeimage(q_data_cap);
1478 notify_src_chg(ctx);
1479 ctx->source_change = 1;
1480 ctx->need_initial_source_change_evt = false;
1481 if (vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx)))
1482 mxc_jpeg_set_last_buffer(ctx);
1483 }
1484
1485 return ctx->source_change ? true : false;
1486 }
1487
mxc_jpeg_job_ready(void * priv)1488 static int mxc_jpeg_job_ready(void *priv)
1489 {
1490 struct mxc_jpeg_ctx *ctx = priv;
1491
1492 return ctx->source_change ? 0 : 1;
1493 }
1494
mxc_jpeg_device_run_timeout(struct work_struct * work)1495 static void mxc_jpeg_device_run_timeout(struct work_struct *work)
1496 {
1497 struct delayed_work *dwork = to_delayed_work(work);
1498 struct mxc_jpeg_ctx *ctx = container_of(dwork, struct mxc_jpeg_ctx, task_timer);
1499 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
1500 unsigned long flags;
1501
1502 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
1503 if (ctx->mxc_jpeg->slot_data.used) {
1504 dev_warn(jpeg->dev, "%s timeout, cancel it\n",
1505 ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? "decode" : "encode");
1506 mxc_jpeg_job_finish(ctx, VB2_BUF_STATE_ERROR, true);
1507 v4l2_m2m_job_finish(ctx->mxc_jpeg->m2m_dev, ctx->fh.m2m_ctx);
1508 }
1509 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
1510 }
1511
mxc_jpeg_device_run(void * priv)1512 static void mxc_jpeg_device_run(void *priv)
1513 {
1514 struct mxc_jpeg_ctx *ctx = priv;
1515 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
1516 void __iomem *reg = jpeg->base_reg;
1517 struct device *dev = jpeg->dev;
1518 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1519 unsigned long flags;
1520 struct mxc_jpeg_q_data *q_data_cap, *q_data_out;
1521 struct mxc_jpeg_src_buf *jpeg_src_buf;
1522
1523 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
1524 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1525 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1526 if (!src_buf || !dst_buf) {
1527 dev_err(dev, "Null src or dst buf\n");
1528 goto end;
1529 }
1530
1531 q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1532 if (!q_data_cap)
1533 goto end;
1534 q_data_out = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
1535 if (!q_data_out)
1536 goto end;
1537 src_buf->sequence = q_data_out->sequence++;
1538 dst_buf->sequence = q_data_cap->sequence++;
1539
1540 v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true);
1541
1542 jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf);
1543 if (q_data_cap->fmt->mem_planes != dst_buf->vb2_buf.num_planes) {
1544 dev_err(dev, "Capture format %s has %d planes, but capture buffer has %d planes\n",
1545 q_data_cap->fmt->name, q_data_cap->fmt->mem_planes,
1546 dst_buf->vb2_buf.num_planes);
1547 jpeg_src_buf->jpeg_parse_error = true;
1548 }
1549 if (jpeg_src_buf->jpeg_parse_error) {
1550 mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf);
1551 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1552 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1553 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
1554 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
1555 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
1556 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1557
1558 return;
1559 }
1560 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) {
1561 if (ctx->source_change || mxc_jpeg_source_change(ctx, jpeg_src_buf)) {
1562 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
1563 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1564 return;
1565 }
1566 }
1567
1568 mxc_jpeg_enable(reg);
1569 mxc_jpeg_set_l_endian(reg, 1);
1570
1571 ctx->slot = mxc_get_free_slot(&jpeg->slot_data);
1572 if (ctx->slot < 0) {
1573 dev_err(dev, "No more free slots\n");
1574 goto end;
1575 }
1576 if (!mxc_jpeg_alloc_slot_data(jpeg)) {
1577 dev_err(dev, "Cannot allocate slot data\n");
1578 goto end;
1579 }
1580
1581 mxc_jpeg_enable_slot(reg, ctx->slot);
1582 mxc_jpeg_enable_irq(reg, ctx->slot);
1583
1584 if (jpeg->mode == MXC_JPEG_ENCODE) {
1585 dev_dbg(dev, "Encoding on slot %d\n", ctx->slot);
1586 ctx->enc_state = MXC_JPEG_ENC_CONF;
1587 mxc_jpeg_config_enc_desc(&dst_buf->vb2_buf, ctx,
1588 &src_buf->vb2_buf, &dst_buf->vb2_buf);
1589 /* start config phase */
1590 mxc_jpeg_enc_mode_conf(dev, reg,
1591 mxc_jpeg_is_extended_sequential(q_data_out->fmt));
1592 } else {
1593 dev_dbg(dev, "Decoding on slot %d\n", ctx->slot);
1594 print_mxc_buf(jpeg, &src_buf->vb2_buf, 0);
1595 mxc_jpeg_config_dec_desc(&dst_buf->vb2_buf, ctx,
1596 &src_buf->vb2_buf, &dst_buf->vb2_buf);
1597 mxc_jpeg_dec_mode_go(dev, reg);
1598 }
1599 schedule_delayed_work(&ctx->task_timer, msecs_to_jiffies(hw_timeout));
1600 end:
1601 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
1602 }
1603
mxc_jpeg_decoder_cmd(struct file * file,void * priv,struct v4l2_decoder_cmd * cmd)1604 static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
1605 struct v4l2_decoder_cmd *cmd)
1606 {
1607 struct v4l2_fh *fh = file->private_data;
1608 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
1609 unsigned long flags;
1610 int ret;
1611
1612 ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
1613 if (ret < 0)
1614 return ret;
1615
1616 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)))
1617 return 0;
1618
1619 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
1620 ret = v4l2_m2m_ioctl_decoder_cmd(file, priv, cmd);
1621 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
1622 if (ret < 0)
1623 return ret;
1624
1625 if (cmd->cmd == V4L2_DEC_CMD_STOP &&
1626 v4l2_m2m_has_stopped(fh->m2m_ctx)) {
1627 notify_eos(ctx);
1628 ctx->header_parsed = false;
1629 }
1630
1631 if (cmd->cmd == V4L2_DEC_CMD_START &&
1632 v4l2_m2m_has_stopped(fh->m2m_ctx))
1633 vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q);
1634 return 0;
1635 }
1636
mxc_jpeg_encoder_cmd(struct file * file,void * priv,struct v4l2_encoder_cmd * cmd)1637 static int mxc_jpeg_encoder_cmd(struct file *file, void *priv,
1638 struct v4l2_encoder_cmd *cmd)
1639 {
1640 struct v4l2_fh *fh = file->private_data;
1641 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
1642 unsigned long flags;
1643 int ret;
1644
1645 ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
1646 if (ret < 0)
1647 return ret;
1648
1649 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)) ||
1650 !vb2_is_streaming(v4l2_m2m_get_dst_vq(fh->m2m_ctx)))
1651 return 0;
1652
1653 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
1654 ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, cmd);
1655 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
1656 if (ret < 0)
1657 return 0;
1658
1659 if (cmd->cmd == V4L2_ENC_CMD_STOP &&
1660 v4l2_m2m_has_stopped(fh->m2m_ctx))
1661 notify_eos(ctx);
1662
1663 if (cmd->cmd == V4L2_ENC_CMD_START &&
1664 v4l2_m2m_has_stopped(fh->m2m_ctx))
1665 vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q);
1666
1667 return 0;
1668 }
1669
mxc_jpeg_queue_setup(struct vb2_queue * q,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],struct device * alloc_ctxs[])1670 static int mxc_jpeg_queue_setup(struct vb2_queue *q,
1671 unsigned int *nbuffers,
1672 unsigned int *nplanes,
1673 unsigned int sizes[],
1674 struct device *alloc_ctxs[])
1675 {
1676 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1677 struct mxc_jpeg_q_data *q_data = NULL;
1678 int i;
1679
1680 q_data = mxc_jpeg_get_q_data(ctx, q->type);
1681 if (!q_data)
1682 return -EINVAL;
1683
1684 /* Handle CREATE_BUFS situation - *nplanes != 0 */
1685 if (*nplanes) {
1686 if (*nplanes != q_data->fmt->mem_planes)
1687 return -EINVAL;
1688 for (i = 0; i < *nplanes; i++) {
1689 if (sizes[i] < mxc_jpeg_get_plane_size(q_data, i))
1690 return -EINVAL;
1691 }
1692 return 0;
1693 }
1694
1695 /* Handle REQBUFS situation */
1696 *nplanes = q_data->fmt->mem_planes;
1697 for (i = 0; i < *nplanes; i++)
1698 sizes[i] = mxc_jpeg_get_plane_size(q_data, i);
1699
1700 if (V4L2_TYPE_IS_OUTPUT(q->type))
1701 ctx->need_initial_source_change_evt = true;
1702
1703 return 0;
1704 }
1705
mxc_jpeg_start_streaming(struct vb2_queue * q,unsigned int count)1706 static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1707 {
1708 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1709 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type);
1710 int ret;
1711
1712 v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q);
1713
1714 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q->type))
1715 ctx->source_change = 0;
1716 dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx);
1717 q_data->sequence = 0;
1718
1719 if (V4L2_TYPE_IS_CAPTURE(q->type))
1720 ctx->need_initial_source_change_evt = false;
1721
1722 ret = pm_runtime_resume_and_get(ctx->mxc_jpeg->dev);
1723 if (ret < 0) {
1724 dev_err(ctx->mxc_jpeg->dev, "Failed to power up jpeg\n");
1725 return ret;
1726 }
1727
1728 return 0;
1729 }
1730
mxc_jpeg_stop_streaming(struct vb2_queue * q)1731 static void mxc_jpeg_stop_streaming(struct vb2_queue *q)
1732 {
1733 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1734 struct vb2_v4l2_buffer *vbuf;
1735
1736 dev_dbg(ctx->mxc_jpeg->dev, "Stop streaming ctx=%p", ctx);
1737
1738 /* Release all active buffers */
1739 for (;;) {
1740 if (V4L2_TYPE_IS_OUTPUT(q->type))
1741 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1742 else
1743 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1744 if (!vbuf)
1745 break;
1746 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
1747 }
1748
1749 v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q);
1750 /* if V4L2_DEC_CMD_STOP is sent before the source change triggered,
1751 * restore the is_draining flag
1752 */
1753 if (V4L2_TYPE_IS_CAPTURE(q->type) && ctx->source_change && ctx->fh.m2m_ctx->last_src_buf)
1754 ctx->fh.m2m_ctx->is_draining = true;
1755
1756 if (V4L2_TYPE_IS_OUTPUT(q->type) &&
1757 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) {
1758 notify_eos(ctx);
1759 ctx->header_parsed = false;
1760 }
1761
1762 pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev);
1763 }
1764
mxc_jpeg_valid_comp_id(struct device * dev,struct mxc_jpeg_sof * sof,struct mxc_jpeg_sos * sos)1765 static int mxc_jpeg_valid_comp_id(struct device *dev,
1766 struct mxc_jpeg_sof *sof,
1767 struct mxc_jpeg_sos *sos)
1768 {
1769 int valid = 1;
1770 int i;
1771
1772 /*
1773 * there's a limitation in the IP that the component IDs must be
1774 * between 0..4, if they are not, let's patch them
1775 */
1776 for (i = 0; i < sof->components_no; i++)
1777 if (sof->comp[i].id > MXC_JPEG_MAX_COMPONENTS) {
1778 valid = 0;
1779 dev_err(dev, "Component %d has invalid ID: %d",
1780 i, sof->comp[i].id);
1781 }
1782 if (!valid)
1783 /* patch all comp IDs if at least one is invalid */
1784 for (i = 0; i < sof->components_no; i++) {
1785 dev_warn(dev, "Component %d ID patched to: %d",
1786 i, i + 1);
1787 sof->comp[i].id = i + 1;
1788 sos->comp[i].id = i + 1;
1789 }
1790
1791 return valid;
1792 }
1793
mxc_jpeg_match_image_format(const struct mxc_jpeg_fmt * fmt,const struct v4l2_jpeg_header * header)1794 static bool mxc_jpeg_match_image_format(const struct mxc_jpeg_fmt *fmt,
1795 const struct v4l2_jpeg_header *header)
1796 {
1797 if (fmt->subsampling != header->frame.subsampling ||
1798 fmt->nc != header->frame.num_components ||
1799 fmt->precision != header->frame.precision)
1800 return false;
1801
1802 /*
1803 * If the transform flag from APP14 marker is 0, images that are
1804 * encoded with 3 components have RGB colorspace, see Recommendation
1805 * ITU-T T.872 chapter 6.5.3 APP14 marker segment for colour encoding
1806 */
1807 if (header->frame.subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_444) {
1808 u8 is_rgb = header->app14_tf == V4L2_JPEG_APP14_TF_CMYK_RGB ? 1 : 0;
1809
1810 if (is_rgb != fmt->is_rgb)
1811 return false;
1812 }
1813 return true;
1814 }
1815
mxc_jpeg_get_image_format(struct device * dev,const struct v4l2_jpeg_header * header)1816 static u32 mxc_jpeg_get_image_format(struct device *dev,
1817 const struct v4l2_jpeg_header *header)
1818 {
1819 int i;
1820 u32 fourcc = 0;
1821
1822 for (i = 0; i < MXC_JPEG_NUM_FORMATS; i++) {
1823 if (mxc_jpeg_match_image_format(&mxc_formats[i], header)) {
1824 fourcc = mxc_formats[i].fourcc;
1825 break;
1826 }
1827 }
1828 if (fourcc == 0) {
1829 dev_err(dev,
1830 "Could not identify image format nc=%d, subsampling=%d, precision=%d\n",
1831 header->frame.num_components,
1832 header->frame.subsampling,
1833 header->frame.precision);
1834 return fourcc;
1835 }
1836
1837 return fourcc;
1838 }
1839
mxc_jpeg_bytesperline(struct mxc_jpeg_q_data * q,u32 precision)1840 static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision)
1841 {
1842 u32 bytesperline[2];
1843
1844 bytesperline[0] = q->bytesperline[0];
1845 bytesperline[1] = q->bytesperline[0]; /*imx-jpeg only support the same line pitch*/
1846 v4l_bound_align_image(&bytesperline[0], 0, MXC_JPEG_MAX_LINE, 2,
1847 &bytesperline[1], 0, MXC_JPEG_MAX_LINE, 2,
1848 0);
1849
1850 /* Bytes distance between the leftmost pixels in two adjacent lines */
1851 if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1852 /* bytesperline unused for compressed formats */
1853 q->bytesperline[0] = 0;
1854 q->bytesperline[1] = 0;
1855 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420) {
1856 /* When the image format is planar the bytesperline value
1857 * applies to the first plane and is divided by the same factor
1858 * as the width field for the other planes
1859 */
1860 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8);
1861 q->bytesperline[1] = q->bytesperline[0];
1862 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_422) {
1863 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8) * 2;
1864 q->bytesperline[1] = 0;
1865 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_444) {
1866 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8) * q->fmt->nc;
1867 q->bytesperline[1] = 0;
1868 } else {
1869 /* grayscale */
1870 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8);
1871 q->bytesperline[1] = 0;
1872 }
1873
1874 if (q->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1875 q->bytesperline[0] = max(q->bytesperline[0], bytesperline[0]);
1876 if (q->fmt->mem_planes > 1)
1877 q->bytesperline[1] = max(q->bytesperline[1], bytesperline[1]);
1878 }
1879 }
1880
mxc_jpeg_sizeimage(struct mxc_jpeg_q_data * q)1881 static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)
1882 {
1883 if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1884 /* if no sizeimage from user, assume worst jpeg compression */
1885 if (!q->sizeimage[0])
1886 q->sizeimage[0] = 6 * q->w * q->h;
1887 q->sizeimage[1] = 0;
1888
1889 if (q->sizeimage[0] > MXC_JPEG_MAX_SIZEIMAGE)
1890 q->sizeimage[0] = MXC_JPEG_MAX_SIZEIMAGE;
1891
1892 /* jpeg stream size must be multiple of 1K */
1893 q->sizeimage[0] = ALIGN(q->sizeimage[0], 1024);
1894 } else {
1895 q->sizeimage[0] = q->bytesperline[0] * q->h_adjusted;
1896 q->sizeimage[1] = 0;
1897 if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420)
1898 q->sizeimage[1] = q->sizeimage[0] / 2;
1899 }
1900 }
1901
mxc_jpeg_parse(struct mxc_jpeg_ctx * ctx,struct vb2_buffer * vb)1902 static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
1903 {
1904 struct device *dev = ctx->mxc_jpeg->dev;
1905 struct mxc_jpeg_q_data *q_data_out;
1906 struct mxc_jpeg_q_data *q_data_cap;
1907 u32 fourcc;
1908 struct v4l2_jpeg_header header;
1909 struct mxc_jpeg_sof *psof = NULL;
1910 struct mxc_jpeg_sos *psos = NULL;
1911 struct mxc_jpeg_src_buf *jpeg_src_buf = vb2_to_mxc_buf(vb);
1912 u8 *src_addr = (u8 *)mxc_jpeg_get_plane_vaddr(vb, 0);
1913 u32 size = mxc_jpeg_get_plane_payload(vb, 0);
1914 int ret;
1915
1916 memset(&header, 0, sizeof(header));
1917 ret = v4l2_jpeg_parse_header((void *)src_addr, size, &header);
1918 if (ret < 0) {
1919 dev_err(dev, "Error parsing JPEG stream markers\n");
1920 return ret;
1921 }
1922
1923 /* if DHT marker present, no need to inject default one */
1924 jpeg_src_buf->dht_needed = (header.num_dht == 0);
1925
1926 q_data_out = mxc_jpeg_get_q_data(ctx,
1927 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
1928 q_data_out->w = header.frame.width;
1929 q_data_out->h = header.frame.height;
1930 if (header.frame.width > MXC_JPEG_MAX_WIDTH ||
1931 header.frame.height > MXC_JPEG_MAX_HEIGHT) {
1932 dev_err(dev, "JPEG width or height should be <= 8192: %dx%d\n",
1933 header.frame.width, header.frame.height);
1934 return -EINVAL;
1935 }
1936 if (header.frame.width < MXC_JPEG_MIN_WIDTH ||
1937 header.frame.height < MXC_JPEG_MIN_HEIGHT) {
1938 dev_err(dev, "JPEG width or height should be > 64: %dx%d\n",
1939 header.frame.width, header.frame.height);
1940 return -EINVAL;
1941 }
1942 if (header.frame.num_components > V4L2_JPEG_MAX_COMPONENTS) {
1943 dev_err(dev, "JPEG number of components should be <=%d",
1944 V4L2_JPEG_MAX_COMPONENTS);
1945 return -EINVAL;
1946 }
1947 /* check and, if necessary, patch component IDs*/
1948 psof = (struct mxc_jpeg_sof *)header.sof.start;
1949 psos = (struct mxc_jpeg_sos *)header.sos.start;
1950 if (!mxc_jpeg_valid_comp_id(dev, psof, psos))
1951 dev_warn(dev, "JPEG component ids should be 0-3 or 1-4");
1952
1953 q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
1954 if (q_data_cap->fmt && mxc_jpeg_match_image_format(q_data_cap->fmt, &header))
1955 fourcc = q_data_cap->fmt->fourcc;
1956 else
1957 fourcc = mxc_jpeg_get_image_format(dev, &header);
1958 if (fourcc == 0)
1959 return -EINVAL;
1960
1961 jpeg_src_buf->fmt = mxc_jpeg_find_format(fourcc);
1962 jpeg_src_buf->w = header.frame.width;
1963 jpeg_src_buf->h = header.frame.height;
1964 ctx->header_parsed = true;
1965
1966 if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx))
1967 mxc_jpeg_source_change(ctx, jpeg_src_buf);
1968
1969 return 0;
1970 }
1971
mxc_jpeg_buf_queue(struct vb2_buffer * vb)1972 static void mxc_jpeg_buf_queue(struct vb2_buffer *vb)
1973 {
1974 int ret;
1975 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1976 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1977 struct mxc_jpeg_src_buf *jpeg_src_buf;
1978
1979 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
1980 vb2_is_streaming(vb->vb2_queue) &&
1981 v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) {
1982 struct mxc_jpeg_q_data *q_data;
1983
1984 q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type);
1985 vbuf->field = V4L2_FIELD_NONE;
1986 vbuf->sequence = q_data->sequence++;
1987 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf);
1988 notify_eos(ctx);
1989 ctx->header_parsed = false;
1990 return;
1991 }
1992
1993 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1994 goto end;
1995
1996 /* for V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE */
1997 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE)
1998 goto end;
1999
2000 jpeg_src_buf = vb2_to_mxc_buf(vb);
2001 jpeg_src_buf->jpeg_parse_error = false;
2002 ret = mxc_jpeg_parse(ctx, vb);
2003 if (ret) {
2004 jpeg_src_buf->jpeg_parse_error = true;
2005
2006 /*
2007 * if the capture queue is not setup, the device_run() won't be scheduled,
2008 * need to drop the error buffer, so that the decoding can continue
2009 */
2010 if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) {
2011 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
2012 return;
2013 }
2014 }
2015
2016 end:
2017 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
2018 }
2019
mxc_jpeg_buf_out_validate(struct vb2_buffer * vb)2020 static int mxc_jpeg_buf_out_validate(struct vb2_buffer *vb)
2021 {
2022 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
2023
2024 vbuf->field = V4L2_FIELD_NONE;
2025
2026 return 0;
2027 }
2028
mxc_jpeg_buf_prepare(struct vb2_buffer * vb)2029 static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb)
2030 {
2031 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
2032 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2033 struct mxc_jpeg_q_data *q_data = NULL;
2034 struct device *dev = ctx->mxc_jpeg->dev;
2035 unsigned long sizeimage;
2036 int i;
2037
2038 vbuf->field = V4L2_FIELD_NONE;
2039
2040 q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type);
2041 if (!q_data)
2042 return -EINVAL;
2043 for (i = 0; i < q_data->fmt->mem_planes; i++) {
2044 sizeimage = mxc_jpeg_get_plane_size(q_data, i);
2045 if (!ctx->source_change && vb2_plane_size(vb, i) < sizeimage) {
2046 dev_err(dev, "plane %d too small (%lu < %lu)",
2047 i, vb2_plane_size(vb, i), sizeimage);
2048 return -EINVAL;
2049 }
2050 if (!IS_ALIGNED(mxc_jpeg_get_plane_dma_addr(vb, i), MXC_JPEG_ADDR_ALIGNMENT)) {
2051 dev_err(dev, "planes[%d] address is not %d aligned\n",
2052 i, MXC_JPEG_ADDR_ALIGNMENT);
2053 return -EINVAL;
2054 }
2055 }
2056 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) {
2057 vb2_set_plane_payload(vb, 0, 0);
2058 vb2_set_plane_payload(vb, 1, 0);
2059 }
2060 return 0;
2061 }
2062
2063 static const struct vb2_ops mxc_jpeg_qops = {
2064 .queue_setup = mxc_jpeg_queue_setup,
2065 .buf_out_validate = mxc_jpeg_buf_out_validate,
2066 .buf_prepare = mxc_jpeg_buf_prepare,
2067 .start_streaming = mxc_jpeg_start_streaming,
2068 .stop_streaming = mxc_jpeg_stop_streaming,
2069 .buf_queue = mxc_jpeg_buf_queue,
2070 };
2071
mxc_jpeg_queue_init(void * priv,struct vb2_queue * src_vq,struct vb2_queue * dst_vq)2072 static int mxc_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
2073 struct vb2_queue *dst_vq)
2074 {
2075 struct mxc_jpeg_ctx *ctx = priv;
2076 int ret;
2077
2078 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2079 src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
2080 src_vq->drv_priv = ctx;
2081 src_vq->buf_struct_size = sizeof(struct mxc_jpeg_src_buf);
2082 src_vq->ops = &mxc_jpeg_qops;
2083 src_vq->mem_ops = &vb2_dma_contig_memops;
2084 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2085 src_vq->lock = &ctx->mxc_jpeg->lock;
2086 src_vq->dev = ctx->mxc_jpeg->dev;
2087
2088 ret = vb2_queue_init(src_vq);
2089 if (ret)
2090 return ret;
2091
2092 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2093 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
2094 dst_vq->drv_priv = ctx;
2095 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2096 dst_vq->ops = &mxc_jpeg_qops;
2097 dst_vq->mem_ops = &vb2_dma_contig_memops;
2098 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2099 dst_vq->lock = &ctx->mxc_jpeg->lock;
2100 dst_vq->dev = ctx->mxc_jpeg->dev;
2101
2102 ret = vb2_queue_init(dst_vq);
2103 return ret;
2104 }
2105
mxc_jpeg_set_default_params(struct mxc_jpeg_ctx * ctx)2106 static void mxc_jpeg_set_default_params(struct mxc_jpeg_ctx *ctx)
2107 {
2108 struct mxc_jpeg_q_data *out_q = &ctx->out_q;
2109 struct mxc_jpeg_q_data *cap_q = &ctx->cap_q;
2110 struct mxc_jpeg_q_data *q[2] = {out_q, cap_q};
2111 int i;
2112
2113 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) {
2114 out_q->fmt = mxc_jpeg_find_format(MXC_JPEG_DEFAULT_PFMT);
2115 cap_q->fmt = mxc_jpeg_find_format(V4L2_PIX_FMT_JPEG);
2116 } else {
2117 out_q->fmt = mxc_jpeg_find_format(V4L2_PIX_FMT_JPEG);
2118 cap_q->fmt = mxc_jpeg_find_format(MXC_JPEG_DEFAULT_PFMT);
2119 }
2120
2121 for (i = 0; i < 2; i++) {
2122 q[i]->w = MXC_JPEG_DEFAULT_WIDTH;
2123 q[i]->h = MXC_JPEG_DEFAULT_HEIGHT;
2124 q[i]->w_adjusted = MXC_JPEG_DEFAULT_WIDTH;
2125 q[i]->h_adjusted = MXC_JPEG_DEFAULT_HEIGHT;
2126 q[i]->crop.left = 0;
2127 q[i]->crop.top = 0;
2128 q[i]->crop.width = MXC_JPEG_DEFAULT_WIDTH;
2129 q[i]->crop.height = MXC_JPEG_DEFAULT_HEIGHT;
2130 mxc_jpeg_bytesperline(q[i], q[i]->fmt->precision);
2131 mxc_jpeg_sizeimage(q[i]);
2132 }
2133 }
2134
mxc_jpeg_s_ctrl(struct v4l2_ctrl * ctrl)2135 static int mxc_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
2136 {
2137 struct mxc_jpeg_ctx *ctx =
2138 container_of(ctrl->handler, struct mxc_jpeg_ctx, ctrl_handler);
2139
2140 switch (ctrl->id) {
2141 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
2142 ctx->jpeg_quality = ctrl->val;
2143 break;
2144 default:
2145 dev_err(ctx->mxc_jpeg->dev, "Invalid control, id = %d, val = %d\n",
2146 ctrl->id, ctrl->val);
2147 return -EINVAL;
2148 }
2149
2150 return 0;
2151 }
2152
2153 static const struct v4l2_ctrl_ops mxc_jpeg_ctrl_ops = {
2154 .s_ctrl = mxc_jpeg_s_ctrl,
2155 };
2156
mxc_jpeg_encode_ctrls(struct mxc_jpeg_ctx * ctx)2157 static void mxc_jpeg_encode_ctrls(struct mxc_jpeg_ctx *ctx)
2158 {
2159 v4l2_ctrl_new_std(&ctx->ctrl_handler, &mxc_jpeg_ctrl_ops,
2160 V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 75);
2161 }
2162
mxc_jpeg_ctrls_setup(struct mxc_jpeg_ctx * ctx)2163 static int mxc_jpeg_ctrls_setup(struct mxc_jpeg_ctx *ctx)
2164 {
2165 int err;
2166
2167 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 2);
2168
2169 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE)
2170 mxc_jpeg_encode_ctrls(ctx);
2171
2172 if (ctx->ctrl_handler.error) {
2173 err = ctx->ctrl_handler.error;
2174
2175 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
2176 return err;
2177 }
2178
2179 err = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
2180 if (err)
2181 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
2182 return err;
2183 }
2184
mxc_jpeg_open(struct file * file)2185 static int mxc_jpeg_open(struct file *file)
2186 {
2187 struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file);
2188 struct video_device *mxc_vfd = video_devdata(file);
2189 struct device *dev = mxc_jpeg->dev;
2190 struct mxc_jpeg_ctx *ctx;
2191 int ret = 0;
2192
2193 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2194 if (!ctx)
2195 return -ENOMEM;
2196
2197 if (mutex_lock_interruptible(&mxc_jpeg->lock)) {
2198 ret = -ERESTARTSYS;
2199 goto free;
2200 }
2201
2202 v4l2_fh_init(&ctx->fh, mxc_vfd);
2203 file->private_data = &ctx->fh;
2204 v4l2_fh_add(&ctx->fh);
2205
2206 ctx->mxc_jpeg = mxc_jpeg;
2207
2208 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(mxc_jpeg->m2m_dev, ctx,
2209 mxc_jpeg_queue_init);
2210
2211 if (IS_ERR(ctx->fh.m2m_ctx)) {
2212 ret = PTR_ERR(ctx->fh.m2m_ctx);
2213 goto error;
2214 }
2215
2216 ret = mxc_jpeg_ctrls_setup(ctx);
2217 if (ret) {
2218 dev_err(ctx->mxc_jpeg->dev, "failed to setup mxc jpeg controls\n");
2219 goto err_ctrls_setup;
2220 }
2221 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
2222 mxc_jpeg_set_default_params(ctx);
2223 ctx->slot = -1; /* slot not allocated yet */
2224 INIT_DELAYED_WORK(&ctx->task_timer, mxc_jpeg_device_run_timeout);
2225
2226 if (mxc_jpeg->mode == MXC_JPEG_DECODE)
2227 dev_dbg(dev, "Opened JPEG decoder instance %p\n", ctx);
2228 else
2229 dev_dbg(dev, "Opened JPEG encoder instance %p\n", ctx);
2230 mutex_unlock(&mxc_jpeg->lock);
2231
2232 return 0;
2233
2234 err_ctrls_setup:
2235 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
2236 error:
2237 v4l2_fh_del(&ctx->fh);
2238 v4l2_fh_exit(&ctx->fh);
2239 mutex_unlock(&mxc_jpeg->lock);
2240 free:
2241 kfree(ctx);
2242 return ret;
2243 }
2244
mxc_jpeg_querycap(struct file * file,void * priv,struct v4l2_capability * cap)2245 static int mxc_jpeg_querycap(struct file *file, void *priv,
2246 struct v4l2_capability *cap)
2247 {
2248 strscpy(cap->driver, MXC_JPEG_NAME " codec", sizeof(cap->driver));
2249 strscpy(cap->card, MXC_JPEG_NAME " codec", sizeof(cap->card));
2250 cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
2251 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
2252
2253 return 0;
2254 }
2255
mxc_jpeg_enum_fmt_vid_cap(struct file * file,void * priv,struct v4l2_fmtdesc * f)2256 static int mxc_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
2257 struct v4l2_fmtdesc *f)
2258 {
2259 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
2260 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type);
2261
2262 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) {
2263 return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
2264 MXC_JPEG_FMT_TYPE_ENC);
2265 } else if (!ctx->header_parsed) {
2266 return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
2267 MXC_JPEG_FMT_TYPE_RAW);
2268 } else {
2269 /* For the decoder CAPTURE queue, only enumerate the raw formats
2270 * supported for the format currently active on OUTPUT
2271 * (more precisely what was propagated on capture queue
2272 * after jpeg parse on the output buffer)
2273 */
2274 int ret = -EINVAL;
2275 const struct mxc_jpeg_fmt *sibling;
2276
2277 switch (f->index) {
2278 case 0:
2279 f->pixelformat = q_data->fmt->fourcc;
2280 ret = 0;
2281 break;
2282 case 1:
2283 sibling = mxc_jpeg_get_sibling_format(q_data->fmt);
2284 if (sibling) {
2285 f->pixelformat = sibling->fourcc;
2286 ret = 0;
2287 }
2288 break;
2289 default:
2290 break;
2291 }
2292 return ret;
2293 }
2294 }
2295
mxc_jpeg_enum_fmt_vid_out(struct file * file,void * priv,struct v4l2_fmtdesc * f)2296 static int mxc_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
2297 struct v4l2_fmtdesc *f)
2298 {
2299 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
2300 u32 type = ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? MXC_JPEG_FMT_TYPE_ENC :
2301 MXC_JPEG_FMT_TYPE_RAW;
2302 int ret;
2303
2304 ret = enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f, type);
2305 if (ret)
2306 return ret;
2307 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE)
2308 f->flags = V4L2_FMT_FLAG_DYN_RESOLUTION;
2309 return 0;
2310 }
2311
mxc_jpeg_get_fmt_type(struct mxc_jpeg_ctx * ctx,u32 type)2312 static u32 mxc_jpeg_get_fmt_type(struct mxc_jpeg_ctx *ctx, u32 type)
2313 {
2314 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE)
2315 return V4L2_TYPE_IS_OUTPUT(type) ? MXC_JPEG_FMT_TYPE_ENC : MXC_JPEG_FMT_TYPE_RAW;
2316 else
2317 return V4L2_TYPE_IS_CAPTURE(type) ? MXC_JPEG_FMT_TYPE_ENC : MXC_JPEG_FMT_TYPE_RAW;
2318 }
2319
mxc_jpeg_get_default_fourcc(struct mxc_jpeg_ctx * ctx,u32 type)2320 static u32 mxc_jpeg_get_default_fourcc(struct mxc_jpeg_ctx *ctx, u32 type)
2321 {
2322 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE)
2323 return V4L2_TYPE_IS_OUTPUT(type) ? V4L2_PIX_FMT_JPEG : MXC_JPEG_DEFAULT_PFMT;
2324 else
2325 return V4L2_TYPE_IS_CAPTURE(type) ? V4L2_PIX_FMT_JPEG : MXC_JPEG_DEFAULT_PFMT;
2326 }
2327
mxc_jpeg_try_fourcc(struct mxc_jpeg_ctx * ctx,u32 fourcc)2328 static u32 mxc_jpeg_try_fourcc(struct mxc_jpeg_ctx *ctx, u32 fourcc)
2329 {
2330 const struct mxc_jpeg_fmt *sibling;
2331 struct mxc_jpeg_q_data *q_data_cap;
2332
2333 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE)
2334 return fourcc;
2335 if (!ctx->header_parsed)
2336 return fourcc;
2337
2338 q_data_cap = &ctx->cap_q;
2339 if (q_data_cap->fmt->fourcc == fourcc)
2340 return fourcc;
2341
2342 sibling = mxc_jpeg_get_sibling_format(q_data_cap->fmt);
2343 if (sibling && sibling->fourcc == fourcc)
2344 return sibling->fourcc;
2345
2346 return q_data_cap->fmt->fourcc;
2347 }
2348
mxc_jpeg_try_fmt(struct v4l2_format * f,struct mxc_jpeg_ctx * ctx,struct mxc_jpeg_q_data * q_data)2349 static int mxc_jpeg_try_fmt(struct v4l2_format *f,
2350 struct mxc_jpeg_ctx *ctx, struct mxc_jpeg_q_data *q_data)
2351 {
2352 const struct mxc_jpeg_fmt *fmt;
2353 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
2354 struct v4l2_plane_pix_format *pfmt;
2355 u32 fourcc = f->fmt.pix_mp.pixelformat;
2356 u32 w = (pix_mp->width < MXC_JPEG_MAX_WIDTH) ?
2357 pix_mp->width : MXC_JPEG_MAX_WIDTH;
2358 u32 h = (pix_mp->height < MXC_JPEG_MAX_HEIGHT) ?
2359 pix_mp->height : MXC_JPEG_MAX_HEIGHT;
2360 int i;
2361
2362 fmt = mxc_jpeg_find_format(fourcc);
2363 if (!fmt || fmt->flags != mxc_jpeg_get_fmt_type(ctx, f->type)) {
2364 dev_warn(ctx->mxc_jpeg->dev, "Format not supported: %c%c%c%c, use the default.\n",
2365 (fourcc & 0xff),
2366 (fourcc >> 8) & 0xff,
2367 (fourcc >> 16) & 0xff,
2368 (fourcc >> 24) & 0xff);
2369 fourcc = mxc_jpeg_get_default_fourcc(ctx, f->type);
2370 fmt = mxc_jpeg_find_format(fourcc);
2371 if (!fmt)
2372 return -EINVAL;
2373 f->fmt.pix_mp.pixelformat = fourcc;
2374 }
2375 q_data->fmt = fmt;
2376
2377 memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
2378 pix_mp->field = V4L2_FIELD_NONE;
2379 pix_mp->num_planes = fmt->mem_planes;
2380 pix_mp->pixelformat = fmt->fourcc;
2381
2382 q_data->w = w;
2383 q_data->h = h;
2384 q_data->w_adjusted = w;
2385 q_data->h_adjusted = h;
2386 v4l_bound_align_image(&q_data->w_adjusted,
2387 w, /* adjust upwards*/
2388 MXC_JPEG_MAX_WIDTH,
2389 fmt->h_align,
2390 &q_data->h_adjusted,
2391 h, /* adjust upwards*/
2392 MXC_JPEG_MAX_HEIGHT,
2393 fmt->v_align,
2394 0);
2395 for (i = 0; i < pix_mp->num_planes; i++) {
2396 pfmt = &pix_mp->plane_fmt[i];
2397 q_data->bytesperline[i] = pfmt->bytesperline;
2398 q_data->sizeimage[i] = pfmt->sizeimage;
2399 }
2400
2401 /* calculate bytesperline & sizeimage */
2402 mxc_jpeg_bytesperline(q_data, fmt->precision);
2403 mxc_jpeg_sizeimage(q_data);
2404
2405 /* adjust user format according to our calculations */
2406 for (i = 0; i < pix_mp->num_planes; i++) {
2407 pfmt = &pix_mp->plane_fmt[i];
2408 memset(pfmt->reserved, 0, sizeof(pfmt->reserved));
2409 pfmt->bytesperline = q_data->bytesperline[i];
2410 pfmt->sizeimage = mxc_jpeg_get_plane_size(q_data, i);
2411 }
2412
2413 /* fix colorspace information to sRGB for both output & capture */
2414 pix_mp->colorspace = V4L2_COLORSPACE_SRGB;
2415 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_601;
2416 pix_mp->xfer_func = V4L2_XFER_FUNC_SRGB;
2417 /*
2418 * this hardware does not change the range of the samples
2419 * but since inside JPEG the YUV quantization is full-range,
2420 * this driver will always use full-range for the raw frames, too
2421 */
2422 pix_mp->quantization = V4L2_QUANTIZATION_FULL_RANGE;
2423
2424 if (fmt->flags == MXC_JPEG_FMT_TYPE_RAW) {
2425 q_data->crop.left = 0;
2426 q_data->crop.top = 0;
2427 q_data->crop.width = q_data->w;
2428 q_data->crop.height = q_data->h;
2429 }
2430
2431 pix_mp->width = q_data->w_adjusted;
2432 pix_mp->height = q_data->h_adjusted;
2433
2434 return 0;
2435 }
2436
mxc_jpeg_try_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * f)2437 static int mxc_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
2438 struct v4l2_format *f)
2439 {
2440 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
2441 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
2442 struct device *dev = jpeg->dev;
2443 struct mxc_jpeg_q_data tmp_q;
2444
2445 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
2446 dev_err(dev, "TRY_FMT with Invalid type: %d\n", f->type);
2447 return -EINVAL;
2448 }
2449
2450 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(f->type))
2451 f->fmt.pix_mp.pixelformat = mxc_jpeg_try_fourcc(ctx, f->fmt.pix_mp.pixelformat);
2452
2453 return mxc_jpeg_try_fmt(f, ctx, &tmp_q);
2454 }
2455
mxc_jpeg_try_fmt_vid_out(struct file * file,void * priv,struct v4l2_format * f)2456 static int mxc_jpeg_try_fmt_vid_out(struct file *file, void *priv,
2457 struct v4l2_format *f)
2458 {
2459 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
2460 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
2461 struct device *dev = jpeg->dev;
2462 struct mxc_jpeg_q_data tmp_q;
2463
2464 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
2465 dev_err(dev, "TRY_FMT with Invalid type: %d\n", f->type);
2466 return -EINVAL;
2467 }
2468
2469 return mxc_jpeg_try_fmt(f, ctx, &tmp_q);
2470 }
2471
mxc_jpeg_s_parsed_fmt(struct mxc_jpeg_ctx * ctx,struct v4l2_format * f)2472 static void mxc_jpeg_s_parsed_fmt(struct mxc_jpeg_ctx *ctx, struct v4l2_format *f)
2473 {
2474 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
2475 struct mxc_jpeg_q_data *q_data_cap;
2476
2477 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE || !V4L2_TYPE_IS_CAPTURE(f->type))
2478 return;
2479 if (!ctx->header_parsed)
2480 return;
2481
2482 q_data_cap = mxc_jpeg_get_q_data(ctx, f->type);
2483 pix_mp->pixelformat = mxc_jpeg_try_fourcc(ctx, pix_mp->pixelformat);
2484 pix_mp->width = q_data_cap->w;
2485 pix_mp->height = q_data_cap->h;
2486 }
2487
mxc_jpeg_s_fmt(struct mxc_jpeg_ctx * ctx,struct v4l2_format * f)2488 static int mxc_jpeg_s_fmt(struct mxc_jpeg_ctx *ctx,
2489 struct v4l2_format *f)
2490 {
2491 struct vb2_queue *vq;
2492 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
2493
2494 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
2495 if (!vq)
2496 return -EINVAL;
2497
2498 if (vb2_is_busy(vq)) {
2499 v4l2_err(&jpeg->v4l2_dev, "queue busy\n");
2500 return -EBUSY;
2501 }
2502
2503 mxc_jpeg_s_parsed_fmt(ctx, f);
2504
2505 return mxc_jpeg_try_fmt(f, ctx, mxc_jpeg_get_q_data(ctx, f->type));
2506 }
2507
mxc_jpeg_s_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * f)2508 static int mxc_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
2509 struct v4l2_format *f)
2510 {
2511 return mxc_jpeg_s_fmt(mxc_jpeg_fh_to_ctx(priv), f);
2512 }
2513
mxc_jpeg_s_fmt_vid_out(struct file * file,void * priv,struct v4l2_format * f)2514 static int mxc_jpeg_s_fmt_vid_out(struct file *file, void *priv,
2515 struct v4l2_format *f)
2516 {
2517 int ret;
2518 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
2519 struct vb2_queue *dst_vq;
2520 struct mxc_jpeg_q_data *q_data_cap;
2521 enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2522 struct v4l2_format fc;
2523
2524 ret = mxc_jpeg_s_fmt(mxc_jpeg_fh_to_ctx(priv), f);
2525 if (ret)
2526 return ret;
2527
2528 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE)
2529 return 0;
2530
2531 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, cap_type);
2532 if (!dst_vq)
2533 return -EINVAL;
2534
2535 if (vb2_is_busy(dst_vq))
2536 return 0;
2537
2538 q_data_cap = mxc_jpeg_get_q_data(ctx, cap_type);
2539 if (q_data_cap->w == f->fmt.pix_mp.width && q_data_cap->h == f->fmt.pix_mp.height)
2540 return 0;
2541 memset(&fc, 0, sizeof(fc));
2542 fc.type = cap_type;
2543 fc.fmt.pix_mp.pixelformat = q_data_cap->fmt->fourcc;
2544 fc.fmt.pix_mp.width = f->fmt.pix_mp.width;
2545 fc.fmt.pix_mp.height = f->fmt.pix_mp.height;
2546
2547 return mxc_jpeg_s_fmt_vid_cap(file, priv, &fc);
2548 }
2549
mxc_jpeg_g_fmt_vid(struct file * file,void * priv,struct v4l2_format * f)2550 static int mxc_jpeg_g_fmt_vid(struct file *file, void *priv,
2551 struct v4l2_format *f)
2552 {
2553 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
2554 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
2555 struct device *dev = jpeg->dev;
2556 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
2557 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type);
2558 int i;
2559
2560 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
2561 dev_err(dev, "G_FMT with Invalid type: %d\n", f->type);
2562 return -EINVAL;
2563 }
2564
2565 pix_mp->pixelformat = q_data->fmt->fourcc;
2566 pix_mp->width = q_data->w;
2567 pix_mp->height = q_data->h;
2568 pix_mp->field = V4L2_FIELD_NONE;
2569 if (q_data->fmt->flags == MXC_JPEG_FMT_TYPE_RAW) {
2570 pix_mp->width = q_data->w_adjusted;
2571 pix_mp->height = q_data->h_adjusted;
2572 }
2573
2574 /* fix colorspace information to sRGB for both output & capture */
2575 pix_mp->colorspace = V4L2_COLORSPACE_SRGB;
2576 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_601;
2577 pix_mp->xfer_func = V4L2_XFER_FUNC_SRGB;
2578 pix_mp->quantization = V4L2_QUANTIZATION_FULL_RANGE;
2579
2580 pix_mp->num_planes = q_data->fmt->mem_planes;
2581 for (i = 0; i < pix_mp->num_planes; i++) {
2582 pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i];
2583 pix_mp->plane_fmt[i].sizeimage = mxc_jpeg_get_plane_size(q_data, i);
2584 }
2585
2586 return 0;
2587 }
2588
mxc_jpeg_dec_g_selection(struct file * file,void * fh,struct v4l2_selection * s)2589 static int mxc_jpeg_dec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
2590 {
2591 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
2592 struct mxc_jpeg_q_data *q_data_cap;
2593
2594 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2595 return -EINVAL;
2596
2597 q_data_cap = mxc_jpeg_get_q_data(ctx, s->type);
2598
2599 switch (s->target) {
2600 case V4L2_SEL_TGT_COMPOSE:
2601 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
2602 s->r = q_data_cap->crop;
2603 break;
2604 case V4L2_SEL_TGT_COMPOSE_PADDED:
2605 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
2606 s->r.left = 0;
2607 s->r.top = 0;
2608 s->r.width = q_data_cap->w_adjusted;
2609 s->r.height = q_data_cap->h_adjusted;
2610 break;
2611 default:
2612 return -EINVAL;
2613 }
2614
2615 return 0;
2616 }
2617
mxc_jpeg_enc_g_selection(struct file * file,void * fh,struct v4l2_selection * s)2618 static int mxc_jpeg_enc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
2619 {
2620 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
2621 struct mxc_jpeg_q_data *q_data_out;
2622
2623 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2624 return -EINVAL;
2625
2626 q_data_out = mxc_jpeg_get_q_data(ctx, s->type);
2627
2628 switch (s->target) {
2629 case V4L2_SEL_TGT_CROP_DEFAULT:
2630 case V4L2_SEL_TGT_CROP_BOUNDS:
2631 s->r.left = 0;
2632 s->r.top = 0;
2633 s->r.width = q_data_out->w;
2634 s->r.height = q_data_out->h;
2635 break;
2636 case V4L2_SEL_TGT_CROP:
2637 s->r = q_data_out->crop;
2638 break;
2639 default:
2640 return -EINVAL;
2641 }
2642
2643 return 0;
2644 }
2645
mxc_jpeg_g_selection(struct file * file,void * fh,struct v4l2_selection * s)2646 static int mxc_jpeg_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
2647 {
2648 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
2649
2650 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE)
2651 return mxc_jpeg_dec_g_selection(file, fh, s);
2652 else
2653 return mxc_jpeg_enc_g_selection(file, fh, s);
2654 }
2655
mxc_jpeg_s_selection(struct file * file,void * fh,struct v4l2_selection * s)2656 static int mxc_jpeg_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
2657 {
2658 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
2659 struct mxc_jpeg_q_data *q_data_out;
2660
2661 if (ctx->mxc_jpeg->mode != MXC_JPEG_ENCODE)
2662 return -ENOTTY;
2663
2664 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2665 return -EINVAL;
2666 if (s->target != V4L2_SEL_TGT_CROP)
2667 return -EINVAL;
2668
2669 q_data_out = mxc_jpeg_get_q_data(ctx, s->type);
2670 if (s->r.left || s->r.top)
2671 return -EINVAL;
2672 if (s->r.width > q_data_out->w || s->r.height > q_data_out->h)
2673 return -EINVAL;
2674
2675 q_data_out->crop.left = 0;
2676 q_data_out->crop.top = 0;
2677 q_data_out->crop.width = s->r.width;
2678 q_data_out->crop.height = s->r.height;
2679
2680 return 0;
2681 }
2682
mxc_jpeg_subscribe_event(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)2683 static int mxc_jpeg_subscribe_event(struct v4l2_fh *fh,
2684 const struct v4l2_event_subscription *sub)
2685 {
2686 switch (sub->type) {
2687 case V4L2_EVENT_EOS:
2688 return v4l2_event_subscribe(fh, sub, 0, NULL);
2689 case V4L2_EVENT_SOURCE_CHANGE:
2690 return v4l2_src_change_event_subscribe(fh, sub);
2691 case V4L2_EVENT_CTRL:
2692 return v4l2_ctrl_subscribe_event(fh, sub);
2693 default:
2694 return -EINVAL;
2695 }
2696 }
2697
2698 static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = {
2699 .vidioc_querycap = mxc_jpeg_querycap,
2700 .vidioc_enum_fmt_vid_cap = mxc_jpeg_enum_fmt_vid_cap,
2701 .vidioc_enum_fmt_vid_out = mxc_jpeg_enum_fmt_vid_out,
2702
2703 .vidioc_try_fmt_vid_cap_mplane = mxc_jpeg_try_fmt_vid_cap,
2704 .vidioc_try_fmt_vid_out_mplane = mxc_jpeg_try_fmt_vid_out,
2705
2706 .vidioc_s_fmt_vid_cap_mplane = mxc_jpeg_s_fmt_vid_cap,
2707 .vidioc_s_fmt_vid_out_mplane = mxc_jpeg_s_fmt_vid_out,
2708
2709 .vidioc_g_fmt_vid_cap_mplane = mxc_jpeg_g_fmt_vid,
2710 .vidioc_g_fmt_vid_out_mplane = mxc_jpeg_g_fmt_vid,
2711
2712 .vidioc_g_selection = mxc_jpeg_g_selection,
2713 .vidioc_s_selection = mxc_jpeg_s_selection,
2714
2715 .vidioc_subscribe_event = mxc_jpeg_subscribe_event,
2716 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
2717
2718 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd,
2719 .vidioc_decoder_cmd = mxc_jpeg_decoder_cmd,
2720 .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd,
2721 .vidioc_encoder_cmd = mxc_jpeg_encoder_cmd,
2722
2723 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
2724 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
2725
2726 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
2727 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
2728 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
2729 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
2730 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
2731 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
2732 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
2733 };
2734
mxc_jpeg_release(struct file * file)2735 static int mxc_jpeg_release(struct file *file)
2736 {
2737 struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file);
2738 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(file->private_data);
2739 struct device *dev = mxc_jpeg->dev;
2740
2741 mutex_lock(&mxc_jpeg->lock);
2742 if (mxc_jpeg->mode == MXC_JPEG_DECODE)
2743 dev_dbg(dev, "Release JPEG decoder instance on slot %d.",
2744 ctx->slot);
2745 else
2746 dev_dbg(dev, "Release JPEG encoder instance on slot %d.",
2747 ctx->slot);
2748 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
2749 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
2750 v4l2_fh_del(&ctx->fh);
2751 v4l2_fh_exit(&ctx->fh);
2752 kfree(ctx);
2753 mutex_unlock(&mxc_jpeg->lock);
2754
2755 return 0;
2756 }
2757
2758 static const struct v4l2_file_operations mxc_jpeg_fops = {
2759 .owner = THIS_MODULE,
2760 .open = mxc_jpeg_open,
2761 .release = mxc_jpeg_release,
2762 .poll = v4l2_m2m_fop_poll,
2763 .unlocked_ioctl = video_ioctl2,
2764 .mmap = v4l2_m2m_fop_mmap,
2765 };
2766
2767 static const struct v4l2_m2m_ops mxc_jpeg_m2m_ops = {
2768 .job_ready = mxc_jpeg_job_ready,
2769 .device_run = mxc_jpeg_device_run,
2770 };
2771
mxc_jpeg_detach_pm_domains(struct mxc_jpeg_dev * jpeg)2772 static void mxc_jpeg_detach_pm_domains(struct mxc_jpeg_dev *jpeg)
2773 {
2774 int i;
2775
2776 for (i = 0; i < jpeg->num_domains; i++) {
2777 if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]) &&
2778 !pm_runtime_suspended(jpeg->pd_dev[i]))
2779 pm_runtime_force_suspend(jpeg->pd_dev[i]);
2780 if (!IS_ERR_OR_NULL(jpeg->pd_link[i]))
2781 device_link_del(jpeg->pd_link[i]);
2782 if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]))
2783 dev_pm_domain_detach(jpeg->pd_dev[i], true);
2784 jpeg->pd_dev[i] = NULL;
2785 jpeg->pd_link[i] = NULL;
2786 }
2787 }
2788
mxc_jpeg_attach_pm_domains(struct mxc_jpeg_dev * jpeg)2789 static int mxc_jpeg_attach_pm_domains(struct mxc_jpeg_dev *jpeg)
2790 {
2791 struct device *dev = jpeg->dev;
2792 struct device_node *np = jpeg->pdev->dev.of_node;
2793 int i;
2794 int ret;
2795
2796 jpeg->num_domains = of_count_phandle_with_args(np, "power-domains",
2797 "#power-domain-cells");
2798 if (jpeg->num_domains < 0) {
2799 dev_err(dev, "No power domains defined for jpeg node\n");
2800 return jpeg->num_domains;
2801 }
2802 if (jpeg->num_domains == 1) {
2803 /* genpd_dev_pm_attach() attach automatically if power domains count is 1 */
2804 jpeg->num_domains = 0;
2805 return 0;
2806 }
2807
2808 jpeg->pd_dev = devm_kmalloc_array(dev, jpeg->num_domains,
2809 sizeof(*jpeg->pd_dev), GFP_KERNEL);
2810 if (!jpeg->pd_dev)
2811 return -ENOMEM;
2812
2813 jpeg->pd_link = devm_kmalloc_array(dev, jpeg->num_domains,
2814 sizeof(*jpeg->pd_link), GFP_KERNEL);
2815 if (!jpeg->pd_link)
2816 return -ENOMEM;
2817
2818 for (i = 0; i < jpeg->num_domains; i++) {
2819 jpeg->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
2820 if (IS_ERR(jpeg->pd_dev[i])) {
2821 ret = PTR_ERR(jpeg->pd_dev[i]);
2822 goto fail;
2823 }
2824
2825 jpeg->pd_link[i] = device_link_add(dev, jpeg->pd_dev[i],
2826 DL_FLAG_STATELESS |
2827 DL_FLAG_PM_RUNTIME);
2828 if (!jpeg->pd_link[i]) {
2829 ret = -EINVAL;
2830 goto fail;
2831 }
2832 }
2833
2834 return 0;
2835 fail:
2836 mxc_jpeg_detach_pm_domains(jpeg);
2837 return ret;
2838 }
2839
mxc_jpeg_probe(struct platform_device * pdev)2840 static int mxc_jpeg_probe(struct platform_device *pdev)
2841 {
2842 struct mxc_jpeg_dev *jpeg;
2843 struct device *dev = &pdev->dev;
2844 int dec_irq;
2845 int ret;
2846 int mode;
2847 const struct of_device_id *of_id;
2848
2849 of_id = of_match_node(mxc_jpeg_match, dev->of_node);
2850 if (!of_id)
2851 return -ENODEV;
2852 mode = *(const int *)of_id->data;
2853
2854 jpeg = devm_kzalloc(dev, sizeof(struct mxc_jpeg_dev), GFP_KERNEL);
2855 if (!jpeg)
2856 return -ENOMEM;
2857
2858 mutex_init(&jpeg->lock);
2859 spin_lock_init(&jpeg->hw_lock);
2860
2861 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
2862 if (ret) {
2863 dev_err(&pdev->dev, "No suitable DMA available.\n");
2864 goto err_irq;
2865 }
2866
2867 jpeg->base_reg = devm_platform_ioremap_resource(pdev, 0);
2868 if (IS_ERR(jpeg->base_reg))
2869 return PTR_ERR(jpeg->base_reg);
2870
2871 ret = of_property_read_u32_index(pdev->dev.of_node, "slot", 0, &jpeg->slot_data.slot);
2872 if (ret)
2873 jpeg->slot_data.slot = 0;
2874 dev_info(&pdev->dev, "choose slot %d\n", jpeg->slot_data.slot);
2875 dec_irq = platform_get_irq(pdev, 0);
2876 if (dec_irq < 0) {
2877 ret = dec_irq;
2878 goto err_irq;
2879 }
2880 ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq,
2881 0, pdev->name, jpeg);
2882 if (ret) {
2883 dev_err(&pdev->dev, "Failed to request irq %d (%d)\n",
2884 dec_irq, ret);
2885 goto err_irq;
2886 }
2887
2888 jpeg->pdev = pdev;
2889 jpeg->dev = dev;
2890 jpeg->mode = mode;
2891
2892 /* Get clocks */
2893 ret = devm_clk_bulk_get_all(&pdev->dev, &jpeg->clks);
2894 if (ret < 0) {
2895 dev_err(dev, "failed to get clock\n");
2896 goto err_clk;
2897 }
2898 jpeg->num_clks = ret;
2899
2900 ret = mxc_jpeg_attach_pm_domains(jpeg);
2901 if (ret < 0) {
2902 dev_err(dev, "failed to attach power domains %d\n", ret);
2903 goto err_clk;
2904 }
2905
2906 /* v4l2 */
2907 ret = v4l2_device_register(dev, &jpeg->v4l2_dev);
2908 if (ret) {
2909 dev_err(dev, "failed to register v4l2 device\n");
2910 goto err_register;
2911 }
2912 jpeg->m2m_dev = v4l2_m2m_init(&mxc_jpeg_m2m_ops);
2913 if (IS_ERR(jpeg->m2m_dev)) {
2914 dev_err(dev, "failed to register v4l2 device\n");
2915 ret = PTR_ERR(jpeg->m2m_dev);
2916 goto err_m2m;
2917 }
2918
2919 jpeg->dec_vdev = video_device_alloc();
2920 if (!jpeg->dec_vdev) {
2921 dev_err(dev, "failed to register v4l2 device\n");
2922 ret = -ENOMEM;
2923 goto err_vdev_alloc;
2924 }
2925 if (mode == MXC_JPEG_ENCODE)
2926 snprintf(jpeg->dec_vdev->name,
2927 sizeof(jpeg->dec_vdev->name),
2928 "%s-enc", MXC_JPEG_NAME);
2929 else
2930 snprintf(jpeg->dec_vdev->name,
2931 sizeof(jpeg->dec_vdev->name),
2932 "%s-dec", MXC_JPEG_NAME);
2933
2934 jpeg->dec_vdev->fops = &mxc_jpeg_fops;
2935 jpeg->dec_vdev->ioctl_ops = &mxc_jpeg_ioctl_ops;
2936 jpeg->dec_vdev->minor = -1;
2937 jpeg->dec_vdev->release = video_device_release;
2938 jpeg->dec_vdev->lock = &jpeg->lock; /* lock for ioctl serialization */
2939 jpeg->dec_vdev->v4l2_dev = &jpeg->v4l2_dev;
2940 jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M;
2941 jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING |
2942 V4L2_CAP_VIDEO_M2M_MPLANE;
2943 video_set_drvdata(jpeg->dec_vdev, jpeg);
2944 if (mode == MXC_JPEG_ENCODE) {
2945 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_DECODER_CMD);
2946 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_DECODER_CMD);
2947 } else {
2948 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_ENCODER_CMD);
2949 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_ENCODER_CMD);
2950 }
2951 ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_VIDEO, -1);
2952 if (ret) {
2953 dev_err(dev, "failed to register video device\n");
2954 goto err_vdev_register;
2955 }
2956 if (mode == MXC_JPEG_ENCODE)
2957 v4l2_info(&jpeg->v4l2_dev,
2958 "encoder device registered as /dev/video%d (%d,%d)\n",
2959 jpeg->dec_vdev->num, VIDEO_MAJOR,
2960 jpeg->dec_vdev->minor);
2961 else
2962 v4l2_info(&jpeg->v4l2_dev,
2963 "decoder device registered as /dev/video%d (%d,%d)\n",
2964 jpeg->dec_vdev->num, VIDEO_MAJOR,
2965 jpeg->dec_vdev->minor);
2966
2967 platform_set_drvdata(pdev, jpeg);
2968 pm_runtime_enable(dev);
2969
2970 return 0;
2971
2972 err_vdev_register:
2973 video_device_release(jpeg->dec_vdev);
2974
2975 err_vdev_alloc:
2976 v4l2_m2m_release(jpeg->m2m_dev);
2977
2978 err_m2m:
2979 v4l2_device_unregister(&jpeg->v4l2_dev);
2980
2981 err_register:
2982 mxc_jpeg_detach_pm_domains(jpeg);
2983
2984 err_irq:
2985 err_clk:
2986 return ret;
2987 }
2988
mxc_jpeg_runtime_resume(struct device * dev)2989 static int mxc_jpeg_runtime_resume(struct device *dev)
2990 {
2991 struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev);
2992 int ret;
2993
2994 ret = clk_bulk_prepare_enable(jpeg->num_clks, jpeg->clks);
2995 if (ret < 0) {
2996 dev_err(dev, "failed to enable clock\n");
2997 return ret;
2998 }
2999
3000 return 0;
3001 }
3002
mxc_jpeg_runtime_suspend(struct device * dev)3003 static int mxc_jpeg_runtime_suspend(struct device *dev)
3004 {
3005 struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev);
3006
3007 clk_bulk_disable_unprepare(jpeg->num_clks, jpeg->clks);
3008
3009 return 0;
3010 }
3011
mxc_jpeg_suspend(struct device * dev)3012 static int mxc_jpeg_suspend(struct device *dev)
3013 {
3014 struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev);
3015
3016 v4l2_m2m_suspend(jpeg->m2m_dev);
3017 return pm_runtime_force_suspend(dev);
3018 }
3019
mxc_jpeg_resume(struct device * dev)3020 static int mxc_jpeg_resume(struct device *dev)
3021 {
3022 struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev);
3023 int ret;
3024
3025 ret = pm_runtime_force_resume(dev);
3026 if (ret < 0)
3027 return ret;
3028
3029 v4l2_m2m_resume(jpeg->m2m_dev);
3030 return ret;
3031 }
3032
3033 static const struct dev_pm_ops mxc_jpeg_pm_ops = {
3034 RUNTIME_PM_OPS(mxc_jpeg_runtime_suspend, mxc_jpeg_runtime_resume, NULL)
3035 SYSTEM_SLEEP_PM_OPS(mxc_jpeg_suspend, mxc_jpeg_resume)
3036 };
3037
mxc_jpeg_remove(struct platform_device * pdev)3038 static void mxc_jpeg_remove(struct platform_device *pdev)
3039 {
3040 struct mxc_jpeg_dev *jpeg = platform_get_drvdata(pdev);
3041
3042 mxc_jpeg_free_slot_data(jpeg);
3043
3044 pm_runtime_disable(&pdev->dev);
3045 video_unregister_device(jpeg->dec_vdev);
3046 v4l2_m2m_release(jpeg->m2m_dev);
3047 v4l2_device_unregister(&jpeg->v4l2_dev);
3048 mxc_jpeg_detach_pm_domains(jpeg);
3049 }
3050
3051 MODULE_DEVICE_TABLE(of, mxc_jpeg_match);
3052
3053 static struct platform_driver mxc_jpeg_driver = {
3054 .probe = mxc_jpeg_probe,
3055 .remove = mxc_jpeg_remove,
3056 .driver = {
3057 .name = "mxc-jpeg",
3058 .of_match_table = mxc_jpeg_match,
3059 .pm = pm_ptr(&mxc_jpeg_pm_ops),
3060 },
3061 };
3062 module_platform_driver(mxc_jpeg_driver);
3063
3064 MODULE_AUTHOR("Zhengyu Shen <zhengyu.shen_1@nxp.com>");
3065 MODULE_AUTHOR("Mirela Rabulea <mirela.rabulea@nxp.com>");
3066 MODULE_DESCRIPTION("V4L2 driver for i.MX8 QXP/QM JPEG encoder/decoder");
3067 MODULE_LICENSE("GPL v2");
3068