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