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