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