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