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