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_free_slot_data(struct mxc_jpeg_dev * jpeg)755 static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg)
756 {
757 /* free descriptor for decoding/encoding phase */
758 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
759 jpeg->slot_data.desc,
760 jpeg->slot_data.desc_handle);
761 jpeg->slot_data.desc = NULL;
762 jpeg->slot_data.desc_handle = 0;
763
764 /* free descriptor for encoder configuration phase / decoder DHT */
765 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc),
766 jpeg->slot_data.cfg_desc,
767 jpeg->slot_data.cfg_desc_handle);
768 jpeg->slot_data.cfg_desc_handle = 0;
769 jpeg->slot_data.cfg_desc = NULL;
770
771 /* free configuration stream */
772 dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM,
773 jpeg->slot_data.cfg_stream_vaddr,
774 jpeg->slot_data.cfg_stream_handle);
775 jpeg->slot_data.cfg_stream_vaddr = NULL;
776 jpeg->slot_data.cfg_stream_handle = 0;
777
778 jpeg->slot_data.used = false;
779 }
780
mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev * jpeg)781 static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg)
782 {
783 struct mxc_jpeg_desc *desc;
784 struct mxc_jpeg_desc *cfg_desc;
785 void *cfg_stm;
786
787 if (jpeg->slot_data.desc)
788 goto skip_alloc; /* already allocated, reuse it */
789
790 /* allocate descriptor for decoding/encoding phase */
791 desc = dma_alloc_coherent(jpeg->dev,
792 sizeof(struct mxc_jpeg_desc),
793 &jpeg->slot_data.desc_handle,
794 GFP_ATOMIC);
795 if (!desc)
796 goto err;
797 jpeg->slot_data.desc = desc;
798
799 /* allocate descriptor for configuration phase (encoder only) */
800 cfg_desc = dma_alloc_coherent(jpeg->dev,
801 sizeof(struct mxc_jpeg_desc),
802 &jpeg->slot_data.cfg_desc_handle,
803 GFP_ATOMIC);
804 if (!cfg_desc)
805 goto err;
806 jpeg->slot_data.cfg_desc = cfg_desc;
807
808 /* allocate configuration stream */
809 cfg_stm = dma_alloc_coherent(jpeg->dev,
810 MXC_JPEG_MAX_CFG_STREAM,
811 &jpeg->slot_data.cfg_stream_handle,
812 GFP_ATOMIC);
813 if (!cfg_stm)
814 goto err;
815 jpeg->slot_data.cfg_stream_vaddr = cfg_stm;
816
817 skip_alloc:
818 jpeg->slot_data.used = true;
819
820 return true;
821 err:
822 dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot);
823 mxc_jpeg_free_slot_data(jpeg);
824
825 return false;
826 }
827
mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx * ctx,struct vb2_v4l2_buffer * src_buf,struct vb2_v4l2_buffer * dst_buf)828 static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx,
829 struct vb2_v4l2_buffer *src_buf,
830 struct vb2_v4l2_buffer *dst_buf)
831 {
832 if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) {
833 dst_buf->flags |= V4L2_BUF_FLAG_LAST;
834 v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx);
835 notify_eos(ctx);
836 ctx->header_parsed = false;
837 }
838 }
839
mxc_jpeg_job_finish(struct mxc_jpeg_ctx * ctx,enum vb2_buffer_state state,bool reset)840 static void mxc_jpeg_job_finish(struct mxc_jpeg_ctx *ctx, enum vb2_buffer_state state, bool reset)
841 {
842 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
843 void __iomem *reg = jpeg->base_reg;
844 struct vb2_v4l2_buffer *src_buf, *dst_buf;
845
846 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
847 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
848 mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf);
849 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
850 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
851 v4l2_m2m_buf_done(src_buf, state);
852 v4l2_m2m_buf_done(dst_buf, state);
853
854 mxc_jpeg_disable_irq(reg, ctx->slot);
855 jpeg->slot_data.used = false;
856 if (reset)
857 mxc_jpeg_sw_reset(reg);
858 }
859
mxc_jpeg_get_plane_size(struct mxc_jpeg_q_data * q_data,u32 plane_no)860 static u32 mxc_jpeg_get_plane_size(struct mxc_jpeg_q_data *q_data, u32 plane_no)
861 {
862 const struct mxc_jpeg_fmt *fmt = q_data->fmt;
863 u32 size;
864 int i;
865
866 if (plane_no >= fmt->mem_planes)
867 return 0;
868
869 if (fmt->mem_planes == fmt->comp_planes)
870 return q_data->sizeimage[plane_no];
871
872 if (plane_no < fmt->mem_planes - 1)
873 return q_data->sizeimage[plane_no];
874
875 size = q_data->sizeimage[fmt->mem_planes - 1];
876
877 /* Should be impossible given mxc_formats. */
878 if (WARN_ON_ONCE(fmt->comp_planes > ARRAY_SIZE(q_data->sizeimage)))
879 return size;
880
881 for (i = fmt->mem_planes; i < fmt->comp_planes; i++)
882 size += q_data->sizeimage[i];
883
884 return size;
885 }
886
mxc_jpeg_dec_irq(int irq,void * priv)887 static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
888 {
889 struct mxc_jpeg_dev *jpeg = priv;
890 struct mxc_jpeg_ctx *ctx;
891 void __iomem *reg = jpeg->base_reg;
892 struct device *dev = jpeg->dev;
893 struct vb2_v4l2_buffer *src_buf, *dst_buf;
894 struct mxc_jpeg_src_buf *jpeg_src_buf;
895 enum vb2_buffer_state buf_state;
896 u32 dec_ret, com_status;
897 unsigned long payload;
898 struct mxc_jpeg_q_data *q_data;
899 enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
900 unsigned int slot;
901
902 spin_lock(&jpeg->hw_lock);
903
904 com_status = readl(reg + COM_STATUS);
905 slot = COM_STATUS_CUR_SLOT(com_status);
906 dev_dbg(dev, "Irq %d on slot %d.\n", irq, slot);
907
908 ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
909 if (WARN_ON(!ctx))
910 goto job_unlock;
911
912 if (slot != ctx->slot) {
913 /* TODO investigate when adding multi-instance support */
914 dev_warn(dev, "IRQ slot %d != context slot %d.\n",
915 slot, ctx->slot);
916 goto job_unlock;
917 }
918
919 if (!jpeg->slot_data.used)
920 goto job_unlock;
921
922 dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
923 writel(dec_ret, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); /* w1c */
924
925 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
926 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
927 if (!dst_buf || !src_buf) {
928 dev_err(dev, "No source or destination buffer.\n");
929 goto job_unlock;
930 }
931 jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf);
932
933 if (dec_ret & SLOT_STATUS_ENC_CONFIG_ERR) {
934 u32 ret = readl(reg + CAST_STATUS12);
935
936 dev_err(dev, "Encoder/decoder error, dec_ret = 0x%08x, status=0x%08x",
937 dec_ret, ret);
938 mxc_jpeg_clr_desc(reg, slot);
939 mxc_jpeg_sw_reset(reg);
940 buf_state = VB2_BUF_STATE_ERROR;
941 goto buffers_done;
942 }
943
944 if (!(dec_ret & SLOT_STATUS_FRMDONE))
945 goto job_unlock;
946
947 if (jpeg->mode == MXC_JPEG_ENCODE &&
948 ctx->enc_state == MXC_JPEG_ENC_CONF) {
949 q_data = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
950 ctx->enc_state = MXC_JPEG_ENCODING;
951 dev_dbg(dev, "Encoder config finished. Start encoding...\n");
952 mxc_jpeg_enc_set_quality(dev, reg, ctx->jpeg_quality);
953 mxc_jpeg_enc_mode_go(dev, reg, mxc_jpeg_is_extended_sequential(q_data->fmt));
954 goto job_unlock;
955 }
956 if (jpeg->mode == MXC_JPEG_DECODE && jpeg_src_buf->dht_needed) {
957 jpeg_src_buf->dht_needed = false;
958 dev_dbg(dev, "Decoder DHT cfg finished. Start decoding...\n");
959 goto job_unlock;
960 }
961
962 if (jpeg->mode == MXC_JPEG_ENCODE) {
963 payload = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR));
964 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload);
965 dev_dbg(dev, "Encoding finished, payload size: %ld\n",
966 payload);
967 } else {
968 q_data = mxc_jpeg_get_q_data(ctx, cap_type);
969 payload = mxc_jpeg_get_plane_size(q_data, 0);
970 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload);
971 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0);
972 if (q_data->fmt->mem_planes == 2) {
973 payload = mxc_jpeg_get_plane_size(q_data, 1);
974 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, payload);
975 }
976 dev_dbg(dev, "Decoding finished, payload size: %ld + %ld\n",
977 vb2_get_plane_payload(&dst_buf->vb2_buf, 0),
978 vb2_get_plane_payload(&dst_buf->vb2_buf, 1));
979 }
980
981 /* short preview of the results */
982 dev_dbg(dev, "src_buf preview: ");
983 print_mxc_buf(jpeg, &src_buf->vb2_buf, 32);
984 dev_dbg(dev, "dst_buf preview: ");
985 print_mxc_buf(jpeg, &dst_buf->vb2_buf, 32);
986 buf_state = VB2_BUF_STATE_DONE;
987
988 buffers_done:
989 mxc_jpeg_job_finish(ctx, buf_state, false);
990 spin_unlock(&jpeg->hw_lock);
991 cancel_delayed_work(&ctx->task_timer);
992 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
993 return IRQ_HANDLED;
994 job_unlock:
995 spin_unlock(&jpeg->hw_lock);
996 return IRQ_HANDLED;
997 }
998
mxc_jpeg_fixup_sof(struct mxc_jpeg_sof * sof,u32 fourcc,u16 w,u16 h)999 static int mxc_jpeg_fixup_sof(struct mxc_jpeg_sof *sof,
1000 u32 fourcc,
1001 u16 w, u16 h)
1002 {
1003 int sof_length;
1004 const struct mxc_jpeg_fmt *fmt = mxc_jpeg_find_format(fourcc);
1005
1006 if (fmt)
1007 sof->precision = fmt->precision;
1008 else
1009 sof->precision = 8; /* TODO allow 8/12 bit precision*/
1010 sof->height = h;
1011 _bswap16(&sof->height);
1012 sof->width = w;
1013 _bswap16(&sof->width);
1014
1015 switch (fourcc) {
1016 case V4L2_PIX_FMT_NV12:
1017 case V4L2_PIX_FMT_NV12M:
1018 case V4L2_PIX_FMT_P012:
1019 case V4L2_PIX_FMT_P012M:
1020 sof->components_no = 3;
1021 sof->comp[0].v = 0x2;
1022 sof->comp[0].h = 0x2;
1023 break;
1024 case V4L2_PIX_FMT_YUYV:
1025 case V4L2_PIX_FMT_Y212:
1026 sof->components_no = 3;
1027 sof->comp[0].v = 0x1;
1028 sof->comp[0].h = 0x2;
1029 break;
1030 case V4L2_PIX_FMT_YUV24:
1031 case V4L2_PIX_FMT_YUV48_12:
1032 case V4L2_PIX_FMT_BGR24:
1033 case V4L2_PIX_FMT_BGR48_12:
1034 default:
1035 sof->components_no = 3;
1036 break;
1037 case V4L2_PIX_FMT_ABGR32:
1038 case V4L2_PIX_FMT_ABGR64_12:
1039 sof->components_no = 4;
1040 break;
1041 case V4L2_PIX_FMT_GREY:
1042 case V4L2_PIX_FMT_Y012:
1043 sof->components_no = 1;
1044 break;
1045 }
1046 sof_length = 8 + 3 * sof->components_no;
1047 sof->length = sof_length;
1048 _bswap16(&sof->length);
1049
1050 return sof_length; /* not swaped */
1051 }
1052
mxc_jpeg_fixup_sos(struct mxc_jpeg_sos * sos,u32 fourcc)1053 static int mxc_jpeg_fixup_sos(struct mxc_jpeg_sos *sos,
1054 u32 fourcc)
1055 {
1056 int sos_length;
1057 u8 *sof_u8 = (u8 *)sos;
1058
1059 switch (fourcc) {
1060 case V4L2_PIX_FMT_NV12:
1061 case V4L2_PIX_FMT_NV12M:
1062 case V4L2_PIX_FMT_P012:
1063 case V4L2_PIX_FMT_P012M:
1064 sos->components_no = 3;
1065 break;
1066 case V4L2_PIX_FMT_YUYV:
1067 case V4L2_PIX_FMT_Y212:
1068 sos->components_no = 3;
1069 break;
1070 case V4L2_PIX_FMT_YUV24:
1071 case V4L2_PIX_FMT_YUV48_12:
1072 case V4L2_PIX_FMT_BGR24:
1073 case V4L2_PIX_FMT_BGR48_12:
1074 default:
1075 sos->components_no = 3;
1076 break;
1077 case V4L2_PIX_FMT_ABGR32:
1078 case V4L2_PIX_FMT_ABGR64_12:
1079 sos->components_no = 4;
1080 break;
1081 case V4L2_PIX_FMT_GREY:
1082 case V4L2_PIX_FMT_Y012:
1083 sos->components_no = 1;
1084 break;
1085 }
1086 sos_length = 6 + 2 * sos->components_no;
1087 sos->length = sos_length;
1088 _bswap16(&sos->length);
1089
1090 /* SOS ignorable bytes, not so ignorable after all */
1091 sof_u8[sos_length - 1] = 0x0;
1092 sof_u8[sos_length - 2] = 0x3f;
1093 sof_u8[sos_length - 3] = 0x0;
1094
1095 return sos_length; /* not swaped */
1096 }
1097
mxc_jpeg_setup_cfg_stream(void * cfg_stream_vaddr,u32 fourcc,u16 w,u16 h)1098 static unsigned int mxc_jpeg_setup_cfg_stream(void *cfg_stream_vaddr,
1099 u32 fourcc,
1100 u16 w, u16 h)
1101 {
1102 /*
1103 * There is a hardware issue that first 128 bytes of configuration data
1104 * can't be loaded correctly.
1105 * To avoid this issue, we need to write the configuration from
1106 * an offset which should be no less than 0x80 (128 bytes).
1107 */
1108 unsigned int offset = 0x80;
1109 u8 *cfg = (u8 *)cfg_stream_vaddr;
1110 struct mxc_jpeg_sof *sof;
1111 struct mxc_jpeg_sos *sos;
1112 const struct mxc_jpeg_fmt *fmt = mxc_jpeg_find_format(fourcc);
1113
1114 if (!fmt)
1115 return 0;
1116
1117 memcpy(cfg + offset, jpeg_soi, ARRAY_SIZE(jpeg_soi));
1118 offset += ARRAY_SIZE(jpeg_soi);
1119
1120 if (fmt->is_rgb) {
1121 memcpy(cfg + offset, jpeg_app14, sizeof(jpeg_app14));
1122 offset += sizeof(jpeg_app14);
1123 } else {
1124 memcpy(cfg + offset, jpeg_app0, sizeof(jpeg_app0));
1125 offset += sizeof(jpeg_app0);
1126 }
1127
1128 if (mxc_jpeg_is_extended_sequential(fmt)) {
1129 memcpy(cfg + offset, jpeg_dqt_extseq, sizeof(jpeg_dqt_extseq));
1130 offset += sizeof(jpeg_dqt_extseq);
1131
1132 memcpy(cfg + offset, jpeg_sof_extseq, sizeof(jpeg_sof_extseq));
1133 } else {
1134 memcpy(cfg + offset, jpeg_dqt, sizeof(jpeg_dqt));
1135 offset += sizeof(jpeg_dqt);
1136
1137 memcpy(cfg + offset, jpeg_sof_maximal, sizeof(jpeg_sof_maximal));
1138 }
1139 offset += 2; /* skip marker ID */
1140 sof = (struct mxc_jpeg_sof *)(cfg + offset);
1141 offset += mxc_jpeg_fixup_sof(sof, fourcc, w, h);
1142
1143 if (mxc_jpeg_is_extended_sequential(fmt)) {
1144 memcpy(cfg + offset, jpeg_dht_extseq, sizeof(jpeg_dht_extseq));
1145 offset += sizeof(jpeg_dht_extseq);
1146 } else {
1147 memcpy(cfg + offset, jpeg_dht, sizeof(jpeg_dht));
1148 offset += sizeof(jpeg_dht);
1149 }
1150
1151 memcpy(cfg + offset, jpeg_dri, sizeof(jpeg_dri));
1152 offset += sizeof(jpeg_dri);
1153
1154 memcpy(cfg + offset, jpeg_sos_maximal, sizeof(jpeg_sos_maximal));
1155 offset += 2; /* skip marker ID */
1156 sos = (struct mxc_jpeg_sos *)(cfg + offset);
1157 offset += mxc_jpeg_fixup_sos(sos, fourcc);
1158
1159 memcpy(cfg + offset, jpeg_image_red, sizeof(jpeg_image_red));
1160 offset += sizeof(jpeg_image_red);
1161
1162 memcpy(cfg + offset, jpeg_eoi, sizeof(jpeg_eoi));
1163 offset += sizeof(jpeg_eoi);
1164
1165 return offset;
1166 }
1167
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)1168 static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf,
1169 struct mxc_jpeg_ctx *ctx,
1170 struct vb2_buffer *src_buf,
1171 struct vb2_buffer *dst_buf)
1172 {
1173 enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1174 struct mxc_jpeg_q_data *q_data_cap;
1175 enum mxc_jpeg_image_format img_fmt;
1176 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
1177 void __iomem *reg = jpeg->base_reg;
1178 unsigned int slot = ctx->slot;
1179 struct mxc_jpeg_desc *desc = jpeg->slot_data.desc;
1180 struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc;
1181 dma_addr_t desc_handle = jpeg->slot_data.desc_handle;
1182 dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle;
1183 dma_addr_t cfg_stream_handle = jpeg->slot_data.cfg_stream_handle;
1184 unsigned int *cfg_size = &jpeg->slot_data.cfg_stream_size;
1185 void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr;
1186 struct mxc_jpeg_src_buf *jpeg_src_buf;
1187
1188 jpeg_src_buf = vb2_to_mxc_buf(src_buf);
1189
1190 /* setup the decoding descriptor */
1191 desc->next_descpt_ptr = 0; /* end of chain */
1192 q_data_cap = mxc_jpeg_get_q_data(ctx, cap_type);
1193 desc->imgsize = q_data_cap->w_adjusted << 16 | q_data_cap->h_adjusted;
1194 img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data_cap->fmt->fourcc);
1195 desc->stm_ctrl &= ~STM_CTRL_IMAGE_FORMAT(0xF); /* clear image format */
1196 desc->stm_ctrl |= STM_CTRL_IMAGE_FORMAT(img_fmt);
1197 desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1);
1198 if (mxc_jpeg_is_extended_sequential(jpeg_src_buf->fmt))
1199 desc->stm_ctrl |= STM_CTRL_PIXEL_PRECISION;
1200 else
1201 desc->stm_ctrl &= ~STM_CTRL_PIXEL_PRECISION;
1202 desc->line_pitch = q_data_cap->bytesperline[0];
1203 mxc_jpeg_addrs(desc, dst_buf, src_buf, 0);
1204 mxc_jpeg_set_bufsize(desc, ALIGN(vb2_plane_size(src_buf, 0), 1024));
1205 print_descriptor_info(jpeg->dev, desc);
1206
1207 if (!jpeg_src_buf->dht_needed) {
1208 /* validate the decoding descriptor */
1209 mxc_jpeg_set_desc(desc_handle, reg, slot);
1210 return;
1211 }
1212
1213 /*
1214 * if a default huffman table is needed, use the config descriptor to
1215 * inject a DHT, by chaining it before the decoding descriptor
1216 */
1217 *cfg_size = mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr,
1218 V4L2_PIX_FMT_YUYV,
1219 MXC_JPEG_MIN_WIDTH,
1220 MXC_JPEG_MIN_HEIGHT);
1221 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN;
1222 cfg_desc->buf_base0 = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
1223 cfg_desc->buf_base1 = 0;
1224 cfg_desc->imgsize = MXC_JPEG_MIN_WIDTH << 16;
1225 cfg_desc->imgsize |= MXC_JPEG_MIN_HEIGHT;
1226 cfg_desc->line_pitch = MXC_JPEG_MIN_WIDTH * 2;
1227 cfg_desc->stm_ctrl = STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV422);
1228 cfg_desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1);
1229 cfg_desc->stm_bufbase = cfg_stream_handle;
1230 cfg_desc->stm_bufsize = ALIGN(*cfg_size, 1024);
1231 print_descriptor_info(jpeg->dev, cfg_desc);
1232
1233 /* validate the configuration descriptor */
1234 mxc_jpeg_set_desc(cfg_desc_handle, reg, slot);
1235 }
1236
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)1237 static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,
1238 struct mxc_jpeg_ctx *ctx,
1239 struct vb2_buffer *src_buf,
1240 struct vb2_buffer *dst_buf)
1241 {
1242 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
1243 void __iomem *reg = jpeg->base_reg;
1244 unsigned int slot = ctx->slot;
1245 struct mxc_jpeg_desc *desc = jpeg->slot_data.desc;
1246 struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc;
1247 dma_addr_t desc_handle = jpeg->slot_data.desc_handle;
1248 dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle;
1249 void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr;
1250 struct mxc_jpeg_q_data *q_data;
1251 enum mxc_jpeg_image_format img_fmt;
1252 int w, h;
1253
1254 q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type);
1255
1256 jpeg->slot_data.cfg_stream_size =
1257 mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr,
1258 q_data->fmt->fourcc,
1259 q_data->crop.width,
1260 q_data->crop.height);
1261
1262 /* chain the config descriptor with the encoding descriptor */
1263 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN;
1264
1265 cfg_desc->buf_base0 = jpeg->slot_data.cfg_stream_handle;
1266 cfg_desc->buf_base1 = 0;
1267 cfg_desc->line_pitch = 0;
1268 cfg_desc->stm_bufbase = 0; /* no output expected */
1269 cfg_desc->stm_bufsize = 0x0;
1270 cfg_desc->imgsize = 0;
1271 cfg_desc->stm_ctrl = STM_CTRL_CONFIG_MOD(1);
1272 cfg_desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1);
1273
1274 desc->next_descpt_ptr = 0; /* end of chain */
1275
1276 /* use adjusted resolution for CAST IP job */
1277 w = q_data->crop.width;
1278 h = q_data->crop.height;
1279 v4l_bound_align_image(&w, w, MXC_JPEG_MAX_WIDTH, q_data->fmt->h_align,
1280 &h, h, MXC_JPEG_MAX_HEIGHT, q_data->fmt->v_align, 0);
1281 mxc_jpeg_set_res(desc, w, h);
1282 mxc_jpeg_set_line_pitch(desc, q_data->bytesperline[0]);
1283 mxc_jpeg_set_bufsize(desc, ALIGN(vb2_plane_size(dst_buf, 0), 1024));
1284 img_fmt = mxc_jpeg_fourcc_to_imgfmt(q_data->fmt->fourcc);
1285 if (img_fmt == MXC_JPEG_INVALID)
1286 dev_err(jpeg->dev, "No valid image format detected\n");
1287 desc->stm_ctrl = STM_CTRL_CONFIG_MOD(0) |
1288 STM_CTRL_IMAGE_FORMAT(img_fmt);
1289 desc->stm_ctrl |= STM_CTRL_BITBUF_PTR_CLR(1);
1290 if (mxc_jpeg_is_extended_sequential(q_data->fmt))
1291 desc->stm_ctrl |= STM_CTRL_PIXEL_PRECISION;
1292 else
1293 desc->stm_ctrl &= ~STM_CTRL_PIXEL_PRECISION;
1294 mxc_jpeg_addrs(desc, src_buf, dst_buf, 0);
1295 dev_dbg(jpeg->dev, "cfg_desc:\n");
1296 print_descriptor_info(jpeg->dev, cfg_desc);
1297 dev_dbg(jpeg->dev, "enc desc:\n");
1298 print_descriptor_info(jpeg->dev, desc);
1299 print_wrapper_info(jpeg->dev, reg);
1300 print_cast_status(jpeg->dev, reg, MXC_JPEG_ENCODE);
1301
1302 /* validate the configuration descriptor */
1303 mxc_jpeg_set_desc(cfg_desc_handle, reg, slot);
1304 }
1305
mxc_jpeg_get_sibling_format(const struct mxc_jpeg_fmt * fmt)1306 static const struct mxc_jpeg_fmt *mxc_jpeg_get_sibling_format(const struct mxc_jpeg_fmt *fmt)
1307 {
1308 int i;
1309
1310 for (i = 0; i < MXC_JPEG_NUM_FORMATS; i++) {
1311 if (mxc_formats[i].subsampling == fmt->subsampling &&
1312 mxc_formats[i].nc == fmt->nc &&
1313 mxc_formats[i].precision == fmt->precision &&
1314 mxc_formats[i].is_rgb == fmt->is_rgb &&
1315 mxc_formats[i].fourcc != fmt->fourcc)
1316 return &mxc_formats[i];
1317 }
1318
1319 return NULL;
1320 }
1321
mxc_jpeg_compare_format(const struct mxc_jpeg_fmt * fmt1,const struct mxc_jpeg_fmt * fmt2)1322 static bool mxc_jpeg_compare_format(const struct mxc_jpeg_fmt *fmt1,
1323 const struct mxc_jpeg_fmt *fmt2)
1324 {
1325 if (fmt1 == fmt2)
1326 return true;
1327 if (mxc_jpeg_get_sibling_format(fmt1) == fmt2)
1328 return true;
1329 return false;
1330 }
1331
mxc_jpeg_set_last_buffer(struct mxc_jpeg_ctx * ctx)1332 static void mxc_jpeg_set_last_buffer(struct mxc_jpeg_ctx *ctx)
1333 {
1334 struct vb2_v4l2_buffer *next_dst_buf;
1335
1336 next_dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1337 if (!next_dst_buf) {
1338 ctx->fh.m2m_ctx->is_draining = true;
1339 ctx->fh.m2m_ctx->next_buf_last = true;
1340 return;
1341 }
1342
1343 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, next_dst_buf);
1344 }
1345
mxc_jpeg_source_change(struct mxc_jpeg_ctx * ctx,struct mxc_jpeg_src_buf * jpeg_src_buf)1346 static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
1347 struct mxc_jpeg_src_buf *jpeg_src_buf)
1348 {
1349 struct device *dev = ctx->mxc_jpeg->dev;
1350 struct mxc_jpeg_q_data *q_data_cap;
1351
1352 if (!jpeg_src_buf->fmt)
1353 return false;
1354
1355 q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1356 if (mxc_jpeg_compare_format(q_data_cap->fmt, jpeg_src_buf->fmt))
1357 jpeg_src_buf->fmt = q_data_cap->fmt;
1358 if (ctx->need_initial_source_change_evt ||
1359 q_data_cap->fmt != jpeg_src_buf->fmt ||
1360 q_data_cap->w != jpeg_src_buf->w ||
1361 q_data_cap->h != jpeg_src_buf->h) {
1362 dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n",
1363 q_data_cap->w, q_data_cap->h,
1364 jpeg_src_buf->w, jpeg_src_buf->h,
1365 (jpeg_src_buf->fmt->fourcc & 0xff),
1366 (jpeg_src_buf->fmt->fourcc >> 8) & 0xff,
1367 (jpeg_src_buf->fmt->fourcc >> 16) & 0xff,
1368 (jpeg_src_buf->fmt->fourcc >> 24) & 0xff);
1369
1370 /*
1371 * set-up the capture queue with the pixelformat and resolution
1372 * detected from the jpeg output stream
1373 */
1374 q_data_cap->w = jpeg_src_buf->w;
1375 q_data_cap->h = jpeg_src_buf->h;
1376 q_data_cap->fmt = jpeg_src_buf->fmt;
1377 q_data_cap->w_adjusted = q_data_cap->w;
1378 q_data_cap->h_adjusted = q_data_cap->h;
1379 q_data_cap->crop.left = 0;
1380 q_data_cap->crop.top = 0;
1381 q_data_cap->crop.width = jpeg_src_buf->w;
1382 q_data_cap->crop.height = jpeg_src_buf->h;
1383 q_data_cap->bytesperline[0] = 0;
1384 q_data_cap->bytesperline[1] = 0;
1385
1386 /*
1387 * align up the resolution for CAST IP,
1388 * but leave the buffer resolution unchanged
1389 */
1390 v4l_bound_align_image(&q_data_cap->w_adjusted,
1391 q_data_cap->w_adjusted, /* adjust up */
1392 MXC_JPEG_MAX_WIDTH,
1393 q_data_cap->fmt->h_align,
1394 &q_data_cap->h_adjusted,
1395 q_data_cap->h_adjusted, /* adjust up */
1396 MXC_JPEG_MAX_HEIGHT,
1397 q_data_cap->fmt->v_align,
1398 0);
1399
1400 /* setup bytesperline/sizeimage for capture queue */
1401 mxc_jpeg_bytesperline(q_data_cap, jpeg_src_buf->fmt->precision);
1402 mxc_jpeg_sizeimage(q_data_cap);
1403 notify_src_chg(ctx);
1404 ctx->source_change = 1;
1405 ctx->need_initial_source_change_evt = false;
1406 if (vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx)))
1407 mxc_jpeg_set_last_buffer(ctx);
1408 }
1409
1410 return ctx->source_change ? true : false;
1411 }
1412
mxc_jpeg_job_ready(void * priv)1413 static int mxc_jpeg_job_ready(void *priv)
1414 {
1415 struct mxc_jpeg_ctx *ctx = priv;
1416
1417 return ctx->source_change ? 0 : 1;
1418 }
1419
mxc_jpeg_device_run_timeout(struct work_struct * work)1420 static void mxc_jpeg_device_run_timeout(struct work_struct *work)
1421 {
1422 struct delayed_work *dwork = to_delayed_work(work);
1423 struct mxc_jpeg_ctx *ctx = container_of(dwork, struct mxc_jpeg_ctx, task_timer);
1424 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
1425 unsigned long flags;
1426
1427 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
1428 if (ctx->mxc_jpeg->slot_data.used) {
1429 dev_warn(jpeg->dev, "%s timeout, cancel it\n",
1430 ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? "decode" : "encode");
1431 mxc_jpeg_job_finish(ctx, VB2_BUF_STATE_ERROR, true);
1432 v4l2_m2m_job_finish(ctx->mxc_jpeg->m2m_dev, ctx->fh.m2m_ctx);
1433 }
1434 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
1435 }
1436
mxc_jpeg_device_run(void * priv)1437 static void mxc_jpeg_device_run(void *priv)
1438 {
1439 struct mxc_jpeg_ctx *ctx = priv;
1440 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
1441 void __iomem *reg = jpeg->base_reg;
1442 struct device *dev = jpeg->dev;
1443 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1444 unsigned long flags;
1445 struct mxc_jpeg_q_data *q_data_cap, *q_data_out;
1446 struct mxc_jpeg_src_buf *jpeg_src_buf;
1447
1448 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
1449 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1450 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1451 if (!src_buf || !dst_buf) {
1452 dev_err(dev, "Null src or dst buf\n");
1453 goto end;
1454 }
1455
1456 q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1457 if (!q_data_cap)
1458 goto end;
1459 q_data_out = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
1460 if (!q_data_out)
1461 goto end;
1462 src_buf->sequence = q_data_out->sequence++;
1463 dst_buf->sequence = q_data_cap->sequence++;
1464
1465 v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true);
1466
1467 jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf);
1468 if (q_data_cap->fmt->mem_planes != dst_buf->vb2_buf.num_planes) {
1469 dev_err(dev, "Capture format %s has %d planes, but capture buffer has %d planes\n",
1470 q_data_cap->fmt->name, q_data_cap->fmt->mem_planes,
1471 dst_buf->vb2_buf.num_planes);
1472 jpeg_src_buf->jpeg_parse_error = true;
1473 }
1474 if (jpeg_src_buf->jpeg_parse_error) {
1475 mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf);
1476 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1477 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1478 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
1479 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
1480 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
1481 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1482
1483 return;
1484 }
1485 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) {
1486 if (ctx->source_change || mxc_jpeg_source_change(ctx, jpeg_src_buf)) {
1487 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
1488 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
1489 return;
1490 }
1491 }
1492
1493 mxc_jpeg_enable(reg);
1494 mxc_jpeg_set_l_endian(reg, 1);
1495
1496 ctx->slot = mxc_get_free_slot(&jpeg->slot_data);
1497 if (ctx->slot < 0) {
1498 dev_err(dev, "No more free slots\n");
1499 goto end;
1500 }
1501 if (!mxc_jpeg_alloc_slot_data(jpeg)) {
1502 dev_err(dev, "Cannot allocate slot data\n");
1503 goto end;
1504 }
1505
1506 mxc_jpeg_enable_slot(reg, ctx->slot);
1507 mxc_jpeg_enable_irq(reg, ctx->slot);
1508
1509 if (jpeg->mode == MXC_JPEG_ENCODE) {
1510 dev_dbg(dev, "Encoding on slot %d\n", ctx->slot);
1511 ctx->enc_state = MXC_JPEG_ENC_CONF;
1512 mxc_jpeg_config_enc_desc(&dst_buf->vb2_buf, ctx,
1513 &src_buf->vb2_buf, &dst_buf->vb2_buf);
1514 /* start config phase */
1515 mxc_jpeg_enc_mode_conf(dev, reg,
1516 mxc_jpeg_is_extended_sequential(q_data_out->fmt));
1517 } else {
1518 dev_dbg(dev, "Decoding on slot %d\n", ctx->slot);
1519 print_mxc_buf(jpeg, &src_buf->vb2_buf, 0);
1520 mxc_jpeg_config_dec_desc(&dst_buf->vb2_buf, ctx,
1521 &src_buf->vb2_buf, &dst_buf->vb2_buf);
1522 mxc_jpeg_dec_mode_go(dev, reg);
1523 }
1524 schedule_delayed_work(&ctx->task_timer, msecs_to_jiffies(hw_timeout));
1525 end:
1526 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
1527 }
1528
mxc_jpeg_decoder_cmd(struct file * file,void * priv,struct v4l2_decoder_cmd * cmd)1529 static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
1530 struct v4l2_decoder_cmd *cmd)
1531 {
1532 struct v4l2_fh *fh = file->private_data;
1533 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
1534 unsigned long flags;
1535 int ret;
1536
1537 ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
1538 if (ret < 0)
1539 return ret;
1540
1541 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)))
1542 return 0;
1543
1544 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
1545 ret = v4l2_m2m_ioctl_decoder_cmd(file, priv, cmd);
1546 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
1547 if (ret < 0)
1548 return ret;
1549
1550 if (cmd->cmd == V4L2_DEC_CMD_STOP &&
1551 v4l2_m2m_has_stopped(fh->m2m_ctx)) {
1552 notify_eos(ctx);
1553 ctx->header_parsed = false;
1554 }
1555
1556 if (cmd->cmd == V4L2_DEC_CMD_START &&
1557 v4l2_m2m_has_stopped(fh->m2m_ctx))
1558 vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q);
1559 return 0;
1560 }
1561
mxc_jpeg_encoder_cmd(struct file * file,void * priv,struct v4l2_encoder_cmd * cmd)1562 static int mxc_jpeg_encoder_cmd(struct file *file, void *priv,
1563 struct v4l2_encoder_cmd *cmd)
1564 {
1565 struct v4l2_fh *fh = file->private_data;
1566 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
1567 unsigned long flags;
1568 int ret;
1569
1570 ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
1571 if (ret < 0)
1572 return ret;
1573
1574 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)) ||
1575 !vb2_is_streaming(v4l2_m2m_get_dst_vq(fh->m2m_ctx)))
1576 return 0;
1577
1578 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags);
1579 ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, cmd);
1580 spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
1581 if (ret < 0)
1582 return 0;
1583
1584 if (cmd->cmd == V4L2_ENC_CMD_STOP &&
1585 v4l2_m2m_has_stopped(fh->m2m_ctx))
1586 notify_eos(ctx);
1587
1588 if (cmd->cmd == V4L2_ENC_CMD_START &&
1589 v4l2_m2m_has_stopped(fh->m2m_ctx))
1590 vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q);
1591
1592 return 0;
1593 }
1594
mxc_jpeg_queue_setup(struct vb2_queue * q,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],struct device * alloc_ctxs[])1595 static int mxc_jpeg_queue_setup(struct vb2_queue *q,
1596 unsigned int *nbuffers,
1597 unsigned int *nplanes,
1598 unsigned int sizes[],
1599 struct device *alloc_ctxs[])
1600 {
1601 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1602 struct mxc_jpeg_q_data *q_data = NULL;
1603 int i;
1604
1605 q_data = mxc_jpeg_get_q_data(ctx, q->type);
1606 if (!q_data)
1607 return -EINVAL;
1608
1609 /* Handle CREATE_BUFS situation - *nplanes != 0 */
1610 if (*nplanes) {
1611 if (*nplanes != q_data->fmt->mem_planes)
1612 return -EINVAL;
1613 for (i = 0; i < *nplanes; i++) {
1614 if (sizes[i] < mxc_jpeg_get_plane_size(q_data, i))
1615 return -EINVAL;
1616 }
1617 return 0;
1618 }
1619
1620 /* Handle REQBUFS situation */
1621 *nplanes = q_data->fmt->mem_planes;
1622 for (i = 0; i < *nplanes; i++)
1623 sizes[i] = mxc_jpeg_get_plane_size(q_data, i);
1624
1625 if (V4L2_TYPE_IS_OUTPUT(q->type))
1626 ctx->need_initial_source_change_evt = true;
1627
1628 return 0;
1629 }
1630
mxc_jpeg_start_streaming(struct vb2_queue * q,unsigned int count)1631 static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1632 {
1633 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1634 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type);
1635 int ret;
1636
1637 v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q);
1638
1639 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q->type))
1640 ctx->source_change = 0;
1641 dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx);
1642 q_data->sequence = 0;
1643
1644 if (V4L2_TYPE_IS_CAPTURE(q->type))
1645 ctx->need_initial_source_change_evt = false;
1646
1647 ret = pm_runtime_resume_and_get(ctx->mxc_jpeg->dev);
1648 if (ret < 0) {
1649 dev_err(ctx->mxc_jpeg->dev, "Failed to power up jpeg\n");
1650 return ret;
1651 }
1652
1653 return 0;
1654 }
1655
mxc_jpeg_stop_streaming(struct vb2_queue * q)1656 static void mxc_jpeg_stop_streaming(struct vb2_queue *q)
1657 {
1658 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1659 struct vb2_v4l2_buffer *vbuf;
1660
1661 dev_dbg(ctx->mxc_jpeg->dev, "Stop streaming ctx=%p", ctx);
1662
1663 /* Release all active buffers */
1664 for (;;) {
1665 if (V4L2_TYPE_IS_OUTPUT(q->type))
1666 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1667 else
1668 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1669 if (!vbuf)
1670 break;
1671 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
1672 }
1673
1674 v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q);
1675 /* if V4L2_DEC_CMD_STOP is sent before the source change triggered,
1676 * restore the is_draining flag
1677 */
1678 if (V4L2_TYPE_IS_CAPTURE(q->type) && ctx->source_change && ctx->fh.m2m_ctx->last_src_buf)
1679 ctx->fh.m2m_ctx->is_draining = true;
1680
1681 if (V4L2_TYPE_IS_OUTPUT(q->type) &&
1682 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) {
1683 notify_eos(ctx);
1684 ctx->header_parsed = false;
1685 }
1686
1687 pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev);
1688 }
1689
mxc_jpeg_valid_comp_id(struct device * dev,struct mxc_jpeg_sof * sof,struct mxc_jpeg_sos * sos)1690 static int mxc_jpeg_valid_comp_id(struct device *dev,
1691 struct mxc_jpeg_sof *sof,
1692 struct mxc_jpeg_sos *sos)
1693 {
1694 int valid = 1;
1695 int i;
1696
1697 /*
1698 * there's a limitation in the IP that the component IDs must be
1699 * between 0..4, if they are not, let's patch them
1700 */
1701 for (i = 0; i < sof->components_no; i++)
1702 if (sof->comp[i].id > MXC_JPEG_MAX_COMPONENTS) {
1703 valid = 0;
1704 dev_err(dev, "Component %d has invalid ID: %d",
1705 i, sof->comp[i].id);
1706 }
1707 if (!valid)
1708 /* patch all comp IDs if at least one is invalid */
1709 for (i = 0; i < sof->components_no; i++) {
1710 dev_warn(dev, "Component %d ID patched to: %d",
1711 i, i + 1);
1712 sof->comp[i].id = i + 1;
1713 sos->comp[i].id = i + 1;
1714 }
1715
1716 return valid;
1717 }
1718
mxc_jpeg_match_image_format(const struct mxc_jpeg_fmt * fmt,const struct v4l2_jpeg_header * header)1719 static bool mxc_jpeg_match_image_format(const struct mxc_jpeg_fmt *fmt,
1720 const struct v4l2_jpeg_header *header)
1721 {
1722 if (fmt->subsampling != header->frame.subsampling ||
1723 fmt->nc != header->frame.num_components ||
1724 fmt->precision != header->frame.precision)
1725 return false;
1726
1727 /*
1728 * If the transform flag from APP14 marker is 0, images that are
1729 * encoded with 3 components have RGB colorspace, see Recommendation
1730 * ITU-T T.872 chapter 6.5.3 APP14 marker segment for colour encoding
1731 */
1732 if (header->frame.subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_444) {
1733 u8 is_rgb = header->app14_tf == V4L2_JPEG_APP14_TF_CMYK_RGB ? 1 : 0;
1734
1735 if (is_rgb != fmt->is_rgb)
1736 return false;
1737 }
1738 return true;
1739 }
1740
mxc_jpeg_get_image_format(struct device * dev,const struct v4l2_jpeg_header * header)1741 static u32 mxc_jpeg_get_image_format(struct device *dev,
1742 const struct v4l2_jpeg_header *header)
1743 {
1744 int i;
1745 u32 fourcc = 0;
1746
1747 for (i = 0; i < MXC_JPEG_NUM_FORMATS; i++) {
1748 if (mxc_jpeg_match_image_format(&mxc_formats[i], header)) {
1749 fourcc = mxc_formats[i].fourcc;
1750 break;
1751 }
1752 }
1753 if (fourcc == 0) {
1754 dev_err(dev,
1755 "Could not identify image format nc=%d, subsampling=%d, precision=%d\n",
1756 header->frame.num_components,
1757 header->frame.subsampling,
1758 header->frame.precision);
1759 return fourcc;
1760 }
1761
1762 return fourcc;
1763 }
1764
mxc_jpeg_bytesperline(struct mxc_jpeg_q_data * q,u32 precision)1765 static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision)
1766 {
1767 u32 bytesperline[2];
1768
1769 bytesperline[0] = q->bytesperline[0];
1770 bytesperline[1] = q->bytesperline[0]; /*imx-jpeg only support the same line pitch*/
1771 v4l_bound_align_image(&bytesperline[0], 0, MXC_JPEG_MAX_LINE, 2,
1772 &bytesperline[1], 0, MXC_JPEG_MAX_LINE, 2,
1773 0);
1774
1775 /* Bytes distance between the leftmost pixels in two adjacent lines */
1776 if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1777 /* bytesperline unused for compressed formats */
1778 q->bytesperline[0] = 0;
1779 q->bytesperline[1] = 0;
1780 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420) {
1781 /* When the image format is planar the bytesperline value
1782 * applies to the first plane and is divided by the same factor
1783 * as the width field for the other planes
1784 */
1785 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8);
1786 q->bytesperline[1] = q->bytesperline[0];
1787 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_422) {
1788 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8) * 2;
1789 q->bytesperline[1] = 0;
1790 } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_444) {
1791 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8) * q->fmt->nc;
1792 q->bytesperline[1] = 0;
1793 } else {
1794 /* grayscale */
1795 q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8);
1796 q->bytesperline[1] = 0;
1797 }
1798
1799 if (q->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1800 q->bytesperline[0] = max(q->bytesperline[0], bytesperline[0]);
1801 if (q->fmt->mem_planes > 1)
1802 q->bytesperline[1] = max(q->bytesperline[1], bytesperline[1]);
1803 }
1804 }
1805
mxc_jpeg_sizeimage(struct mxc_jpeg_q_data * q)1806 static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)
1807 {
1808 if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1809 /* if no sizeimage from user, assume worst jpeg compression */
1810 if (!q->sizeimage[0])
1811 q->sizeimage[0] = 6 * q->w * q->h;
1812 q->sizeimage[1] = 0;
1813
1814 if (q->sizeimage[0] > MXC_JPEG_MAX_SIZEIMAGE)
1815 q->sizeimage[0] = MXC_JPEG_MAX_SIZEIMAGE;
1816
1817 /* jpeg stream size must be multiple of 1K */
1818 q->sizeimage[0] = ALIGN(q->sizeimage[0], 1024);
1819 } else {
1820 q->sizeimage[0] = q->bytesperline[0] * q->h_adjusted;
1821 q->sizeimage[1] = 0;
1822 if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420)
1823 q->sizeimage[1] = q->sizeimage[0] / 2;
1824 }
1825 }
1826
mxc_jpeg_parse(struct mxc_jpeg_ctx * ctx,struct vb2_buffer * vb)1827 static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
1828 {
1829 struct device *dev = ctx->mxc_jpeg->dev;
1830 struct mxc_jpeg_q_data *q_data_out;
1831 struct mxc_jpeg_q_data *q_data_cap;
1832 u32 fourcc;
1833 struct v4l2_jpeg_header header;
1834 struct mxc_jpeg_sof *psof = NULL;
1835 struct mxc_jpeg_sos *psos = NULL;
1836 struct mxc_jpeg_src_buf *jpeg_src_buf = vb2_to_mxc_buf(vb);
1837 u8 *src_addr = (u8 *)vb2_plane_vaddr(vb, 0);
1838 u32 size = vb2_get_plane_payload(vb, 0);
1839 int ret;
1840
1841 memset(&header, 0, sizeof(header));
1842 ret = v4l2_jpeg_parse_header((void *)src_addr, size, &header);
1843 if (ret < 0) {
1844 dev_err(dev, "Error parsing JPEG stream markers\n");
1845 return ret;
1846 }
1847
1848 /* if DHT marker present, no need to inject default one */
1849 jpeg_src_buf->dht_needed = (header.num_dht == 0);
1850
1851 q_data_out = mxc_jpeg_get_q_data(ctx,
1852 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
1853 q_data_out->w = header.frame.width;
1854 q_data_out->h = header.frame.height;
1855 if (header.frame.width > MXC_JPEG_MAX_WIDTH ||
1856 header.frame.height > MXC_JPEG_MAX_HEIGHT) {
1857 dev_err(dev, "JPEG width or height should be <= 8192: %dx%d\n",
1858 header.frame.width, header.frame.height);
1859 return -EINVAL;
1860 }
1861 if (header.frame.width < MXC_JPEG_MIN_WIDTH ||
1862 header.frame.height < MXC_JPEG_MIN_HEIGHT) {
1863 dev_err(dev, "JPEG width or height should be > 64: %dx%d\n",
1864 header.frame.width, header.frame.height);
1865 return -EINVAL;
1866 }
1867 if (header.frame.num_components > V4L2_JPEG_MAX_COMPONENTS) {
1868 dev_err(dev, "JPEG number of components should be <=%d",
1869 V4L2_JPEG_MAX_COMPONENTS);
1870 return -EINVAL;
1871 }
1872 /* check and, if necessary, patch component IDs*/
1873 psof = (struct mxc_jpeg_sof *)header.sof.start;
1874 psos = (struct mxc_jpeg_sos *)header.sos.start;
1875 if (!mxc_jpeg_valid_comp_id(dev, psof, psos))
1876 dev_warn(dev, "JPEG component ids should be 0-3 or 1-4");
1877
1878 q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
1879 if (q_data_cap->fmt && mxc_jpeg_match_image_format(q_data_cap->fmt, &header))
1880 fourcc = q_data_cap->fmt->fourcc;
1881 else
1882 fourcc = mxc_jpeg_get_image_format(dev, &header);
1883 if (fourcc == 0)
1884 return -EINVAL;
1885
1886 jpeg_src_buf->fmt = mxc_jpeg_find_format(fourcc);
1887 jpeg_src_buf->w = header.frame.width;
1888 jpeg_src_buf->h = header.frame.height;
1889 ctx->header_parsed = true;
1890
1891 if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx))
1892 mxc_jpeg_source_change(ctx, jpeg_src_buf);
1893
1894 return 0;
1895 }
1896
mxc_jpeg_buf_queue(struct vb2_buffer * vb)1897 static void mxc_jpeg_buf_queue(struct vb2_buffer *vb)
1898 {
1899 int ret;
1900 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1901 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1902 struct mxc_jpeg_src_buf *jpeg_src_buf;
1903
1904 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
1905 vb2_is_streaming(vb->vb2_queue) &&
1906 v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) {
1907 struct mxc_jpeg_q_data *q_data;
1908
1909 q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type);
1910 vbuf->field = V4L2_FIELD_NONE;
1911 vbuf->sequence = q_data->sequence++;
1912 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf);
1913 notify_eos(ctx);
1914 ctx->header_parsed = false;
1915 return;
1916 }
1917
1918 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1919 goto end;
1920
1921 /* for V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE */
1922 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE)
1923 goto end;
1924
1925 jpeg_src_buf = vb2_to_mxc_buf(vb);
1926 jpeg_src_buf->jpeg_parse_error = false;
1927 ret = mxc_jpeg_parse(ctx, vb);
1928 if (ret) {
1929 jpeg_src_buf->jpeg_parse_error = true;
1930
1931 /*
1932 * if the capture queue is not setup, the device_run() won't be scheduled,
1933 * need to drop the error buffer, so that the decoding can continue
1934 */
1935 if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) {
1936 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
1937 return;
1938 }
1939 }
1940
1941 end:
1942 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1943 }
1944
mxc_jpeg_buf_out_validate(struct vb2_buffer * vb)1945 static int mxc_jpeg_buf_out_validate(struct vb2_buffer *vb)
1946 {
1947 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1948
1949 vbuf->field = V4L2_FIELD_NONE;
1950
1951 return 0;
1952 }
1953
mxc_jpeg_buf_prepare(struct vb2_buffer * vb)1954 static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb)
1955 {
1956 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1957 struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1958 struct mxc_jpeg_q_data *q_data = NULL;
1959 struct device *dev = ctx->mxc_jpeg->dev;
1960 unsigned long sizeimage;
1961 int i;
1962
1963 vbuf->field = V4L2_FIELD_NONE;
1964
1965 q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type);
1966 if (!q_data)
1967 return -EINVAL;
1968 for (i = 0; i < q_data->fmt->mem_planes; i++) {
1969 sizeimage = mxc_jpeg_get_plane_size(q_data, i);
1970 if (!ctx->source_change && vb2_plane_size(vb, i) < sizeimage) {
1971 dev_err(dev, "plane %d too small (%lu < %lu)",
1972 i, vb2_plane_size(vb, i), sizeimage);
1973 return -EINVAL;
1974 }
1975 }
1976 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) {
1977 vb2_set_plane_payload(vb, 0, 0);
1978 vb2_set_plane_payload(vb, 1, 0);
1979 }
1980 return 0;
1981 }
1982
1983 static const struct vb2_ops mxc_jpeg_qops = {
1984 .queue_setup = mxc_jpeg_queue_setup,
1985 .wait_prepare = vb2_ops_wait_prepare,
1986 .wait_finish = vb2_ops_wait_finish,
1987 .buf_out_validate = mxc_jpeg_buf_out_validate,
1988 .buf_prepare = mxc_jpeg_buf_prepare,
1989 .start_streaming = mxc_jpeg_start_streaming,
1990 .stop_streaming = mxc_jpeg_stop_streaming,
1991 .buf_queue = mxc_jpeg_buf_queue,
1992 };
1993
mxc_jpeg_queue_init(void * priv,struct vb2_queue * src_vq,struct vb2_queue * dst_vq)1994 static int mxc_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
1995 struct vb2_queue *dst_vq)
1996 {
1997 struct mxc_jpeg_ctx *ctx = priv;
1998 int ret;
1999
2000 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2001 src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
2002 src_vq->drv_priv = ctx;
2003 src_vq->buf_struct_size = sizeof(struct mxc_jpeg_src_buf);
2004 src_vq->ops = &mxc_jpeg_qops;
2005 src_vq->mem_ops = &vb2_dma_contig_memops;
2006 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2007 src_vq->lock = &ctx->mxc_jpeg->lock;
2008 src_vq->dev = ctx->mxc_jpeg->dev;
2009
2010 ret = vb2_queue_init(src_vq);
2011 if (ret)
2012 return ret;
2013
2014 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2015 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
2016 dst_vq->drv_priv = ctx;
2017 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2018 dst_vq->ops = &mxc_jpeg_qops;
2019 dst_vq->mem_ops = &vb2_dma_contig_memops;
2020 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2021 dst_vq->lock = &ctx->mxc_jpeg->lock;
2022 dst_vq->dev = ctx->mxc_jpeg->dev;
2023
2024 ret = vb2_queue_init(dst_vq);
2025 return ret;
2026 }
2027
mxc_jpeg_set_default_params(struct mxc_jpeg_ctx * ctx)2028 static void mxc_jpeg_set_default_params(struct mxc_jpeg_ctx *ctx)
2029 {
2030 struct mxc_jpeg_q_data *out_q = &ctx->out_q;
2031 struct mxc_jpeg_q_data *cap_q = &ctx->cap_q;
2032 struct mxc_jpeg_q_data *q[2] = {out_q, cap_q};
2033 int i;
2034
2035 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) {
2036 out_q->fmt = mxc_jpeg_find_format(MXC_JPEG_DEFAULT_PFMT);
2037 cap_q->fmt = mxc_jpeg_find_format(V4L2_PIX_FMT_JPEG);
2038 } else {
2039 out_q->fmt = mxc_jpeg_find_format(V4L2_PIX_FMT_JPEG);
2040 cap_q->fmt = mxc_jpeg_find_format(MXC_JPEG_DEFAULT_PFMT);
2041 }
2042
2043 for (i = 0; i < 2; i++) {
2044 q[i]->w = MXC_JPEG_DEFAULT_WIDTH;
2045 q[i]->h = MXC_JPEG_DEFAULT_HEIGHT;
2046 q[i]->w_adjusted = MXC_JPEG_DEFAULT_WIDTH;
2047 q[i]->h_adjusted = MXC_JPEG_DEFAULT_HEIGHT;
2048 q[i]->crop.left = 0;
2049 q[i]->crop.top = 0;
2050 q[i]->crop.width = MXC_JPEG_DEFAULT_WIDTH;
2051 q[i]->crop.height = MXC_JPEG_DEFAULT_HEIGHT;
2052 mxc_jpeg_bytesperline(q[i], q[i]->fmt->precision);
2053 mxc_jpeg_sizeimage(q[i]);
2054 }
2055 }
2056
mxc_jpeg_s_ctrl(struct v4l2_ctrl * ctrl)2057 static int mxc_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
2058 {
2059 struct mxc_jpeg_ctx *ctx =
2060 container_of(ctrl->handler, struct mxc_jpeg_ctx, ctrl_handler);
2061
2062 switch (ctrl->id) {
2063 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
2064 ctx->jpeg_quality = ctrl->val;
2065 break;
2066 default:
2067 dev_err(ctx->mxc_jpeg->dev, "Invalid control, id = %d, val = %d\n",
2068 ctrl->id, ctrl->val);
2069 return -EINVAL;
2070 }
2071
2072 return 0;
2073 }
2074
2075 static const struct v4l2_ctrl_ops mxc_jpeg_ctrl_ops = {
2076 .s_ctrl = mxc_jpeg_s_ctrl,
2077 };
2078
mxc_jpeg_encode_ctrls(struct mxc_jpeg_ctx * ctx)2079 static void mxc_jpeg_encode_ctrls(struct mxc_jpeg_ctx *ctx)
2080 {
2081 v4l2_ctrl_new_std(&ctx->ctrl_handler, &mxc_jpeg_ctrl_ops,
2082 V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 75);
2083 }
2084
mxc_jpeg_ctrls_setup(struct mxc_jpeg_ctx * ctx)2085 static int mxc_jpeg_ctrls_setup(struct mxc_jpeg_ctx *ctx)
2086 {
2087 int err;
2088
2089 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 2);
2090
2091 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE)
2092 mxc_jpeg_encode_ctrls(ctx);
2093
2094 if (ctx->ctrl_handler.error) {
2095 err = ctx->ctrl_handler.error;
2096
2097 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
2098 return err;
2099 }
2100
2101 err = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
2102 if (err)
2103 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
2104 return err;
2105 }
2106
mxc_jpeg_open(struct file * file)2107 static int mxc_jpeg_open(struct file *file)
2108 {
2109 struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file);
2110 struct video_device *mxc_vfd = video_devdata(file);
2111 struct device *dev = mxc_jpeg->dev;
2112 struct mxc_jpeg_ctx *ctx;
2113 int ret = 0;
2114
2115 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2116 if (!ctx)
2117 return -ENOMEM;
2118
2119 if (mutex_lock_interruptible(&mxc_jpeg->lock)) {
2120 ret = -ERESTARTSYS;
2121 goto free;
2122 }
2123
2124 v4l2_fh_init(&ctx->fh, mxc_vfd);
2125 file->private_data = &ctx->fh;
2126 v4l2_fh_add(&ctx->fh);
2127
2128 ctx->mxc_jpeg = mxc_jpeg;
2129
2130 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(mxc_jpeg->m2m_dev, ctx,
2131 mxc_jpeg_queue_init);
2132
2133 if (IS_ERR(ctx->fh.m2m_ctx)) {
2134 ret = PTR_ERR(ctx->fh.m2m_ctx);
2135 goto error;
2136 }
2137
2138 ret = mxc_jpeg_ctrls_setup(ctx);
2139 if (ret) {
2140 dev_err(ctx->mxc_jpeg->dev, "failed to setup mxc jpeg controls\n");
2141 goto err_ctrls_setup;
2142 }
2143 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
2144 mxc_jpeg_set_default_params(ctx);
2145 ctx->slot = -1; /* slot not allocated yet */
2146 INIT_DELAYED_WORK(&ctx->task_timer, mxc_jpeg_device_run_timeout);
2147
2148 if (mxc_jpeg->mode == MXC_JPEG_DECODE)
2149 dev_dbg(dev, "Opened JPEG decoder instance %p\n", ctx);
2150 else
2151 dev_dbg(dev, "Opened JPEG encoder instance %p\n", ctx);
2152 mutex_unlock(&mxc_jpeg->lock);
2153
2154 return 0;
2155
2156 err_ctrls_setup:
2157 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
2158 error:
2159 v4l2_fh_del(&ctx->fh);
2160 v4l2_fh_exit(&ctx->fh);
2161 mutex_unlock(&mxc_jpeg->lock);
2162 free:
2163 kfree(ctx);
2164 return ret;
2165 }
2166
mxc_jpeg_querycap(struct file * file,void * priv,struct v4l2_capability * cap)2167 static int mxc_jpeg_querycap(struct file *file, void *priv,
2168 struct v4l2_capability *cap)
2169 {
2170 strscpy(cap->driver, MXC_JPEG_NAME " codec", sizeof(cap->driver));
2171 strscpy(cap->card, MXC_JPEG_NAME " codec", sizeof(cap->card));
2172 cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
2173 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
2174
2175 return 0;
2176 }
2177
mxc_jpeg_enum_fmt_vid_cap(struct file * file,void * priv,struct v4l2_fmtdesc * f)2178 static int mxc_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
2179 struct v4l2_fmtdesc *f)
2180 {
2181 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
2182 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type);
2183
2184 if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) {
2185 return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
2186 MXC_JPEG_FMT_TYPE_ENC);
2187 } else if (!ctx->header_parsed) {
2188 return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
2189 MXC_JPEG_FMT_TYPE_RAW);
2190 } else {
2191 /* For the decoder CAPTURE queue, only enumerate the raw formats
2192 * supported for the format currently active on OUTPUT
2193 * (more precisely what was propagated on capture queue
2194 * after jpeg parse on the output buffer)
2195 */
2196 int ret = -EINVAL;
2197 const struct mxc_jpeg_fmt *sibling;
2198
2199 switch (f->index) {
2200 case 0:
2201 f->pixelformat = q_data->fmt->fourcc;
2202 ret = 0;
2203 break;
2204 case 1:
2205 sibling = mxc_jpeg_get_sibling_format(q_data->fmt);
2206 if (sibling) {
2207 f->pixelformat = sibling->fourcc;
2208 ret = 0;
2209 }
2210 break;
2211 default:
2212 break;
2213 }
2214 return ret;
2215 }
2216 }
2217
mxc_jpeg_enum_fmt_vid_out(struct file * file,void * priv,struct v4l2_fmtdesc * f)2218 static int mxc_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
2219 struct v4l2_fmtdesc *f)
2220 {
2221 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
2222 u32 type = ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? MXC_JPEG_FMT_TYPE_ENC :
2223 MXC_JPEG_FMT_TYPE_RAW;
2224 int ret;
2225
2226 ret = enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f, type);
2227 if (ret)
2228 return ret;
2229 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE)
2230 f->flags = V4L2_FMT_FLAG_DYN_RESOLUTION;
2231 return 0;
2232 }
2233
mxc_jpeg_get_fmt_type(struct mxc_jpeg_ctx * ctx,u32 type)2234 static u32 mxc_jpeg_get_fmt_type(struct mxc_jpeg_ctx *ctx, u32 type)
2235 {
2236 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE)
2237 return V4L2_TYPE_IS_OUTPUT(type) ? MXC_JPEG_FMT_TYPE_ENC : MXC_JPEG_FMT_TYPE_RAW;
2238 else
2239 return V4L2_TYPE_IS_CAPTURE(type) ? MXC_JPEG_FMT_TYPE_ENC : MXC_JPEG_FMT_TYPE_RAW;
2240 }
2241
mxc_jpeg_get_default_fourcc(struct mxc_jpeg_ctx * ctx,u32 type)2242 static u32 mxc_jpeg_get_default_fourcc(struct mxc_jpeg_ctx *ctx, u32 type)
2243 {
2244 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE)
2245 return V4L2_TYPE_IS_OUTPUT(type) ? V4L2_PIX_FMT_JPEG : MXC_JPEG_DEFAULT_PFMT;
2246 else
2247 return V4L2_TYPE_IS_CAPTURE(type) ? V4L2_PIX_FMT_JPEG : MXC_JPEG_DEFAULT_PFMT;
2248 }
2249
mxc_jpeg_try_fourcc(struct mxc_jpeg_ctx * ctx,u32 fourcc)2250 static u32 mxc_jpeg_try_fourcc(struct mxc_jpeg_ctx *ctx, u32 fourcc)
2251 {
2252 const struct mxc_jpeg_fmt *sibling;
2253 struct mxc_jpeg_q_data *q_data_cap;
2254
2255 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE)
2256 return fourcc;
2257 if (!ctx->header_parsed)
2258 return fourcc;
2259
2260 q_data_cap = &ctx->cap_q;
2261 if (q_data_cap->fmt->fourcc == fourcc)
2262 return fourcc;
2263
2264 sibling = mxc_jpeg_get_sibling_format(q_data_cap->fmt);
2265 if (sibling && sibling->fourcc == fourcc)
2266 return sibling->fourcc;
2267
2268 return q_data_cap->fmt->fourcc;
2269 }
2270
mxc_jpeg_try_fmt(struct v4l2_format * f,struct mxc_jpeg_ctx * ctx,struct mxc_jpeg_q_data * q_data)2271 static int mxc_jpeg_try_fmt(struct v4l2_format *f,
2272 struct mxc_jpeg_ctx *ctx, struct mxc_jpeg_q_data *q_data)
2273 {
2274 const struct mxc_jpeg_fmt *fmt;
2275 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
2276 struct v4l2_plane_pix_format *pfmt;
2277 u32 fourcc = f->fmt.pix_mp.pixelformat;
2278 u32 w = (pix_mp->width < MXC_JPEG_MAX_WIDTH) ?
2279 pix_mp->width : MXC_JPEG_MAX_WIDTH;
2280 u32 h = (pix_mp->height < MXC_JPEG_MAX_HEIGHT) ?
2281 pix_mp->height : MXC_JPEG_MAX_HEIGHT;
2282 int i;
2283
2284 fmt = mxc_jpeg_find_format(fourcc);
2285 if (!fmt || fmt->flags != mxc_jpeg_get_fmt_type(ctx, f->type)) {
2286 dev_warn(ctx->mxc_jpeg->dev, "Format not supported: %c%c%c%c, use the default.\n",
2287 (fourcc & 0xff),
2288 (fourcc >> 8) & 0xff,
2289 (fourcc >> 16) & 0xff,
2290 (fourcc >> 24) & 0xff);
2291 fourcc = mxc_jpeg_get_default_fourcc(ctx, f->type);
2292 fmt = mxc_jpeg_find_format(fourcc);
2293 if (!fmt)
2294 return -EINVAL;
2295 f->fmt.pix_mp.pixelformat = fourcc;
2296 }
2297 q_data->fmt = fmt;
2298
2299 memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
2300 pix_mp->field = V4L2_FIELD_NONE;
2301 pix_mp->num_planes = fmt->mem_planes;
2302 pix_mp->pixelformat = fmt->fourcc;
2303
2304 q_data->w = w;
2305 q_data->h = h;
2306 q_data->w_adjusted = w;
2307 q_data->h_adjusted = h;
2308 v4l_bound_align_image(&q_data->w_adjusted,
2309 w, /* adjust upwards*/
2310 MXC_JPEG_MAX_WIDTH,
2311 fmt->h_align,
2312 &q_data->h_adjusted,
2313 h, /* adjust upwards*/
2314 MXC_JPEG_MAX_HEIGHT,
2315 fmt->v_align,
2316 0);
2317 for (i = 0; i < pix_mp->num_planes; i++) {
2318 pfmt = &pix_mp->plane_fmt[i];
2319 q_data->bytesperline[i] = pfmt->bytesperline;
2320 q_data->sizeimage[i] = pfmt->sizeimage;
2321 }
2322
2323 /* calculate bytesperline & sizeimage */
2324 mxc_jpeg_bytesperline(q_data, fmt->precision);
2325 mxc_jpeg_sizeimage(q_data);
2326
2327 /* adjust user format according to our calculations */
2328 for (i = 0; i < pix_mp->num_planes; i++) {
2329 pfmt = &pix_mp->plane_fmt[i];
2330 memset(pfmt->reserved, 0, sizeof(pfmt->reserved));
2331 pfmt->bytesperline = q_data->bytesperline[i];
2332 pfmt->sizeimage = mxc_jpeg_get_plane_size(q_data, i);
2333 }
2334
2335 /* fix colorspace information to sRGB for both output & capture */
2336 pix_mp->colorspace = V4L2_COLORSPACE_SRGB;
2337 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_601;
2338 pix_mp->xfer_func = V4L2_XFER_FUNC_SRGB;
2339 /*
2340 * this hardware does not change the range of the samples
2341 * but since inside JPEG the YUV quantization is full-range,
2342 * this driver will always use full-range for the raw frames, too
2343 */
2344 pix_mp->quantization = V4L2_QUANTIZATION_FULL_RANGE;
2345
2346 if (fmt->flags == MXC_JPEG_FMT_TYPE_RAW) {
2347 q_data->crop.left = 0;
2348 q_data->crop.top = 0;
2349 q_data->crop.width = q_data->w;
2350 q_data->crop.height = q_data->h;
2351 }
2352
2353 pix_mp->width = q_data->w_adjusted;
2354 pix_mp->height = q_data->h_adjusted;
2355
2356 return 0;
2357 }
2358
mxc_jpeg_try_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * f)2359 static int mxc_jpeg_try_fmt_vid_cap(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 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(f->type))
2373 f->fmt.pix_mp.pixelformat = mxc_jpeg_try_fourcc(ctx, f->fmt.pix_mp.pixelformat);
2374
2375 return mxc_jpeg_try_fmt(f, ctx, &tmp_q);
2376 }
2377
mxc_jpeg_try_fmt_vid_out(struct file * file,void * priv,struct v4l2_format * f)2378 static int mxc_jpeg_try_fmt_vid_out(struct file *file, void *priv,
2379 struct v4l2_format *f)
2380 {
2381 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
2382 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
2383 struct device *dev = jpeg->dev;
2384 struct mxc_jpeg_q_data tmp_q;
2385
2386 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
2387 dev_err(dev, "TRY_FMT with Invalid type: %d\n", f->type);
2388 return -EINVAL;
2389 }
2390
2391 return mxc_jpeg_try_fmt(f, ctx, &tmp_q);
2392 }
2393
mxc_jpeg_s_parsed_fmt(struct mxc_jpeg_ctx * ctx,struct v4l2_format * f)2394 static void mxc_jpeg_s_parsed_fmt(struct mxc_jpeg_ctx *ctx, struct v4l2_format *f)
2395 {
2396 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
2397 struct mxc_jpeg_q_data *q_data_cap;
2398
2399 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE || !V4L2_TYPE_IS_CAPTURE(f->type))
2400 return;
2401 if (!ctx->header_parsed)
2402 return;
2403
2404 q_data_cap = mxc_jpeg_get_q_data(ctx, f->type);
2405 pix_mp->pixelformat = mxc_jpeg_try_fourcc(ctx, pix_mp->pixelformat);
2406 pix_mp->width = q_data_cap->w;
2407 pix_mp->height = q_data_cap->h;
2408 }
2409
mxc_jpeg_s_fmt(struct mxc_jpeg_ctx * ctx,struct v4l2_format * f)2410 static int mxc_jpeg_s_fmt(struct mxc_jpeg_ctx *ctx,
2411 struct v4l2_format *f)
2412 {
2413 struct vb2_queue *vq;
2414 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
2415
2416 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
2417 if (!vq)
2418 return -EINVAL;
2419
2420 if (vb2_is_busy(vq)) {
2421 v4l2_err(&jpeg->v4l2_dev, "queue busy\n");
2422 return -EBUSY;
2423 }
2424
2425 mxc_jpeg_s_parsed_fmt(ctx, f);
2426
2427 return mxc_jpeg_try_fmt(f, ctx, mxc_jpeg_get_q_data(ctx, f->type));
2428 }
2429
mxc_jpeg_s_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * f)2430 static int mxc_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
2431 struct v4l2_format *f)
2432 {
2433 return mxc_jpeg_s_fmt(mxc_jpeg_fh_to_ctx(priv), f);
2434 }
2435
mxc_jpeg_s_fmt_vid_out(struct file * file,void * priv,struct v4l2_format * f)2436 static int mxc_jpeg_s_fmt_vid_out(struct file *file, void *priv,
2437 struct v4l2_format *f)
2438 {
2439 int ret;
2440 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
2441 struct vb2_queue *dst_vq;
2442 struct mxc_jpeg_q_data *q_data_cap;
2443 enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2444 struct v4l2_format fc;
2445
2446 ret = mxc_jpeg_s_fmt(mxc_jpeg_fh_to_ctx(priv), f);
2447 if (ret)
2448 return ret;
2449
2450 if (ctx->mxc_jpeg->mode != MXC_JPEG_DECODE)
2451 return 0;
2452
2453 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, cap_type);
2454 if (!dst_vq)
2455 return -EINVAL;
2456
2457 if (vb2_is_busy(dst_vq))
2458 return 0;
2459
2460 q_data_cap = mxc_jpeg_get_q_data(ctx, cap_type);
2461 if (q_data_cap->w == f->fmt.pix_mp.width && q_data_cap->h == f->fmt.pix_mp.height)
2462 return 0;
2463 memset(&fc, 0, sizeof(fc));
2464 fc.type = cap_type;
2465 fc.fmt.pix_mp.pixelformat = q_data_cap->fmt->fourcc;
2466 fc.fmt.pix_mp.width = f->fmt.pix_mp.width;
2467 fc.fmt.pix_mp.height = f->fmt.pix_mp.height;
2468
2469 return mxc_jpeg_s_fmt_vid_cap(file, priv, &fc);
2470 }
2471
mxc_jpeg_g_fmt_vid(struct file * file,void * priv,struct v4l2_format * f)2472 static int mxc_jpeg_g_fmt_vid(struct file *file, void *priv,
2473 struct v4l2_format *f)
2474 {
2475 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
2476 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
2477 struct device *dev = jpeg->dev;
2478 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
2479 struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type);
2480 int i;
2481
2482 if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
2483 dev_err(dev, "G_FMT with Invalid type: %d\n", f->type);
2484 return -EINVAL;
2485 }
2486
2487 pix_mp->pixelformat = q_data->fmt->fourcc;
2488 pix_mp->width = q_data->w;
2489 pix_mp->height = q_data->h;
2490 pix_mp->field = V4L2_FIELD_NONE;
2491 if (q_data->fmt->flags == MXC_JPEG_FMT_TYPE_RAW) {
2492 pix_mp->width = q_data->w_adjusted;
2493 pix_mp->height = q_data->h_adjusted;
2494 }
2495
2496 /* fix colorspace information to sRGB for both output & capture */
2497 pix_mp->colorspace = V4L2_COLORSPACE_SRGB;
2498 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_601;
2499 pix_mp->xfer_func = V4L2_XFER_FUNC_SRGB;
2500 pix_mp->quantization = V4L2_QUANTIZATION_FULL_RANGE;
2501
2502 pix_mp->num_planes = q_data->fmt->mem_planes;
2503 for (i = 0; i < pix_mp->num_planes; i++) {
2504 pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i];
2505 pix_mp->plane_fmt[i].sizeimage = mxc_jpeg_get_plane_size(q_data, i);
2506 }
2507
2508 return 0;
2509 }
2510
mxc_jpeg_dec_g_selection(struct file * file,void * fh,struct v4l2_selection * s)2511 static int mxc_jpeg_dec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
2512 {
2513 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
2514 struct mxc_jpeg_q_data *q_data_cap;
2515
2516 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
2517 return -EINVAL;
2518
2519 q_data_cap = mxc_jpeg_get_q_data(ctx, s->type);
2520
2521 switch (s->target) {
2522 case V4L2_SEL_TGT_COMPOSE:
2523 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
2524 s->r = q_data_cap->crop;
2525 break;
2526 case V4L2_SEL_TGT_COMPOSE_PADDED:
2527 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
2528 s->r.left = 0;
2529 s->r.top = 0;
2530 s->r.width = q_data_cap->w_adjusted;
2531 s->r.height = q_data_cap->h_adjusted;
2532 break;
2533 default:
2534 return -EINVAL;
2535 }
2536
2537 return 0;
2538 }
2539
mxc_jpeg_enc_g_selection(struct file * file,void * fh,struct v4l2_selection * s)2540 static int mxc_jpeg_enc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
2541 {
2542 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
2543 struct mxc_jpeg_q_data *q_data_out;
2544
2545 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2546 return -EINVAL;
2547
2548 q_data_out = mxc_jpeg_get_q_data(ctx, s->type);
2549
2550 switch (s->target) {
2551 case V4L2_SEL_TGT_CROP_DEFAULT:
2552 case V4L2_SEL_TGT_CROP_BOUNDS:
2553 s->r.left = 0;
2554 s->r.top = 0;
2555 s->r.width = q_data_out->w;
2556 s->r.height = q_data_out->h;
2557 break;
2558 case V4L2_SEL_TGT_CROP:
2559 s->r = q_data_out->crop;
2560 break;
2561 default:
2562 return -EINVAL;
2563 }
2564
2565 return 0;
2566 }
2567
mxc_jpeg_g_selection(struct file * file,void * fh,struct v4l2_selection * s)2568 static int mxc_jpeg_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
2569 {
2570 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
2571
2572 if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE)
2573 return mxc_jpeg_dec_g_selection(file, fh, s);
2574 else
2575 return mxc_jpeg_enc_g_selection(file, fh, s);
2576 }
2577
mxc_jpeg_s_selection(struct file * file,void * fh,struct v4l2_selection * s)2578 static int mxc_jpeg_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
2579 {
2580 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
2581 struct mxc_jpeg_q_data *q_data_out;
2582
2583 if (ctx->mxc_jpeg->mode != MXC_JPEG_ENCODE)
2584 return -ENOTTY;
2585
2586 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
2587 return -EINVAL;
2588 if (s->target != V4L2_SEL_TGT_CROP)
2589 return -EINVAL;
2590
2591 q_data_out = mxc_jpeg_get_q_data(ctx, s->type);
2592 if (s->r.left || s->r.top)
2593 return -EINVAL;
2594 if (s->r.width > q_data_out->w || s->r.height > q_data_out->h)
2595 return -EINVAL;
2596
2597 q_data_out->crop.left = 0;
2598 q_data_out->crop.top = 0;
2599 q_data_out->crop.width = s->r.width;
2600 q_data_out->crop.height = s->r.height;
2601
2602 return 0;
2603 }
2604
mxc_jpeg_subscribe_event(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)2605 static int mxc_jpeg_subscribe_event(struct v4l2_fh *fh,
2606 const struct v4l2_event_subscription *sub)
2607 {
2608 switch (sub->type) {
2609 case V4L2_EVENT_EOS:
2610 return v4l2_event_subscribe(fh, sub, 0, NULL);
2611 case V4L2_EVENT_SOURCE_CHANGE:
2612 return v4l2_src_change_event_subscribe(fh, sub);
2613 case V4L2_EVENT_CTRL:
2614 return v4l2_ctrl_subscribe_event(fh, sub);
2615 default:
2616 return -EINVAL;
2617 }
2618 }
2619
2620 static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = {
2621 .vidioc_querycap = mxc_jpeg_querycap,
2622 .vidioc_enum_fmt_vid_cap = mxc_jpeg_enum_fmt_vid_cap,
2623 .vidioc_enum_fmt_vid_out = mxc_jpeg_enum_fmt_vid_out,
2624
2625 .vidioc_try_fmt_vid_cap_mplane = mxc_jpeg_try_fmt_vid_cap,
2626 .vidioc_try_fmt_vid_out_mplane = mxc_jpeg_try_fmt_vid_out,
2627
2628 .vidioc_s_fmt_vid_cap_mplane = mxc_jpeg_s_fmt_vid_cap,
2629 .vidioc_s_fmt_vid_out_mplane = mxc_jpeg_s_fmt_vid_out,
2630
2631 .vidioc_g_fmt_vid_cap_mplane = mxc_jpeg_g_fmt_vid,
2632 .vidioc_g_fmt_vid_out_mplane = mxc_jpeg_g_fmt_vid,
2633
2634 .vidioc_g_selection = mxc_jpeg_g_selection,
2635 .vidioc_s_selection = mxc_jpeg_s_selection,
2636
2637 .vidioc_subscribe_event = mxc_jpeg_subscribe_event,
2638 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
2639
2640 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd,
2641 .vidioc_decoder_cmd = mxc_jpeg_decoder_cmd,
2642 .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd,
2643 .vidioc_encoder_cmd = mxc_jpeg_encoder_cmd,
2644
2645 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
2646 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
2647
2648 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
2649 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
2650 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
2651 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
2652 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
2653 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
2654 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
2655 };
2656
mxc_jpeg_release(struct file * file)2657 static int mxc_jpeg_release(struct file *file)
2658 {
2659 struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file);
2660 struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(file->private_data);
2661 struct device *dev = mxc_jpeg->dev;
2662
2663 mutex_lock(&mxc_jpeg->lock);
2664 if (mxc_jpeg->mode == MXC_JPEG_DECODE)
2665 dev_dbg(dev, "Release JPEG decoder instance on slot %d.",
2666 ctx->slot);
2667 else
2668 dev_dbg(dev, "Release JPEG encoder instance on slot %d.",
2669 ctx->slot);
2670 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
2671 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
2672 v4l2_fh_del(&ctx->fh);
2673 v4l2_fh_exit(&ctx->fh);
2674 kfree(ctx);
2675 mutex_unlock(&mxc_jpeg->lock);
2676
2677 return 0;
2678 }
2679
2680 static const struct v4l2_file_operations mxc_jpeg_fops = {
2681 .owner = THIS_MODULE,
2682 .open = mxc_jpeg_open,
2683 .release = mxc_jpeg_release,
2684 .poll = v4l2_m2m_fop_poll,
2685 .unlocked_ioctl = video_ioctl2,
2686 .mmap = v4l2_m2m_fop_mmap,
2687 };
2688
2689 static const struct v4l2_m2m_ops mxc_jpeg_m2m_ops = {
2690 .job_ready = mxc_jpeg_job_ready,
2691 .device_run = mxc_jpeg_device_run,
2692 };
2693
mxc_jpeg_detach_pm_domains(struct mxc_jpeg_dev * jpeg)2694 static void mxc_jpeg_detach_pm_domains(struct mxc_jpeg_dev *jpeg)
2695 {
2696 int i;
2697
2698 for (i = 0; i < jpeg->num_domains; i++) {
2699 if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]) &&
2700 !pm_runtime_suspended(jpeg->pd_dev[i]))
2701 pm_runtime_force_suspend(jpeg->pd_dev[i]);
2702 if (!IS_ERR_OR_NULL(jpeg->pd_link[i]))
2703 device_link_del(jpeg->pd_link[i]);
2704 if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]))
2705 dev_pm_domain_detach(jpeg->pd_dev[i], true);
2706 jpeg->pd_dev[i] = NULL;
2707 jpeg->pd_link[i] = NULL;
2708 }
2709 }
2710
mxc_jpeg_attach_pm_domains(struct mxc_jpeg_dev * jpeg)2711 static int mxc_jpeg_attach_pm_domains(struct mxc_jpeg_dev *jpeg)
2712 {
2713 struct device *dev = jpeg->dev;
2714 struct device_node *np = jpeg->pdev->dev.of_node;
2715 int i;
2716 int ret;
2717
2718 jpeg->num_domains = of_count_phandle_with_args(np, "power-domains",
2719 "#power-domain-cells");
2720 if (jpeg->num_domains < 0) {
2721 dev_err(dev, "No power domains defined for jpeg node\n");
2722 return jpeg->num_domains;
2723 }
2724 if (jpeg->num_domains == 1) {
2725 /* genpd_dev_pm_attach() attach automatically if power domains count is 1 */
2726 jpeg->num_domains = 0;
2727 return 0;
2728 }
2729
2730 jpeg->pd_dev = devm_kmalloc_array(dev, jpeg->num_domains,
2731 sizeof(*jpeg->pd_dev), GFP_KERNEL);
2732 if (!jpeg->pd_dev)
2733 return -ENOMEM;
2734
2735 jpeg->pd_link = devm_kmalloc_array(dev, jpeg->num_domains,
2736 sizeof(*jpeg->pd_link), GFP_KERNEL);
2737 if (!jpeg->pd_link)
2738 return -ENOMEM;
2739
2740 for (i = 0; i < jpeg->num_domains; i++) {
2741 jpeg->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
2742 if (IS_ERR(jpeg->pd_dev[i])) {
2743 ret = PTR_ERR(jpeg->pd_dev[i]);
2744 goto fail;
2745 }
2746
2747 jpeg->pd_link[i] = device_link_add(dev, jpeg->pd_dev[i],
2748 DL_FLAG_STATELESS |
2749 DL_FLAG_PM_RUNTIME);
2750 if (!jpeg->pd_link[i]) {
2751 ret = -EINVAL;
2752 goto fail;
2753 }
2754 }
2755
2756 return 0;
2757 fail:
2758 mxc_jpeg_detach_pm_domains(jpeg);
2759 return ret;
2760 }
2761
mxc_jpeg_probe(struct platform_device * pdev)2762 static int mxc_jpeg_probe(struct platform_device *pdev)
2763 {
2764 struct mxc_jpeg_dev *jpeg;
2765 struct device *dev = &pdev->dev;
2766 int dec_irq;
2767 int ret;
2768 int mode;
2769 const struct of_device_id *of_id;
2770
2771 of_id = of_match_node(mxc_jpeg_match, dev->of_node);
2772 if (!of_id)
2773 return -ENODEV;
2774 mode = *(const int *)of_id->data;
2775
2776 jpeg = devm_kzalloc(dev, sizeof(struct mxc_jpeg_dev), GFP_KERNEL);
2777 if (!jpeg)
2778 return -ENOMEM;
2779
2780 mutex_init(&jpeg->lock);
2781 spin_lock_init(&jpeg->hw_lock);
2782
2783 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
2784 if (ret) {
2785 dev_err(&pdev->dev, "No suitable DMA available.\n");
2786 goto err_irq;
2787 }
2788
2789 jpeg->base_reg = devm_platform_ioremap_resource(pdev, 0);
2790 if (IS_ERR(jpeg->base_reg))
2791 return PTR_ERR(jpeg->base_reg);
2792
2793 ret = of_property_read_u32_index(pdev->dev.of_node, "slot", 0, &jpeg->slot_data.slot);
2794 if (ret)
2795 jpeg->slot_data.slot = 0;
2796 dev_info(&pdev->dev, "choose slot %d\n", jpeg->slot_data.slot);
2797 dec_irq = platform_get_irq(pdev, 0);
2798 if (dec_irq < 0) {
2799 ret = dec_irq;
2800 goto err_irq;
2801 }
2802 ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq,
2803 0, pdev->name, jpeg);
2804 if (ret) {
2805 dev_err(&pdev->dev, "Failed to request irq %d (%d)\n",
2806 dec_irq, ret);
2807 goto err_irq;
2808 }
2809
2810 jpeg->pdev = pdev;
2811 jpeg->dev = dev;
2812 jpeg->mode = mode;
2813
2814 /* Get clocks */
2815 ret = devm_clk_bulk_get_all(&pdev->dev, &jpeg->clks);
2816 if (ret < 0) {
2817 dev_err(dev, "failed to get clock\n");
2818 goto err_clk;
2819 }
2820 jpeg->num_clks = ret;
2821
2822 ret = mxc_jpeg_attach_pm_domains(jpeg);
2823 if (ret < 0) {
2824 dev_err(dev, "failed to attach power domains %d\n", ret);
2825 goto err_clk;
2826 }
2827
2828 /* v4l2 */
2829 ret = v4l2_device_register(dev, &jpeg->v4l2_dev);
2830 if (ret) {
2831 dev_err(dev, "failed to register v4l2 device\n");
2832 goto err_register;
2833 }
2834 jpeg->m2m_dev = v4l2_m2m_init(&mxc_jpeg_m2m_ops);
2835 if (IS_ERR(jpeg->m2m_dev)) {
2836 dev_err(dev, "failed to register v4l2 device\n");
2837 ret = PTR_ERR(jpeg->m2m_dev);
2838 goto err_m2m;
2839 }
2840
2841 jpeg->dec_vdev = video_device_alloc();
2842 if (!jpeg->dec_vdev) {
2843 dev_err(dev, "failed to register v4l2 device\n");
2844 ret = -ENOMEM;
2845 goto err_vdev_alloc;
2846 }
2847 if (mode == MXC_JPEG_ENCODE)
2848 snprintf(jpeg->dec_vdev->name,
2849 sizeof(jpeg->dec_vdev->name),
2850 "%s-enc", MXC_JPEG_NAME);
2851 else
2852 snprintf(jpeg->dec_vdev->name,
2853 sizeof(jpeg->dec_vdev->name),
2854 "%s-dec", MXC_JPEG_NAME);
2855
2856 jpeg->dec_vdev->fops = &mxc_jpeg_fops;
2857 jpeg->dec_vdev->ioctl_ops = &mxc_jpeg_ioctl_ops;
2858 jpeg->dec_vdev->minor = -1;
2859 jpeg->dec_vdev->release = video_device_release;
2860 jpeg->dec_vdev->lock = &jpeg->lock; /* lock for ioctl serialization */
2861 jpeg->dec_vdev->v4l2_dev = &jpeg->v4l2_dev;
2862 jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M;
2863 jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING |
2864 V4L2_CAP_VIDEO_M2M_MPLANE;
2865 video_set_drvdata(jpeg->dec_vdev, jpeg);
2866 if (mode == MXC_JPEG_ENCODE) {
2867 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_DECODER_CMD);
2868 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_DECODER_CMD);
2869 } else {
2870 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_ENCODER_CMD);
2871 v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_ENCODER_CMD);
2872 }
2873 ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_VIDEO, -1);
2874 if (ret) {
2875 dev_err(dev, "failed to register video device\n");
2876 goto err_vdev_register;
2877 }
2878 if (mode == MXC_JPEG_ENCODE)
2879 v4l2_info(&jpeg->v4l2_dev,
2880 "encoder device registered as /dev/video%d (%d,%d)\n",
2881 jpeg->dec_vdev->num, VIDEO_MAJOR,
2882 jpeg->dec_vdev->minor);
2883 else
2884 v4l2_info(&jpeg->v4l2_dev,
2885 "decoder device registered as /dev/video%d (%d,%d)\n",
2886 jpeg->dec_vdev->num, VIDEO_MAJOR,
2887 jpeg->dec_vdev->minor);
2888
2889 platform_set_drvdata(pdev, jpeg);
2890 pm_runtime_enable(dev);
2891
2892 return 0;
2893
2894 err_vdev_register:
2895 video_device_release(jpeg->dec_vdev);
2896
2897 err_vdev_alloc:
2898 v4l2_m2m_release(jpeg->m2m_dev);
2899
2900 err_m2m:
2901 v4l2_device_unregister(&jpeg->v4l2_dev);
2902
2903 err_register:
2904 mxc_jpeg_detach_pm_domains(jpeg);
2905
2906 err_irq:
2907 err_clk:
2908 return ret;
2909 }
2910
2911 #ifdef CONFIG_PM
mxc_jpeg_runtime_resume(struct device * dev)2912 static int mxc_jpeg_runtime_resume(struct device *dev)
2913 {
2914 struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev);
2915 int ret;
2916
2917 ret = clk_bulk_prepare_enable(jpeg->num_clks, jpeg->clks);
2918 if (ret < 0) {
2919 dev_err(dev, "failed to enable clock\n");
2920 return ret;
2921 }
2922
2923 return 0;
2924 }
2925
mxc_jpeg_runtime_suspend(struct device * dev)2926 static int mxc_jpeg_runtime_suspend(struct device *dev)
2927 {
2928 struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev);
2929
2930 clk_bulk_disable_unprepare(jpeg->num_clks, jpeg->clks);
2931
2932 return 0;
2933 }
2934 #endif
2935
2936 #ifdef CONFIG_PM_SLEEP
mxc_jpeg_suspend(struct device * dev)2937 static int mxc_jpeg_suspend(struct device *dev)
2938 {
2939 struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev);
2940
2941 v4l2_m2m_suspend(jpeg->m2m_dev);
2942 return pm_runtime_force_suspend(dev);
2943 }
2944
mxc_jpeg_resume(struct device * dev)2945 static int mxc_jpeg_resume(struct device *dev)
2946 {
2947 struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev);
2948 int ret;
2949
2950 ret = pm_runtime_force_resume(dev);
2951 if (ret < 0)
2952 return ret;
2953
2954 v4l2_m2m_resume(jpeg->m2m_dev);
2955 return ret;
2956 }
2957 #endif
2958
2959 static const struct dev_pm_ops mxc_jpeg_pm_ops = {
2960 SET_RUNTIME_PM_OPS(mxc_jpeg_runtime_suspend,
2961 mxc_jpeg_runtime_resume, NULL)
2962 SET_SYSTEM_SLEEP_PM_OPS(mxc_jpeg_suspend, mxc_jpeg_resume)
2963 };
2964
mxc_jpeg_remove(struct platform_device * pdev)2965 static void mxc_jpeg_remove(struct platform_device *pdev)
2966 {
2967 struct mxc_jpeg_dev *jpeg = platform_get_drvdata(pdev);
2968
2969 mxc_jpeg_free_slot_data(jpeg);
2970
2971 pm_runtime_disable(&pdev->dev);
2972 video_unregister_device(jpeg->dec_vdev);
2973 v4l2_m2m_release(jpeg->m2m_dev);
2974 v4l2_device_unregister(&jpeg->v4l2_dev);
2975 mxc_jpeg_detach_pm_domains(jpeg);
2976 }
2977
2978 MODULE_DEVICE_TABLE(of, mxc_jpeg_match);
2979
2980 static struct platform_driver mxc_jpeg_driver = {
2981 .probe = mxc_jpeg_probe,
2982 .remove_new = mxc_jpeg_remove,
2983 .driver = {
2984 .name = "mxc-jpeg",
2985 .of_match_table = mxc_jpeg_match,
2986 .pm = &mxc_jpeg_pm_ops,
2987 },
2988 };
2989 module_platform_driver(mxc_jpeg_driver);
2990
2991 MODULE_AUTHOR("Zhengyu Shen <zhengyu.shen_1@nxp.com>");
2992 MODULE_AUTHOR("Mirela Rabulea <mirela.rabulea@nxp.com>");
2993 MODULE_DESCRIPTION("V4L2 driver for i.MX8 QXP/QM JPEG encoder/decoder");
2994 MODULE_LICENSE("GPL v2");
2995