diff options
author | Javier Martin <javier.martin@vista-silicon.com> | 2012-01-30 07:14:10 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-03-08 07:37:52 -0500 |
commit | c6a41e3271c61f6f5aec1a91b4458330d4266e5f (patch) | |
tree | f627cd6c0b10dc0a010b06f7062d0b01448fec9d /drivers/media/video | |
parent | 2c9ba37d7a4e889d51cba320cbfa4ce53880b2b0 (diff) |
[media] media i.MX27 camera: migrate driver to videobuf2
Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/mx2_camera.c | 289 |
1 files changed, 127 insertions, 162 deletions
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index f771f53b2998..22f5dbcf6db8 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2008, Sascha Hauer, Pengutronix | 4 | * Copyright (C) 2008, Sascha Hauer, Pengutronix |
5 | * Copyright (C) 2010, Baruch Siach, Orex Computed Radiography | 5 | * Copyright (C) 2010, Baruch Siach, Orex Computed Radiography |
6 | * Copyright (C) 2012, Javier Martin, Vista Silicon S.L. | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -30,8 +31,8 @@ | |||
30 | 31 | ||
31 | #include <media/v4l2-common.h> | 32 | #include <media/v4l2-common.h> |
32 | #include <media/v4l2-dev.h> | 33 | #include <media/v4l2-dev.h> |
33 | #include <media/videobuf-core.h> | 34 | #include <media/videobuf2-core.h> |
34 | #include <media/videobuf-dma-contig.h> | 35 | #include <media/videobuf2-dma-contig.h> |
35 | #include <media/soc_camera.h> | 36 | #include <media/soc_camera.h> |
36 | #include <media/soc_mediabus.h> | 37 | #include <media/soc_mediabus.h> |
37 | 38 | ||
@@ -221,6 +222,22 @@ struct mx2_fmt_cfg { | |||
221 | struct mx2_prp_cfg cfg; | 222 | struct mx2_prp_cfg cfg; |
222 | }; | 223 | }; |
223 | 224 | ||
225 | enum mx2_buffer_state { | ||
226 | MX2_STATE_QUEUED, | ||
227 | MX2_STATE_ACTIVE, | ||
228 | MX2_STATE_DONE, | ||
229 | }; | ||
230 | |||
231 | /* buffer for one video frame */ | ||
232 | struct mx2_buffer { | ||
233 | /* common v4l buffer stuff -- must be first */ | ||
234 | struct vb2_buffer vb; | ||
235 | struct list_head queue; | ||
236 | enum mx2_buffer_state state; | ||
237 | |||
238 | int bufnum; | ||
239 | }; | ||
240 | |||
224 | struct mx2_camera_dev { | 241 | struct mx2_camera_dev { |
225 | struct device *dev; | 242 | struct device *dev; |
226 | struct soc_camera_host soc_host; | 243 | struct soc_camera_host soc_host; |
@@ -252,16 +269,7 @@ struct mx2_camera_dev { | |||
252 | size_t discard_size; | 269 | size_t discard_size; |
253 | struct mx2_fmt_cfg *emma_prp; | 270 | struct mx2_fmt_cfg *emma_prp; |
254 | u32 frame_count; | 271 | u32 frame_count; |
255 | }; | 272 | struct vb2_alloc_ctx *alloc_ctx; |
256 | |||
257 | /* buffer for one video frame */ | ||
258 | struct mx2_buffer { | ||
259 | /* common v4l buffer stuff -- must be first */ | ||
260 | struct videobuf_buffer vb; | ||
261 | |||
262 | enum v4l2_mbus_pixelcode code; | ||
263 | |||
264 | int bufnum; | ||
265 | }; | 273 | }; |
266 | 274 | ||
267 | static struct mx2_fmt_cfg mx27_emma_prp_table[] = { | 275 | static struct mx2_fmt_cfg mx27_emma_prp_table[] = { |
@@ -398,7 +406,7 @@ static void mx2_camera_remove_device(struct soc_camera_device *icd) | |||
398 | static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, | 406 | static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, |
399 | int state) | 407 | int state) |
400 | { | 408 | { |
401 | struct videobuf_buffer *vb; | 409 | struct vb2_buffer *vb; |
402 | struct mx2_buffer *buf; | 410 | struct mx2_buffer *buf; |
403 | struct mx2_buffer **fb_active = fb == 1 ? &pcdev->fb1_active : | 411 | struct mx2_buffer **fb_active = fb == 1 ? &pcdev->fb1_active : |
404 | &pcdev->fb2_active; | 412 | &pcdev->fb2_active; |
@@ -411,25 +419,24 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, | |||
411 | goto out; | 419 | goto out; |
412 | 420 | ||
413 | vb = &(*fb_active)->vb; | 421 | vb = &(*fb_active)->vb; |
414 | dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 422 | dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__, |
415 | vb, vb->baddr, vb->bsize); | 423 | vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); |
416 | 424 | ||
417 | vb->state = state; | 425 | do_gettimeofday(&vb->v4l2_buf.timestamp); |
418 | do_gettimeofday(&vb->ts); | 426 | vb->v4l2_buf.sequence++; |
419 | vb->field_count++; | 427 | vb2_buffer_done(vb, VB2_BUF_STATE_DONE); |
420 | |||
421 | wake_up(&vb->done); | ||
422 | 428 | ||
423 | if (list_empty(&pcdev->capture)) { | 429 | if (list_empty(&pcdev->capture)) { |
424 | buf = NULL; | 430 | buf = NULL; |
425 | writel(0, pcdev->base_csi + fb_reg); | 431 | writel(0, pcdev->base_csi + fb_reg); |
426 | } else { | 432 | } else { |
427 | buf = list_entry(pcdev->capture.next, struct mx2_buffer, | 433 | buf = list_entry(pcdev->capture.next, struct mx2_buffer, |
428 | vb.queue); | 434 | queue); |
429 | vb = &buf->vb; | 435 | vb = &buf->vb; |
430 | list_del(&vb->queue); | 436 | list_del(&buf->queue); |
431 | vb->state = VIDEOBUF_ACTIVE; | 437 | buf->state = MX2_STATE_ACTIVE; |
432 | writel(videobuf_to_dma_contig(vb), pcdev->base_csi + fb_reg); | 438 | writel(vb2_dma_contig_plane_dma_addr(vb, 0), |
439 | pcdev->base_csi + fb_reg); | ||
433 | } | 440 | } |
434 | 441 | ||
435 | *fb_active = buf; | 442 | *fb_active = buf; |
@@ -444,9 +451,9 @@ static irqreturn_t mx25_camera_irq(int irq_csi, void *data) | |||
444 | u32 status = readl(pcdev->base_csi + CSISR); | 451 | u32 status = readl(pcdev->base_csi + CSISR); |
445 | 452 | ||
446 | if (status & CSISR_DMA_TSF_FB1_INT) | 453 | if (status & CSISR_DMA_TSF_FB1_INT) |
447 | mx25_camera_frame_done(pcdev, 1, VIDEOBUF_DONE); | 454 | mx25_camera_frame_done(pcdev, 1, MX2_STATE_DONE); |
448 | else if (status & CSISR_DMA_TSF_FB2_INT) | 455 | else if (status & CSISR_DMA_TSF_FB2_INT) |
449 | mx25_camera_frame_done(pcdev, 2, VIDEOBUF_DONE); | 456 | mx25_camera_frame_done(pcdev, 2, MX2_STATE_DONE); |
450 | 457 | ||
451 | /* FIXME: handle CSISR_RFF_OR_INT */ | 458 | /* FIXME: handle CSISR_RFF_OR_INT */ |
452 | 459 | ||
@@ -458,59 +465,50 @@ static irqreturn_t mx25_camera_irq(int irq_csi, void *data) | |||
458 | /* | 465 | /* |
459 | * Videobuf operations | 466 | * Videobuf operations |
460 | */ | 467 | */ |
461 | static int mx2_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, | 468 | static int mx2_videobuf_setup(struct vb2_queue *vq, |
462 | unsigned int *size) | 469 | const struct v4l2_format *fmt, |
470 | unsigned int *count, unsigned int *num_planes, | ||
471 | unsigned int sizes[], void *alloc_ctxs[]) | ||
463 | { | 472 | { |
464 | struct soc_camera_device *icd = vq->priv_data; | 473 | struct soc_camera_device *icd = soc_camera_from_vb2q(vq); |
474 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | ||
475 | struct mx2_camera_dev *pcdev = ici->priv; | ||
465 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | 476 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, |
466 | icd->current_fmt->host_fmt); | 477 | icd->current_fmt->host_fmt); |
467 | 478 | ||
468 | dev_dbg(icd->parent, "count=%d, size=%d\n", *count, *size); | 479 | dev_dbg(icd->parent, "count=%d, size=%d\n", *count, sizes[0]); |
480 | |||
481 | /* TODO: support for VIDIOC_CREATE_BUFS not ready */ | ||
482 | if (fmt != NULL) | ||
483 | return -ENOTTY; | ||
469 | 484 | ||
470 | if (bytes_per_line < 0) | 485 | if (bytes_per_line < 0) |
471 | return bytes_per_line; | 486 | return bytes_per_line; |
472 | 487 | ||
473 | *size = bytes_per_line * icd->user_height; | 488 | alloc_ctxs[0] = pcdev->alloc_ctx; |
489 | |||
490 | sizes[0] = bytes_per_line * icd->user_height; | ||
474 | 491 | ||
475 | if (0 == *count) | 492 | if (0 == *count) |
476 | *count = 32; | 493 | *count = 32; |
477 | if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024) | 494 | if (!*num_planes && |
478 | *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size; | 495 | sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024) |
496 | *count = (MAX_VIDEO_MEM * 1024 * 1024) / sizes[0]; | ||
479 | 497 | ||
480 | return 0; | 498 | *num_planes = 1; |
481 | } | ||
482 | |||
483 | static void free_buffer(struct videobuf_queue *vq, struct mx2_buffer *buf) | ||
484 | { | ||
485 | struct soc_camera_device *icd = vq->priv_data; | ||
486 | struct videobuf_buffer *vb = &buf->vb; | ||
487 | 499 | ||
488 | dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 500 | return 0; |
489 | vb, vb->baddr, vb->bsize); | ||
490 | |||
491 | /* | ||
492 | * This waits until this buffer is out of danger, i.e., until it is no | ||
493 | * longer in state VIDEOBUF_QUEUED or VIDEOBUF_ACTIVE | ||
494 | */ | ||
495 | videobuf_waiton(vq, vb, 0, 0); | ||
496 | |||
497 | videobuf_dma_contig_free(vq, vb); | ||
498 | dev_dbg(icd->parent, "%s freed\n", __func__); | ||
499 | |||
500 | vb->state = VIDEOBUF_NEEDS_INIT; | ||
501 | } | 501 | } |
502 | 502 | ||
503 | static int mx2_videobuf_prepare(struct videobuf_queue *vq, | 503 | static int mx2_videobuf_prepare(struct vb2_buffer *vb) |
504 | struct videobuf_buffer *vb, enum v4l2_field field) | ||
505 | { | 504 | { |
506 | struct soc_camera_device *icd = vq->priv_data; | 505 | struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); |
507 | struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); | ||
508 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | 506 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, |
509 | icd->current_fmt->host_fmt); | 507 | icd->current_fmt->host_fmt); |
510 | int ret = 0; | 508 | int ret = 0; |
511 | 509 | ||
512 | dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 510 | dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, |
513 | vb, vb->baddr, vb->bsize); | 511 | vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); |
514 | 512 | ||
515 | if (bytes_per_line < 0) | 513 | if (bytes_per_line < 0) |
516 | return bytes_per_line; | 514 | return bytes_per_line; |
@@ -520,78 +518,58 @@ static int mx2_videobuf_prepare(struct videobuf_queue *vq, | |||
520 | * This can be useful if you want to see if we actually fill | 518 | * This can be useful if you want to see if we actually fill |
521 | * the buffer with something | 519 | * the buffer with something |
522 | */ | 520 | */ |
523 | memset((void *)vb->baddr, 0xaa, vb->bsize); | 521 | memset((void *)vb2_plane_vaddr(vb, 0), |
522 | 0xaa, vb2_get_plane_payload(vb, 0)); | ||
524 | #endif | 523 | #endif |
525 | 524 | ||
526 | if (buf->code != icd->current_fmt->code || | 525 | vb2_set_plane_payload(vb, 0, bytes_per_line * icd->user_height); |
527 | vb->width != icd->user_width || | 526 | if (vb2_plane_vaddr(vb, 0) && |
528 | vb->height != icd->user_height || | 527 | vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) { |
529 | vb->field != field) { | ||
530 | buf->code = icd->current_fmt->code; | ||
531 | vb->width = icd->user_width; | ||
532 | vb->height = icd->user_height; | ||
533 | vb->field = field; | ||
534 | vb->state = VIDEOBUF_NEEDS_INIT; | ||
535 | } | ||
536 | |||
537 | vb->size = bytes_per_line * vb->height; | ||
538 | if (vb->baddr && vb->bsize < vb->size) { | ||
539 | ret = -EINVAL; | 528 | ret = -EINVAL; |
540 | goto out; | 529 | goto out; |
541 | } | 530 | } |
542 | 531 | ||
543 | if (vb->state == VIDEOBUF_NEEDS_INIT) { | ||
544 | ret = videobuf_iolock(vq, vb, NULL); | ||
545 | if (ret) | ||
546 | goto fail; | ||
547 | |||
548 | vb->state = VIDEOBUF_PREPARED; | ||
549 | } | ||
550 | |||
551 | return 0; | 532 | return 0; |
552 | 533 | ||
553 | fail: | ||
554 | free_buffer(vq, buf); | ||
555 | out: | 534 | out: |
556 | return ret; | 535 | return ret; |
557 | } | 536 | } |
558 | 537 | ||
559 | static void mx2_videobuf_queue(struct videobuf_queue *vq, | 538 | static void mx2_videobuf_queue(struct vb2_buffer *vb) |
560 | struct videobuf_buffer *vb) | ||
561 | { | 539 | { |
562 | struct soc_camera_device *icd = vq->priv_data; | 540 | struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); |
563 | struct soc_camera_host *ici = | 541 | struct soc_camera_host *ici = |
564 | to_soc_camera_host(icd->parent); | 542 | to_soc_camera_host(icd->parent); |
565 | struct mx2_camera_dev *pcdev = ici->priv; | 543 | struct mx2_camera_dev *pcdev = ici->priv; |
566 | struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); | 544 | struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); |
567 | unsigned long flags; | 545 | unsigned long flags; |
568 | 546 | ||
569 | dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 547 | dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, |
570 | vb, vb->baddr, vb->bsize); | 548 | vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); |
571 | 549 | ||
572 | spin_lock_irqsave(&pcdev->lock, flags); | 550 | spin_lock_irqsave(&pcdev->lock, flags); |
573 | 551 | ||
574 | vb->state = VIDEOBUF_QUEUED; | 552 | buf->state = MX2_STATE_QUEUED; |
575 | list_add_tail(&vb->queue, &pcdev->capture); | 553 | list_add_tail(&buf->queue, &pcdev->capture); |
576 | 554 | ||
577 | if (cpu_is_mx25()) { | 555 | if (cpu_is_mx25()) { |
578 | u32 csicr3, dma_inten = 0; | 556 | u32 csicr3, dma_inten = 0; |
579 | 557 | ||
580 | if (pcdev->fb1_active == NULL) { | 558 | if (pcdev->fb1_active == NULL) { |
581 | writel(videobuf_to_dma_contig(vb), | 559 | writel(vb2_dma_contig_plane_dma_addr(vb, 0), |
582 | pcdev->base_csi + CSIDMASA_FB1); | 560 | pcdev->base_csi + CSIDMASA_FB1); |
583 | pcdev->fb1_active = buf; | 561 | pcdev->fb1_active = buf; |
584 | dma_inten = CSICR1_FB1_DMA_INTEN; | 562 | dma_inten = CSICR1_FB1_DMA_INTEN; |
585 | } else if (pcdev->fb2_active == NULL) { | 563 | } else if (pcdev->fb2_active == NULL) { |
586 | writel(videobuf_to_dma_contig(vb), | 564 | writel(vb2_dma_contig_plane_dma_addr(vb, 0), |
587 | pcdev->base_csi + CSIDMASA_FB2); | 565 | pcdev->base_csi + CSIDMASA_FB2); |
588 | pcdev->fb2_active = buf; | 566 | pcdev->fb2_active = buf; |
589 | dma_inten = CSICR1_FB2_DMA_INTEN; | 567 | dma_inten = CSICR1_FB2_DMA_INTEN; |
590 | } | 568 | } |
591 | 569 | ||
592 | if (dma_inten) { | 570 | if (dma_inten) { |
593 | list_del(&vb->queue); | 571 | list_del(&buf->queue); |
594 | vb->state = VIDEOBUF_ACTIVE; | 572 | buf->state = MX2_STATE_ACTIVE; |
595 | 573 | ||
596 | csicr3 = readl(pcdev->base_csi + CSICR3); | 574 | csicr3 = readl(pcdev->base_csi + CSICR3); |
597 | 575 | ||
@@ -613,32 +591,28 @@ static void mx2_videobuf_queue(struct videobuf_queue *vq, | |||
613 | spin_unlock_irqrestore(&pcdev->lock, flags); | 591 | spin_unlock_irqrestore(&pcdev->lock, flags); |
614 | } | 592 | } |
615 | 593 | ||
616 | static void mx2_videobuf_release(struct videobuf_queue *vq, | 594 | static void mx2_videobuf_release(struct vb2_buffer *vb) |
617 | struct videobuf_buffer *vb) | ||
618 | { | 595 | { |
619 | struct soc_camera_device *icd = vq->priv_data; | 596 | struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); |
620 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 597 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
621 | struct mx2_camera_dev *pcdev = ici->priv; | 598 | struct mx2_camera_dev *pcdev = ici->priv; |
622 | struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); | 599 | struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); |
623 | unsigned long flags; | 600 | unsigned long flags; |
624 | 601 | ||
625 | #ifdef DEBUG | 602 | #ifdef DEBUG |
626 | dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 603 | dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, |
627 | vb, vb->baddr, vb->bsize); | 604 | vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); |
628 | 605 | ||
629 | switch (vb->state) { | 606 | switch (buf->state) { |
630 | case VIDEOBUF_ACTIVE: | 607 | case MX2_STATE_ACTIVE: |
631 | dev_info(icd->parent, "%s (active)\n", __func__); | 608 | dev_info(icd->parent, "%s (active)\n", __func__); |
632 | break; | 609 | break; |
633 | case VIDEOBUF_QUEUED: | 610 | case MX2_STATE_QUEUED: |
634 | dev_info(icd->parent, "%s (queued)\n", __func__); | 611 | dev_info(icd->parent, "%s (queued)\n", __func__); |
635 | break; | 612 | break; |
636 | case VIDEOBUF_PREPARED: | ||
637 | dev_info(icd->parent, "%s (prepared)\n", __func__); | ||
638 | break; | ||
639 | default: | 613 | default: |
640 | dev_info(icd->parent, "%s (unknown) %d\n", __func__, | 614 | dev_info(icd->parent, "%s (unknown) %d\n", __func__, |
641 | vb->state); | 615 | buf->state); |
642 | break; | 616 | break; |
643 | } | 617 | } |
644 | #endif | 618 | #endif |
@@ -652,11 +626,10 @@ static void mx2_videobuf_release(struct videobuf_queue *vq, | |||
652 | * state. This requires a specific handling for each of the these DMA | 626 | * state. This requires a specific handling for each of the these DMA |
653 | * types. | 627 | * types. |
654 | */ | 628 | */ |
629 | |||
655 | spin_lock_irqsave(&pcdev->lock, flags); | 630 | spin_lock_irqsave(&pcdev->lock, flags); |
656 | if (vb->state == VIDEOBUF_QUEUED) { | 631 | list_del_init(&buf->queue); |
657 | list_del(&vb->queue); | 632 | if (cpu_is_mx25() && buf->state == MX2_STATE_ACTIVE) { |
658 | vb->state = VIDEOBUF_ERROR; | ||
659 | } else if (cpu_is_mx25() && vb->state == VIDEOBUF_ACTIVE) { | ||
660 | if (pcdev->fb1_active == buf) { | 633 | if (pcdev->fb1_active == buf) { |
661 | pcdev->csicr1 &= ~CSICR1_FB1_DMA_INTEN; | 634 | pcdev->csicr1 &= ~CSICR1_FB1_DMA_INTEN; |
662 | writel(0, pcdev->base_csi + CSIDMASA_FB1); | 635 | writel(0, pcdev->base_csi + CSIDMASA_FB1); |
@@ -667,30 +640,28 @@ static void mx2_videobuf_release(struct videobuf_queue *vq, | |||
667 | pcdev->fb2_active = NULL; | 640 | pcdev->fb2_active = NULL; |
668 | } | 641 | } |
669 | writel(pcdev->csicr1, pcdev->base_csi + CSICR1); | 642 | writel(pcdev->csicr1, pcdev->base_csi + CSICR1); |
670 | vb->state = VIDEOBUF_ERROR; | ||
671 | } | 643 | } |
672 | spin_unlock_irqrestore(&pcdev->lock, flags); | 644 | spin_unlock_irqrestore(&pcdev->lock, flags); |
673 | |||
674 | free_buffer(vq, buf); | ||
675 | } | 645 | } |
676 | 646 | ||
677 | static struct videobuf_queue_ops mx2_videobuf_ops = { | 647 | static struct vb2_ops mx2_videobuf_ops = { |
678 | .buf_setup = mx2_videobuf_setup, | 648 | .queue_setup = mx2_videobuf_setup, |
679 | .buf_prepare = mx2_videobuf_prepare, | 649 | .buf_prepare = mx2_videobuf_prepare, |
680 | .buf_queue = mx2_videobuf_queue, | 650 | .buf_queue = mx2_videobuf_queue, |
681 | .buf_release = mx2_videobuf_release, | 651 | .buf_cleanup = mx2_videobuf_release, |
682 | }; | 652 | }; |
683 | 653 | ||
684 | static void mx2_camera_init_videobuf(struct videobuf_queue *q, | 654 | static int mx2_camera_init_videobuf(struct vb2_queue *q, |
685 | struct soc_camera_device *icd) | 655 | struct soc_camera_device *icd) |
686 | { | 656 | { |
687 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 657 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
688 | struct mx2_camera_dev *pcdev = ici->priv; | 658 | q->io_modes = VB2_MMAP | VB2_USERPTR; |
689 | 659 | q->drv_priv = icd; | |
690 | videobuf_queue_dma_contig_init(q, &mx2_videobuf_ops, pcdev->dev, | 660 | q->ops = &mx2_videobuf_ops; |
691 | &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, | 661 | q->mem_ops = &vb2_dma_contig_memops; |
692 | V4L2_FIELD_NONE, sizeof(struct mx2_buffer), | 662 | q->buf_struct_size = sizeof(struct mx2_buffer); |
693 | icd, &icd->video_lock); | 663 | |
664 | return vb2_queue_init(q); | ||
694 | } | 665 | } |
695 | 666 | ||
696 | #define MX2_BUS_FLAGS (V4L2_MBUS_MASTER | \ | 667 | #define MX2_BUS_FLAGS (V4L2_MBUS_MASTER | \ |
@@ -1122,25 +1093,11 @@ static int mx2_camera_querycap(struct soc_camera_host *ici, | |||
1122 | return 0; | 1093 | return 0; |
1123 | } | 1094 | } |
1124 | 1095 | ||
1125 | static int mx2_camera_reqbufs(struct soc_camera_device *icd, | ||
1126 | struct v4l2_requestbuffers *p) | ||
1127 | { | ||
1128 | int i; | ||
1129 | |||
1130 | for (i = 0; i < p->count; i++) { | ||
1131 | struct mx2_buffer *buf = container_of(icd->vb_vidq.bufs[i], | ||
1132 | struct mx2_buffer, vb); | ||
1133 | INIT_LIST_HEAD(&buf->vb.queue); | ||
1134 | } | ||
1135 | |||
1136 | return 0; | ||
1137 | } | ||
1138 | |||
1139 | static unsigned int mx2_camera_poll(struct file *file, poll_table *pt) | 1096 | static unsigned int mx2_camera_poll(struct file *file, poll_table *pt) |
1140 | { | 1097 | { |
1141 | struct soc_camera_device *icd = file->private_data; | 1098 | struct soc_camera_device *icd = file->private_data; |
1142 | 1099 | ||
1143 | return videobuf_poll_stream(file, &icd->vb_vidq, pt); | 1100 | return vb2_poll(&icd->vb2_vidq, file, pt); |
1144 | } | 1101 | } |
1145 | 1102 | ||
1146 | static struct soc_camera_host_ops mx2_soc_camera_host_ops = { | 1103 | static struct soc_camera_host_ops mx2_soc_camera_host_ops = { |
@@ -1151,31 +1108,30 @@ static struct soc_camera_host_ops mx2_soc_camera_host_ops = { | |||
1151 | .set_crop = mx2_camera_set_crop, | 1108 | .set_crop = mx2_camera_set_crop, |
1152 | .get_formats = mx2_camera_get_formats, | 1109 | .get_formats = mx2_camera_get_formats, |
1153 | .try_fmt = mx2_camera_try_fmt, | 1110 | .try_fmt = mx2_camera_try_fmt, |
1154 | .init_videobuf = mx2_camera_init_videobuf, | 1111 | .init_videobuf2 = mx2_camera_init_videobuf, |
1155 | .reqbufs = mx2_camera_reqbufs, | ||
1156 | .poll = mx2_camera_poll, | 1112 | .poll = mx2_camera_poll, |
1157 | .querycap = mx2_camera_querycap, | 1113 | .querycap = mx2_camera_querycap, |
1158 | .set_bus_param = mx2_camera_set_bus_param, | 1114 | .set_bus_param = mx2_camera_set_bus_param, |
1159 | }; | 1115 | }; |
1160 | 1116 | ||
1161 | static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, | 1117 | static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, |
1162 | int bufnum, int state) | 1118 | int bufnum) |
1163 | { | 1119 | { |
1164 | u32 imgsize = pcdev->icd->user_height * pcdev->icd->user_width; | 1120 | u32 imgsize = pcdev->icd->user_height * pcdev->icd->user_width; |
1165 | struct mx2_fmt_cfg *prp = pcdev->emma_prp; | 1121 | struct mx2_fmt_cfg *prp = pcdev->emma_prp; |
1166 | struct mx2_buffer *buf; | 1122 | struct mx2_buffer *buf; |
1167 | struct videobuf_buffer *vb; | 1123 | struct vb2_buffer *vb; |
1168 | unsigned long phys; | 1124 | unsigned long phys; |
1169 | 1125 | ||
1170 | if (!list_empty(&pcdev->active_bufs)) { | 1126 | if (!list_empty(&pcdev->active_bufs)) { |
1171 | buf = list_entry(pcdev->active_bufs.next, | 1127 | buf = list_entry(pcdev->active_bufs.next, |
1172 | struct mx2_buffer, vb.queue); | 1128 | struct mx2_buffer, queue); |
1173 | 1129 | ||
1174 | BUG_ON(buf->bufnum != bufnum); | 1130 | BUG_ON(buf->bufnum != bufnum); |
1175 | 1131 | ||
1176 | vb = &buf->vb; | 1132 | vb = &buf->vb; |
1177 | #ifdef DEBUG | 1133 | #ifdef DEBUG |
1178 | phys = videobuf_to_dma_contig(vb); | 1134 | phys = vb2_dma_contig_plane_dma_addr(vb, 0); |
1179 | if (prp->cfg.channel == 1) { | 1135 | if (prp->cfg.channel == 1) { |
1180 | if (readl(pcdev->base_emma + PRP_DEST_RGB1_PTR + | 1136 | if (readl(pcdev->base_emma + PRP_DEST_RGB1_PTR + |
1181 | 4 * bufnum) != phys) { | 1137 | 4 * bufnum) != phys) { |
@@ -1194,16 +1150,15 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, | |||
1194 | } | 1150 | } |
1195 | } | 1151 | } |
1196 | #endif | 1152 | #endif |
1197 | dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, | 1153 | dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__, vb, |
1198 | vb->baddr, vb->bsize); | 1154 | vb2_plane_vaddr(vb, 0), |
1155 | vb2_get_plane_payload(vb, 0)); | ||
1199 | 1156 | ||
1200 | list_del(&vb->queue); | 1157 | list_del_init(&buf->queue); |
1201 | vb->state = state; | 1158 | do_gettimeofday(&vb->v4l2_buf.timestamp); |
1202 | do_gettimeofday(&vb->ts); | ||
1203 | vb->field_count = pcdev->frame_count * 2; | ||
1204 | pcdev->frame_count++; | 1159 | pcdev->frame_count++; |
1205 | 1160 | vb->v4l2_buf.sequence = pcdev->frame_count; | |
1206 | wake_up(&vb->done); | 1161 | vb2_buffer_done(vb, VB2_BUF_STATE_DONE); |
1207 | } | 1162 | } |
1208 | 1163 | ||
1209 | if (list_empty(&pcdev->capture)) { | 1164 | if (list_empty(&pcdev->capture)) { |
@@ -1227,16 +1182,16 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, | |||
1227 | } | 1182 | } |
1228 | 1183 | ||
1229 | buf = list_entry(pcdev->capture.next, | 1184 | buf = list_entry(pcdev->capture.next, |
1230 | struct mx2_buffer, vb.queue); | 1185 | struct mx2_buffer, queue); |
1231 | 1186 | ||
1232 | buf->bufnum = !bufnum; | 1187 | buf->bufnum = !bufnum; |
1233 | 1188 | ||
1234 | list_move_tail(pcdev->capture.next, &pcdev->active_bufs); | 1189 | list_move_tail(pcdev->capture.next, &pcdev->active_bufs); |
1235 | 1190 | ||
1236 | vb = &buf->vb; | 1191 | vb = &buf->vb; |
1237 | vb->state = VIDEOBUF_ACTIVE; | 1192 | buf->state = MX2_STATE_ACTIVE; |
1238 | 1193 | ||
1239 | phys = videobuf_to_dma_contig(vb); | 1194 | phys = vb2_dma_contig_plane_dma_addr(vb, 0); |
1240 | if (prp->cfg.channel == 1) { | 1195 | if (prp->cfg.channel == 1) { |
1241 | writel(phys, pcdev->base_emma + PRP_DEST_RGB1_PTR + 4 * bufnum); | 1196 | writel(phys, pcdev->base_emma + PRP_DEST_RGB1_PTR + 4 * bufnum); |
1242 | } else { | 1197 | } else { |
@@ -1280,14 +1235,14 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) | |||
1280 | * to first | 1235 | * to first |
1281 | */ | 1236 | */ |
1282 | buf = list_entry(pcdev->active_bufs.next, | 1237 | buf = list_entry(pcdev->active_bufs.next, |
1283 | struct mx2_buffer, vb.queue); | 1238 | struct mx2_buffer, queue); |
1284 | mx27_camera_frame_done_emma(pcdev, buf->bufnum, VIDEOBUF_DONE); | 1239 | mx27_camera_frame_done_emma(pcdev, buf->bufnum); |
1285 | status &= ~(1 << (6 - buf->bufnum)); /* mark processed */ | 1240 | status &= ~(1 << (6 - buf->bufnum)); /* mark processed */ |
1286 | } | 1241 | } |
1287 | if ((status & (1 << 6)) || (status & (1 << 4))) | 1242 | if ((status & (1 << 6)) || (status & (1 << 4))) |
1288 | mx27_camera_frame_done_emma(pcdev, 0, VIDEOBUF_DONE); | 1243 | mx27_camera_frame_done_emma(pcdev, 0); |
1289 | if ((status & (1 << 5)) || (status & (1 << 3))) | 1244 | if ((status & (1 << 5)) || (status & (1 << 3))) |
1290 | mx27_camera_frame_done_emma(pcdev, 1, VIDEOBUF_DONE); | 1245 | mx27_camera_frame_done_emma(pcdev, 1); |
1291 | 1246 | ||
1292 | writel(status, pcdev->base_emma + PRP_INTRSTATUS); | 1247 | writel(status, pcdev->base_emma + PRP_INTRSTATUS); |
1293 | 1248 | ||
@@ -1449,6 +1404,12 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev) | |||
1449 | pcdev->soc_host.priv = pcdev; | 1404 | pcdev->soc_host.priv = pcdev; |
1450 | pcdev->soc_host.v4l2_dev.dev = &pdev->dev; | 1405 | pcdev->soc_host.v4l2_dev.dev = &pdev->dev; |
1451 | pcdev->soc_host.nr = pdev->id; | 1406 | pcdev->soc_host.nr = pdev->id; |
1407 | |||
1408 | pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); | ||
1409 | if (IS_ERR(pcdev->alloc_ctx)) { | ||
1410 | err = PTR_ERR(pcdev->alloc_ctx); | ||
1411 | goto eallocctx; | ||
1412 | } | ||
1452 | err = soc_camera_host_register(&pcdev->soc_host); | 1413 | err = soc_camera_host_register(&pcdev->soc_host); |
1453 | if (err) | 1414 | if (err) |
1454 | goto exit_free_emma; | 1415 | goto exit_free_emma; |
@@ -1459,6 +1420,8 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev) | |||
1459 | return 0; | 1420 | return 0; |
1460 | 1421 | ||
1461 | exit_free_emma: | 1422 | exit_free_emma: |
1423 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); | ||
1424 | eallocctx: | ||
1462 | if (cpu_is_mx27()) { | 1425 | if (cpu_is_mx27()) { |
1463 | free_irq(pcdev->irq_emma, pcdev); | 1426 | free_irq(pcdev->irq_emma, pcdev); |
1464 | clk_disable(pcdev->clk_emma); | 1427 | clk_disable(pcdev->clk_emma); |
@@ -1496,6 +1459,8 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev) | |||
1496 | 1459 | ||
1497 | soc_camera_host_unregister(&pcdev->soc_host); | 1460 | soc_camera_host_unregister(&pcdev->soc_host); |
1498 | 1461 | ||
1462 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); | ||
1463 | |||
1499 | iounmap(pcdev->base_csi); | 1464 | iounmap(pcdev->base_csi); |
1500 | 1465 | ||
1501 | if (cpu_is_mx27()) { | 1466 | if (cpu_is_mx27()) { |