1 /*
2  * V4L2 Capture IC Preprocess Subdev for Freescale i.MX5/6 SOC
3  *
4  * This subdevice handles capture of video frames from the CSI or VDIC,
5  * which are routed directly to the Image Converter preprocess tasks,
6  * for resizing, colorspace conversion, and rotation.
7  *
8  * Copyright (c) 2012-2017 Mentor Graphics Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  */
15 #include <linux/delay.h>
16 #include <linux/interrupt.h>
17 #include <linux/module.h>
18 #include <linux/sched.h>
19 #include <linux/slab.h>
20 #include <linux/spinlock.h>
21 #include <linux/timer.h>
22 #include <media/v4l2-ctrls.h>
23 #include <media/v4l2-device.h>
24 #include <media/v4l2-ioctl.h>
25 #include <media/v4l2-mc.h>
26 #include <media/v4l2-subdev.h>
27 #include <media/imx.h>
28 #include "imx-media.h"
29 #include "imx-ic.h"
30 
31 /*
32  * Min/Max supported width and heights.
33  *
34  * We allow planar output, so we have to align width at the source pad
35  * by 16 pixels to meet IDMAC alignment requirements for possible planar
36  * output.
37  *
38  * TODO: move this into pad format negotiation, if capture device
39  * has not requested a planar format, we should allow 8 pixel
40  * alignment at the source pad.
41  */
42 #define MIN_W_SINK  176
43 #define MIN_H_SINK  144
44 #define MAX_W_SINK 4096
45 #define MAX_H_SINK 4096
46 #define W_ALIGN_SINK  3 /* multiple of 8 pixels */
47 #define H_ALIGN_SINK  1 /* multiple of 2 lines */
48 
49 #define MAX_W_SRC  1024
50 #define MAX_H_SRC  1024
51 #define W_ALIGN_SRC   4 /* multiple of 16 pixels */
52 #define H_ALIGN_SRC   1 /* multiple of 2 lines */
53 
54 #define S_ALIGN       1 /* multiple of 2 */
55 
56 struct prp_priv {
57 	struct imx_media_dev *md;
58 	struct imx_ic_priv *ic_priv;
59 	struct media_pad pad[PRPENCVF_NUM_PADS];
60 	/* the video device at output pad */
61 	struct imx_media_video_dev *vdev;
62 
63 	/* lock to protect all members below */
64 	struct mutex lock;
65 
66 	/* IPU units we require */
67 	struct ipu_soc *ipu;
68 	struct ipu_ic *ic;
69 	struct ipuv3_channel *out_ch;
70 	struct ipuv3_channel *rot_in_ch;
71 	struct ipuv3_channel *rot_out_ch;
72 
73 	/* active vb2 buffers to send to video dev sink */
74 	struct imx_media_buffer *active_vb2_buf[2];
75 	struct imx_media_dma_buf underrun_buf;
76 
77 	int ipu_buf_num;  /* ipu double buffer index: 0-1 */
78 
79 	/* the sink for the captured frames */
80 	struct media_entity *sink;
81 	/* the source subdev */
82 	struct v4l2_subdev *src_sd;
83 
84 	struct v4l2_mbus_framefmt format_mbus[PRPENCVF_NUM_PADS];
85 	const struct imx_media_pixfmt *cc[PRPENCVF_NUM_PADS];
86 	struct v4l2_fract frame_interval;
87 
88 	struct imx_media_dma_buf rot_buf[2];
89 
90 	/* controls */
91 	struct v4l2_ctrl_handler ctrl_hdlr;
92 	int  rotation; /* degrees */
93 	bool hflip;
94 	bool vflip;
95 
96 	/* derived from rotation, hflip, vflip controls */
97 	enum ipu_rotate_mode rot_mode;
98 
99 	spinlock_t irqlock; /* protect eof_irq handler */
100 
101 	struct timer_list eof_timeout_timer;
102 	int eof_irq;
103 	int nfb4eof_irq;
104 
105 	int stream_count;
106 	u32 frame_sequence; /* frame sequence counter */
107 	bool last_eof;  /* waiting for last EOF at stream off */
108 	bool nfb4eof;    /* NFB4EOF encountered during streaming */
109 	struct completion last_eof_comp;
110 };
111 
112 static const struct prp_channels {
113 	u32 out_ch;
114 	u32 rot_in_ch;
115 	u32 rot_out_ch;
116 } prp_channel[] = {
117 	[IC_TASK_ENCODER] = {
118 		.out_ch = IPUV3_CHANNEL_IC_PRP_ENC_MEM,
119 		.rot_in_ch = IPUV3_CHANNEL_MEM_ROT_ENC,
120 		.rot_out_ch = IPUV3_CHANNEL_ROT_ENC_MEM,
121 	},
122 	[IC_TASK_VIEWFINDER] = {
123 		.out_ch = IPUV3_CHANNEL_IC_PRP_VF_MEM,
124 		.rot_in_ch = IPUV3_CHANNEL_MEM_ROT_VF,
125 		.rot_out_ch = IPUV3_CHANNEL_ROT_VF_MEM,
126 	},
127 };
128 
129 static inline struct prp_priv *sd_to_priv(struct v4l2_subdev *sd)
130 {
131 	struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd);
132 
133 	return ic_priv->task_priv;
134 }
135 
136 static void prp_put_ipu_resources(struct prp_priv *priv)
137 {
138 	if (priv->ic)
139 		ipu_ic_put(priv->ic);
140 	priv->ic = NULL;
141 
142 	if (priv->out_ch)
143 		ipu_idmac_put(priv->out_ch);
144 	priv->out_ch = NULL;
145 
146 	if (priv->rot_in_ch)
147 		ipu_idmac_put(priv->rot_in_ch);
148 	priv->rot_in_ch = NULL;
149 
150 	if (priv->rot_out_ch)
151 		ipu_idmac_put(priv->rot_out_ch);
152 	priv->rot_out_ch = NULL;
153 }
154 
155 static int prp_get_ipu_resources(struct prp_priv *priv)
156 {
157 	struct imx_ic_priv *ic_priv = priv->ic_priv;
158 	struct ipu_ic *ic;
159 	struct ipuv3_channel *out_ch, *rot_in_ch, *rot_out_ch;
160 	int ret, task = ic_priv->task_id;
161 
162 	priv->ipu = priv->md->ipu[ic_priv->ipu_id];
163 
164 	ic = ipu_ic_get(priv->ipu, task);
165 	if (IS_ERR(ic)) {
166 		v4l2_err(&ic_priv->sd, "failed to get IC\n");
167 		ret = PTR_ERR(ic);
168 		goto out;
169 	}
170 	priv->ic = ic;
171 
172 	out_ch = ipu_idmac_get(priv->ipu, prp_channel[task].out_ch);
173 	if (IS_ERR(out_ch)) {
174 		v4l2_err(&ic_priv->sd, "could not get IDMAC channel %u\n",
175 			 prp_channel[task].out_ch);
176 		ret = PTR_ERR(out_ch);
177 		goto out;
178 	}
179 	priv->out_ch = out_ch;
180 
181 	rot_in_ch = ipu_idmac_get(priv->ipu, prp_channel[task].rot_in_ch);
182 	if (IS_ERR(rot_in_ch)) {
183 		v4l2_err(&ic_priv->sd, "could not get IDMAC channel %u\n",
184 			 prp_channel[task].rot_in_ch);
185 		ret = PTR_ERR(rot_in_ch);
186 		goto out;
187 	}
188 	priv->rot_in_ch = rot_in_ch;
189 
190 	rot_out_ch = ipu_idmac_get(priv->ipu, prp_channel[task].rot_out_ch);
191 	if (IS_ERR(rot_out_ch)) {
192 		v4l2_err(&ic_priv->sd, "could not get IDMAC channel %u\n",
193 			 prp_channel[task].rot_out_ch);
194 		ret = PTR_ERR(rot_out_ch);
195 		goto out;
196 	}
197 	priv->rot_out_ch = rot_out_ch;
198 
199 	return 0;
200 out:
201 	prp_put_ipu_resources(priv);
202 	return ret;
203 }
204 
205 static void prp_vb2_buf_done(struct prp_priv *priv, struct ipuv3_channel *ch)
206 {
207 	struct imx_media_video_dev *vdev = priv->vdev;
208 	struct imx_media_buffer *done, *next;
209 	struct vb2_buffer *vb;
210 	dma_addr_t phys;
211 
212 	done = priv->active_vb2_buf[priv->ipu_buf_num];
213 	if (done) {
214 		done->vbuf.field = vdev->fmt.fmt.pix.field;
215 		done->vbuf.sequence = priv->frame_sequence;
216 		vb = &done->vbuf.vb2_buf;
217 		vb->timestamp = ktime_get_ns();
218 		vb2_buffer_done(vb, priv->nfb4eof ?
219 				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
220 	}
221 
222 	priv->frame_sequence++;
223 	priv->nfb4eof = false;
224 
225 	/* get next queued buffer */
226 	next = imx_media_capture_device_next_buf(vdev);
227 	if (next) {
228 		phys = vb2_dma_contig_plane_dma_addr(&next->vbuf.vb2_buf, 0);
229 		priv->active_vb2_buf[priv->ipu_buf_num] = next;
230 	} else {
231 		phys = priv->underrun_buf.phys;
232 		priv->active_vb2_buf[priv->ipu_buf_num] = NULL;
233 	}
234 
235 	if (ipu_idmac_buffer_is_ready(ch, priv->ipu_buf_num))
236 		ipu_idmac_clear_buffer(ch, priv->ipu_buf_num);
237 
238 	ipu_cpmem_set_buffer(ch, priv->ipu_buf_num, phys);
239 }
240 
241 static irqreturn_t prp_eof_interrupt(int irq, void *dev_id)
242 {
243 	struct prp_priv *priv = dev_id;
244 	struct ipuv3_channel *channel;
245 
246 	spin_lock(&priv->irqlock);
247 
248 	if (priv->last_eof) {
249 		complete(&priv->last_eof_comp);
250 		priv->last_eof = false;
251 		goto unlock;
252 	}
253 
254 	channel = (ipu_rot_mode_is_irt(priv->rot_mode)) ?
255 		priv->rot_out_ch : priv->out_ch;
256 
257 	prp_vb2_buf_done(priv, channel);
258 
259 	/* select new IPU buf */
260 	ipu_idmac_select_buffer(channel, priv->ipu_buf_num);
261 	/* toggle IPU double-buffer index */
262 	priv->ipu_buf_num ^= 1;
263 
264 	/* bump the EOF timeout timer */
265 	mod_timer(&priv->eof_timeout_timer,
266 		  jiffies + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT));
267 
268 unlock:
269 	spin_unlock(&priv->irqlock);
270 	return IRQ_HANDLED;
271 }
272 
273 static irqreturn_t prp_nfb4eof_interrupt(int irq, void *dev_id)
274 {
275 	struct prp_priv *priv = dev_id;
276 	struct imx_ic_priv *ic_priv = priv->ic_priv;
277 
278 	spin_lock(&priv->irqlock);
279 
280 	/*
281 	 * this is not an unrecoverable error, just mark
282 	 * the next captured frame with vb2 error flag.
283 	 */
284 	priv->nfb4eof = true;
285 
286 	v4l2_err(&ic_priv->sd, "NFB4EOF\n");
287 
288 	spin_unlock(&priv->irqlock);
289 
290 	return IRQ_HANDLED;
291 }
292 
293 /*
294  * EOF timeout timer function.
295  */
296 /*
297  * EOF timeout timer function. This is an unrecoverable condition
298  * without a stream restart.
299  */
300 static void prp_eof_timeout(struct timer_list *t)
301 {
302 	struct prp_priv *priv = from_timer(priv, t, eof_timeout_timer);
303 	struct imx_media_video_dev *vdev = priv->vdev;
304 	struct imx_ic_priv *ic_priv = priv->ic_priv;
305 
306 	v4l2_err(&ic_priv->sd, "EOF timeout\n");
307 
308 	/* signal a fatal error to capture device */
309 	imx_media_capture_device_error(vdev);
310 }
311 
312 static void prp_setup_vb2_buf(struct prp_priv *priv, dma_addr_t *phys)
313 {
314 	struct imx_media_video_dev *vdev = priv->vdev;
315 	struct imx_media_buffer *buf;
316 	int i;
317 
318 	for (i = 0; i < 2; i++) {
319 		buf = imx_media_capture_device_next_buf(vdev);
320 		if (buf) {
321 			priv->active_vb2_buf[i] = buf;
322 			phys[i] = vb2_dma_contig_plane_dma_addr(
323 				&buf->vbuf.vb2_buf, 0);
324 		} else {
325 			priv->active_vb2_buf[i] = NULL;
326 			phys[i] = priv->underrun_buf.phys;
327 		}
328 	}
329 }
330 
331 static void prp_unsetup_vb2_buf(struct prp_priv *priv,
332 				enum vb2_buffer_state return_status)
333 {
334 	struct imx_media_buffer *buf;
335 	int i;
336 
337 	/* return any remaining active frames with return_status */
338 	for (i = 0; i < 2; i++) {
339 		buf = priv->active_vb2_buf[i];
340 		if (buf) {
341 			struct vb2_buffer *vb = &buf->vbuf.vb2_buf;
342 
343 			vb->timestamp = ktime_get_ns();
344 			vb2_buffer_done(vb, return_status);
345 		}
346 	}
347 }
348 
349 static int prp_setup_channel(struct prp_priv *priv,
350 			     struct ipuv3_channel *channel,
351 			     enum ipu_rotate_mode rot_mode,
352 			     dma_addr_t addr0, dma_addr_t addr1,
353 			     bool rot_swap_width_height)
354 {
355 	struct imx_media_video_dev *vdev = priv->vdev;
356 	const struct imx_media_pixfmt *outcc;
357 	struct v4l2_mbus_framefmt *infmt;
358 	unsigned int burst_size;
359 	struct ipu_image image;
360 	int ret;
361 
362 	infmt = &priv->format_mbus[PRPENCVF_SINK_PAD];
363 	outcc = vdev->cc;
364 
365 	ipu_cpmem_zero(channel);
366 
367 	memset(&image, 0, sizeof(image));
368 	image.pix = vdev->fmt.fmt.pix;
369 	image.rect.width = image.pix.width;
370 	image.rect.height = image.pix.height;
371 
372 	if (rot_swap_width_height) {
373 		swap(image.pix.width, image.pix.height);
374 		swap(image.rect.width, image.rect.height);
375 		/* recalc stride using swapped width */
376 		image.pix.bytesperline = outcc->planar ?
377 			image.pix.width :
378 			(image.pix.width * outcc->bpp) >> 3;
379 	}
380 
381 	image.phys0 = addr0;
382 	image.phys1 = addr1;
383 
384 	if (channel == priv->out_ch || channel == priv->rot_out_ch) {
385 		switch (image.pix.pixelformat) {
386 		case V4L2_PIX_FMT_YUV420:
387 		case V4L2_PIX_FMT_YVU420:
388 		case V4L2_PIX_FMT_NV12:
389 			/* Skip writing U and V components to odd rows */
390 			ipu_cpmem_skip_odd_chroma_rows(channel);
391 			break;
392 		}
393 	}
394 
395 	ret = ipu_cpmem_set_image(channel, &image);
396 	if (ret)
397 		return ret;
398 
399 	if (channel == priv->rot_in_ch ||
400 	    channel == priv->rot_out_ch) {
401 		burst_size = 8;
402 		ipu_cpmem_set_block_mode(channel);
403 	} else {
404 		burst_size = (image.pix.width & 0xf) ? 8 : 16;
405 	}
406 
407 	ipu_cpmem_set_burstsize(channel, burst_size);
408 
409 	if (rot_mode)
410 		ipu_cpmem_set_rotation(channel, rot_mode);
411 
412 	if (image.pix.field == V4L2_FIELD_NONE &&
413 	    V4L2_FIELD_HAS_BOTH(infmt->field) &&
414 	    channel == priv->out_ch)
415 		ipu_cpmem_interlaced_scan(channel, image.pix.bytesperline);
416 
417 	ret = ipu_ic_task_idma_init(priv->ic, channel,
418 				    image.pix.width, image.pix.height,
419 				    burst_size, rot_mode);
420 	if (ret)
421 		return ret;
422 
423 	ipu_cpmem_set_axi_id(channel, 1);
424 
425 	ipu_idmac_set_double_buffer(channel, true);
426 
427 	return 0;
428 }
429 
430 static int prp_setup_rotation(struct prp_priv *priv)
431 {
432 	struct imx_media_video_dev *vdev = priv->vdev;
433 	struct imx_ic_priv *ic_priv = priv->ic_priv;
434 	const struct imx_media_pixfmt *outcc, *incc;
435 	struct v4l2_mbus_framefmt *infmt;
436 	struct v4l2_pix_format *outfmt;
437 	dma_addr_t phys[2];
438 	int ret;
439 
440 	infmt = &priv->format_mbus[PRPENCVF_SINK_PAD];
441 	outfmt = &vdev->fmt.fmt.pix;
442 	incc = priv->cc[PRPENCVF_SINK_PAD];
443 	outcc = vdev->cc;
444 
445 	ret = imx_media_alloc_dma_buf(priv->md, &priv->rot_buf[0],
446 				      outfmt->sizeimage);
447 	if (ret) {
448 		v4l2_err(&ic_priv->sd, "failed to alloc rot_buf[0], %d\n", ret);
449 		return ret;
450 	}
451 	ret = imx_media_alloc_dma_buf(priv->md, &priv->rot_buf[1],
452 				      outfmt->sizeimage);
453 	if (ret) {
454 		v4l2_err(&ic_priv->sd, "failed to alloc rot_buf[1], %d\n", ret);
455 		goto free_rot0;
456 	}
457 
458 	ret = ipu_ic_task_init(priv->ic,
459 			       infmt->width, infmt->height,
460 			       outfmt->height, outfmt->width,
461 			       incc->cs, outcc->cs);
462 	if (ret) {
463 		v4l2_err(&ic_priv->sd, "ipu_ic_task_init failed, %d\n", ret);
464 		goto free_rot1;
465 	}
466 
467 	/* init the IC-PRP-->MEM IDMAC channel */
468 	ret = prp_setup_channel(priv, priv->out_ch, IPU_ROTATE_NONE,
469 				priv->rot_buf[0].phys, priv->rot_buf[1].phys,
470 				true);
471 	if (ret) {
472 		v4l2_err(&ic_priv->sd,
473 			 "prp_setup_channel(out_ch) failed, %d\n", ret);
474 		goto free_rot1;
475 	}
476 
477 	/* init the MEM-->IC-PRP ROT IDMAC channel */
478 	ret = prp_setup_channel(priv, priv->rot_in_ch, priv->rot_mode,
479 				priv->rot_buf[0].phys, priv->rot_buf[1].phys,
480 				true);
481 	if (ret) {
482 		v4l2_err(&ic_priv->sd,
483 			 "prp_setup_channel(rot_in_ch) failed, %d\n", ret);
484 		goto free_rot1;
485 	}
486 
487 	prp_setup_vb2_buf(priv, phys);
488 
489 	/* init the destination IC-PRP ROT-->MEM IDMAC channel */
490 	ret = prp_setup_channel(priv, priv->rot_out_ch, IPU_ROTATE_NONE,
491 				phys[0], phys[1],
492 				false);
493 	if (ret) {
494 		v4l2_err(&ic_priv->sd,
495 			 "prp_setup_channel(rot_out_ch) failed, %d\n", ret);
496 		goto unsetup_vb2;
497 	}
498 
499 	/* now link IC-PRP-->MEM to MEM-->IC-PRP ROT */
500 	ipu_idmac_link(priv->out_ch, priv->rot_in_ch);
501 
502 	/* enable the IC */
503 	ipu_ic_enable(priv->ic);
504 
505 	/* set buffers ready */
506 	ipu_idmac_select_buffer(priv->out_ch, 0);
507 	ipu_idmac_select_buffer(priv->out_ch, 1);
508 	ipu_idmac_select_buffer(priv->rot_out_ch, 0);
509 	ipu_idmac_select_buffer(priv->rot_out_ch, 1);
510 
511 	/* enable the channels */
512 	ipu_idmac_enable_channel(priv->out_ch);
513 	ipu_idmac_enable_channel(priv->rot_in_ch);
514 	ipu_idmac_enable_channel(priv->rot_out_ch);
515 
516 	/* and finally enable the IC PRP task */
517 	ipu_ic_task_enable(priv->ic);
518 
519 	return 0;
520 
521 unsetup_vb2:
522 	prp_unsetup_vb2_buf(priv, VB2_BUF_STATE_QUEUED);
523 free_rot1:
524 	imx_media_free_dma_buf(priv->md, &priv->rot_buf[1]);
525 free_rot0:
526 	imx_media_free_dma_buf(priv->md, &priv->rot_buf[0]);
527 	return ret;
528 }
529 
530 static void prp_unsetup_rotation(struct prp_priv *priv)
531 {
532 	ipu_ic_task_disable(priv->ic);
533 
534 	ipu_idmac_disable_channel(priv->out_ch);
535 	ipu_idmac_disable_channel(priv->rot_in_ch);
536 	ipu_idmac_disable_channel(priv->rot_out_ch);
537 
538 	ipu_idmac_unlink(priv->out_ch, priv->rot_in_ch);
539 
540 	ipu_ic_disable(priv->ic);
541 
542 	imx_media_free_dma_buf(priv->md, &priv->rot_buf[0]);
543 	imx_media_free_dma_buf(priv->md, &priv->rot_buf[1]);
544 }
545 
546 static int prp_setup_norotation(struct prp_priv *priv)
547 {
548 	struct imx_media_video_dev *vdev = priv->vdev;
549 	struct imx_ic_priv *ic_priv = priv->ic_priv;
550 	const struct imx_media_pixfmt *outcc, *incc;
551 	struct v4l2_mbus_framefmt *infmt;
552 	struct v4l2_pix_format *outfmt;
553 	dma_addr_t phys[2];
554 	int ret;
555 
556 	infmt = &priv->format_mbus[PRPENCVF_SINK_PAD];
557 	outfmt = &vdev->fmt.fmt.pix;
558 	incc = priv->cc[PRPENCVF_SINK_PAD];
559 	outcc = vdev->cc;
560 
561 	ret = ipu_ic_task_init(priv->ic,
562 			       infmt->width, infmt->height,
563 			       outfmt->width, outfmt->height,
564 			       incc->cs, outcc->cs);
565 	if (ret) {
566 		v4l2_err(&ic_priv->sd, "ipu_ic_task_init failed, %d\n", ret);
567 		return ret;
568 	}
569 
570 	prp_setup_vb2_buf(priv, phys);
571 
572 	/* init the IC PRP-->MEM IDMAC channel */
573 	ret = prp_setup_channel(priv, priv->out_ch, priv->rot_mode,
574 				phys[0], phys[1], false);
575 	if (ret) {
576 		v4l2_err(&ic_priv->sd,
577 			 "prp_setup_channel(out_ch) failed, %d\n", ret);
578 		goto unsetup_vb2;
579 	}
580 
581 	ipu_cpmem_dump(priv->out_ch);
582 	ipu_ic_dump(priv->ic);
583 	ipu_dump(priv->ipu);
584 
585 	ipu_ic_enable(priv->ic);
586 
587 	/* set buffers ready */
588 	ipu_idmac_select_buffer(priv->out_ch, 0);
589 	ipu_idmac_select_buffer(priv->out_ch, 1);
590 
591 	/* enable the channels */
592 	ipu_idmac_enable_channel(priv->out_ch);
593 
594 	/* enable the IC task */
595 	ipu_ic_task_enable(priv->ic);
596 
597 	return 0;
598 
599 unsetup_vb2:
600 	prp_unsetup_vb2_buf(priv, VB2_BUF_STATE_QUEUED);
601 	return ret;
602 }
603 
604 static void prp_unsetup_norotation(struct prp_priv *priv)
605 {
606 	ipu_ic_task_disable(priv->ic);
607 	ipu_idmac_disable_channel(priv->out_ch);
608 	ipu_ic_disable(priv->ic);
609 }
610 
611 static void prp_unsetup(struct prp_priv *priv,
612 			enum vb2_buffer_state state)
613 {
614 	if (ipu_rot_mode_is_irt(priv->rot_mode))
615 		prp_unsetup_rotation(priv);
616 	else
617 		prp_unsetup_norotation(priv);
618 
619 	prp_unsetup_vb2_buf(priv, state);
620 }
621 
622 static int prp_start(struct prp_priv *priv)
623 {
624 	struct imx_ic_priv *ic_priv = priv->ic_priv;
625 	struct imx_media_video_dev *vdev = priv->vdev;
626 	struct v4l2_pix_format *outfmt;
627 	int ret;
628 
629 	ret = prp_get_ipu_resources(priv);
630 	if (ret)
631 		return ret;
632 
633 	outfmt = &vdev->fmt.fmt.pix;
634 
635 	ret = imx_media_alloc_dma_buf(priv->md, &priv->underrun_buf,
636 				      outfmt->sizeimage);
637 	if (ret)
638 		goto out_put_ipu;
639 
640 	priv->ipu_buf_num = 0;
641 
642 	/* init EOF completion waitq */
643 	init_completion(&priv->last_eof_comp);
644 	priv->frame_sequence = 0;
645 	priv->last_eof = false;
646 	priv->nfb4eof = false;
647 
648 	if (ipu_rot_mode_is_irt(priv->rot_mode))
649 		ret = prp_setup_rotation(priv);
650 	else
651 		ret = prp_setup_norotation(priv);
652 	if (ret)
653 		goto out_free_underrun;
654 
655 	priv->nfb4eof_irq = ipu_idmac_channel_irq(priv->ipu,
656 						  priv->out_ch,
657 						  IPU_IRQ_NFB4EOF);
658 	ret = devm_request_irq(ic_priv->dev, priv->nfb4eof_irq,
659 			       prp_nfb4eof_interrupt, 0,
660 			       "imx-ic-prp-nfb4eof", priv);
661 	if (ret) {
662 		v4l2_err(&ic_priv->sd,
663 			 "Error registering NFB4EOF irq: %d\n", ret);
664 		goto out_unsetup;
665 	}
666 
667 	if (ipu_rot_mode_is_irt(priv->rot_mode))
668 		priv->eof_irq = ipu_idmac_channel_irq(
669 			priv->ipu, priv->rot_out_ch, IPU_IRQ_EOF);
670 	else
671 		priv->eof_irq = ipu_idmac_channel_irq(
672 			priv->ipu, priv->out_ch, IPU_IRQ_EOF);
673 
674 	ret = devm_request_irq(ic_priv->dev, priv->eof_irq,
675 			       prp_eof_interrupt, 0,
676 			       "imx-ic-prp-eof", priv);
677 	if (ret) {
678 		v4l2_err(&ic_priv->sd,
679 			 "Error registering eof irq: %d\n", ret);
680 		goto out_free_nfb4eof_irq;
681 	}
682 
683 	/* start the EOF timeout timer */
684 	mod_timer(&priv->eof_timeout_timer,
685 		  jiffies + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT));
686 
687 	return 0;
688 
689 out_free_nfb4eof_irq:
690 	devm_free_irq(ic_priv->dev, priv->nfb4eof_irq, priv);
691 out_unsetup:
692 	prp_unsetup(priv, VB2_BUF_STATE_QUEUED);
693 out_free_underrun:
694 	imx_media_free_dma_buf(priv->md, &priv->underrun_buf);
695 out_put_ipu:
696 	prp_put_ipu_resources(priv);
697 	return ret;
698 }
699 
700 static void prp_stop(struct prp_priv *priv)
701 {
702 	struct imx_ic_priv *ic_priv = priv->ic_priv;
703 	unsigned long flags;
704 	int ret;
705 
706 	/* mark next EOF interrupt as the last before stream off */
707 	spin_lock_irqsave(&priv->irqlock, flags);
708 	priv->last_eof = true;
709 	spin_unlock_irqrestore(&priv->irqlock, flags);
710 
711 	/*
712 	 * and then wait for interrupt handler to mark completion.
713 	 */
714 	ret = wait_for_completion_timeout(
715 		&priv->last_eof_comp,
716 		msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT));
717 	if (ret == 0)
718 		v4l2_warn(&ic_priv->sd, "wait last EOF timeout\n");
719 
720 	devm_free_irq(ic_priv->dev, priv->eof_irq, priv);
721 	devm_free_irq(ic_priv->dev, priv->nfb4eof_irq, priv);
722 
723 	prp_unsetup(priv, VB2_BUF_STATE_ERROR);
724 
725 	imx_media_free_dma_buf(priv->md, &priv->underrun_buf);
726 
727 	/* cancel the EOF timeout timer */
728 	del_timer_sync(&priv->eof_timeout_timer);
729 
730 	prp_put_ipu_resources(priv);
731 }
732 
733 static struct v4l2_mbus_framefmt *
734 __prp_get_fmt(struct prp_priv *priv, struct v4l2_subdev_pad_config *cfg,
735 	      unsigned int pad, enum v4l2_subdev_format_whence which)
736 {
737 	struct imx_ic_priv *ic_priv = priv->ic_priv;
738 
739 	if (which == V4L2_SUBDEV_FORMAT_TRY)
740 		return v4l2_subdev_get_try_format(&ic_priv->sd, cfg, pad);
741 	else
742 		return &priv->format_mbus[pad];
743 }
744 
745 /*
746  * Applies IC resizer and IDMAC alignment restrictions to output
747  * rectangle given the input rectangle, and depending on given
748  * rotation mode.
749  *
750  * The IC resizer cannot downsize more than 4:1. Note also that
751  * for 90 or 270 rotation, _both_ output width and height must
752  * be aligned by W_ALIGN_SRC, because the intermediate rotation
753  * buffer swaps output width/height, and the final output buffer
754  * does not.
755  *
756  * Returns true if the output rectangle was modified.
757  */
758 static bool prp_bound_align_output(struct v4l2_mbus_framefmt *outfmt,
759 				   struct v4l2_mbus_framefmt *infmt,
760 				   enum ipu_rotate_mode rot_mode)
761 {
762 	u32 orig_width = outfmt->width;
763 	u32 orig_height = outfmt->height;
764 
765 	if (ipu_rot_mode_is_irt(rot_mode))
766 		v4l_bound_align_image(&outfmt->width,
767 				      infmt->height / 4, MAX_H_SRC,
768 				      W_ALIGN_SRC,
769 				      &outfmt->height,
770 				      infmt->width / 4, MAX_W_SRC,
771 				      W_ALIGN_SRC, S_ALIGN);
772 	else
773 		v4l_bound_align_image(&outfmt->width,
774 				      infmt->width / 4, MAX_W_SRC,
775 				      W_ALIGN_SRC,
776 				      &outfmt->height,
777 				      infmt->height / 4, MAX_H_SRC,
778 				      H_ALIGN_SRC, S_ALIGN);
779 
780 	return outfmt->width != orig_width || outfmt->height != orig_height;
781 }
782 
783 /*
784  * V4L2 subdev operations.
785  */
786 
787 static int prp_enum_mbus_code(struct v4l2_subdev *sd,
788 			      struct v4l2_subdev_pad_config *cfg,
789 			      struct v4l2_subdev_mbus_code_enum *code)
790 {
791 	if (code->pad >= PRPENCVF_NUM_PADS)
792 		return -EINVAL;
793 
794 	return imx_media_enum_ipu_format(&code->code, code->index, CS_SEL_ANY);
795 }
796 
797 static int prp_get_fmt(struct v4l2_subdev *sd,
798 		       struct v4l2_subdev_pad_config *cfg,
799 		       struct v4l2_subdev_format *sdformat)
800 {
801 	struct prp_priv *priv = sd_to_priv(sd);
802 	struct v4l2_mbus_framefmt *fmt;
803 	int ret = 0;
804 
805 	if (sdformat->pad >= PRPENCVF_NUM_PADS)
806 		return -EINVAL;
807 
808 	mutex_lock(&priv->lock);
809 
810 	fmt = __prp_get_fmt(priv, cfg, sdformat->pad, sdformat->which);
811 	if (!fmt) {
812 		ret = -EINVAL;
813 		goto out;
814 	}
815 
816 	sdformat->format = *fmt;
817 out:
818 	mutex_unlock(&priv->lock);
819 	return ret;
820 }
821 
822 static void prp_try_fmt(struct prp_priv *priv,
823 			struct v4l2_subdev_pad_config *cfg,
824 			struct v4l2_subdev_format *sdformat,
825 			const struct imx_media_pixfmt **cc)
826 {
827 	struct v4l2_mbus_framefmt *infmt;
828 
829 	*cc = imx_media_find_ipu_format(sdformat->format.code, CS_SEL_ANY);
830 	if (!*cc) {
831 		u32 code;
832 
833 		imx_media_enum_ipu_format(&code, 0, CS_SEL_ANY);
834 		*cc = imx_media_find_ipu_format(code, CS_SEL_ANY);
835 		sdformat->format.code = (*cc)->codes[0];
836 	}
837 
838 	infmt = __prp_get_fmt(priv, cfg, PRPENCVF_SINK_PAD, sdformat->which);
839 
840 	if (sdformat->pad == PRPENCVF_SRC_PAD) {
841 		if (sdformat->format.field != V4L2_FIELD_NONE)
842 			sdformat->format.field = infmt->field;
843 
844 		prp_bound_align_output(&sdformat->format, infmt,
845 				       priv->rot_mode);
846 
847 		/* propagate colorimetry from sink */
848 		sdformat->format.colorspace = infmt->colorspace;
849 		sdformat->format.xfer_func = infmt->xfer_func;
850 		sdformat->format.quantization = infmt->quantization;
851 		sdformat->format.ycbcr_enc = infmt->ycbcr_enc;
852 	} else {
853 		v4l_bound_align_image(&sdformat->format.width,
854 				      MIN_W_SINK, MAX_W_SINK, W_ALIGN_SINK,
855 				      &sdformat->format.height,
856 				      MIN_H_SINK, MAX_H_SINK, H_ALIGN_SINK,
857 				      S_ALIGN);
858 
859 		imx_media_fill_default_mbus_fields(&sdformat->format, infmt,
860 						   true);
861 	}
862 }
863 
864 static int prp_set_fmt(struct v4l2_subdev *sd,
865 		       struct v4l2_subdev_pad_config *cfg,
866 		       struct v4l2_subdev_format *sdformat)
867 {
868 	struct prp_priv *priv = sd_to_priv(sd);
869 	struct imx_media_video_dev *vdev = priv->vdev;
870 	const struct imx_media_pixfmt *cc;
871 	struct v4l2_pix_format vdev_fmt;
872 	struct v4l2_mbus_framefmt *fmt;
873 	int ret = 0;
874 
875 	if (sdformat->pad >= PRPENCVF_NUM_PADS)
876 		return -EINVAL;
877 
878 	mutex_lock(&priv->lock);
879 
880 	if (priv->stream_count > 0) {
881 		ret = -EBUSY;
882 		goto out;
883 	}
884 
885 	prp_try_fmt(priv, cfg, sdformat, &cc);
886 
887 	fmt = __prp_get_fmt(priv, cfg, sdformat->pad, sdformat->which);
888 	*fmt = sdformat->format;
889 
890 	/* propagate a default format to source pad */
891 	if (sdformat->pad == PRPENCVF_SINK_PAD) {
892 		const struct imx_media_pixfmt *outcc;
893 		struct v4l2_mbus_framefmt *outfmt;
894 		struct v4l2_subdev_format format;
895 
896 		format.pad = PRPENCVF_SRC_PAD;
897 		format.which = sdformat->which;
898 		format.format = sdformat->format;
899 		prp_try_fmt(priv, cfg, &format, &outcc);
900 
901 		outfmt = __prp_get_fmt(priv, cfg, PRPENCVF_SRC_PAD,
902 				       sdformat->which);
903 		*outfmt = format.format;
904 		if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
905 			priv->cc[PRPENCVF_SRC_PAD] = outcc;
906 	}
907 
908 	if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY)
909 		goto out;
910 
911 	priv->cc[sdformat->pad] = cc;
912 
913 	/* propagate output pad format to capture device */
914 	imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt,
915 				      &priv->format_mbus[PRPENCVF_SRC_PAD],
916 				      priv->cc[PRPENCVF_SRC_PAD]);
917 	mutex_unlock(&priv->lock);
918 	imx_media_capture_device_set_format(vdev, &vdev_fmt);
919 
920 	return 0;
921 out:
922 	mutex_unlock(&priv->lock);
923 	return ret;
924 }
925 
926 static int prp_enum_frame_size(struct v4l2_subdev *sd,
927 			       struct v4l2_subdev_pad_config *cfg,
928 			       struct v4l2_subdev_frame_size_enum *fse)
929 {
930 	struct prp_priv *priv = sd_to_priv(sd);
931 	struct v4l2_subdev_format format = {};
932 	const struct imx_media_pixfmt *cc;
933 	int ret = 0;
934 
935 	if (fse->pad >= PRPENCVF_NUM_PADS || fse->index != 0)
936 		return -EINVAL;
937 
938 	mutex_lock(&priv->lock);
939 
940 	format.pad = fse->pad;
941 	format.which = fse->which;
942 	format.format.code = fse->code;
943 	format.format.width = 1;
944 	format.format.height = 1;
945 	prp_try_fmt(priv, cfg, &format, &cc);
946 	fse->min_width = format.format.width;
947 	fse->min_height = format.format.height;
948 
949 	if (format.format.code != fse->code) {
950 		ret = -EINVAL;
951 		goto out;
952 	}
953 
954 	format.format.code = fse->code;
955 	format.format.width = -1;
956 	format.format.height = -1;
957 	prp_try_fmt(priv, cfg, &format, &cc);
958 	fse->max_width = format.format.width;
959 	fse->max_height = format.format.height;
960 out:
961 	mutex_unlock(&priv->lock);
962 	return ret;
963 }
964 
965 static int prp_link_setup(struct media_entity *entity,
966 			  const struct media_pad *local,
967 			  const struct media_pad *remote, u32 flags)
968 {
969 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
970 	struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd);
971 	struct prp_priv *priv = ic_priv->task_priv;
972 	struct v4l2_subdev *remote_sd;
973 	int ret = 0;
974 
975 	dev_dbg(ic_priv->dev, "link setup %s -> %s", remote->entity->name,
976 		local->entity->name);
977 
978 	mutex_lock(&priv->lock);
979 
980 	if (local->flags & MEDIA_PAD_FL_SINK) {
981 		if (!is_media_entity_v4l2_subdev(remote->entity)) {
982 			ret = -EINVAL;
983 			goto out;
984 		}
985 
986 		remote_sd = media_entity_to_v4l2_subdev(remote->entity);
987 
988 		if (flags & MEDIA_LNK_FL_ENABLED) {
989 			if (priv->src_sd) {
990 				ret = -EBUSY;
991 				goto out;
992 			}
993 			priv->src_sd = remote_sd;
994 		} else {
995 			priv->src_sd = NULL;
996 		}
997 
998 		goto out;
999 	}
1000 
1001 	/* this is the source pad */
1002 
1003 	/* the remote must be the device node */
1004 	if (!is_media_entity_v4l2_video_device(remote->entity)) {
1005 		ret = -EINVAL;
1006 		goto out;
1007 	}
1008 
1009 	if (flags & MEDIA_LNK_FL_ENABLED) {
1010 		if (priv->sink) {
1011 			ret = -EBUSY;
1012 			goto out;
1013 		}
1014 	} else {
1015 		priv->sink = NULL;
1016 		goto out;
1017 	}
1018 
1019 	priv->sink = remote->entity;
1020 out:
1021 	mutex_unlock(&priv->lock);
1022 	return ret;
1023 }
1024 
1025 static int prp_s_ctrl(struct v4l2_ctrl *ctrl)
1026 {
1027 	struct prp_priv *priv = container_of(ctrl->handler,
1028 					       struct prp_priv, ctrl_hdlr);
1029 	struct imx_ic_priv *ic_priv = priv->ic_priv;
1030 	enum ipu_rotate_mode rot_mode;
1031 	int rotation, ret = 0;
1032 	bool hflip, vflip;
1033 
1034 	mutex_lock(&priv->lock);
1035 
1036 	rotation = priv->rotation;
1037 	hflip = priv->hflip;
1038 	vflip = priv->vflip;
1039 
1040 	switch (ctrl->id) {
1041 	case V4L2_CID_HFLIP:
1042 		hflip = (ctrl->val == 1);
1043 		break;
1044 	case V4L2_CID_VFLIP:
1045 		vflip = (ctrl->val == 1);
1046 		break;
1047 	case V4L2_CID_ROTATE:
1048 		rotation = ctrl->val;
1049 		break;
1050 	default:
1051 		v4l2_err(&ic_priv->sd, "Invalid control\n");
1052 		ret = -EINVAL;
1053 		goto out;
1054 	}
1055 
1056 	ret = ipu_degrees_to_rot_mode(&rot_mode, rotation, hflip, vflip);
1057 	if (ret)
1058 		goto out;
1059 
1060 	if (rot_mode != priv->rot_mode) {
1061 		struct v4l2_mbus_framefmt outfmt, infmt;
1062 
1063 		/* can't change rotation mid-streaming */
1064 		if (priv->stream_count > 0) {
1065 			ret = -EBUSY;
1066 			goto out;
1067 		}
1068 
1069 		outfmt = priv->format_mbus[PRPENCVF_SRC_PAD];
1070 		infmt = priv->format_mbus[PRPENCVF_SINK_PAD];
1071 
1072 		if (prp_bound_align_output(&outfmt, &infmt, rot_mode)) {
1073 			ret = -EINVAL;
1074 			goto out;
1075 		}
1076 
1077 		priv->rot_mode = rot_mode;
1078 		priv->rotation = rotation;
1079 		priv->hflip = hflip;
1080 		priv->vflip = vflip;
1081 	}
1082 
1083 out:
1084 	mutex_unlock(&priv->lock);
1085 	return ret;
1086 }
1087 
1088 static const struct v4l2_ctrl_ops prp_ctrl_ops = {
1089 	.s_ctrl = prp_s_ctrl,
1090 };
1091 
1092 static int prp_init_controls(struct prp_priv *priv)
1093 {
1094 	struct imx_ic_priv *ic_priv = priv->ic_priv;
1095 	struct v4l2_ctrl_handler *hdlr = &priv->ctrl_hdlr;
1096 	int ret;
1097 
1098 	v4l2_ctrl_handler_init(hdlr, 3);
1099 
1100 	v4l2_ctrl_new_std(hdlr, &prp_ctrl_ops, V4L2_CID_HFLIP,
1101 			  0, 1, 1, 0);
1102 	v4l2_ctrl_new_std(hdlr, &prp_ctrl_ops, V4L2_CID_VFLIP,
1103 			  0, 1, 1, 0);
1104 	v4l2_ctrl_new_std(hdlr, &prp_ctrl_ops, V4L2_CID_ROTATE,
1105 			  0, 270, 90, 0);
1106 
1107 	ic_priv->sd.ctrl_handler = hdlr;
1108 
1109 	if (hdlr->error) {
1110 		ret = hdlr->error;
1111 		goto out_free;
1112 	}
1113 
1114 	v4l2_ctrl_handler_setup(hdlr);
1115 	return 0;
1116 
1117 out_free:
1118 	v4l2_ctrl_handler_free(hdlr);
1119 	return ret;
1120 }
1121 
1122 static int prp_s_stream(struct v4l2_subdev *sd, int enable)
1123 {
1124 	struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd);
1125 	struct prp_priv *priv = ic_priv->task_priv;
1126 	int ret = 0;
1127 
1128 	mutex_lock(&priv->lock);
1129 
1130 	if (!priv->src_sd || !priv->sink) {
1131 		ret = -EPIPE;
1132 		goto out;
1133 	}
1134 
1135 	/*
1136 	 * enable/disable streaming only if stream_count is
1137 	 * going from 0 to 1 / 1 to 0.
1138 	 */
1139 	if (priv->stream_count != !enable)
1140 		goto update_count;
1141 
1142 	dev_dbg(ic_priv->dev, "stream %s\n", enable ? "ON" : "OFF");
1143 
1144 	if (enable)
1145 		ret = prp_start(priv);
1146 	else
1147 		prp_stop(priv);
1148 	if (ret)
1149 		goto out;
1150 
1151 	/* start/stop upstream */
1152 	ret = v4l2_subdev_call(priv->src_sd, video, s_stream, enable);
1153 	ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0;
1154 	if (ret) {
1155 		if (enable)
1156 			prp_stop(priv);
1157 		goto out;
1158 	}
1159 
1160 update_count:
1161 	priv->stream_count += enable ? 1 : -1;
1162 	if (priv->stream_count < 0)
1163 		priv->stream_count = 0;
1164 out:
1165 	mutex_unlock(&priv->lock);
1166 	return ret;
1167 }
1168 
1169 static int prp_g_frame_interval(struct v4l2_subdev *sd,
1170 				struct v4l2_subdev_frame_interval *fi)
1171 {
1172 	struct prp_priv *priv = sd_to_priv(sd);
1173 
1174 	if (fi->pad >= PRPENCVF_NUM_PADS)
1175 		return -EINVAL;
1176 
1177 	mutex_lock(&priv->lock);
1178 	fi->interval = priv->frame_interval;
1179 	mutex_unlock(&priv->lock);
1180 
1181 	return 0;
1182 }
1183 
1184 static int prp_s_frame_interval(struct v4l2_subdev *sd,
1185 				struct v4l2_subdev_frame_interval *fi)
1186 {
1187 	struct prp_priv *priv = sd_to_priv(sd);
1188 
1189 	if (fi->pad >= PRPENCVF_NUM_PADS)
1190 		return -EINVAL;
1191 
1192 	/* No limits on frame interval */
1193 	mutex_lock(&priv->lock);
1194 	priv->frame_interval = fi->interval;
1195 	mutex_unlock(&priv->lock);
1196 
1197 	return 0;
1198 }
1199 
1200 /*
1201  * retrieve our pads parsed from the OF graph by the media device
1202  */
1203 static int prp_registered(struct v4l2_subdev *sd)
1204 {
1205 	struct prp_priv *priv = sd_to_priv(sd);
1206 	int i, ret;
1207 	u32 code;
1208 
1209 	/* get media device */
1210 	priv->md = dev_get_drvdata(sd->v4l2_dev->dev);
1211 
1212 	for (i = 0; i < PRPENCVF_NUM_PADS; i++) {
1213 		priv->pad[i].flags = (i == PRPENCVF_SINK_PAD) ?
1214 			MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
1215 
1216 		/* set a default mbus format  */
1217 		imx_media_enum_ipu_format(&code, 0, CS_SEL_YUV);
1218 		ret = imx_media_init_mbus_fmt(&priv->format_mbus[i],
1219 					      640, 480, code, V4L2_FIELD_NONE,
1220 					      &priv->cc[i]);
1221 		if (ret)
1222 			return ret;
1223 	}
1224 
1225 	/* init default frame interval */
1226 	priv->frame_interval.numerator = 1;
1227 	priv->frame_interval.denominator = 30;
1228 
1229 	ret = media_entity_pads_init(&sd->entity, PRPENCVF_NUM_PADS,
1230 				     priv->pad);
1231 	if (ret)
1232 		return ret;
1233 
1234 	ret = imx_media_capture_device_register(priv->vdev);
1235 	if (ret)
1236 		return ret;
1237 
1238 	ret = imx_media_add_video_device(priv->md, priv->vdev);
1239 	if (ret)
1240 		goto unreg;
1241 
1242 	ret = prp_init_controls(priv);
1243 	if (ret)
1244 		goto unreg;
1245 
1246 	return 0;
1247 unreg:
1248 	imx_media_capture_device_unregister(priv->vdev);
1249 	return ret;
1250 }
1251 
1252 static void prp_unregistered(struct v4l2_subdev *sd)
1253 {
1254 	struct prp_priv *priv = sd_to_priv(sd);
1255 
1256 	imx_media_capture_device_unregister(priv->vdev);
1257 	v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
1258 }
1259 
1260 static const struct v4l2_subdev_pad_ops prp_pad_ops = {
1261 	.init_cfg = imx_media_init_cfg,
1262 	.enum_mbus_code = prp_enum_mbus_code,
1263 	.enum_frame_size = prp_enum_frame_size,
1264 	.get_fmt = prp_get_fmt,
1265 	.set_fmt = prp_set_fmt,
1266 };
1267 
1268 static const struct v4l2_subdev_video_ops prp_video_ops = {
1269 	.g_frame_interval = prp_g_frame_interval,
1270 	.s_frame_interval = prp_s_frame_interval,
1271 	.s_stream = prp_s_stream,
1272 };
1273 
1274 static const struct media_entity_operations prp_entity_ops = {
1275 	.link_setup = prp_link_setup,
1276 	.link_validate = v4l2_subdev_link_validate,
1277 };
1278 
1279 static const struct v4l2_subdev_ops prp_subdev_ops = {
1280 	.video = &prp_video_ops,
1281 	.pad = &prp_pad_ops,
1282 };
1283 
1284 static const struct v4l2_subdev_internal_ops prp_internal_ops = {
1285 	.registered = prp_registered,
1286 	.unregistered = prp_unregistered,
1287 };
1288 
1289 static int prp_init(struct imx_ic_priv *ic_priv)
1290 {
1291 	struct prp_priv *priv;
1292 
1293 	priv = devm_kzalloc(ic_priv->dev, sizeof(*priv), GFP_KERNEL);
1294 	if (!priv)
1295 		return -ENOMEM;
1296 
1297 	ic_priv->task_priv = priv;
1298 	priv->ic_priv = ic_priv;
1299 
1300 	spin_lock_init(&priv->irqlock);
1301 	timer_setup(&priv->eof_timeout_timer, prp_eof_timeout, 0);
1302 
1303 	priv->vdev = imx_media_capture_device_init(&ic_priv->sd,
1304 						   PRPENCVF_SRC_PAD);
1305 	if (IS_ERR(priv->vdev))
1306 		return PTR_ERR(priv->vdev);
1307 
1308 	mutex_init(&priv->lock);
1309 
1310 	return 0;
1311 }
1312 
1313 static void prp_remove(struct imx_ic_priv *ic_priv)
1314 {
1315 	struct prp_priv *priv = ic_priv->task_priv;
1316 
1317 	mutex_destroy(&priv->lock);
1318 	imx_media_capture_device_remove(priv->vdev);
1319 }
1320 
1321 struct imx_ic_ops imx_ic_prpencvf_ops = {
1322 	.subdev_ops = &prp_subdev_ops,
1323 	.internal_ops = &prp_internal_ops,
1324 	.entity_ops = &prp_entity_ops,
1325 	.init = prp_init,
1326 	.remove = prp_remove,
1327 };
1328