xref: /linux/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * V4L2 Capture ISI subdev driver for i.MX8QXP/QM platform
4  *
5  * ISI is a Image Sensor Interface of i.MX8QXP/QM platform, which
6  * used to process image from camera sensor to memory or DC
7  *
8  * Copyright (c) 2019 NXP Semiconductor
9  */
10 
11 #include <linux/device.h>
12 #include <linux/dma-mapping.h>
13 #include <linux/errno.h>
14 #include <linux/kernel.h>
15 #include <linux/media-bus-format.h>
16 #include <linux/minmax.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/string.h>
19 #include <linux/types.h>
20 #include <linux/videodev2.h>
21 
22 #include <media/media-entity.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-dev.h>
25 #include <media/v4l2-event.h>
26 #include <media/v4l2-fh.h>
27 #include <media/v4l2-ioctl.h>
28 #include <media/v4l2-subdev.h>
29 #include <media/videobuf2-core.h>
30 #include <media/videobuf2-dma-contig.h>
31 #include <media/videobuf2-v4l2.h>
32 
33 #include "imx8-isi-core.h"
34 #include "imx8-isi-regs.h"
35 
36 /* Keep the first entry matching MXC_ISI_DEF_PIXEL_FORMAT */
37 static const struct mxc_isi_format_info mxc_isi_formats[] = {
38 	/* YUV formats */
39 	{
40 		.mbus_code	= MEDIA_BUS_FMT_YUV8_1X24,
41 		.fourcc		= V4L2_PIX_FMT_YUYV,
42 		.type		= MXC_ISI_VIDEO_CAP | MXC_ISI_VIDEO_M2M_OUT
43 				| MXC_ISI_VIDEO_M2M_CAP,
44 		.isi_in_format	= CHNL_MEM_RD_CTRL_IMG_TYPE_YUV422_1P8P,
45 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_YUV422_1P8P,
46 		.mem_planes	= 1,
47 		.color_planes	= 1,
48 		.depth		= { 16 },
49 		.encoding	= MXC_ISI_ENC_YUV,
50 	}, {
51 		.mbus_code	= MEDIA_BUS_FMT_YUV8_1X24,
52 		.fourcc		= V4L2_PIX_FMT_YUVA32,
53 		.type		= MXC_ISI_VIDEO_CAP | MXC_ISI_VIDEO_M2M_CAP,
54 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_YUV444_1P8,
55 		.mem_planes	= 1,
56 		.color_planes	= 1,
57 		.depth		= { 32 },
58 		.encoding	= MXC_ISI_ENC_YUV,
59 	}, {
60 		.mbus_code	= MEDIA_BUS_FMT_YUV8_1X24,
61 		.fourcc		= V4L2_PIX_FMT_NV12,
62 		.type		= MXC_ISI_VIDEO_CAP | MXC_ISI_VIDEO_M2M_CAP,
63 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_YUV420_2P8P,
64 		.color_planes	= 2,
65 		.mem_planes	= 1,
66 		.depth		= { 8, 16 },
67 		.hsub		= 2,
68 		.vsub		= 2,
69 		.encoding	= MXC_ISI_ENC_YUV,
70 	}, {
71 		.mbus_code	= MEDIA_BUS_FMT_YUV8_1X24,
72 		.fourcc		= V4L2_PIX_FMT_NV12M,
73 		.type		= MXC_ISI_VIDEO_CAP | MXC_ISI_VIDEO_M2M_CAP,
74 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_YUV420_2P8P,
75 		.mem_planes	= 2,
76 		.color_planes	= 2,
77 		.depth		= { 8, 16 },
78 		.hsub		= 2,
79 		.vsub		= 2,
80 		.encoding	= MXC_ISI_ENC_YUV,
81 	}, {
82 		.mbus_code	= MEDIA_BUS_FMT_YUV8_1X24,
83 		.fourcc		= V4L2_PIX_FMT_NV16,
84 		.type		= MXC_ISI_VIDEO_CAP | MXC_ISI_VIDEO_M2M_CAP,
85 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_YUV422_2P8P,
86 		.color_planes	= 2,
87 		.mem_planes	= 1,
88 		.depth		= { 8, 16 },
89 		.hsub		= 2,
90 		.vsub		= 1,
91 		.encoding	= MXC_ISI_ENC_YUV,
92 	}, {
93 		.mbus_code	= MEDIA_BUS_FMT_YUV8_1X24,
94 		.fourcc		= V4L2_PIX_FMT_NV16M,
95 		.type		= MXC_ISI_VIDEO_CAP | MXC_ISI_VIDEO_M2M_CAP,
96 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_YUV422_2P8P,
97 		.mem_planes	= 2,
98 		.color_planes	= 2,
99 		.depth		= { 8, 16 },
100 		.hsub		= 2,
101 		.vsub		= 1,
102 		.encoding	= MXC_ISI_ENC_YUV,
103 	}, {
104 		.mbus_code	= MEDIA_BUS_FMT_YUV8_1X24,
105 		.fourcc		= V4L2_PIX_FMT_YUV444M,
106 		.type		= MXC_ISI_VIDEO_CAP | MXC_ISI_VIDEO_M2M_CAP,
107 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_YUV444_3P8P,
108 		.mem_planes	= 3,
109 		.color_planes	= 3,
110 		.depth		= { 8, 8, 8 },
111 		.hsub		= 1,
112 		.vsub		= 1,
113 		.encoding	= MXC_ISI_ENC_YUV,
114 	},
115 	/* RGB formats */
116 	{
117 		.mbus_code	= MEDIA_BUS_FMT_RGB888_1X24,
118 		.fourcc		= V4L2_PIX_FMT_RGB565,
119 		.type		= MXC_ISI_VIDEO_CAP | MXC_ISI_VIDEO_M2M_OUT
120 				| MXC_ISI_VIDEO_M2M_CAP,
121 		.isi_in_format	= CHNL_MEM_RD_CTRL_IMG_TYPE_RGB565,
122 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RGB565,
123 		.mem_planes	= 1,
124 		.color_planes	= 1,
125 		.depth		= { 16 },
126 		.encoding	= MXC_ISI_ENC_RGB,
127 	}, {
128 		.mbus_code	= MEDIA_BUS_FMT_RGB888_1X24,
129 		.fourcc		= V4L2_PIX_FMT_RGB24,
130 		.type		= MXC_ISI_VIDEO_CAP | MXC_ISI_VIDEO_M2M_OUT
131 				| MXC_ISI_VIDEO_M2M_CAP,
132 		.isi_in_format	= CHNL_MEM_RD_CTRL_IMG_TYPE_BGR8P,
133 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_BGR888P,
134 		.mem_planes	= 1,
135 		.color_planes	= 1,
136 		.depth		= { 24 },
137 		.encoding	= MXC_ISI_ENC_RGB,
138 	}, {
139 		.mbus_code	= MEDIA_BUS_FMT_RGB888_1X24,
140 		.fourcc		= V4L2_PIX_FMT_BGR24,
141 		.type		= MXC_ISI_VIDEO_CAP | MXC_ISI_VIDEO_M2M_OUT
142 				| MXC_ISI_VIDEO_M2M_CAP,
143 		.isi_in_format	= CHNL_MEM_RD_CTRL_IMG_TYPE_RGB8P,
144 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RGB888P,
145 		.mem_planes	= 1,
146 		.color_planes	= 1,
147 		.depth		= { 24 },
148 		.encoding	= MXC_ISI_ENC_RGB,
149 	}, {
150 		.mbus_code	= MEDIA_BUS_FMT_RGB888_1X24,
151 		.fourcc		= V4L2_PIX_FMT_XBGR32,
152 		.type		= MXC_ISI_VIDEO_CAP | MXC_ISI_VIDEO_M2M_OUT
153 				| MXC_ISI_VIDEO_M2M_CAP,
154 		.isi_in_format	= CHNL_MEM_RD_CTRL_IMG_TYPE_XBGR8,
155 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_XRGB888,
156 		.mem_planes	= 1,
157 		.color_planes	= 1,
158 		.depth		= { 32 },
159 		.encoding	= MXC_ISI_ENC_RGB,
160 	}, {
161 		.mbus_code	= MEDIA_BUS_FMT_RGB888_1X24,
162 		.fourcc		= V4L2_PIX_FMT_ABGR32,
163 		.type		= MXC_ISI_VIDEO_CAP | MXC_ISI_VIDEO_M2M_CAP,
164 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_ARGB8888,
165 		.mem_planes	= 1,
166 		.color_planes	= 1,
167 		.depth		= { 32 },
168 		.encoding	= MXC_ISI_ENC_RGB,
169 	},
170 	/*
171 	 * RAW formats
172 	 *
173 	 * The ISI shifts the 10-bit and 12-bit formats left by 6 and 4 bits
174 	 * when using CHNL_IMG_CTRL_FORMAT_RAW10 or MXC_ISI_OUT_FMT_RAW12
175 	 * respectively, to align the bits to the left and pad with zeros in
176 	 * the LSBs. The corresponding V4L2 formats are however right-aligned,
177 	 * we have to use CHNL_IMG_CTRL_FORMAT_RAW16 to avoid the left shift.
178 	 */
179 	{
180 		.mbus_code	= MEDIA_BUS_FMT_Y8_1X8,
181 		.fourcc		= V4L2_PIX_FMT_GREY,
182 		.type		= MXC_ISI_VIDEO_CAP,
183 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW8,
184 		.mem_planes	= 1,
185 		.color_planes	= 1,
186 		.depth		= { 8 },
187 		.encoding	= MXC_ISI_ENC_RAW,
188 	}, {
189 		.mbus_code	= MEDIA_BUS_FMT_Y10_1X10,
190 		.fourcc		= V4L2_PIX_FMT_Y10,
191 		.type		= MXC_ISI_VIDEO_CAP,
192 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
193 		.mem_planes	= 1,
194 		.color_planes	= 1,
195 		.depth		= { 16 },
196 		.encoding	= MXC_ISI_ENC_RAW,
197 	}, {
198 		.mbus_code	= MEDIA_BUS_FMT_Y12_1X12,
199 		.fourcc		= V4L2_PIX_FMT_Y12,
200 		.type		= MXC_ISI_VIDEO_CAP,
201 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
202 		.mem_planes	= 1,
203 		.color_planes	= 1,
204 		.depth		= { 16 },
205 		.encoding	= MXC_ISI_ENC_RAW,
206 	}, {
207 		.mbus_code	= MEDIA_BUS_FMT_Y14_1X14,
208 		.fourcc		= V4L2_PIX_FMT_Y14,
209 		.type		= MXC_ISI_VIDEO_CAP,
210 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
211 		.mem_planes	= 1,
212 		.color_planes	= 1,
213 		.depth		= { 16 },
214 		.encoding	= MXC_ISI_ENC_RAW,
215 	}, {
216 		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
217 		.fourcc		= V4L2_PIX_FMT_SBGGR8,
218 		.type		= MXC_ISI_VIDEO_CAP,
219 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW8,
220 		.mem_planes	= 1,
221 		.color_planes	= 1,
222 		.depth		= { 8 },
223 		.encoding	= MXC_ISI_ENC_RAW,
224 	}, {
225 		.mbus_code	= MEDIA_BUS_FMT_SGBRG8_1X8,
226 		.fourcc		= V4L2_PIX_FMT_SGBRG8,
227 		.type		= MXC_ISI_VIDEO_CAP,
228 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW8,
229 		.mem_planes	= 1,
230 		.color_planes	= 1,
231 		.depth		= { 8 },
232 		.encoding	= MXC_ISI_ENC_RAW,
233 	}, {
234 		.mbus_code	= MEDIA_BUS_FMT_SGRBG8_1X8,
235 		.fourcc		= V4L2_PIX_FMT_SGRBG8,
236 		.type		= MXC_ISI_VIDEO_CAP,
237 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW8,
238 		.mem_planes	= 1,
239 		.color_planes	= 1,
240 		.depth		= { 8 },
241 		.encoding	= MXC_ISI_ENC_RAW,
242 	}, {
243 		.mbus_code	= MEDIA_BUS_FMT_SRGGB8_1X8,
244 		.fourcc		= V4L2_PIX_FMT_SRGGB8,
245 		.type		= MXC_ISI_VIDEO_CAP,
246 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW8,
247 		.mem_planes	= 1,
248 		.color_planes	= 1,
249 		.depth		= { 8 },
250 		.encoding	= MXC_ISI_ENC_RAW,
251 	}, {
252 		.mbus_code	= MEDIA_BUS_FMT_SBGGR10_1X10,
253 		.fourcc		= V4L2_PIX_FMT_SBGGR10,
254 		.type		= MXC_ISI_VIDEO_CAP,
255 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
256 		.mem_planes	= 1,
257 		.color_planes	= 1,
258 		.depth		= { 16 },
259 		.encoding	= MXC_ISI_ENC_RAW,
260 	}, {
261 		.mbus_code	= MEDIA_BUS_FMT_SGBRG10_1X10,
262 		.fourcc		= V4L2_PIX_FMT_SGBRG10,
263 		.type		= MXC_ISI_VIDEO_CAP,
264 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
265 		.mem_planes	= 1,
266 		.color_planes	= 1,
267 		.depth		= { 16 },
268 		.encoding	= MXC_ISI_ENC_RAW,
269 	}, {
270 		.mbus_code	= MEDIA_BUS_FMT_SGRBG10_1X10,
271 		.fourcc		= V4L2_PIX_FMT_SGRBG10,
272 		.type		= MXC_ISI_VIDEO_CAP,
273 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
274 		.mem_planes	= 1,
275 		.color_planes	= 1,
276 		.depth		= { 16 },
277 		.encoding	= MXC_ISI_ENC_RAW,
278 	}, {
279 		.mbus_code	= MEDIA_BUS_FMT_SRGGB10_1X10,
280 		.fourcc		= V4L2_PIX_FMT_SRGGB10,
281 		.type		= MXC_ISI_VIDEO_CAP,
282 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
283 		.mem_planes	= 1,
284 		.color_planes	= 1,
285 		.depth		= { 16 },
286 		.encoding	= MXC_ISI_ENC_RAW,
287 	}, {
288 		.mbus_code	= MEDIA_BUS_FMT_SBGGR12_1X12,
289 		.fourcc		= V4L2_PIX_FMT_SBGGR12,
290 		.type		= MXC_ISI_VIDEO_CAP,
291 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
292 		.mem_planes	= 1,
293 		.color_planes	= 1,
294 		.depth		= { 16 },
295 		.encoding	= MXC_ISI_ENC_RAW,
296 	}, {
297 		.mbus_code	= MEDIA_BUS_FMT_SGBRG12_1X12,
298 		.fourcc		= V4L2_PIX_FMT_SGBRG12,
299 		.type		= MXC_ISI_VIDEO_CAP,
300 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
301 		.mem_planes	= 1,
302 		.color_planes	= 1,
303 		.depth		= { 16 },
304 		.encoding	= MXC_ISI_ENC_RAW,
305 	}, {
306 		.mbus_code	= MEDIA_BUS_FMT_SGRBG12_1X12,
307 		.fourcc		= V4L2_PIX_FMT_SGRBG12,
308 		.type		= MXC_ISI_VIDEO_CAP,
309 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
310 		.mem_planes	= 1,
311 		.color_planes	= 1,
312 		.depth		= { 16 },
313 		.encoding	= MXC_ISI_ENC_RAW,
314 	}, {
315 		.mbus_code	= MEDIA_BUS_FMT_SRGGB12_1X12,
316 		.fourcc		= V4L2_PIX_FMT_SRGGB12,
317 		.type		= MXC_ISI_VIDEO_CAP,
318 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
319 		.mem_planes	= 1,
320 		.color_planes	= 1,
321 		.depth		= { 16 },
322 		.encoding	= MXC_ISI_ENC_RAW,
323 	}, {
324 		.mbus_code	= MEDIA_BUS_FMT_SBGGR14_1X14,
325 		.fourcc		= V4L2_PIX_FMT_SBGGR14,
326 		.type		= MXC_ISI_VIDEO_CAP,
327 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
328 		.mem_planes	= 1,
329 		.color_planes	= 1,
330 		.depth		= { 16 },
331 		.encoding	= MXC_ISI_ENC_RAW,
332 	}, {
333 		.mbus_code	= MEDIA_BUS_FMT_SGBRG14_1X14,
334 		.fourcc		= V4L2_PIX_FMT_SGBRG14,
335 		.type		= MXC_ISI_VIDEO_CAP,
336 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
337 		.mem_planes	= 1,
338 		.color_planes	= 1,
339 		.depth		= { 16 },
340 		.encoding	= MXC_ISI_ENC_RAW,
341 	}, {
342 		.mbus_code	= MEDIA_BUS_FMT_SGRBG14_1X14,
343 		.fourcc		= V4L2_PIX_FMT_SGRBG14,
344 		.type		= MXC_ISI_VIDEO_CAP,
345 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
346 		.mem_planes	= 1,
347 		.color_planes	= 1,
348 		.depth		= { 16 },
349 		.encoding	= MXC_ISI_ENC_RAW,
350 	}, {
351 		.mbus_code	= MEDIA_BUS_FMT_SRGGB14_1X14,
352 		.fourcc		= V4L2_PIX_FMT_SRGGB14,
353 		.type		= MXC_ISI_VIDEO_CAP,
354 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW16,
355 		.mem_planes	= 1,
356 		.color_planes	= 1,
357 		.depth		= { 16 },
358 		.encoding	= MXC_ISI_ENC_RAW,
359 	},
360 	/* JPEG */
361 	{
362 		.mbus_code	= MEDIA_BUS_FMT_JPEG_1X8,
363 		.fourcc		= V4L2_PIX_FMT_MJPEG,
364 		.type		= MXC_ISI_VIDEO_CAP,
365 		.isi_out_format	= CHNL_IMG_CTRL_FORMAT_RAW8,
366 		.mem_planes	= 1,
367 		.color_planes	= 1,
368 		.depth		= { 8 },
369 		.encoding	= MXC_ISI_ENC_RAW,
370 	}
371 };
372 
373 const struct mxc_isi_format_info *
374 mxc_isi_format_by_fourcc(u32 fourcc, enum mxc_isi_video_type type)
375 {
376 	unsigned int i;
377 
378 	for (i = 0; i < ARRAY_SIZE(mxc_isi_formats); i++) {
379 		const struct mxc_isi_format_info *fmt = &mxc_isi_formats[i];
380 
381 		if (fmt->fourcc == fourcc && fmt->type & type)
382 			return fmt;
383 	}
384 
385 	return NULL;
386 }
387 
388 const struct mxc_isi_format_info *
389 mxc_isi_format_enum(unsigned int index, enum mxc_isi_video_type type)
390 {
391 	unsigned int i;
392 
393 	for (i = 0; i < ARRAY_SIZE(mxc_isi_formats); i++) {
394 		const struct mxc_isi_format_info *fmt = &mxc_isi_formats[i];
395 
396 		if (!(fmt->type & type))
397 			continue;
398 
399 		if (!index)
400 			return fmt;
401 
402 		index--;
403 	}
404 
405 	return NULL;
406 }
407 
408 const struct mxc_isi_format_info *
409 mxc_isi_format_try(struct mxc_isi_pipe *pipe, struct v4l2_pix_format_mplane *pix,
410 		   enum mxc_isi_video_type type)
411 {
412 	const struct mxc_isi_format_info *fmt;
413 	unsigned int max_width;
414 	unsigned int i;
415 
416 	max_width = pipe->id == pipe->isi->pdata->num_channels - 1
417 		  ? MXC_ISI_MAX_WIDTH_UNCHAINED
418 		  : MXC_ISI_MAX_WIDTH_CHAINED;
419 
420 	fmt = mxc_isi_format_by_fourcc(pix->pixelformat, type);
421 	if (!fmt)
422 		fmt = &mxc_isi_formats[0];
423 
424 	pix->width = clamp(pix->width, MXC_ISI_MIN_WIDTH, max_width);
425 	pix->height = clamp(pix->height, MXC_ISI_MIN_HEIGHT, MXC_ISI_MAX_HEIGHT);
426 	pix->pixelformat = fmt->fourcc;
427 	pix->field = V4L2_FIELD_NONE;
428 
429 	if (pix->colorspace == V4L2_COLORSPACE_DEFAULT) {
430 		pix->colorspace = MXC_ISI_DEF_COLOR_SPACE;
431 		pix->ycbcr_enc = MXC_ISI_DEF_YCBCR_ENC;
432 		pix->quantization = MXC_ISI_DEF_QUANTIZATION;
433 		pix->xfer_func = MXC_ISI_DEF_XFER_FUNC;
434 	}
435 
436 	if (pix->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
437 		pix->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace);
438 	if (pix->quantization == V4L2_QUANTIZATION_DEFAULT) {
439 		bool is_rgb = fmt->encoding == MXC_ISI_ENC_RGB;
440 
441 		pix->quantization =
442 			V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb, pix->colorspace,
443 						      pix->ycbcr_enc);
444 	}
445 	if (pix->xfer_func == V4L2_XFER_FUNC_DEFAULT)
446 		pix->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace);
447 
448 	pix->num_planes = fmt->mem_planes;
449 
450 	for (i = 0; i < fmt->color_planes; ++i) {
451 		struct v4l2_plane_pix_format *plane = &pix->plane_fmt[i];
452 		unsigned int bpl;
453 
454 		/* The pitch must be identical for all planes. */
455 		if (i == 0)
456 			bpl = clamp(plane->bytesperline,
457 				    pix->width * fmt->depth[0] / 8,
458 				    65535U);
459 		else
460 			bpl = pix->plane_fmt[0].bytesperline;
461 
462 		plane->bytesperline = bpl;
463 
464 		plane->sizeimage = plane->bytesperline * pix->height;
465 		if (i >= 1)
466 			plane->sizeimage /= fmt->vsub;
467 	}
468 
469 	/*
470 	 * For single-planar pixel formats with multiple color planes,
471 	 * concatenate the size of all planes and clear all planes but the
472 	 * first one.
473 	 */
474 	if (fmt->color_planes != fmt->mem_planes) {
475 		for (i = 1; i < fmt->color_planes; ++i) {
476 			struct v4l2_plane_pix_format *plane = &pix->plane_fmt[i];
477 
478 			pix->plane_fmt[0].sizeimage += plane->sizeimage;
479 			plane->bytesperline = 0;
480 			plane->sizeimage = 0;
481 		}
482 	}
483 
484 	return fmt;
485 }
486 
487 /* -----------------------------------------------------------------------------
488  * videobuf2 queue operations
489  */
490 
491 static void mxc_isi_video_frame_write_done(struct mxc_isi_pipe *pipe,
492 					   u32 status)
493 {
494 	struct mxc_isi_video *video = &pipe->video;
495 	struct device *dev = pipe->isi->dev;
496 	struct mxc_isi_buffer *next_buf;
497 	struct mxc_isi_buffer *buf;
498 	enum mxc_isi_buf_id buf_id;
499 
500 	spin_lock(&video->buf_lock);
501 
502 	/*
503 	 * The ISI hardware handles buffers using a ping-pong mechanism with
504 	 * two sets of destination addresses (with shadow registers to allow
505 	 * programming addresses for all planes atomically) named BUF1 and
506 	 * BUF2. Addresses can be loaded and copied to shadow registers at any
507 	 * at any time.
508 	 *
509 	 * The hardware keeps track of which buffer is being written to and
510 	 * automatically switches to the other buffer at frame end, copying the
511 	 * corresponding address to another set of shadow registers that track
512 	 * the address being written to. The active buffer tracking bits are
513 	 * accessible through the CHNL_STS register.
514 	 *
515 	 *  BUF1        BUF2  |   Event   | Action
516 	 *                    |           |
517 	 *                    |           | Program initial buffers
518 	 *                    |           | B0 in BUF1, B1 in BUF2
519 	 *                    | Start ISI |
520 	 * +----+             |           |
521 	 * | B0 |             |           |
522 	 * +----+             |           |
523 	 *             +----+ | FRM IRQ 0 | B0 complete, BUF2 now active
524 	 *             | B1 | |           | Program B2 in BUF1
525 	 *             +----+ |           |
526 	 * +----+             | FRM IRQ 1 | B1 complete, BUF1 now active
527 	 * | B2 |             |           | Program B3 in BUF2
528 	 * +----+             |           |
529 	 *             +----+ | FRM IRQ 2 | B2 complete, BUF2 now active
530 	 *             | B3 | |           | Program B4 in BUF1
531 	 *             +----+ |           |
532 	 * +----+             | FRM IRQ 3 | B3 complete, BUF1 now active
533 	 * | B4 |             |           | Program B5 in BUF2
534 	 * +----+             |           |
535 	 *        ...         |           |
536 	 *
537 	 * Races between address programming and buffer switching can be
538 	 * detected by checking if a frame end interrupt occurred after
539 	 * programming the addresses.
540 	 *
541 	 * As none of the shadow registers are accessible, races can occur
542 	 * between address programming and buffer switching. It is possible to
543 	 * detect the race condition by checking if a frame end interrupt
544 	 * occurred after programming the addresses, but impossible to
545 	 * determine if the race has been won or lost.
546 	 *
547 	 * In addition to this, we need to use discard buffers if no pending
548 	 * buffers are available. To simplify handling of discard buffer, we
549 	 * need to allocate three of them, as two can be active concurrently
550 	 * and we need to still be able to get hold of a next buffer. The logic
551 	 * could be improved to use two buffers only, but as all discard
552 	 * buffers share the same memory, an additional buffer is cheap.
553 	 */
554 
555 	/* Check which buffer has just completed. */
556 	buf_id = pipe->isi->pdata->buf_active_reverse
557 	       ? (status & CHNL_STS_BUF1_ACTIVE ? MXC_ISI_BUF2 : MXC_ISI_BUF1)
558 	       : (status & CHNL_STS_BUF1_ACTIVE ? MXC_ISI_BUF1 : MXC_ISI_BUF2);
559 
560 	buf = list_first_entry_or_null(&video->out_active,
561 				       struct mxc_isi_buffer, list);
562 
563 	/* Safety check, this should really never happen. */
564 	if (!buf) {
565 		dev_warn(dev, "trying to access empty active list\n");
566 		goto done;
567 	}
568 
569 	/*
570 	 * If the buffer that has completed doesn't match the buffer on the
571 	 * front of the active list, it means we have lost one frame end
572 	 * interrupt (or possibly a large odd number of interrupts, although
573 	 * quite unlikely).
574 	 *
575 	 * For instance, if IRQ1 is lost and we handle IRQ2, both B1 and B2
576 	 * have been completed, but B3 hasn't been programmed, BUF2 still
577 	 * addresses B1 and the ISI is now writing in B1 instead of B3. We
578 	 * can't complete B2 as that would result in out-of-order completion.
579 	 *
580 	 * The only option is to ignore this interrupt and try again. When IRQ3
581 	 * will be handled, we will complete B1 and be in sync again.
582 	 */
583 	if (buf->id != buf_id) {
584 		dev_dbg(dev, "buffer ID mismatch (expected %u, got %u), skipping\n",
585 			buf->id, buf_id);
586 
587 		/*
588 		 * Increment the frame count by two to account for the missed
589 		 * and the ignored interrupts.
590 		 */
591 		video->frame_count += 2;
592 		goto done;
593 	}
594 
595 	/* Pick the next buffer and queue it to the hardware. */
596 	next_buf = list_first_entry_or_null(&video->out_pending,
597 					    struct mxc_isi_buffer, list);
598 	if (!next_buf) {
599 		next_buf = list_first_entry_or_null(&video->out_discard,
600 						    struct mxc_isi_buffer, list);
601 
602 		/* Safety check, this should never happen. */
603 		if (!next_buf) {
604 			dev_warn(dev, "trying to access empty discard list\n");
605 			goto done;
606 		}
607 	}
608 
609 	mxc_isi_channel_set_outbuf(pipe, next_buf->dma_addrs, buf_id);
610 	next_buf->id = buf_id;
611 
612 	/*
613 	 * Check if we have raced with the end of frame interrupt. If so, we
614 	 * can't tell if the ISI has recorded the new address, or is still
615 	 * using the previous buffer. We must assume the latter as that is the
616 	 * worst case.
617 	 *
618 	 * For instance, if we are handling IRQ1 and now detect the FRM
619 	 * interrupt, assume B2 has completed and the ISI has switched to BUF2
620 	 * using B1 just before we programmed B3. Unlike in the previous race
621 	 * condition, B3 has been programmed and will be written to the next
622 	 * time the ISI switches to BUF2. We can however handle this exactly as
623 	 * the first race condition, as we'll program B3 (still at the head of
624 	 * the pending list) when handling IRQ3.
625 	 */
626 	status = mxc_isi_channel_irq_status(pipe, false);
627 	if (status & CHNL_STS_FRM_STRD) {
628 		dev_dbg(dev, "raced with frame end interrupt\n");
629 		video->frame_count += 2;
630 		goto done;
631 	}
632 
633 	/*
634 	 * The next buffer has been queued successfully, move it to the active
635 	 * list, and complete the current buffer.
636 	 */
637 	list_move_tail(&next_buf->list, &video->out_active);
638 
639 	if (!buf->discard) {
640 		list_del_init(&buf->list);
641 		buf->v4l2_buf.sequence = video->frame_count;
642 		buf->v4l2_buf.vb2_buf.timestamp = ktime_get_ns();
643 		vb2_buffer_done(&buf->v4l2_buf.vb2_buf, VB2_BUF_STATE_DONE);
644 	} else {
645 		list_move_tail(&buf->list, &video->out_discard);
646 	}
647 
648 	video->frame_count++;
649 
650 done:
651 	spin_unlock(&video->buf_lock);
652 }
653 
654 static void mxc_isi_video_free_discard_buffers(struct mxc_isi_video *video)
655 {
656 	unsigned int i;
657 
658 	for (i = 0; i < video->pix.num_planes; i++) {
659 		struct mxc_isi_dma_buffer *buf = &video->discard_buffer[i];
660 
661 		if (!buf->addr)
662 			continue;
663 
664 		dma_free_coherent(video->pipe->isi->dev, buf->size, buf->addr,
665 				  buf->dma);
666 		buf->addr = NULL;
667 	}
668 }
669 
670 static int mxc_isi_video_alloc_discard_buffers(struct mxc_isi_video *video)
671 {
672 	unsigned int i, j;
673 
674 	/* Allocate memory for each plane. */
675 	for (i = 0; i < video->pix.num_planes; i++) {
676 		struct mxc_isi_dma_buffer *buf = &video->discard_buffer[i];
677 
678 		buf->size = PAGE_ALIGN(video->pix.plane_fmt[i].sizeimage);
679 		buf->addr = dma_alloc_coherent(video->pipe->isi->dev, buf->size,
680 					       &buf->dma, GFP_DMA | GFP_KERNEL);
681 		if (!buf->addr) {
682 			mxc_isi_video_free_discard_buffers(video);
683 			return -ENOMEM;
684 		}
685 
686 		dev_dbg(video->pipe->isi->dev,
687 			"discard buffer plane %u: %zu bytes @%pad (CPU address %p)\n",
688 			i, buf->size, &buf->dma, buf->addr);
689 	}
690 
691 	/* Fill the DMA addresses in the discard buffers. */
692 	for (i = 0; i < ARRAY_SIZE(video->buf_discard); ++i) {
693 		struct mxc_isi_buffer *buf = &video->buf_discard[i];
694 
695 		buf->discard = true;
696 
697 		for (j = 0; j < video->pix.num_planes; ++j)
698 			buf->dma_addrs[j] = video->discard_buffer[j].dma;
699 	}
700 
701 	return 0;
702 }
703 
704 static int mxc_isi_video_validate_format(struct mxc_isi_video *video)
705 {
706 	const struct v4l2_mbus_framefmt *format;
707 	const struct mxc_isi_format_info *info;
708 	struct v4l2_subdev_state *state;
709 	struct v4l2_subdev *sd = &video->pipe->sd;
710 	int ret = 0;
711 
712 	state = v4l2_subdev_lock_and_get_active_state(sd);
713 
714 	info = mxc_isi_format_by_fourcc(video->pix.pixelformat,
715 					MXC_ISI_VIDEO_CAP);
716 	format = v4l2_subdev_state_get_format(state, MXC_ISI_PIPE_PAD_SOURCE);
717 
718 	if (format->code != info->mbus_code ||
719 	    format->width != video->pix.width ||
720 	    format->height != video->pix.height) {
721 		dev_dbg(video->pipe->isi->dev,
722 			"%s: configuration mismatch, 0x%04x/%ux%u != 0x%04x/%ux%u\n",
723 			__func__, format->code, format->width, format->height,
724 			info->mbus_code, video->pix.width, video->pix.height);
725 		ret = -EINVAL;
726 	}
727 
728 	v4l2_subdev_unlock_state(state);
729 
730 	return ret;
731 }
732 
733 static void mxc_isi_video_return_buffers(struct mxc_isi_video *video,
734 					 enum vb2_buffer_state state)
735 {
736 	struct mxc_isi_buffer *buf;
737 
738 	spin_lock_irq(&video->buf_lock);
739 
740 	while (!list_empty(&video->out_active)) {
741 		buf = list_first_entry(&video->out_active,
742 				       struct mxc_isi_buffer, list);
743 		list_del_init(&buf->list);
744 		if (buf->discard)
745 			continue;
746 
747 		vb2_buffer_done(&buf->v4l2_buf.vb2_buf, state);
748 	}
749 
750 	while (!list_empty(&video->out_pending)) {
751 		buf = list_first_entry(&video->out_pending,
752 				       struct mxc_isi_buffer, list);
753 		list_del_init(&buf->list);
754 		vb2_buffer_done(&buf->v4l2_buf.vb2_buf, state);
755 	}
756 
757 	while (!list_empty(&video->out_discard)) {
758 		buf = list_first_entry(&video->out_discard,
759 				       struct mxc_isi_buffer, list);
760 		list_del_init(&buf->list);
761 	}
762 
763 	INIT_LIST_HEAD(&video->out_active);
764 	INIT_LIST_HEAD(&video->out_pending);
765 	INIT_LIST_HEAD(&video->out_discard);
766 
767 	spin_unlock_irq(&video->buf_lock);
768 }
769 
770 static void mxc_isi_video_queue_first_buffers(struct mxc_isi_video *video)
771 {
772 	unsigned int discard;
773 	unsigned int i;
774 
775 	lockdep_assert_held(&video->buf_lock);
776 
777 	/*
778 	 * Queue two ISI channel output buffers. We are not guaranteed to have
779 	 * any buffer in the pending list when this function is called from the
780 	 * system resume handler. Use pending buffers as much as possible, and
781 	 * use discard buffers to fill the remaining slots.
782 	 */
783 
784 	/* How many discard buffers do we need to queue first ? */
785 	discard = list_empty(&video->out_pending) ? 2
786 		: list_is_singular(&video->out_pending) ? 1
787 		: 0;
788 
789 	for (i = 0; i < 2; ++i) {
790 		enum mxc_isi_buf_id buf_id = i == 0 ? MXC_ISI_BUF1
791 					   : MXC_ISI_BUF2;
792 		struct mxc_isi_buffer *buf;
793 		struct list_head *list;
794 
795 		list = i < discard ? &video->out_discard : &video->out_pending;
796 		buf = list_first_entry(list, struct mxc_isi_buffer, list);
797 
798 		mxc_isi_channel_set_outbuf(video->pipe, buf->dma_addrs, buf_id);
799 		buf->id = buf_id;
800 		list_move_tail(&buf->list, &video->out_active);
801 	}
802 }
803 
804 static inline struct mxc_isi_buffer *to_isi_buffer(struct vb2_v4l2_buffer *v4l2_buf)
805 {
806 	return container_of(v4l2_buf, struct mxc_isi_buffer, v4l2_buf);
807 }
808 
809 int mxc_isi_video_queue_setup(const struct v4l2_pix_format_mplane *format,
810 			      const struct mxc_isi_format_info *info,
811 			      unsigned int *num_buffers,
812 			      unsigned int *num_planes, unsigned int sizes[])
813 {
814 	unsigned int i;
815 
816 	if (*num_planes) {
817 		if (*num_planes != info->mem_planes)
818 			return -EINVAL;
819 
820 		for (i = 0; i < info->mem_planes; ++i) {
821 			if (sizes[i] < format->plane_fmt[i].sizeimage)
822 				return -EINVAL;
823 		}
824 
825 		return 0;
826 	}
827 
828 	*num_planes = info->mem_planes;
829 
830 	for (i = 0; i < info->mem_planes; ++i)
831 		sizes[i] = format->plane_fmt[i].sizeimage;
832 
833 	return 0;
834 }
835 
836 void mxc_isi_video_buffer_init(struct vb2_buffer *vb2, dma_addr_t dma_addrs[3],
837 			       const struct mxc_isi_format_info *info,
838 			       const struct v4l2_pix_format_mplane *pix)
839 {
840 	unsigned int i;
841 
842 	for (i = 0; i < info->mem_planes; ++i)
843 		dma_addrs[i] = vb2_dma_contig_plane_dma_addr(vb2, i);
844 
845 	/*
846 	 * For single-planar pixel formats with multiple color planes, split
847 	 * the buffer into color planes.
848 	 */
849 	if (info->color_planes != info->mem_planes) {
850 		unsigned int size = pix->plane_fmt[0].bytesperline * pix->height;
851 
852 		for (i = 1; i < info->color_planes; ++i) {
853 			unsigned int vsub = i > 1 ? info->vsub : 1;
854 
855 			dma_addrs[i] = dma_addrs[i - 1] + size / vsub;
856 		}
857 	}
858 }
859 
860 int mxc_isi_video_buffer_prepare(struct mxc_isi_dev *isi, struct vb2_buffer *vb2,
861 				 const struct mxc_isi_format_info *info,
862 				 const struct v4l2_pix_format_mplane *pix)
863 {
864 	unsigned int i;
865 
866 	for (i = 0; i < info->mem_planes; i++) {
867 		unsigned long size = pix->plane_fmt[i].sizeimage;
868 
869 		if (vb2_plane_size(vb2, i) < size) {
870 			dev_err(isi->dev, "User buffer too small (%ld < %ld)\n",
871 				vb2_plane_size(vb2, i), size);
872 			return -EINVAL;
873 		}
874 
875 		vb2_set_plane_payload(vb2, i, size);
876 	}
877 
878 	return 0;
879 }
880 
881 static int mxc_isi_vb2_queue_setup(struct vb2_queue *q,
882 				   unsigned int *num_buffers,
883 				   unsigned int *num_planes,
884 				   unsigned int sizes[],
885 				   struct device *alloc_devs[])
886 {
887 	struct mxc_isi_video *video = vb2_get_drv_priv(q);
888 
889 	return mxc_isi_video_queue_setup(&video->pix, video->fmtinfo,
890 					 num_buffers, num_planes, sizes);
891 }
892 
893 static int mxc_isi_vb2_buffer_init(struct vb2_buffer *vb2)
894 {
895 	struct mxc_isi_buffer *buf = to_isi_buffer(to_vb2_v4l2_buffer(vb2));
896 	struct mxc_isi_video *video = vb2_get_drv_priv(vb2->vb2_queue);
897 
898 	mxc_isi_video_buffer_init(vb2, buf->dma_addrs, video->fmtinfo,
899 				  &video->pix);
900 
901 	return 0;
902 }
903 
904 static int mxc_isi_vb2_buffer_prepare(struct vb2_buffer *vb2)
905 {
906 	struct mxc_isi_video *video = vb2_get_drv_priv(vb2->vb2_queue);
907 
908 	return mxc_isi_video_buffer_prepare(video->pipe->isi, vb2,
909 					    video->fmtinfo, &video->pix);
910 }
911 
912 static void mxc_isi_vb2_buffer_queue(struct vb2_buffer *vb2)
913 {
914 	struct vb2_v4l2_buffer *v4l2_buf = to_vb2_v4l2_buffer(vb2);
915 	struct mxc_isi_buffer *buf = to_isi_buffer(v4l2_buf);
916 	struct mxc_isi_video *video = vb2_get_drv_priv(vb2->vb2_queue);
917 
918 	spin_lock_irq(&video->buf_lock);
919 	list_add_tail(&buf->list, &video->out_pending);
920 	spin_unlock_irq(&video->buf_lock);
921 }
922 
923 static void mxc_isi_video_init_channel(struct mxc_isi_video *video)
924 {
925 	struct mxc_isi_pipe *pipe = video->pipe;
926 
927 	mxc_isi_channel_get(pipe);
928 
929 	mutex_lock(video->ctrls.handler.lock);
930 	mxc_isi_channel_set_alpha(pipe, video->ctrls.alpha);
931 	mxc_isi_channel_set_flip(pipe, video->ctrls.hflip, video->ctrls.vflip);
932 	mutex_unlock(video->ctrls.handler.lock);
933 
934 	mxc_isi_channel_set_output_format(pipe, video->fmtinfo, &video->pix);
935 }
936 
937 static int mxc_isi_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
938 {
939 	struct mxc_isi_video *video = vb2_get_drv_priv(q);
940 	unsigned int i;
941 	int ret;
942 
943 	/* Initialize the ISI channel. */
944 	mxc_isi_video_init_channel(video);
945 
946 	spin_lock_irq(&video->buf_lock);
947 
948 	/* Add the discard buffers to the out_discard list. */
949 	for (i = 0; i < ARRAY_SIZE(video->buf_discard); ++i) {
950 		struct mxc_isi_buffer *buf = &video->buf_discard[i];
951 
952 		list_add_tail(&buf->list, &video->out_discard);
953 	}
954 
955 	/* Queue the first buffers. */
956 	mxc_isi_video_queue_first_buffers(video);
957 
958 	/* Clear frame count */
959 	video->frame_count = 0;
960 
961 	spin_unlock_irq(&video->buf_lock);
962 
963 	ret = mxc_isi_pipe_enable(video->pipe);
964 	if (ret)
965 		goto error;
966 
967 	return 0;
968 
969 error:
970 	mxc_isi_channel_put(video->pipe);
971 	mxc_isi_video_return_buffers(video, VB2_BUF_STATE_QUEUED);
972 	return ret;
973 }
974 
975 static void mxc_isi_vb2_stop_streaming(struct vb2_queue *q)
976 {
977 	struct mxc_isi_video *video = vb2_get_drv_priv(q);
978 
979 	mxc_isi_pipe_disable(video->pipe);
980 	mxc_isi_channel_put(video->pipe);
981 
982 	mxc_isi_video_return_buffers(video, VB2_BUF_STATE_ERROR);
983 }
984 
985 static const struct vb2_ops mxc_isi_vb2_qops = {
986 	.queue_setup		= mxc_isi_vb2_queue_setup,
987 	.buf_init		= mxc_isi_vb2_buffer_init,
988 	.buf_prepare		= mxc_isi_vb2_buffer_prepare,
989 	.buf_queue		= mxc_isi_vb2_buffer_queue,
990 	.start_streaming	= mxc_isi_vb2_start_streaming,
991 	.stop_streaming		= mxc_isi_vb2_stop_streaming,
992 };
993 
994 /* -----------------------------------------------------------------------------
995  * V4L2 controls
996  */
997 
998 static inline struct mxc_isi_video *ctrl_to_isi_video(struct v4l2_ctrl *ctrl)
999 {
1000 	return container_of(ctrl->handler, struct mxc_isi_video, ctrls.handler);
1001 }
1002 
1003 static int mxc_isi_video_s_ctrl(struct v4l2_ctrl *ctrl)
1004 {
1005 	struct mxc_isi_video *video = ctrl_to_isi_video(ctrl);
1006 
1007 	switch (ctrl->id) {
1008 	case V4L2_CID_ALPHA_COMPONENT:
1009 		video->ctrls.alpha = ctrl->val;
1010 		break;
1011 	case V4L2_CID_VFLIP:
1012 		video->ctrls.vflip = ctrl->val;
1013 		break;
1014 	case V4L2_CID_HFLIP:
1015 		video->ctrls.hflip = ctrl->val;
1016 		break;
1017 	}
1018 
1019 	return 0;
1020 }
1021 
1022 static const struct v4l2_ctrl_ops mxc_isi_video_ctrl_ops = {
1023 	.s_ctrl = mxc_isi_video_s_ctrl,
1024 };
1025 
1026 static int mxc_isi_video_ctrls_create(struct mxc_isi_video *video)
1027 {
1028 	struct v4l2_ctrl_handler *handler = &video->ctrls.handler;
1029 	int ret;
1030 
1031 	v4l2_ctrl_handler_init(handler, 3);
1032 
1033 	v4l2_ctrl_new_std(handler, &mxc_isi_video_ctrl_ops,
1034 			  V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
1035 
1036 	v4l2_ctrl_new_std(handler, &mxc_isi_video_ctrl_ops,
1037 			  V4L2_CID_VFLIP, 0, 1, 1, 0);
1038 
1039 	v4l2_ctrl_new_std(handler, &mxc_isi_video_ctrl_ops,
1040 			  V4L2_CID_HFLIP, 0, 1, 1, 0);
1041 
1042 	if (handler->error) {
1043 		ret = handler->error;
1044 		v4l2_ctrl_handler_free(handler);
1045 		return ret;
1046 	}
1047 
1048 	video->vdev.ctrl_handler = handler;
1049 
1050 	return 0;
1051 }
1052 
1053 static void mxc_isi_video_ctrls_delete(struct mxc_isi_video *video)
1054 {
1055 	v4l2_ctrl_handler_free(&video->ctrls.handler);
1056 }
1057 
1058 /* -----------------------------------------------------------------------------
1059  * V4L2 ioctls
1060  */
1061 
1062 static int mxc_isi_video_querycap(struct file *file, void *priv,
1063 				  struct v4l2_capability *cap)
1064 {
1065 	strscpy(cap->driver, MXC_ISI_DRIVER_NAME, sizeof(cap->driver));
1066 	strscpy(cap->card, MXC_ISI_CAPTURE, sizeof(cap->card));
1067 
1068 	return 0;
1069 }
1070 
1071 static int mxc_isi_video_enum_fmt(struct file *file, void *priv,
1072 				  struct v4l2_fmtdesc *f)
1073 {
1074 	const struct mxc_isi_format_info *fmt;
1075 	unsigned int index = f->index;
1076 	unsigned int i;
1077 
1078 	if (f->mbus_code) {
1079 		/*
1080 		 * If a media bus code is specified, only enumerate formats
1081 		 * compatible with it.
1082 		 */
1083 		for (i = 0; i < ARRAY_SIZE(mxc_isi_formats); i++) {
1084 			fmt = &mxc_isi_formats[i];
1085 			if (fmt->mbus_code != f->mbus_code)
1086 				continue;
1087 
1088 			if (index == 0)
1089 				break;
1090 
1091 			index--;
1092 		}
1093 
1094 		if (i == ARRAY_SIZE(mxc_isi_formats))
1095 			return -EINVAL;
1096 	} else {
1097 		/* Otherwise, enumerate all formatS. */
1098 		if (f->index >= ARRAY_SIZE(mxc_isi_formats))
1099 			return -EINVAL;
1100 
1101 		fmt = &mxc_isi_formats[f->index];
1102 	}
1103 
1104 	f->pixelformat = fmt->fourcc;
1105 	f->flags |= V4L2_FMT_FLAG_CSC_COLORSPACE | V4L2_FMT_FLAG_CSC_YCBCR_ENC
1106 		 |  V4L2_FMT_FLAG_CSC_QUANTIZATION | V4L2_FMT_FLAG_CSC_XFER_FUNC;
1107 
1108 	return 0;
1109 }
1110 
1111 static int mxc_isi_video_g_fmt(struct file *file, void *fh,
1112 			       struct v4l2_format *f)
1113 {
1114 	struct mxc_isi_video *video = video_drvdata(file);
1115 
1116 	f->fmt.pix_mp = video->pix;
1117 
1118 	return 0;
1119 }
1120 
1121 static int mxc_isi_video_try_fmt(struct file *file, void *fh,
1122 				 struct v4l2_format *f)
1123 {
1124 	struct mxc_isi_video *video = video_drvdata(file);
1125 
1126 	mxc_isi_format_try(video->pipe, &f->fmt.pix_mp, MXC_ISI_VIDEO_CAP);
1127 	return 0;
1128 }
1129 
1130 static int mxc_isi_video_s_fmt(struct file *file, void *priv,
1131 			       struct v4l2_format *f)
1132 {
1133 	struct mxc_isi_video *video = video_drvdata(file);
1134 	struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
1135 
1136 	if (vb2_is_busy(&video->vb2_q))
1137 		return -EBUSY;
1138 
1139 	video->fmtinfo = mxc_isi_format_try(video->pipe, pix, MXC_ISI_VIDEO_CAP);
1140 	video->pix = *pix;
1141 
1142 	return 0;
1143 }
1144 
1145 static int mxc_isi_video_streamon(struct file *file, void *priv,
1146 				  enum v4l2_buf_type type)
1147 {
1148 	struct mxc_isi_video *video = video_drvdata(file);
1149 	struct media_device *mdev = &video->pipe->isi->media_dev;
1150 	struct media_pipeline *pipe;
1151 	int ret;
1152 
1153 	if (vb2_queue_is_busy(&video->vb2_q, file))
1154 		return -EBUSY;
1155 
1156 	/*
1157 	 * Get a pipeline for the video node and start it. This must be done
1158 	 * here and not in the queue .start_streaming() handler, so that
1159 	 * pipeline start errors can be reported from VIDIOC_STREAMON and not
1160 	 * delayed until subsequent VIDIOC_QBUF calls.
1161 	 */
1162 	mutex_lock(&mdev->graph_mutex);
1163 
1164 	ret = mxc_isi_pipe_acquire(video->pipe, &mxc_isi_video_frame_write_done);
1165 	if (ret) {
1166 		mutex_unlock(&mdev->graph_mutex);
1167 		return ret;
1168 	}
1169 
1170 	pipe = media_entity_pipeline(&video->vdev.entity) ? : &video->pipe->pipe;
1171 
1172 	ret = __video_device_pipeline_start(&video->vdev, pipe);
1173 	if (ret) {
1174 		mutex_unlock(&mdev->graph_mutex);
1175 		goto err_release;
1176 	}
1177 
1178 	mutex_unlock(&mdev->graph_mutex);
1179 
1180 	/* Verify that the video format matches the output of the subdev. */
1181 	ret = mxc_isi_video_validate_format(video);
1182 	if (ret)
1183 		goto err_stop;
1184 
1185 	/* Allocate buffers for discard operation. */
1186 	ret = mxc_isi_video_alloc_discard_buffers(video);
1187 	if (ret)
1188 		goto err_stop;
1189 
1190 	ret = vb2_streamon(&video->vb2_q, type);
1191 	if (ret)
1192 		goto err_free;
1193 
1194 	video->is_streaming = true;
1195 
1196 	return 0;
1197 
1198 err_free:
1199 	mxc_isi_video_free_discard_buffers(video);
1200 err_stop:
1201 	video_device_pipeline_stop(&video->vdev);
1202 err_release:
1203 	mxc_isi_pipe_release(video->pipe);
1204 	return ret;
1205 }
1206 
1207 static void mxc_isi_video_cleanup_streaming(struct mxc_isi_video *video)
1208 {
1209 	lockdep_assert_held(&video->lock);
1210 
1211 	if (!video->is_streaming)
1212 		return;
1213 
1214 	mxc_isi_video_free_discard_buffers(video);
1215 	video_device_pipeline_stop(&video->vdev);
1216 	mxc_isi_pipe_release(video->pipe);
1217 
1218 	video->is_streaming = false;
1219 }
1220 
1221 static int mxc_isi_video_streamoff(struct file *file, void *priv,
1222 				   enum v4l2_buf_type type)
1223 {
1224 	struct mxc_isi_video *video = video_drvdata(file);
1225 	int ret;
1226 
1227 	ret = vb2_ioctl_streamoff(file, priv, type);
1228 	if (ret)
1229 		return ret;
1230 
1231 	mxc_isi_video_cleanup_streaming(video);
1232 
1233 	return 0;
1234 }
1235 
1236 static int mxc_isi_video_enum_framesizes(struct file *file, void *priv,
1237 					 struct v4l2_frmsizeenum *fsize)
1238 {
1239 	struct mxc_isi_video *video = video_drvdata(file);
1240 	const struct mxc_isi_format_info *info;
1241 	unsigned int max_width;
1242 	unsigned int h_align;
1243 	unsigned int v_align;
1244 
1245 	if (fsize->index)
1246 		return -EINVAL;
1247 
1248 	info = mxc_isi_format_by_fourcc(fsize->pixel_format, MXC_ISI_VIDEO_CAP);
1249 	if (!info)
1250 		return -EINVAL;
1251 
1252 	h_align = max_t(unsigned int, info->hsub, 1);
1253 	v_align = max_t(unsigned int, info->vsub, 1);
1254 
1255 	max_width = video->pipe->id == video->pipe->isi->pdata->num_channels - 1
1256 		  ? MXC_ISI_MAX_WIDTH_UNCHAINED
1257 		  : MXC_ISI_MAX_WIDTH_CHAINED;
1258 
1259 	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
1260 	fsize->stepwise.min_width = ALIGN(MXC_ISI_MIN_WIDTH, h_align);
1261 	fsize->stepwise.min_height = ALIGN(MXC_ISI_MIN_HEIGHT, v_align);
1262 	fsize->stepwise.max_width = ALIGN_DOWN(max_width, h_align);
1263 	fsize->stepwise.max_height = ALIGN_DOWN(MXC_ISI_MAX_HEIGHT, v_align);
1264 	fsize->stepwise.step_width = h_align;
1265 	fsize->stepwise.step_height = v_align;
1266 
1267 	/*
1268 	 * The width can be further restricted due to line buffer sharing
1269 	 * between pipelines when scaling, but we have no way to know here if
1270 	 * the scaler will be used.
1271 	 */
1272 
1273 	return 0;
1274 }
1275 
1276 static const struct v4l2_ioctl_ops mxc_isi_video_ioctl_ops = {
1277 	.vidioc_querycap		= mxc_isi_video_querycap,
1278 
1279 	.vidioc_enum_fmt_vid_cap	= mxc_isi_video_enum_fmt,
1280 	.vidioc_try_fmt_vid_cap_mplane	= mxc_isi_video_try_fmt,
1281 	.vidioc_s_fmt_vid_cap_mplane	= mxc_isi_video_s_fmt,
1282 	.vidioc_g_fmt_vid_cap_mplane	= mxc_isi_video_g_fmt,
1283 
1284 	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
1285 	.vidioc_querybuf		= vb2_ioctl_querybuf,
1286 	.vidioc_qbuf			= vb2_ioctl_qbuf,
1287 	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
1288 	.vidioc_expbuf			= vb2_ioctl_expbuf,
1289 	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
1290 	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
1291 
1292 	.vidioc_streamon		= mxc_isi_video_streamon,
1293 	.vidioc_streamoff		= mxc_isi_video_streamoff,
1294 
1295 	.vidioc_enum_framesizes		= mxc_isi_video_enum_framesizes,
1296 
1297 	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
1298 	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
1299 };
1300 
1301 /* -----------------------------------------------------------------------------
1302  * Video device file operations
1303  */
1304 
1305 static int mxc_isi_video_open(struct file *file)
1306 {
1307 	struct mxc_isi_video *video = video_drvdata(file);
1308 	int ret;
1309 
1310 	ret = v4l2_fh_open(file);
1311 	if (ret)
1312 		return ret;
1313 
1314 	ret = pm_runtime_resume_and_get(video->pipe->isi->dev);
1315 	if (ret) {
1316 		v4l2_fh_release(file);
1317 		return ret;
1318 	}
1319 
1320 	return 0;
1321 }
1322 
1323 static int mxc_isi_video_release(struct file *file)
1324 {
1325 	struct mxc_isi_video *video = video_drvdata(file);
1326 	int ret;
1327 
1328 	ret = vb2_fop_release(file);
1329 	if (ret)
1330 		dev_err(video->pipe->isi->dev, "%s fail\n", __func__);
1331 
1332 	mutex_lock(&video->lock);
1333 	mxc_isi_video_cleanup_streaming(video);
1334 	mutex_unlock(&video->lock);
1335 
1336 	pm_runtime_put(video->pipe->isi->dev);
1337 	return ret;
1338 }
1339 
1340 static const struct v4l2_file_operations mxc_isi_video_fops = {
1341 	.owner		= THIS_MODULE,
1342 	.open		= mxc_isi_video_open,
1343 	.release	= mxc_isi_video_release,
1344 	.poll		= vb2_fop_poll,
1345 	.unlocked_ioctl	= video_ioctl2,
1346 	.mmap		= vb2_fop_mmap,
1347 };
1348 
1349 /* -----------------------------------------------------------------------------
1350  * Suspend & resume
1351  */
1352 
1353 void mxc_isi_video_suspend(struct mxc_isi_pipe *pipe)
1354 {
1355 	struct mxc_isi_video *video = &pipe->video;
1356 
1357 	if (!video->is_streaming)
1358 		return;
1359 
1360 	mxc_isi_pipe_disable(pipe);
1361 	mxc_isi_channel_put(pipe);
1362 
1363 	spin_lock_irq(&video->buf_lock);
1364 
1365 	/*
1366 	 * Move the active buffers back to the pending or discard list. We must
1367 	 * iterate the active list backward and move the buffers to the head of
1368 	 * the pending list to preserve the buffer queueing order.
1369 	 */
1370 	while (!list_empty(&video->out_active)) {
1371 		struct mxc_isi_buffer *buf =
1372 			list_last_entry(&video->out_active,
1373 					struct mxc_isi_buffer, list);
1374 
1375 		if (buf->discard)
1376 			list_move(&buf->list, &video->out_discard);
1377 		else
1378 			list_move(&buf->list, &video->out_pending);
1379 	}
1380 
1381 	spin_unlock_irq(&video->buf_lock);
1382 }
1383 
1384 int mxc_isi_video_resume(struct mxc_isi_pipe *pipe)
1385 {
1386 	struct mxc_isi_video *video = &pipe->video;
1387 
1388 	if (!video->is_streaming)
1389 		return 0;
1390 
1391 	mxc_isi_video_init_channel(video);
1392 
1393 	spin_lock_irq(&video->buf_lock);
1394 	mxc_isi_video_queue_first_buffers(video);
1395 	spin_unlock_irq(&video->buf_lock);
1396 
1397 	return mxc_isi_pipe_enable(pipe);
1398 }
1399 
1400 /* -----------------------------------------------------------------------------
1401  * Registration
1402  */
1403 
1404 int mxc_isi_video_register(struct mxc_isi_pipe *pipe,
1405 			   struct v4l2_device *v4l2_dev)
1406 {
1407 	struct mxc_isi_video *video = &pipe->video;
1408 	struct v4l2_pix_format_mplane *pix = &video->pix;
1409 	struct video_device *vdev = &video->vdev;
1410 	struct vb2_queue *q = &video->vb2_q;
1411 	int ret = -ENOMEM;
1412 
1413 	video->pipe = pipe;
1414 
1415 	mutex_init(&video->lock);
1416 	spin_lock_init(&video->buf_lock);
1417 
1418 	pix->width = MXC_ISI_DEF_WIDTH;
1419 	pix->height = MXC_ISI_DEF_HEIGHT;
1420 	pix->pixelformat = MXC_ISI_DEF_PIXEL_FORMAT;
1421 	pix->colorspace = MXC_ISI_DEF_COLOR_SPACE;
1422 	pix->ycbcr_enc = MXC_ISI_DEF_YCBCR_ENC;
1423 	pix->quantization = MXC_ISI_DEF_QUANTIZATION;
1424 	pix->xfer_func = MXC_ISI_DEF_XFER_FUNC;
1425 	video->fmtinfo = mxc_isi_format_try(video->pipe, pix, MXC_ISI_VIDEO_CAP);
1426 
1427 	memset(vdev, 0, sizeof(*vdev));
1428 	snprintf(vdev->name, sizeof(vdev->name), "mxc_isi.%d.capture", pipe->id);
1429 
1430 	vdev->fops	= &mxc_isi_video_fops;
1431 	vdev->ioctl_ops	= &mxc_isi_video_ioctl_ops;
1432 	vdev->v4l2_dev	= v4l2_dev;
1433 	vdev->minor	= -1;
1434 	vdev->release	= video_device_release_empty;
1435 	vdev->queue	= q;
1436 	vdev->lock	= &video->lock;
1437 
1438 	vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE
1439 			  | V4L2_CAP_IO_MC;
1440 	video_set_drvdata(vdev, video);
1441 
1442 	INIT_LIST_HEAD(&video->out_pending);
1443 	INIT_LIST_HEAD(&video->out_active);
1444 	INIT_LIST_HEAD(&video->out_discard);
1445 
1446 	memset(q, 0, sizeof(*q));
1447 	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1448 	q->io_modes = VB2_MMAP | VB2_DMABUF;
1449 	q->drv_priv = video;
1450 	q->ops = &mxc_isi_vb2_qops;
1451 	q->mem_ops = &vb2_dma_contig_memops;
1452 	q->buf_struct_size = sizeof(struct mxc_isi_buffer);
1453 	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1454 	q->min_queued_buffers = 2;
1455 	q->lock = &video->lock;
1456 	q->dev = pipe->isi->dev;
1457 
1458 	ret = vb2_queue_init(q);
1459 	if (ret)
1460 		goto err_free_ctx;
1461 
1462 	video->pad.flags = MEDIA_PAD_FL_SINK;
1463 	vdev->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
1464 	ret = media_entity_pads_init(&vdev->entity, 1, &video->pad);
1465 	if (ret)
1466 		goto err_free_ctx;
1467 
1468 	ret = mxc_isi_video_ctrls_create(video);
1469 	if (ret)
1470 		goto err_me_cleanup;
1471 
1472 	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1473 	if (ret)
1474 		goto err_ctrl_free;
1475 
1476 	ret = media_create_pad_link(&pipe->sd.entity,
1477 				    MXC_ISI_PIPE_PAD_SOURCE,
1478 				    &vdev->entity, 0,
1479 				    MEDIA_LNK_FL_IMMUTABLE |
1480 				    MEDIA_LNK_FL_ENABLED);
1481 	if (ret)
1482 		goto err_video_unreg;
1483 
1484 	return 0;
1485 
1486 err_video_unreg:
1487 	video_unregister_device(vdev);
1488 err_ctrl_free:
1489 	mxc_isi_video_ctrls_delete(video);
1490 err_me_cleanup:
1491 	media_entity_cleanup(&vdev->entity);
1492 err_free_ctx:
1493 	return ret;
1494 }
1495 
1496 void mxc_isi_video_unregister(struct mxc_isi_pipe *pipe)
1497 {
1498 	struct mxc_isi_video *video = &pipe->video;
1499 	struct video_device *vdev = &video->vdev;
1500 
1501 	mutex_lock(&video->lock);
1502 
1503 	if (video_is_registered(vdev)) {
1504 		video_unregister_device(vdev);
1505 		mxc_isi_video_ctrls_delete(video);
1506 		media_entity_cleanup(&vdev->entity);
1507 	}
1508 
1509 	mutex_unlock(&video->lock);
1510 }
1511