imx-ic-prpencvf.c (33940B)
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 52struct 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 107static 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 124static 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 131static 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 150static 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; 193out: 194 prp_put_ipu_resources(priv); 195 return ret; 196} 197 198static 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 237static 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 264unlock: 265 spin_unlock(&priv->irqlock); 266 return IRQ_HANDLED; 267} 268 269static 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 */ 296static 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 308static 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 327static 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 345static 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 448static 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 550unsetup_vb2: 551 prp_unsetup_vb2_buf(priv, VB2_BUF_STATE_QUEUED); 552free_rot1: 553 imx_media_free_dma_buf(ic_priv->ipu_dev, &priv->rot_buf[1]); 554free_rot0: 555 imx_media_free_dma_buf(ic_priv->ipu_dev, &priv->rot_buf[0]); 556 return ret; 557} 558 559static 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 577static 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 641unsetup_vb2: 642 prp_unsetup_vb2_buf(priv, VB2_BUF_STATE_QUEUED); 643 return ret; 644} 645 646static 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 653static 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 664static 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 737out_free_eof_irq: 738 devm_free_irq(ic_priv->ipu_dev, priv->eof_irq, priv); 739out_free_nfb4eof_irq: 740 devm_free_irq(ic_priv->ipu_dev, priv->nfb4eof_irq, priv); 741out_unsetup: 742 prp_unsetup(priv, VB2_BUF_STATE_QUEUED); 743out_free_underrun: 744 imx_media_free_dma_buf(ic_priv->ipu_dev, &priv->underrun_buf); 745out_put_ipu: 746 prp_put_ipu_resources(priv); 747 return ret; 748} 749 750static 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 789static 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 struct imx_ic_priv *ic_priv = priv->ic_priv; 794 795 if (which == V4L2_SUBDEV_FORMAT_TRY) 796 return v4l2_subdev_get_try_format(&ic_priv->sd, sd_state, pad); 797 else 798 return &priv->format_mbus[pad]; 799} 800 801/* 802 * Applies IC resizer and IDMAC alignment restrictions to output 803 * rectangle given the input rectangle, and depending on given 804 * rotation mode. 805 * 806 * The IC resizer cannot downsize more than 4:1. Note also that 807 * for 90 or 270 rotation, _both_ output width and height must 808 * be aligned by W_ALIGN_SRC, because the intermediate rotation 809 * buffer swaps output width/height, and the final output buffer 810 * does not. 811 * 812 * Returns true if the output rectangle was modified. 813 */ 814static bool prp_bound_align_output(struct v4l2_mbus_framefmt *outfmt, 815 struct v4l2_mbus_framefmt *infmt, 816 enum ipu_rotate_mode rot_mode) 817{ 818 u32 orig_width = outfmt->width; 819 u32 orig_height = outfmt->height; 820 821 if (ipu_rot_mode_is_irt(rot_mode)) 822 v4l_bound_align_image(&outfmt->width, 823 infmt->height / 4, MAX_H_SRC, 824 W_ALIGN_SRC, 825 &outfmt->height, 826 infmt->width / 4, MAX_W_SRC, 827 W_ALIGN_SRC, S_ALIGN); 828 else 829 v4l_bound_align_image(&outfmt->width, 830 infmt->width / 4, MAX_W_SRC, 831 W_ALIGN_SRC, 832 &outfmt->height, 833 infmt->height / 4, MAX_H_SRC, 834 H_ALIGN_SRC, S_ALIGN); 835 836 return outfmt->width != orig_width || outfmt->height != orig_height; 837} 838 839/* 840 * V4L2 subdev operations. 841 */ 842 843static int prp_enum_mbus_code(struct v4l2_subdev *sd, 844 struct v4l2_subdev_state *sd_state, 845 struct v4l2_subdev_mbus_code_enum *code) 846{ 847 if (code->pad >= PRPENCVF_NUM_PADS) 848 return -EINVAL; 849 850 return imx_media_enum_ipu_formats(&code->code, code->index, 851 PIXFMT_SEL_YUV_RGB); 852} 853 854static int prp_get_fmt(struct v4l2_subdev *sd, 855 struct v4l2_subdev_state *sd_state, 856 struct v4l2_subdev_format *sdformat) 857{ 858 struct prp_priv *priv = sd_to_priv(sd); 859 struct v4l2_mbus_framefmt *fmt; 860 int ret = 0; 861 862 if (sdformat->pad >= PRPENCVF_NUM_PADS) 863 return -EINVAL; 864 865 mutex_lock(&priv->lock); 866 867 fmt = __prp_get_fmt(priv, sd_state, sdformat->pad, sdformat->which); 868 if (!fmt) { 869 ret = -EINVAL; 870 goto out; 871 } 872 873 sdformat->format = *fmt; 874out: 875 mutex_unlock(&priv->lock); 876 return ret; 877} 878 879static void prp_try_fmt(struct prp_priv *priv, 880 struct v4l2_subdev_state *sd_state, 881 struct v4l2_subdev_format *sdformat, 882 const struct imx_media_pixfmt **cc) 883{ 884 struct v4l2_mbus_framefmt *infmt; 885 886 *cc = imx_media_find_ipu_format(sdformat->format.code, 887 PIXFMT_SEL_YUV_RGB); 888 if (!*cc) { 889 u32 code; 890 891 imx_media_enum_ipu_formats(&code, 0, PIXFMT_SEL_YUV_RGB); 892 *cc = imx_media_find_ipu_format(code, PIXFMT_SEL_YUV_RGB); 893 894 sdformat->format.code = (*cc)->codes[0]; 895 } 896 897 infmt = __prp_get_fmt(priv, sd_state, PRPENCVF_SINK_PAD, 898 sdformat->which); 899 900 if (sdformat->pad == PRPENCVF_SRC_PAD) { 901 sdformat->format.field = infmt->field; 902 903 prp_bound_align_output(&sdformat->format, infmt, 904 priv->rot_mode); 905 906 /* propagate colorimetry from sink */ 907 sdformat->format.colorspace = infmt->colorspace; 908 sdformat->format.xfer_func = infmt->xfer_func; 909 } else { 910 v4l_bound_align_image(&sdformat->format.width, 911 MIN_W_SINK, MAX_W_SINK, W_ALIGN_SINK, 912 &sdformat->format.height, 913 MIN_H_SINK, MAX_H_SINK, H_ALIGN_SINK, 914 S_ALIGN); 915 916 if (sdformat->format.field == V4L2_FIELD_ANY) 917 sdformat->format.field = V4L2_FIELD_NONE; 918 } 919 920 imx_media_try_colorimetry(&sdformat->format, true); 921} 922 923static int prp_set_fmt(struct v4l2_subdev *sd, 924 struct v4l2_subdev_state *sd_state, 925 struct v4l2_subdev_format *sdformat) 926{ 927 struct prp_priv *priv = sd_to_priv(sd); 928 const struct imx_media_pixfmt *cc; 929 struct v4l2_mbus_framefmt *fmt; 930 int ret = 0; 931 932 if (sdformat->pad >= PRPENCVF_NUM_PADS) 933 return -EINVAL; 934 935 mutex_lock(&priv->lock); 936 937 if (priv->stream_count > 0) { 938 ret = -EBUSY; 939 goto out; 940 } 941 942 prp_try_fmt(priv, sd_state, sdformat, &cc); 943 944 fmt = __prp_get_fmt(priv, sd_state, sdformat->pad, sdformat->which); 945 *fmt = sdformat->format; 946 947 /* propagate a default format to source pad */ 948 if (sdformat->pad == PRPENCVF_SINK_PAD) { 949 const struct imx_media_pixfmt *outcc; 950 struct v4l2_mbus_framefmt *outfmt; 951 struct v4l2_subdev_format format; 952 953 format.pad = PRPENCVF_SRC_PAD; 954 format.which = sdformat->which; 955 format.format = sdformat->format; 956 prp_try_fmt(priv, sd_state, &format, &outcc); 957 958 outfmt = __prp_get_fmt(priv, sd_state, PRPENCVF_SRC_PAD, 959 sdformat->which); 960 *outfmt = format.format; 961 if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) 962 priv->cc[PRPENCVF_SRC_PAD] = outcc; 963 } 964 965 if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) 966 priv->cc[sdformat->pad] = cc; 967 968out: 969 mutex_unlock(&priv->lock); 970 return ret; 971} 972 973static int prp_enum_frame_size(struct v4l2_subdev *sd, 974 struct v4l2_subdev_state *sd_state, 975 struct v4l2_subdev_frame_size_enum *fse) 976{ 977 struct prp_priv *priv = sd_to_priv(sd); 978 struct v4l2_subdev_format format = {}; 979 const struct imx_media_pixfmt *cc; 980 int ret = 0; 981 982 if (fse->pad >= PRPENCVF_NUM_PADS || fse->index != 0) 983 return -EINVAL; 984 985 mutex_lock(&priv->lock); 986 987 format.pad = fse->pad; 988 format.which = fse->which; 989 format.format.code = fse->code; 990 format.format.width = 1; 991 format.format.height = 1; 992 prp_try_fmt(priv, sd_state, &format, &cc); 993 fse->min_width = format.format.width; 994 fse->min_height = format.format.height; 995 996 if (format.format.code != fse->code) { 997 ret = -EINVAL; 998 goto out; 999 } 1000 1001 format.format.code = fse->code; 1002 format.format.width = -1; 1003 format.format.height = -1; 1004 prp_try_fmt(priv, sd_state, &format, &cc); 1005 fse->max_width = format.format.width; 1006 fse->max_height = format.format.height; 1007out: 1008 mutex_unlock(&priv->lock); 1009 return ret; 1010} 1011 1012static int prp_link_setup(struct media_entity *entity, 1013 const struct media_pad *local, 1014 const struct media_pad *remote, u32 flags) 1015{ 1016 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 1017 struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd); 1018 struct prp_priv *priv = ic_priv->task_priv; 1019 struct v4l2_subdev *remote_sd; 1020 int ret = 0; 1021 1022 dev_dbg(ic_priv->ipu_dev, "%s: link setup %s -> %s", 1023 ic_priv->sd.name, remote->entity->name, local->entity->name); 1024 1025 mutex_lock(&priv->lock); 1026 1027 if (local->flags & MEDIA_PAD_FL_SINK) { 1028 if (!is_media_entity_v4l2_subdev(remote->entity)) { 1029 ret = -EINVAL; 1030 goto out; 1031 } 1032 1033 remote_sd = media_entity_to_v4l2_subdev(remote->entity); 1034 1035 if (flags & MEDIA_LNK_FL_ENABLED) { 1036 if (priv->src_sd) { 1037 ret = -EBUSY; 1038 goto out; 1039 } 1040 priv->src_sd = remote_sd; 1041 } else { 1042 priv->src_sd = NULL; 1043 } 1044 1045 goto out; 1046 } 1047 1048 /* this is the source pad */ 1049 1050 /* the remote must be the device node */ 1051 if (!is_media_entity_v4l2_video_device(remote->entity)) { 1052 ret = -EINVAL; 1053 goto out; 1054 } 1055 1056 if (flags & MEDIA_LNK_FL_ENABLED) { 1057 if (priv->sink) { 1058 ret = -EBUSY; 1059 goto out; 1060 } 1061 } else { 1062 priv->sink = NULL; 1063 goto out; 1064 } 1065 1066 priv->sink = remote->entity; 1067out: 1068 mutex_unlock(&priv->lock); 1069 return ret; 1070} 1071 1072static int prp_s_ctrl(struct v4l2_ctrl *ctrl) 1073{ 1074 struct prp_priv *priv = container_of(ctrl->handler, 1075 struct prp_priv, ctrl_hdlr); 1076 struct imx_ic_priv *ic_priv = priv->ic_priv; 1077 enum ipu_rotate_mode rot_mode; 1078 int rotation, ret = 0; 1079 bool hflip, vflip; 1080 1081 mutex_lock(&priv->lock); 1082 1083 rotation = priv->rotation; 1084 hflip = priv->hflip; 1085 vflip = priv->vflip; 1086 1087 switch (ctrl->id) { 1088 case V4L2_CID_HFLIP: 1089 hflip = (ctrl->val == 1); 1090 break; 1091 case V4L2_CID_VFLIP: 1092 vflip = (ctrl->val == 1); 1093 break; 1094 case V4L2_CID_ROTATE: 1095 rotation = ctrl->val; 1096 break; 1097 default: 1098 v4l2_err(&ic_priv->sd, "Invalid control\n"); 1099 ret = -EINVAL; 1100 goto out; 1101 } 1102 1103 ret = ipu_degrees_to_rot_mode(&rot_mode, rotation, hflip, vflip); 1104 if (ret) 1105 goto out; 1106 1107 if (rot_mode != priv->rot_mode) { 1108 struct v4l2_mbus_framefmt outfmt, infmt; 1109 1110 /* can't change rotation mid-streaming */ 1111 if (priv->stream_count > 0) { 1112 ret = -EBUSY; 1113 goto out; 1114 } 1115 1116 outfmt = priv->format_mbus[PRPENCVF_SRC_PAD]; 1117 infmt = priv->format_mbus[PRPENCVF_SINK_PAD]; 1118 1119 if (prp_bound_align_output(&outfmt, &infmt, rot_mode)) { 1120 ret = -EINVAL; 1121 goto out; 1122 } 1123 1124 priv->rot_mode = rot_mode; 1125 priv->rotation = rotation; 1126 priv->hflip = hflip; 1127 priv->vflip = vflip; 1128 } 1129 1130out: 1131 mutex_unlock(&priv->lock); 1132 return ret; 1133} 1134 1135static const struct v4l2_ctrl_ops prp_ctrl_ops = { 1136 .s_ctrl = prp_s_ctrl, 1137}; 1138 1139static int prp_init_controls(struct prp_priv *priv) 1140{ 1141 struct imx_ic_priv *ic_priv = priv->ic_priv; 1142 struct v4l2_ctrl_handler *hdlr = &priv->ctrl_hdlr; 1143 int ret; 1144 1145 v4l2_ctrl_handler_init(hdlr, 3); 1146 1147 v4l2_ctrl_new_std(hdlr, &prp_ctrl_ops, V4L2_CID_HFLIP, 1148 0, 1, 1, 0); 1149 v4l2_ctrl_new_std(hdlr, &prp_ctrl_ops, V4L2_CID_VFLIP, 1150 0, 1, 1, 0); 1151 v4l2_ctrl_new_std(hdlr, &prp_ctrl_ops, V4L2_CID_ROTATE, 1152 0, 270, 90, 0); 1153 1154 ic_priv->sd.ctrl_handler = hdlr; 1155 1156 if (hdlr->error) { 1157 ret = hdlr->error; 1158 goto out_free; 1159 } 1160 1161 v4l2_ctrl_handler_setup(hdlr); 1162 return 0; 1163 1164out_free: 1165 v4l2_ctrl_handler_free(hdlr); 1166 return ret; 1167} 1168 1169static int prp_s_stream(struct v4l2_subdev *sd, int enable) 1170{ 1171 struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd); 1172 struct prp_priv *priv = ic_priv->task_priv; 1173 int ret = 0; 1174 1175 mutex_lock(&priv->lock); 1176 1177 if (!priv->src_sd || !priv->sink) { 1178 ret = -EPIPE; 1179 goto out; 1180 } 1181 1182 /* 1183 * enable/disable streaming only if stream_count is 1184 * going from 0 to 1 / 1 to 0. 1185 */ 1186 if (priv->stream_count != !enable) 1187 goto update_count; 1188 1189 dev_dbg(ic_priv->ipu_dev, "%s: stream %s\n", sd->name, 1190 enable ? "ON" : "OFF"); 1191 1192 if (enable) 1193 ret = prp_start(priv); 1194 else 1195 prp_stop(priv); 1196 if (ret) 1197 goto out; 1198 1199update_count: 1200 priv->stream_count += enable ? 1 : -1; 1201 if (priv->stream_count < 0) 1202 priv->stream_count = 0; 1203out: 1204 mutex_unlock(&priv->lock); 1205 return ret; 1206} 1207 1208static int prp_g_frame_interval(struct v4l2_subdev *sd, 1209 struct v4l2_subdev_frame_interval *fi) 1210{ 1211 struct prp_priv *priv = sd_to_priv(sd); 1212 1213 if (fi->pad >= PRPENCVF_NUM_PADS) 1214 return -EINVAL; 1215 1216 mutex_lock(&priv->lock); 1217 fi->interval = priv->frame_interval; 1218 mutex_unlock(&priv->lock); 1219 1220 return 0; 1221} 1222 1223static int prp_s_frame_interval(struct v4l2_subdev *sd, 1224 struct v4l2_subdev_frame_interval *fi) 1225{ 1226 struct prp_priv *priv = sd_to_priv(sd); 1227 1228 if (fi->pad >= PRPENCVF_NUM_PADS) 1229 return -EINVAL; 1230 1231 mutex_lock(&priv->lock); 1232 1233 /* No limits on valid frame intervals */ 1234 if (fi->interval.numerator == 0 || fi->interval.denominator == 0) 1235 fi->interval = priv->frame_interval; 1236 else 1237 priv->frame_interval = fi->interval; 1238 1239 mutex_unlock(&priv->lock); 1240 1241 return 0; 1242} 1243 1244static int prp_registered(struct v4l2_subdev *sd) 1245{ 1246 struct prp_priv *priv = sd_to_priv(sd); 1247 struct imx_ic_priv *ic_priv = priv->ic_priv; 1248 int i, ret; 1249 u32 code; 1250 1251 /* set a default mbus format */ 1252 imx_media_enum_ipu_formats(&code, 0, PIXFMT_SEL_YUV); 1253 1254 for (i = 0; i < PRPENCVF_NUM_PADS; i++) { 1255 ret = imx_media_init_mbus_fmt(&priv->format_mbus[i], 1256 IMX_MEDIA_DEF_PIX_WIDTH, 1257 IMX_MEDIA_DEF_PIX_HEIGHT, code, 1258 V4L2_FIELD_NONE, &priv->cc[i]); 1259 if (ret) 1260 return ret; 1261 } 1262 1263 /* init default frame interval */ 1264 priv->frame_interval.numerator = 1; 1265 priv->frame_interval.denominator = 30; 1266 1267 priv->vdev = imx_media_capture_device_init(ic_priv->ipu_dev, 1268 &ic_priv->sd, 1269 PRPENCVF_SRC_PAD, true); 1270 if (IS_ERR(priv->vdev)) 1271 return PTR_ERR(priv->vdev); 1272 1273 ret = imx_media_capture_device_register(priv->vdev, 0); 1274 if (ret) 1275 goto remove_vdev; 1276 1277 ret = prp_init_controls(priv); 1278 if (ret) 1279 goto unreg_vdev; 1280 1281 return 0; 1282 1283unreg_vdev: 1284 imx_media_capture_device_unregister(priv->vdev); 1285remove_vdev: 1286 imx_media_capture_device_remove(priv->vdev); 1287 return ret; 1288} 1289 1290static void prp_unregistered(struct v4l2_subdev *sd) 1291{ 1292 struct prp_priv *priv = sd_to_priv(sd); 1293 1294 imx_media_capture_device_unregister(priv->vdev); 1295 imx_media_capture_device_remove(priv->vdev); 1296 1297 v4l2_ctrl_handler_free(&priv->ctrl_hdlr); 1298} 1299 1300static const struct v4l2_subdev_pad_ops prp_pad_ops = { 1301 .init_cfg = imx_media_init_cfg, 1302 .enum_mbus_code = prp_enum_mbus_code, 1303 .enum_frame_size = prp_enum_frame_size, 1304 .get_fmt = prp_get_fmt, 1305 .set_fmt = prp_set_fmt, 1306}; 1307 1308static const struct v4l2_subdev_video_ops prp_video_ops = { 1309 .g_frame_interval = prp_g_frame_interval, 1310 .s_frame_interval = prp_s_frame_interval, 1311 .s_stream = prp_s_stream, 1312}; 1313 1314static const struct media_entity_operations prp_entity_ops = { 1315 .link_setup = prp_link_setup, 1316 .link_validate = v4l2_subdev_link_validate, 1317}; 1318 1319static const struct v4l2_subdev_ops prp_subdev_ops = { 1320 .video = &prp_video_ops, 1321 .pad = &prp_pad_ops, 1322}; 1323 1324static const struct v4l2_subdev_internal_ops prp_internal_ops = { 1325 .registered = prp_registered, 1326 .unregistered = prp_unregistered, 1327}; 1328 1329static int prp_init(struct imx_ic_priv *ic_priv) 1330{ 1331 struct prp_priv *priv; 1332 int i, ret; 1333 1334 priv = devm_kzalloc(ic_priv->ipu_dev, sizeof(*priv), GFP_KERNEL); 1335 if (!priv) 1336 return -ENOMEM; 1337 1338 ic_priv->task_priv = priv; 1339 priv->ic_priv = ic_priv; 1340 1341 spin_lock_init(&priv->irqlock); 1342 timer_setup(&priv->eof_timeout_timer, prp_eof_timeout, 0); 1343 1344 mutex_init(&priv->lock); 1345 1346 for (i = 0; i < PRPENCVF_NUM_PADS; i++) { 1347 priv->pad[i].flags = (i == PRPENCVF_SINK_PAD) ? 1348 MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; 1349 } 1350 1351 ret = media_entity_pads_init(&ic_priv->sd.entity, PRPENCVF_NUM_PADS, 1352 priv->pad); 1353 if (ret) 1354 mutex_destroy(&priv->lock); 1355 1356 return ret; 1357} 1358 1359static void prp_remove(struct imx_ic_priv *ic_priv) 1360{ 1361 struct prp_priv *priv = ic_priv->task_priv; 1362 1363 mutex_destroy(&priv->lock); 1364} 1365 1366struct imx_ic_ops imx_ic_prpencvf_ops = { 1367 .subdev_ops = &prp_subdev_ops, 1368 .internal_ops = &prp_internal_ops, 1369 .entity_ops = &prp_entity_ops, 1370 .init = prp_init, 1371 .remove = prp_remove, 1372};