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